aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2008-08-27 22:04:29 -0400
committerLen Brown <len.brown@intel.com>2008-09-23 23:04:43 -0400
commit6bd00a61ab63d4ceb635ae0316353c11c900b8d8 (patch)
tree249e417279df1448f1ad43c135c22990b5dde2cb
parentdb350b084dc2cf816288643861ce07b0562dd723 (diff)
ACPI: introduce notifier change to avoid duplicates
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>
-rw-r--r--drivers/acpi/bus.c15
-rw-r--r--drivers/acpi/dock.c46
-rw-r--r--include/acpi/acpi_bus.h3
3 files changed, 42 insertions, 22 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ccae305ee55d..0dc44945725e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -496,6 +496,19 @@ static int acpi_bus_check_scope(struct acpi_device *device)
496 return 0; 496 return 0;
497} 497}
498 498
499static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
500int register_acpi_bus_notifier(struct notifier_block *nb)
501{
502 return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
503}
504EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
505
506void unregister_acpi_bus_notifier(struct notifier_block *nb)
507{
508 blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
509}
510EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
511
499/** 512/**
500 * acpi_bus_notify 513 * acpi_bus_notify
501 * --------------- 514 * ---------------
@@ -506,6 +519,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
506 int result = 0; 519 int result = 0;
507 struct acpi_device *device = NULL; 520 struct acpi_device *device = NULL;
508 521
522 blocking_notifier_call_chain(&acpi_bus_notify_list,
523 type, (void *)handle);
509 524
510 if (acpi_bus_get_device(handle, &device)) 525 if (acpi_bus_get_device(handle, &device))
511 return; 526 return;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 799a0fdbb62d..2563bc62987d 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -748,6 +748,28 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
748 } 748 }
749} 749}
750 750
751static int acpi_dock_notifier_call(struct notifier_block *this,
752 unsigned long event, void *data)
753{
754 struct dock_station *dock_station;
755 acpi_handle handle = (acpi_handle)data;
756
757 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
758 && event != ACPI_NOTIFY_EJECT_REQUEST)
759 return 0;
760 list_for_each_entry(dock_station, &dock_stations, sibiling) {
761 if (dock_station->handle == handle) {
762 dock_notify(handle, event, dock_station);
763 return 0 ;
764 }
765 }
766 return 0;
767}
768
769static struct notifier_block dock_acpi_notifier = {
770 .notifier_call = acpi_dock_notifier_call,
771};
772
751/** 773/**
752 * find_dock_devices - find devices on the dock station 774 * find_dock_devices - find devices on the dock station
753 * @handle: the handle of the device we are examining 775 * @handle: the handle of the device we are examining
@@ -861,7 +883,6 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
861static int dock_add(acpi_handle handle) 883static int dock_add(acpi_handle handle)
862{ 884{
863 int ret; 885 int ret;
864 acpi_status status;
865 struct dock_dependent_device *dd; 886 struct dock_dependent_device *dd;
866 struct dock_station *dock_station; 887 struct dock_station *dock_station;
867 struct platform_device *dock_device; 888 struct platform_device *dock_device;
@@ -956,23 +977,10 @@ static int dock_add(acpi_handle handle)
956 } 977 }
957 add_dock_dependent_device(dock_station, dd); 978 add_dock_dependent_device(dock_station, dd);
958 979
959 /* register for dock events */
960 status = acpi_install_notify_handler(dock_station->handle,
961 ACPI_SYSTEM_NOTIFY,
962 dock_notify, dock_station);
963
964 if (ACPI_FAILURE(status)) {
965 printk(KERN_ERR PREFIX "Error installing notify handler\n");
966 ret = -ENODEV;
967 goto dock_add_err;
968 }
969
970 dock_station_count++; 980 dock_station_count++;
971 list_add(&dock_station->sibiling, &dock_stations); 981 list_add(&dock_station->sibiling, &dock_stations);
972 return 0; 982 return 0;
973 983
974dock_add_err:
975 kfree(dd);
976dock_add_err_unregister: 984dock_add_err_unregister:
977 device_remove_file(&dock_device->dev, &dev_attr_docked); 985 device_remove_file(&dock_device->dev, &dev_attr_docked);
978 device_remove_file(&dock_device->dev, &dev_attr_undock); 986 device_remove_file(&dock_device->dev, &dev_attr_undock);
@@ -990,7 +998,6 @@ dock_add_err_unregister:
990static int dock_remove(struct dock_station *dock_station) 998static int dock_remove(struct dock_station *dock_station)
991{ 999{
992 struct dock_dependent_device *dd, *tmp; 1000 struct dock_dependent_device *dd, *tmp;
993 acpi_status status;
994 struct platform_device *dock_device = dock_station->dock_device; 1001 struct platform_device *dock_device = dock_station->dock_device;
995 1002
996 if (!dock_station_count) 1003 if (!dock_station_count)
@@ -1001,13 +1008,6 @@ static int dock_remove(struct dock_station *dock_station)
1001 list) 1008 list)
1002 kfree(dd); 1009 kfree(dd);
1003 1010
1004 /* remove dock notify handler */
1005 status = acpi_remove_notify_handler(dock_station->handle,
1006 ACPI_SYSTEM_NOTIFY,
1007 dock_notify);
1008 if (ACPI_FAILURE(status))
1009 printk(KERN_ERR "Error removing notify handler\n");
1010
1011 /* cleanup sysfs */ 1011 /* cleanup sysfs */
1012 device_remove_file(&dock_device->dev, &dev_attr_docked); 1012 device_remove_file(&dock_device->dev, &dev_attr_docked);
1013 device_remove_file(&dock_device->dev, &dev_attr_undock); 1013 device_remove_file(&dock_device->dev, &dev_attr_undock);
@@ -1069,6 +1069,7 @@ static int __init dock_init(void)
1069 return 0; 1069 return 0;
1070 } 1070 }
1071 1071
1072 register_acpi_bus_notifier(&dock_acpi_notifier);
1072 printk(KERN_INFO PREFIX "%s: %d docks/bays found\n", 1073 printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
1073 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); 1074 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
1074 return 0; 1075 return 0;
@@ -1078,6 +1079,7 @@ static void __exit dock_exit(void)
1078{ 1079{
1079 struct dock_station *dock_station; 1080 struct dock_station *dock_station;
1080 1081
1082 unregister_acpi_bus_notifier(&dock_acpi_notifier);
1081 list_for_each_entry(dock_station, &dock_stations, sibiling) 1083 list_for_each_entry(dock_station, &dock_stations, sibiling)
1082 dock_remove(dock_station); 1084 dock_remove(dock_station);
1083} 1085}
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a5ac0bc7f52e..f74f882609f8 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -327,6 +327,9 @@ int acpi_bus_get_private_data(acpi_handle, void **);
327extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); 327extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
328extern int register_acpi_notifier(struct notifier_block *); 328extern int register_acpi_notifier(struct notifier_block *);
329extern int unregister_acpi_notifier(struct notifier_block *); 329extern int unregister_acpi_notifier(struct notifier_block *);
330
331extern int register_acpi_bus_notifier(struct notifier_block *nb);
332extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
330/* 333/*
331 * External Functions 334 * External Functions
332 */ 335 */