Skip to content

Commit

Permalink
ACPI: introduce notifier change to avoid duplicates
Browse files Browse the repository at this point in the history
The battery driver already registers notification handler.
To avoid registering notification handler again,
introduce a notifier chain in global system notifier handler
and use it in dock driver.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Shaohua Li authored and Len Brown committed Sep 24, 2008
1 parent db350b0 commit 6bd00a6
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 22 deletions.
15 changes: 15 additions & 0 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,19 @@ static int acpi_bus_check_scope(struct acpi_device *device)
return 0;
}

static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
int register_acpi_bus_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);

void unregister_acpi_bus_notifier(struct notifier_block *nb)
{
blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);

/**
* acpi_bus_notify
* ---------------
Expand All @@ -506,6 +519,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
int result = 0;
struct acpi_device *device = NULL;

blocking_notifier_call_chain(&acpi_bus_notify_list,
type, (void *)handle);

if (acpi_bus_get_device(handle, &device))
return;
Expand Down
46 changes: 24 additions & 22 deletions drivers/acpi/dock.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,28 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
}
}

static int acpi_dock_notifier_call(struct notifier_block *this,
unsigned long event, void *data)
{
struct dock_station *dock_station;
acpi_handle handle = (acpi_handle)data;

if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
&& event != ACPI_NOTIFY_EJECT_REQUEST)
return 0;
list_for_each_entry(dock_station, &dock_stations, sibiling) {
if (dock_station->handle == handle) {
dock_notify(handle, event, dock_station);
return 0 ;
}
}
return 0;
}

static struct notifier_block dock_acpi_notifier = {
.notifier_call = acpi_dock_notifier_call,
};

/**
* find_dock_devices - find devices on the dock station
* @handle: the handle of the device we are examining
Expand Down Expand Up @@ -861,7 +883,6 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
static int dock_add(acpi_handle handle)
{
int ret;
acpi_status status;
struct dock_dependent_device *dd;
struct dock_station *dock_station;
struct platform_device *dock_device;
Expand Down Expand Up @@ -956,23 +977,10 @@ static int dock_add(acpi_handle handle)
}
add_dock_dependent_device(dock_station, dd);

/* register for dock events */
status = acpi_install_notify_handler(dock_station->handle,
ACPI_SYSTEM_NOTIFY,
dock_notify, dock_station);

if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Error installing notify handler\n");
ret = -ENODEV;
goto dock_add_err;
}

dock_station_count++;
list_add(&dock_station->sibiling, &dock_stations);
return 0;

dock_add_err:
kfree(dd);
dock_add_err_unregister:
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
Expand All @@ -990,7 +998,6 @@ static int dock_add(acpi_handle handle)
static int dock_remove(struct dock_station *dock_station)
{
struct dock_dependent_device *dd, *tmp;
acpi_status status;
struct platform_device *dock_device = dock_station->dock_device;

if (!dock_station_count)
Expand All @@ -1001,13 +1008,6 @@ static int dock_remove(struct dock_station *dock_station)
list)
kfree(dd);

/* remove dock notify handler */
status = acpi_remove_notify_handler(dock_station->handle,
ACPI_SYSTEM_NOTIFY,
dock_notify);
if (ACPI_FAILURE(status))
printk(KERN_ERR "Error removing notify handler\n");

/* cleanup sysfs */
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
Expand Down Expand Up @@ -1069,6 +1069,7 @@ static int __init dock_init(void)
return 0;
}

register_acpi_bus_notifier(&dock_acpi_notifier);
printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
return 0;
Expand All @@ -1078,6 +1079,7 @@ static void __exit dock_exit(void)
{
struct dock_station *dock_station;

unregister_acpi_bus_notifier(&dock_acpi_notifier);
list_for_each_entry(dock_station, &dock_stations, sibiling)
dock_remove(dock_station);
}
Expand Down
3 changes: 3 additions & 0 deletions include/acpi/acpi_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ int acpi_bus_get_private_data(acpi_handle, void **);
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
extern int register_acpi_notifier(struct notifier_block *);
extern int unregister_acpi_notifier(struct notifier_block *);

extern int register_acpi_bus_notifier(struct notifier_block *nb);
extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
/*
* External Functions
*/
Expand Down

0 comments on commit 6bd00a6

Please sign in to comment.