summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/Kconfig4
-rw-r--r--drivers/acpi/acpi_configfs.c54
-rw-r--r--drivers/acpi/bus.c12
-rw-r--r--drivers/acpi/glue.c51
-rw-r--r--drivers/acpi/numa/Kconfig2
-rw-r--r--drivers/acpi/numa/srat.c2
-rw-r--r--drivers/acpi/pmic/intel_pmic_xpower.c47
-rw-r--r--drivers/base/base.h3
-rw-r--r--drivers/base/core.c35
-rw-r--r--drivers/base/swnode.c61
-rw-r--r--include/linux/acpi.h12
-rw-r--r--include/linux/property.h2
12 files changed, 149 insertions, 136 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8f9940f40baa..1da360c51d66 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -280,9 +280,9 @@ config ACPI_CPPC_LIB
config ACPI_PROCESSOR
tristate "Processor"
- depends on X86 || IA64 || ARM64
+ depends on X86 || IA64 || ARM64 || LOONGARCH
select ACPI_PROCESSOR_IDLE
- select ACPI_CPU_FREQ_PSS if X86 || IA64
+ select ACPI_CPU_FREQ_PSS if X86 || IA64 || LOONGARCH
default y
help
This driver adds support for the ACPI Processor package. It is required
diff --git a/drivers/acpi/acpi_configfs.c b/drivers/acpi/acpi_configfs.c
index 76b83b181356..c970792b11a4 100644
--- a/drivers/acpi/acpi_configfs.c
+++ b/drivers/acpi/acpi_configfs.c
@@ -70,7 +70,7 @@ static inline struct acpi_table_header *get_header(struct config_item *cfg)
if (!table->header)
pr_err("table not loaded\n");
- return table->header;
+ return table->header ?: ERR_PTR(-EINVAL);
}
static ssize_t acpi_table_aml_read(struct config_item *cfg,
@@ -78,8 +78,8 @@ static ssize_t acpi_table_aml_read(struct config_item *cfg,
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
if (data)
memcpy(data, h, h->length);
@@ -100,60 +100,60 @@ static ssize_t acpi_table_signature_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->signature);
+ return sysfs_emit(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->signature);
}
static ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%d\n", h->length);
+ return sysfs_emit(str, "%d\n", h->length);
}
static ssize_t acpi_table_revision_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%d\n", h->revision);
+ return sysfs_emit(str, "%d\n", h->revision);
}
static ssize_t acpi_table_oem_id_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%.*s\n", ACPI_OEM_ID_SIZE, h->oem_id);
+ return sysfs_emit(str, "%.*s\n", ACPI_OEM_ID_SIZE, h->oem_id);
}
static ssize_t acpi_table_oem_table_id_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%.*s\n", ACPI_OEM_TABLE_ID_SIZE, h->oem_table_id);
+ return sysfs_emit(str, "%.*s\n", ACPI_OEM_TABLE_ID_SIZE, h->oem_table_id);
}
static ssize_t acpi_table_oem_revision_show(struct config_item *cfg, char *str)
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%d\n", h->oem_revision);
+ return sysfs_emit(str, "%d\n", h->oem_revision);
}
static ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg,
@@ -161,10 +161,10 @@ static ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg,
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->asl_compiler_id);
+ return sysfs_emit(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->asl_compiler_id);
}
static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
@@ -172,10 +172,10 @@ static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
{
struct acpi_table_header *h = get_header(cfg);
- if (!h)
- return -EINVAL;
+ if (IS_ERR(h))
+ return PTR_ERR(h);
- return sprintf(str, "%d\n", h->asl_compiler_revision);
+ return sysfs_emit(str, "%d\n", h->asl_compiler_revision);
}
CONFIGFS_ATTR_RO(acpi_table_, signature);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index f854bcb8d010..3abb4373d11b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -498,24 +498,24 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
acpi_evaluate_ost(handle, type, ost_code, NULL);
}
-static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_notify_device(acpi_handle handle, u32 event, void *data)
{
struct acpi_device *device = data;
device->driver->ops.notify(device, event);
}
-static void acpi_device_notify_fixed(void *data)
+static void acpi_notify_device_fixed(void *data)
{
struct acpi_device *device = data;
/* Fixed hardware devices have no handles */
- acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
+ acpi_notify_device(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
}
static u32 acpi_device_fixed_event(void *data)
{
- acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data);
+ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_notify_device_fixed, data);
return ACPI_INTERRUPT_HANDLED;
}
@@ -536,7 +536,7 @@ static int acpi_device_install_notify_handler(struct acpi_device *device)
else
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
- acpi_device_notify,
+ acpi_notify_device,
device);
if (ACPI_FAILURE(status))
@@ -554,7 +554,7 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
acpi_device_fixed_event);
else
acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_device_notify);
+ acpi_notify_device);
}
/* Handle events targeting \_SB device (at present only graceful shutdown) */
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fce3f3bba714..7a33a6d985f8 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -285,29 +285,27 @@ int acpi_unbind_one(struct device *dev)
}
EXPORT_SYMBOL_GPL(acpi_unbind_one);
-static int acpi_device_notify(struct device *dev)
+void acpi_device_notify(struct device *dev)
{
struct acpi_bus_type *type = acpi_get_bus_type(dev);
struct acpi_device *adev;
int ret;
ret = acpi_bind_one(dev, NULL);
- if (ret && type) {
- struct acpi_device *adev;
+ if (ret) {
+ if (!type)
+ goto err;
adev = type->find_companion(dev);
if (!adev) {
- pr_debug("Unable to get handle for %s\n", dev_name(dev));
- ret = -ENODEV;
- goto out;
+ dev_dbg(dev, "ACPI companion not found\n");
+ goto err;
}
ret = acpi_bind_one(dev, adev);
if (ret)
- goto out;
+ goto err;
}
adev = ACPI_COMPANION(dev);
- if (!adev)
- goto out;
if (dev_is_platform(dev))
acpi_configure_pmsi_domain(dev);
@@ -317,27 +315,22 @@ static int acpi_device_notify(struct device *dev)
else if (adev->handler && adev->handler->bind)
adev->handler->bind(dev);
- out:
- if (!ret) {
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_handle_debug(ACPI_HANDLE(dev), "Bound to device %s\n",
+ dev_name(dev));
- acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer);
- pr_debug("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
- kfree(buffer.pointer);
- } else {
- pr_debug("Device %s -> No ACPI support\n", dev_name(dev));
- }
+ return;
- return ret;
+err:
+ dev_dbg(dev, "No ACPI support\n");
}
-static int acpi_device_notify_remove(struct device *dev)
+void acpi_device_notify_remove(struct device *dev)
{
struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_bus_type *type;
if (!adev)
- return 0;
+ return;
type = acpi_get_bus_type(dev);
if (type && type->cleanup)
@@ -346,20 +339,4 @@ static int acpi_device_notify_remove(struct device *dev)
adev->handler->unbind(dev);
acpi_unbind_one(dev);
- return 0;
-}
-
-int acpi_platform_notify(struct device *dev, enum kobject_action action)
-{
- switch (action) {
- case KOBJ_ADD:
- acpi_device_notify(dev);
- break;
- case KOBJ_REMOVE:
- acpi_device_notify_remove(dev);
- break;
- default:
- break;
- }
- return 0;
}
diff --git a/drivers/acpi/numa/Kconfig b/drivers/acpi/numa/Kconfig
index fcf2e556d69d..39b1f34c21df 100644
--- a/drivers/acpi/numa/Kconfig
+++ b/drivers/acpi/numa/Kconfig
@@ -2,7 +2,7 @@
config ACPI_NUMA
bool "NUMA support"
depends on NUMA
- depends on (X86 || IA64 || ARM64)
+ depends on (X86 || IA64 || ARM64 || LOONGARCH)
default y if IA64 || ARM64
config ACPI_HMAT
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 6021a1013442..b8795fc49097 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -206,7 +206,7 @@ int __init srat_disabled(void)
return acpi_numa < 0;
}
-#if defined(CONFIG_X86) || defined(CONFIG_ARM64)
+#if defined(CONFIG_X86) || defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
/*
* Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
* I/O localities since SRAT does not list them. I/O localities are
diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c
index a091d5a8392c..cbe08e600fa3 100644
--- a/drivers/acpi/pmic/intel_pmic_xpower.c
+++ b/drivers/acpi/pmic/intel_pmic_xpower.c
@@ -178,15 +178,17 @@ static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg,
{
int data, ret;
- /* GPIO1 LDO regulator needs special handling */
- if (reg == XPOWER_GPI1_CTRL)
- return regmap_update_bits(regmap, reg, GPI1_LDO_MASK,
- on ? GPI1_LDO_ON : GPI1_LDO_OFF);
-
ret = iosf_mbi_block_punit_i2c_access();
if (ret)
return ret;
+ /* GPIO1 LDO regulator needs special handling */
+ if (reg == XPOWER_GPI1_CTRL) {
+ ret = regmap_update_bits(regmap, reg, GPI1_LDO_MASK,
+ on ? GPI1_LDO_ON : GPI1_LDO_OFF);
+ goto out;
+ }
+
if (regmap_read(regmap, reg, &data)) {
ret = -EIO;
goto out;
@@ -234,6 +236,11 @@ static int intel_xpower_pmic_get_raw_temp(struct regmap *regmap, int reg)
return ret;
if (adc_ts_pin_ctrl & AXP288_ADC_TS_CURRENT_ON_OFF_MASK) {
+ /*
+ * AXP288_ADC_TS_PIN_CTRL reads are cached by the regmap, so
+ * this does to a single I2C-transfer, and thus there is no
+ * need to explicitly call iosf_mbi_block_punit_i2c_access().
+ */
ret = regmap_update_bits(regmap, AXP288_ADC_TS_PIN_CTRL,
AXP288_ADC_TS_CURRENT_ON_OFF_MASK,
AXP288_ADC_TS_CURRENT_ON_ONDEMAND);
@@ -244,6 +251,10 @@ static int intel_xpower_pmic_get_raw_temp(struct regmap *regmap, int reg)
usleep_range(6000, 10000);
}
+ ret = iosf_mbi_block_punit_i2c_access();
+ if (ret)
+ return ret;
+
ret = regmap_bulk_read(regmap, AXP288_GP_ADC_H, buf, 2);
if (ret == 0)
ret = (buf[0] << 4) + ((buf[1] >> 4) & 0x0f);
@@ -254,6 +265,31 @@ static int intel_xpower_pmic_get_raw_temp(struct regmap *regmap, int reg)
AXP288_ADC_TS_CURRENT_ON);
}
+ iosf_mbi_unblock_punit_i2c_access();
+
+ return ret;
+}
+
+static int intel_xpower_exec_mipi_pmic_seq_element(struct regmap *regmap,
+ u16 i2c_address, u32 reg_address,
+ u32 value, u32 mask)
+{
+ int ret;
+
+ if (i2c_address != 0x34) {
+ pr_err("%s: Unexpected i2c-addr: 0x%02x (reg-addr 0x%x value 0x%x mask 0x%x)\n",
+ __func__, i2c_address, reg_address, value, mask);
+ return -ENXIO;
+ }
+
+ ret = iosf_mbi_block_punit_i2c_access();
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(regmap, reg_address, mask, value);
+
+ iosf_mbi_unblock_punit_i2c_access();
+
return ret;
}
@@ -261,6 +297,7 @@ static struct intel_pmic_opregion_data intel_xpower_pmic_opregion_data = {
.get_power = intel_xpower_pmic_get_power,
.update_power = intel_xpower_pmic_update_power,
.get_raw_temp = intel_xpower_pmic_get_raw_temp,
+ .exec_mipi_pmic_seq_element = intel_xpower_exec_mipi_pmic_seq_element,
.power_table = power_table,
.power_table_count = ARRAY_SIZE(power_table),
.thermal_table = thermal_table,
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 404db83ee5ec..2882af26392a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -202,3 +202,6 @@ int devtmpfs_delete_node(struct device *dev);
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
#endif
+
+void software_node_notify(struct device *dev);
+void software_node_notify_remove(struct device *dev);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6c0ef9d55a34..3a72241b87c6 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2002,24 +2002,24 @@ static inline int device_is_not_partition(struct device *dev)
}
#endif
-static int
-device_platform_notify(struct device *dev, enum kobject_action action)
+static void device_platform_notify(struct device *dev)
{
- int ret;
+ acpi_device_notify(dev);
- ret = acpi_platform_notify(dev, action);
- if (ret)
- return ret;
+ software_node_notify(dev);
- ret = software_node_notify(dev, action);
- if (ret)
- return ret;
-
- if (platform_notify && action == KOBJ_ADD)
+ if (platform_notify)
platform_notify(dev);
- else if (platform_notify_remove && action == KOBJ_REMOVE)
+}
+
+static void device_platform_notify_remove(struct device *dev)
+{
+ acpi_device_notify_remove(dev);
+
+ software_node_notify_remove(dev);
+
+ if (platform_notify_remove)
platform_notify_remove(dev);
- return 0;
}
/**
@@ -3292,9 +3292,7 @@ int device_add(struct device *dev)
}
/* notify platform of device entry */
- error = device_platform_notify(dev, KOBJ_ADD);
- if (error)
- goto platform_error;
+ device_platform_notify(dev);
error = device_create_file(dev, &dev_attr_uevent);
if (error)
@@ -3397,8 +3395,7 @@ done:
SymlinkError:
device_remove_file(dev, &dev_attr_uevent);
attrError:
- device_platform_notify(dev, KOBJ_REMOVE);
-platform_error:
+ device_platform_notify_remove(dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
glue_dir = get_glue_dir(dev);
kobject_del(&dev->kobj);
@@ -3543,7 +3540,7 @@ void device_del(struct device *dev)
bus_remove_device(dev);
device_pm_remove(dev);
driver_deferred_probe_del(dev);
- device_platform_notify(dev, KOBJ_REMOVE);
+ device_platform_notify_remove(dev);
device_remove_properties(dev);
device_links_purge(dev);
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index d1f1a8240120..7bd0f3cfb7eb 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -11,6 +11,8 @@
#include <linux/property.h>
#include <linux/slab.h>
+#include "base.h"
+
struct swnode {
struct kobject kobj;
struct fwnode_handle fwnode;
@@ -1053,7 +1055,7 @@ int device_add_software_node(struct device *dev, const struct software_node *nod
* balance.
*/
if (device_is_registered(dev))
- software_node_notify(dev, KOBJ_ADD);
+ software_node_notify(dev);
return 0;
}
@@ -1074,7 +1076,8 @@ void device_remove_software_node(struct device *dev)
return;
if (device_is_registered(dev))
- software_node_notify(dev, KOBJ_REMOVE);
+ software_node_notify_remove(dev);
+
set_secondary_fwnode(dev, NULL);
kobject_put(&swnode->kobj);
}
@@ -1117,44 +1120,44 @@ int device_create_managed_software_node(struct device *dev,
}
EXPORT_SYMBOL_GPL(device_create_managed_software_node);
-int software_node_notify(struct device *dev, unsigned long action)
+void software_node_notify(struct device *dev)
{
struct swnode *swnode;
int ret;
swnode = dev_to_swnode(dev);
if (!swnode)
- return 0;
+ return;
- switch (action) {
- case KOBJ_ADD:
- ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
- if (ret)
- break;
+ ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
+ if (ret)
+ return;
- ret = sysfs_create_link(&swnode->kobj, &dev->kobj,
- dev_name(dev));
- if (ret) {
- sysfs_remove_link(&dev->kobj, "software_node");
- break;
- }
- kobject_get(&swnode->kobj);
- break;
- case KOBJ_REMOVE:
- sysfs_remove_link(&swnode->kobj, dev_name(dev));
+ ret = sysfs_create_link(&swnode->kobj, &dev->kobj, dev_name(dev));
+ if (ret) {
sysfs_remove_link(&dev->kobj, "software_node");
- kobject_put(&swnode->kobj);
-
- if (swnode->managed) {
- set_secondary_fwnode(dev, NULL);
- kobject_put(&swnode->kobj);
- }
- break;
- default:
- break;
+ return;
}
- return 0;
+ kobject_get(&swnode->kobj);
+}
+
+void software_node_notify_remove(struct device *dev)
+{
+ struct swnode *swnode;
+
+ swnode = dev_to_swnode(dev);
+ if (!swnode)
+ return;
+
+ sysfs_remove_link(&swnode->kobj, dev_name(dev));
+ sysfs_remove_link(&dev->kobj, "software_node");
+ kobject_put(&swnode->kobj);
+
+ if (swnode->managed) {
+ set_secondary_fwnode(dev, NULL);
+ kobject_put(&swnode->kobj);
+ }
}
static int __init software_node_init(void)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 72e4f7fd268c..974d497a897d 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -249,7 +249,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
/* the following numa functions are architecture-dependent */
void acpi_numa_slit_init (struct acpi_table_slit *slit);
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_LOONGARCH)
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
#else
static inline void
@@ -1380,13 +1380,11 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
#endif
#ifdef CONFIG_ACPI
-extern int acpi_platform_notify(struct device *dev, enum kobject_action action);
+extern void acpi_device_notify(struct device *dev);
+extern void acpi_device_notify_remove(struct device *dev);
#else
-static inline int
-acpi_platform_notify(struct device *dev, enum kobject_action action)
-{
- return 0;
-}
+static inline void acpi_device_notify(struct device *dev) { }
+static inline void acpi_device_notify_remove(struct device *dev) { }
#endif
#endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/property.h b/include/linux/property.h
index 073e680c35e2..357513a977e5 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -484,8 +484,6 @@ void software_node_unregister_node_group(const struct software_node **node_group
int software_node_register(const struct software_node *node);
void software_node_unregister(const struct software_node *node);
-int software_node_notify(struct device *dev, unsigned long action);
-
struct fwnode_handle *
fwnode_create_software_node(const struct property_entry *properties,
const struct fwnode_handle *parent);