mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
Merge branches 'acpi-bus', 'acpi-scan' and 'acpi-tables'
* acpi-bus: ACPI: Remove redundant clearing of context->ret.pointer from acpi_run_osc() * acpi-scan: ACPI: scan: Simplify acpi_table_events_fn() ACPI: scan: Fix race related to dropping dependencies ACPI: scan: Reorganize acpi_device_add() ACPI: scan: Fix device object rescan in acpi_scan_clear_dep() ACPI: scan: Make acpi_walk_dep_device_list() ACPI: scan: Rearrange acpi_dev_get_first_consumer_dev_cb() ACPI: scan: Define acpi_bus_put_acpi_device() as static inline ACPI: scan: initialize local variable to avoid garbage being returned ACPI: scan: Add function to fetch dependent of ACPI device ACPI: scan: Extend acpi_walk_dep_device_list() ACPI: scan: Rearrange dep_unmet initialization * acpi-tables: ACPI: tables: Add custom DSDT file as makefile prerequisite ACPI: bgrt: Use sysfs_emit ACPI: bgrt: Fix CFI violation ACPI: tables: FPDT: Add missing acpi_put_table() in acpi_init_fpdt() ACPI: tables: PPTT: Populate cache-id if provided by firmware
This commit is contained in:
commit
dfef7710d7
@ -8,6 +8,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
|
||||
#
|
||||
# ACPI Boot-Time Table Parsing
|
||||
#
|
||||
ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y)
|
||||
tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ;
|
||||
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_ACPI) += tables.o
|
||||
obj-$(CONFIG_X86) += blacklist.o
|
||||
|
||||
|
@ -240,8 +240,10 @@ static int __init acpi_init_fpdt(void)
|
||||
return 0;
|
||||
|
||||
fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
|
||||
if (!fpdt_kobj)
|
||||
if (!fpdt_kobj) {
|
||||
acpi_put_table(header);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
while (offset < header->length) {
|
||||
subtable = (void *)header + offset;
|
||||
|
@ -15,40 +15,19 @@
|
||||
static void *bgrt_image;
|
||||
static struct kobject *bgrt_kobj;
|
||||
|
||||
static ssize_t version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version);
|
||||
}
|
||||
static DEVICE_ATTR_RO(version);
|
||||
#define BGRT_SHOW(_name, _member) \
|
||||
static ssize_t _name##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return sysfs_emit(buf, "%d\n", bgrt_tab._member); \
|
||||
} \
|
||||
struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
|
||||
|
||||
static ssize_t status_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status);
|
||||
}
|
||||
static DEVICE_ATTR_RO(status);
|
||||
|
||||
static ssize_t type_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type);
|
||||
}
|
||||
static DEVICE_ATTR_RO(type);
|
||||
|
||||
static ssize_t xoffset_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x);
|
||||
}
|
||||
static DEVICE_ATTR_RO(xoffset);
|
||||
|
||||
static ssize_t yoffset_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y);
|
||||
}
|
||||
static DEVICE_ATTR_RO(yoffset);
|
||||
BGRT_SHOW(version, version);
|
||||
BGRT_SHOW(status, status);
|
||||
BGRT_SHOW(type, image_type);
|
||||
BGRT_SHOW(xoffset, image_offset_x);
|
||||
BGRT_SHOW(yoffset, image_offset_y);
|
||||
|
||||
static ssize_t image_read(struct file *file, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf, loff_t off, size_t count)
|
||||
@ -60,11 +39,11 @@ static ssize_t image_read(struct file *file, struct kobject *kobj,
|
||||
static BIN_ATTR_RO(image, 0); /* size gets filled in later */
|
||||
|
||||
static struct attribute *bgrt_attributes[] = {
|
||||
&dev_attr_version.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_type.attr,
|
||||
&dev_attr_xoffset.attr,
|
||||
&dev_attr_yoffset.attr,
|
||||
&bgrt_attr_version.attr,
|
||||
&bgrt_attr_status.attr,
|
||||
&bgrt_attr_type.attr,
|
||||
&bgrt_attr_xoffset.attr,
|
||||
&bgrt_attr_yoffset.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -262,8 +262,6 @@ out_success:
|
||||
|
||||
out_kfree:
|
||||
kfree(output.pointer);
|
||||
if (status != AE_OK)
|
||||
context->ret.pointer = NULL;
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_run_osc);
|
||||
@ -1195,7 +1193,8 @@ void __init acpi_subsystem_init(void)
|
||||
|
||||
static acpi_status acpi_bus_table_handler(u32 event, void *table, void *context)
|
||||
{
|
||||
acpi_scan_table_handler(event, table, context);
|
||||
if (event == ACPI_TABLE_EVENT_LOAD)
|
||||
acpi_scan_table_notify();
|
||||
|
||||
return acpi_sysfs_table_handler(event, table, context);
|
||||
}
|
||||
|
@ -1627,7 +1627,7 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||
|
||||
/* Reprobe devices depending on the EC */
|
||||
acpi_walk_dep_device_list(ec->handle);
|
||||
acpi_dev_clear_dependencies(device);
|
||||
|
||||
acpi_handle_debug(ec->handle, "enumerated.\n");
|
||||
return 0;
|
||||
|
@ -88,7 +88,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src);
|
||||
bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
|
||||
|
||||
acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context);
|
||||
void acpi_scan_table_handler(u32 event, void *table, void *context);
|
||||
void acpi_scan_table_notify(void);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Device Node Initialization / Removal
|
||||
|
@ -117,7 +117,7 @@ static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
|
||||
/* Re-enumerate devices depending on PMIC */
|
||||
acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent));
|
||||
acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -347,6 +347,7 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
|
||||
* @this_leaf: Kernel cache info structure being updated
|
||||
* @found_cache: The PPTT node describing this cache instance
|
||||
* @cpu_node: A unique reference to describe this cache instance
|
||||
* @revision: The revision of the PPTT table
|
||||
*
|
||||
* The ACPI spec implies that the fields in the cache structures are used to
|
||||
* extend and correct the information probed from the hardware. Lets only
|
||||
@ -356,8 +357,11 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
|
||||
*/
|
||||
static void update_cache_properties(struct cacheinfo *this_leaf,
|
||||
struct acpi_pptt_cache *found_cache,
|
||||
struct acpi_pptt_processor *cpu_node)
|
||||
struct acpi_pptt_processor *cpu_node,
|
||||
u8 revision)
|
||||
{
|
||||
struct acpi_pptt_cache_v1* found_cache_v1;
|
||||
|
||||
this_leaf->fw_token = cpu_node;
|
||||
if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID)
|
||||
this_leaf->size = found_cache->size;
|
||||
@ -405,6 +409,13 @@ static void update_cache_properties(struct cacheinfo *this_leaf,
|
||||
if (this_leaf->type == CACHE_TYPE_NOCACHE &&
|
||||
found_cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)
|
||||
this_leaf->type = CACHE_TYPE_UNIFIED;
|
||||
|
||||
if (revision >= 3 && (found_cache->flags & ACPI_PPTT_CACHE_ID_VALID)) {
|
||||
found_cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1,
|
||||
found_cache, sizeof(struct acpi_pptt_cache));
|
||||
this_leaf->id = found_cache_v1->cache_id;
|
||||
this_leaf->attributes |= CACHE_ID;
|
||||
}
|
||||
}
|
||||
|
||||
static void cache_setup_acpi_cpu(struct acpi_table_header *table,
|
||||
@ -425,9 +436,8 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table,
|
||||
&cpu_node);
|
||||
pr_debug("found = %p %p\n", found_cache, cpu_node);
|
||||
if (found_cache)
|
||||
update_cache_properties(this_leaf,
|
||||
found_cache,
|
||||
cpu_node);
|
||||
update_cache_properties(this_leaf, found_cache,
|
||||
cpu_node, table->revision);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
@ -47,12 +47,6 @@ static DEFINE_MUTEX(acpi_hp_context_lock);
|
||||
*/
|
||||
static u64 spcr_uart_addr;
|
||||
|
||||
struct acpi_dep_data {
|
||||
struct list_head node;
|
||||
acpi_handle supplier;
|
||||
acpi_handle consumer;
|
||||
};
|
||||
|
||||
void acpi_scan_lock_acquire(void)
|
||||
{
|
||||
mutex_lock(&acpi_scan_lock);
|
||||
@ -612,11 +606,6 @@ struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
|
||||
return handle_to_device(handle, get_acpi_device);
|
||||
}
|
||||
|
||||
void acpi_bus_put_acpi_device(struct acpi_device *adev)
|
||||
{
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
|
||||
static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
|
||||
{
|
||||
struct acpi_device_bus_id *acpi_device_bus_id;
|
||||
@ -644,24 +633,29 @@ static int acpi_device_set_name(struct acpi_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_device_add(struct acpi_device *device,
|
||||
void (*release)(struct device *))
|
||||
static int acpi_tie_acpi_dev(struct acpi_device *adev)
|
||||
{
|
||||
acpi_handle handle = adev->handle;
|
||||
acpi_status status;
|
||||
|
||||
if (!handle)
|
||||
return 0;
|
||||
|
||||
status = acpi_attach_data(handle, acpi_scan_drop_device, adev);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_err(handle, "Unable to attach device data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __acpi_device_add(struct acpi_device *device,
|
||||
void (*release)(struct device *))
|
||||
{
|
||||
struct acpi_device_bus_id *acpi_device_bus_id;
|
||||
int result;
|
||||
|
||||
if (device->handle) {
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_attach_data(device->handle, acpi_scan_drop_device,
|
||||
device);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_err(device->handle,
|
||||
"Unable to attach device data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Linkage
|
||||
* -------
|
||||
@ -750,6 +744,17 @@ err_unlock:
|
||||
return result;
|
||||
}
|
||||
|
||||
int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = acpi_tie_acpi_dev(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return __acpi_device_add(adev, release);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Device Enumeration
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -1671,8 +1676,16 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
||||
device_initialize(&device->dev);
|
||||
dev_set_uevent_suppress(&device->dev, true);
|
||||
acpi_init_coherency(device);
|
||||
/* Assume there are unmet deps to start with. */
|
||||
device->dep_unmet = 1;
|
||||
}
|
||||
|
||||
static void acpi_scan_dep_init(struct acpi_device *adev)
|
||||
{
|
||||
struct acpi_dep_data *dep;
|
||||
|
||||
list_for_each_entry(dep, &acpi_dep_list, node) {
|
||||
if (dep->consumer == adev->handle)
|
||||
adev->dep_unmet++;
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_device_add_finalize(struct acpi_device *device)
|
||||
@ -1688,9 +1701,10 @@ static void acpi_scan_init_status(struct acpi_device *adev)
|
||||
}
|
||||
|
||||
static int acpi_add_single_object(struct acpi_device **child,
|
||||
acpi_handle handle, int type)
|
||||
acpi_handle handle, int type, bool dep_init)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
bool release_dep_lock = false;
|
||||
int result;
|
||||
|
||||
device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
|
||||
@ -1703,13 +1717,32 @@ static int acpi_add_single_object(struct acpi_device **child,
|
||||
* acpi_bus_get_status() and use its quirk handling. Note that
|
||||
* this must be done before the get power-/wakeup_dev-flags calls.
|
||||
*/
|
||||
if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR)
|
||||
if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) {
|
||||
if (dep_init) {
|
||||
mutex_lock(&acpi_dep_list_lock);
|
||||
/*
|
||||
* Hold the lock until the acpi_tie_acpi_dev() call
|
||||
* below to prevent concurrent acpi_scan_clear_dep()
|
||||
* from deleting a dependency list entry without
|
||||
* updating dep_unmet for the device.
|
||||
*/
|
||||
release_dep_lock = true;
|
||||
acpi_scan_dep_init(device);
|
||||
}
|
||||
acpi_scan_init_status(device);
|
||||
}
|
||||
|
||||
acpi_bus_get_power_flags(device);
|
||||
acpi_bus_get_wakeup_device_flags(device);
|
||||
|
||||
result = acpi_device_add(device, acpi_device_release);
|
||||
result = acpi_tie_acpi_dev(device);
|
||||
|
||||
if (release_dep_lock)
|
||||
mutex_unlock(&acpi_dep_list_lock);
|
||||
|
||||
if (!result)
|
||||
result = __acpi_device_add(device, acpi_device_release);
|
||||
|
||||
if (result) {
|
||||
acpi_device_release(&device->dev);
|
||||
return result;
|
||||
@ -1886,22 +1919,6 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
|
||||
return count;
|
||||
}
|
||||
|
||||
static void acpi_scan_dep_init(struct acpi_device *adev)
|
||||
{
|
||||
struct acpi_dep_data *dep;
|
||||
|
||||
adev->dep_unmet = 0;
|
||||
|
||||
mutex_lock(&acpi_dep_list_lock);
|
||||
|
||||
list_for_each_entry(dep, &acpi_dep_list, node) {
|
||||
if (dep->consumer == adev->handle)
|
||||
adev->dep_unmet++;
|
||||
}
|
||||
|
||||
mutex_unlock(&acpi_dep_list_lock);
|
||||
}
|
||||
|
||||
static bool acpi_bus_scan_second_pass;
|
||||
|
||||
static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
|
||||
@ -1949,19 +1966,15 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_add_single_object(&device, handle, type);
|
||||
if (!device)
|
||||
return AE_CTRL_DEPTH;
|
||||
|
||||
acpi_scan_init_hotplug(device);
|
||||
/*
|
||||
* If check_dep is true at this point, the device has no dependencies,
|
||||
* or the creation of the device object would have been postponed above.
|
||||
*/
|
||||
if (check_dep)
|
||||
device->dep_unmet = 0;
|
||||
else
|
||||
acpi_scan_dep_init(device);
|
||||
acpi_add_single_object(&device, handle, type, !check_dep);
|
||||
if (!device)
|
||||
return AE_CTRL_DEPTH;
|
||||
|
||||
acpi_scan_init_hotplug(device);
|
||||
|
||||
out:
|
||||
if (!*adev_p)
|
||||
@ -2111,29 +2124,141 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
|
||||
device->handler->hotplug.notify_online(device);
|
||||
}
|
||||
|
||||
void acpi_walk_dep_device_list(acpi_handle handle)
|
||||
static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
|
||||
adev = acpi_bus_get_acpi_device(dep->consumer);
|
||||
if (adev) {
|
||||
*(struct acpi_device **)data = adev;
|
||||
return 1;
|
||||
}
|
||||
/* Continue parsing if the device object is not present. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct acpi_scan_clear_dep_work {
|
||||
struct work_struct work;
|
||||
struct acpi_device *adev;
|
||||
};
|
||||
|
||||
static void acpi_scan_clear_dep_fn(struct work_struct *work)
|
||||
{
|
||||
struct acpi_scan_clear_dep_work *cdw;
|
||||
|
||||
cdw = container_of(work, struct acpi_scan_clear_dep_work, work);
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
acpi_bus_attach(cdw->adev, true);
|
||||
acpi_scan_lock_release();
|
||||
|
||||
acpi_dev_put(cdw->adev);
|
||||
kfree(cdw);
|
||||
}
|
||||
|
||||
static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
|
||||
{
|
||||
struct acpi_scan_clear_dep_work *cdw;
|
||||
|
||||
if (adev->dep_unmet)
|
||||
return false;
|
||||
|
||||
cdw = kmalloc(sizeof(*cdw), GFP_KERNEL);
|
||||
if (!cdw)
|
||||
return false;
|
||||
|
||||
cdw->adev = adev;
|
||||
INIT_WORK(&cdw->work, acpi_scan_clear_dep_fn);
|
||||
/*
|
||||
* Since the work function may block on the lock until the entire
|
||||
* initial enumeration of devices is complete, put it into the unbound
|
||||
* workqueue.
|
||||
*/
|
||||
queue_work(system_unbound_wq, &cdw->work);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
|
||||
{
|
||||
struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer);
|
||||
|
||||
if (adev) {
|
||||
adev->dep_unmet--;
|
||||
if (!acpi_scan_clear_dep_queue(adev))
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
|
||||
list_del(&dep->node);
|
||||
kfree(dep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_walk_dep_device_list - Apply a callback to every entry in acpi_dep_list
|
||||
* @handle: The ACPI handle of the supplier device
|
||||
* @callback: Pointer to the callback function to apply
|
||||
* @data: Pointer to some data to pass to the callback
|
||||
*
|
||||
* The return value of the callback determines this function's behaviour. If 0
|
||||
* is returned we continue to iterate over acpi_dep_list. If a positive value
|
||||
* is returned then the loop is broken but this function returns 0. If a
|
||||
* negative value is returned by the callback then the loop is broken and that
|
||||
* value is returned as the final error.
|
||||
*/
|
||||
static int acpi_walk_dep_device_list(acpi_handle handle,
|
||||
int (*callback)(struct acpi_dep_data *, void *),
|
||||
void *data)
|
||||
{
|
||||
struct acpi_dep_data *dep, *tmp;
|
||||
struct acpi_device *adev;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&acpi_dep_list_lock);
|
||||
list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
|
||||
if (dep->supplier == handle) {
|
||||
acpi_bus_get_device(dep->consumer, &adev);
|
||||
|
||||
if (adev) {
|
||||
adev->dep_unmet--;
|
||||
if (!adev->dep_unmet)
|
||||
acpi_bus_attach(adev, true);
|
||||
}
|
||||
|
||||
list_del(&dep->node);
|
||||
kfree(dep);
|
||||
ret = callback(dep, data);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&acpi_dep_list_lock);
|
||||
|
||||
return ret > 0 ? 0 : ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);
|
||||
|
||||
/**
|
||||
* acpi_dev_clear_dependencies - Inform consumers that the device is now active
|
||||
* @supplier: Pointer to the supplier &struct acpi_device
|
||||
*
|
||||
* Clear dependencies on the given device.
|
||||
*/
|
||||
void acpi_dev_clear_dependencies(struct acpi_device *supplier)
|
||||
{
|
||||
acpi_walk_dep_device_list(supplier->handle, acpi_scan_clear_dep, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
|
||||
|
||||
/**
|
||||
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
|
||||
* @supplier: Pointer to the dependee device
|
||||
*
|
||||
* Returns the first &struct acpi_device which declares itself dependent on
|
||||
* @supplier via the _DEP buffer, parsed from the acpi_dep_list.
|
||||
*
|
||||
* The caller is responsible for putting the reference to adev when it is no
|
||||
* longer needed.
|
||||
*/
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
|
||||
{
|
||||
struct acpi_device *adev = NULL;
|
||||
|
||||
acpi_walk_dep_device_list(supplier->handle,
|
||||
acpi_dev_get_first_consumer_dev_cb, &adev);
|
||||
|
||||
return adev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
|
||||
|
||||
/**
|
||||
* acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
|
||||
@ -2223,7 +2348,7 @@ int acpi_bus_register_early_device(int type)
|
||||
struct acpi_device *device = NULL;
|
||||
int result;
|
||||
|
||||
result = acpi_add_single_object(&device, NULL, type);
|
||||
result = acpi_add_single_object(&device, NULL, type, false);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@ -2243,7 +2368,7 @@ static int acpi_bus_scan_fixed(void)
|
||||
struct acpi_device *device = NULL;
|
||||
|
||||
result = acpi_add_single_object(&device, NULL,
|
||||
ACPI_BUS_TYPE_POWER_BUTTON);
|
||||
ACPI_BUS_TYPE_POWER_BUTTON, false);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@ -2259,7 +2384,7 @@ static int acpi_bus_scan_fixed(void)
|
||||
struct acpi_device *device = NULL;
|
||||
|
||||
result = acpi_add_single_object(&device, NULL,
|
||||
ACPI_BUS_TYPE_SLEEP_BUTTON);
|
||||
ACPI_BUS_TYPE_SLEEP_BUTTON, false);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@ -2408,46 +2533,28 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
|
||||
return count;
|
||||
}
|
||||
|
||||
struct acpi_table_events_work {
|
||||
struct work_struct work;
|
||||
void *table;
|
||||
u32 event;
|
||||
};
|
||||
|
||||
static void acpi_table_events_fn(struct work_struct *work)
|
||||
{
|
||||
struct acpi_table_events_work *tew;
|
||||
acpi_scan_lock_acquire();
|
||||
acpi_bus_scan(ACPI_ROOT_OBJECT);
|
||||
acpi_scan_lock_release();
|
||||
|
||||
tew = container_of(work, struct acpi_table_events_work, work);
|
||||
|
||||
if (tew->event == ACPI_TABLE_EVENT_LOAD) {
|
||||
acpi_scan_lock_acquire();
|
||||
acpi_bus_scan(ACPI_ROOT_OBJECT);
|
||||
acpi_scan_lock_release();
|
||||
}
|
||||
|
||||
kfree(tew);
|
||||
kfree(work);
|
||||
}
|
||||
|
||||
void acpi_scan_table_handler(u32 event, void *table, void *context)
|
||||
void acpi_scan_table_notify(void)
|
||||
{
|
||||
struct acpi_table_events_work *tew;
|
||||
struct work_struct *work;
|
||||
|
||||
if (!acpi_scan_initialized)
|
||||
return;
|
||||
|
||||
if (event != ACPI_TABLE_EVENT_LOAD)
|
||||
work = kmalloc(sizeof(*work), GFP_KERNEL);
|
||||
if (!work)
|
||||
return;
|
||||
|
||||
tew = kmalloc(sizeof(*tew), GFP_KERNEL);
|
||||
if (!tew)
|
||||
return;
|
||||
|
||||
INIT_WORK(&tew->work, acpi_table_events_fn);
|
||||
tew->table = table;
|
||||
tew->event = event;
|
||||
|
||||
schedule_work(&tew->work);
|
||||
INIT_WORK(work, acpi_table_events_fn);
|
||||
schedule_work(work);
|
||||
}
|
||||
|
||||
int acpi_reconfig_notifier_register(struct notifier_block *nb)
|
||||
|
@ -1233,14 +1233,14 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip)
|
||||
void acpi_gpiochip_add(struct gpio_chip *chip)
|
||||
{
|
||||
struct acpi_gpio_chip *acpi_gpio;
|
||||
acpi_handle handle;
|
||||
struct acpi_device *adev;
|
||||
acpi_status status;
|
||||
|
||||
if (!chip || !chip->parent)
|
||||
return;
|
||||
|
||||
handle = ACPI_HANDLE(chip->parent);
|
||||
if (!handle)
|
||||
adev = ACPI_COMPANION(chip->parent);
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
|
||||
@ -1254,7 +1254,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
|
||||
INIT_LIST_HEAD(&acpi_gpio->events);
|
||||
INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry);
|
||||
|
||||
status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
|
||||
status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n");
|
||||
kfree(acpi_gpio);
|
||||
@ -1263,7 +1263,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
|
||||
|
||||
acpi_gpiochip_request_regions(acpi_gpio);
|
||||
acpi_gpiochip_scan_gpios(acpi_gpio);
|
||||
acpi_walk_dep_device_list(handle);
|
||||
acpi_dev_clear_dependencies(adev);
|
||||
}
|
||||
|
||||
void acpi_gpiochip_remove(struct gpio_chip *chip)
|
||||
|
@ -259,8 +259,8 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
|
||||
*/
|
||||
void i2c_acpi_register_devices(struct i2c_adapter *adap)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
|
||||
if (!has_acpi_companion(&adap->dev))
|
||||
return;
|
||||
@ -275,11 +275,11 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
|
||||
if (!adap->dev.parent)
|
||||
return;
|
||||
|
||||
handle = ACPI_HANDLE(adap->dev.parent);
|
||||
if (!handle)
|
||||
adev = ACPI_COMPANION(adap->dev.parent);
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
acpi_walk_dep_device_list(handle);
|
||||
acpi_dev_clear_dependencies(adev);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
|
||||
|
@ -621,8 +621,8 @@ static const struct acpi_gpio_mapping ssam_acpi_gpios[] = {
|
||||
|
||||
static int ssam_serial_hub_probe(struct serdev_device *serdev)
|
||||
{
|
||||
struct acpi_device *ssh = ACPI_COMPANION(&serdev->dev);
|
||||
struct ssam_controller *ctrl;
|
||||
acpi_handle *ssh = ACPI_HANDLE(&serdev->dev);
|
||||
acpi_status astatus;
|
||||
int status;
|
||||
|
||||
@ -652,7 +652,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
|
||||
if (status)
|
||||
goto err_devopen;
|
||||
|
||||
astatus = ssam_serdev_setup_via_acpi(ssh, serdev);
|
||||
astatus = ssam_serdev_setup_via_acpi(ssh->handle, serdev);
|
||||
if (ACPI_FAILURE(astatus)) {
|
||||
status = -ENXIO;
|
||||
goto err_devinit;
|
||||
@ -706,7 +706,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
|
||||
* For now let's thus default power/wakeup to false.
|
||||
*/
|
||||
device_set_wakeup_capable(&serdev->dev, true);
|
||||
acpi_walk_dep_device_list(ssh);
|
||||
acpi_dev_clear_dependencies(ssh);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -446,12 +446,12 @@ mshw0011_space_handler(u32 function, acpi_physical_address command,
|
||||
|
||||
static int mshw0011_install_space_handler(struct i2c_client *client)
|
||||
{
|
||||
acpi_handle handle;
|
||||
struct acpi_device *adev;
|
||||
struct mshw0011_handler_data *data;
|
||||
acpi_status status;
|
||||
|
||||
handle = ACPI_HANDLE(&client->dev);
|
||||
if (!handle)
|
||||
adev = ACPI_COMPANION(&client->dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct mshw0011_handler_data),
|
||||
@ -460,25 +460,25 @@ static int mshw0011_install_space_handler(struct i2c_client *client)
|
||||
return -ENOMEM;
|
||||
|
||||
data->client = client;
|
||||
status = acpi_bus_attach_private_data(handle, (void *)data);
|
||||
status = acpi_bus_attach_private_data(adev->handle, (void *)data);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
kfree(data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
status = acpi_install_address_space_handler(handle,
|
||||
ACPI_ADR_SPACE_GSBUS,
|
||||
&mshw0011_space_handler,
|
||||
NULL,
|
||||
data);
|
||||
status = acpi_install_address_space_handler(adev->handle,
|
||||
ACPI_ADR_SPACE_GSBUS,
|
||||
&mshw0011_space_handler,
|
||||
NULL,
|
||||
data);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&client->dev, "Error installing i2c space handler\n");
|
||||
acpi_bus_detach_private_data(handle);
|
||||
acpi_bus_detach_private_data(adev->handle);
|
||||
kfree(data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
acpi_walk_dep_device_list(handle);
|
||||
acpi_dev_clear_dependencies(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -798,7 +798,7 @@ static int san_consumer_links_setup(struct platform_device *pdev)
|
||||
|
||||
static int san_probe(struct platform_device *pdev)
|
||||
{
|
||||
acpi_handle san = ACPI_HANDLE(&pdev->dev);
|
||||
struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
|
||||
struct ssam_controller *ctrl;
|
||||
struct san_data *data;
|
||||
acpi_status astatus;
|
||||
@ -821,7 +821,8 @@ static int san_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
astatus = acpi_install_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
|
||||
astatus = acpi_install_address_space_handler(san->handle,
|
||||
ACPI_ADR_SPACE_GSBUS,
|
||||
&san_opreg_handler, NULL,
|
||||
&data->info);
|
||||
if (ACPI_FAILURE(astatus))
|
||||
@ -835,7 +836,7 @@ static int san_probe(struct platform_device *pdev)
|
||||
if (status)
|
||||
goto err_install_dev;
|
||||
|
||||
acpi_walk_dep_device_list(san);
|
||||
acpi_dev_clear_dependencies(san);
|
||||
return 0;
|
||||
|
||||
err_install_dev:
|
||||
|
@ -280,6 +280,12 @@ struct acpi_device_power {
|
||||
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
|
||||
};
|
||||
|
||||
struct acpi_dep_data {
|
||||
struct list_head node;
|
||||
acpi_handle supplier;
|
||||
acpi_handle consumer;
|
||||
};
|
||||
|
||||
/* Performance Management */
|
||||
|
||||
struct acpi_device_perf_flags {
|
||||
@ -498,8 +504,6 @@ extern int unregister_acpi_notifier(struct notifier_block *);
|
||||
*/
|
||||
|
||||
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
|
||||
void acpi_bus_put_acpi_device(struct acpi_device *adev);
|
||||
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
|
||||
unsigned long long *sta);
|
||||
int acpi_bus_get_status(struct acpi_device *device);
|
||||
@ -685,6 +689,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
||||
|
||||
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
|
||||
|
||||
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
|
||||
struct acpi_device *
|
||||
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
|
||||
struct acpi_device *
|
||||
@ -718,6 +724,13 @@ static inline void acpi_dev_put(struct acpi_device *adev)
|
||||
{
|
||||
put_device(&adev->dev);
|
||||
}
|
||||
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
|
||||
|
||||
static inline void acpi_bus_put_acpi_device(struct acpi_device *adev)
|
||||
{
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
||||
|
@ -666,7 +666,6 @@ extern bool acpi_driver_match_device(struct device *dev,
|
||||
const struct device_driver *drv);
|
||||
int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
|
||||
int acpi_device_modalias(struct device *, char *, int);
|
||||
void acpi_walk_dep_device_list(acpi_handle handle);
|
||||
|
||||
struct platform_device *acpi_create_platform_device(struct acpi_device *,
|
||||
struct property_entry *);
|
||||
|
Loading…
Reference in New Issue
Block a user