]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/acpi-dock-Fix-duplicate-notification-handler-register.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / acpi-dock-Fix-duplicate-notification-handler-register.patch
1 From: Shaohua Li <shaohua.li@intel.com>
2 Subject: Fix duplicate notification handler register
3 Patch-mainline: submitted 2008-08-28
4 References: fate#304731,bnc#401740
5
6 Battery driver already registers notification handler. To avoid register
7 notification handler again, the patch introduced a notifier chain in
8 global system notifier handler and use it in dock driver, so we can
9 avoid register notification handler.
10
11 Signed-off-by: Shaohua Li <shaohua.li@intel.com>
12 Signed-off-by: Holger Macht <hmacht@suse.de>
13 ---
14
15 ---
16 drivers/acpi/bus.c | 15 +++++++++++++++
17 drivers/acpi/dock.c | 46 ++++++++++++++++++++++++----------------------
18 include/acpi/acpi_bus.h | 3 +++
19 3 files changed, 42 insertions(+), 22 deletions(-)
20
21 --- a/drivers/acpi/bus.c
22 +++ b/drivers/acpi/bus.c
23 @@ -496,6 +496,19 @@ static int acpi_bus_check_scope(struct a
24 return 0;
25 }
26
27 +static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
28 +int register_acpi_bus_notifier(struct notifier_block *nb)
29 +{
30 + return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
31 +}
32 +EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
33 +
34 +void unregister_acpi_bus_notifier(struct notifier_block *nb)
35 +{
36 + blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
37 +}
38 +EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
39 +
40 /**
41 * acpi_bus_notify
42 * ---------------
43 @@ -506,6 +519,8 @@ static void acpi_bus_notify(acpi_handle
44 int result = 0;
45 struct acpi_device *device = NULL;
46
47 + blocking_notifier_call_chain(&acpi_bus_notify_list,
48 + type, (void *)handle);
49
50 if (acpi_bus_get_device(handle, &device))
51 return;
52 --- a/drivers/acpi/dock.c
53 +++ b/drivers/acpi/dock.c
54 @@ -748,6 +748,28 @@ static void dock_notify(acpi_handle hand
55 }
56 }
57
58 +static int acpi_dock_notifier_call(struct notifier_block *this,
59 + unsigned long event, void *data)
60 +{
61 + struct dock_station *dock_station;
62 + acpi_handle handle = (acpi_handle)data;
63 +
64 + if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
65 + && event != ACPI_NOTIFY_EJECT_REQUEST)
66 + return 0;
67 + list_for_each_entry(dock_station, &dock_stations, sibiling) {
68 + if (dock_station->handle == handle) {
69 + dock_notify(handle, event, dock_station);
70 + return 0 ;
71 + }
72 + }
73 + return 0;
74 +}
75 +
76 +static struct notifier_block dock_acpi_notifier = {
77 + .notifier_call = acpi_dock_notifier_call,
78 +};
79 +
80 /**
81 * find_dock_devices - find devices on the dock station
82 * @handle: the handle of the device we are examining
83 @@ -859,7 +881,6 @@ static DEVICE_ATTR(uid, S_IRUGO, show_do
84 static int dock_add(acpi_handle handle)
85 {
86 int ret;
87 - acpi_status status;
88 struct dock_dependent_device *dd;
89 struct dock_station *dock_station;
90 struct platform_device *dock_device;
91 @@ -954,23 +975,10 @@ static int dock_add(acpi_handle handle)
92 }
93 add_dock_dependent_device(dock_station, dd);
94
95 - /* register for dock events */
96 - status = acpi_install_notify_handler(dock_station->handle,
97 - ACPI_SYSTEM_NOTIFY,
98 - dock_notify, dock_station);
99 -
100 - if (ACPI_FAILURE(status)) {
101 - printk(KERN_ERR PREFIX "Error installing notify handler\n");
102 - ret = -ENODEV;
103 - goto dock_add_err;
104 - }
105 -
106 dock_station_count++;
107 list_add(&dock_station->sibiling, &dock_stations);
108 return 0;
109
110 -dock_add_err:
111 - kfree(dd);
112 dock_add_err_unregister:
113 device_remove_file(&dock_device->dev, &dev_attr_docked);
114 device_remove_file(&dock_device->dev, &dev_attr_undock);
115 @@ -988,7 +996,6 @@ dock_add_err_unregister:
116 static int dock_remove(struct dock_station *dock_station)
117 {
118 struct dock_dependent_device *dd, *tmp;
119 - acpi_status status;
120 struct platform_device *dock_device = dock_station->dock_device;
121
122 if (!dock_station_count)
123 @@ -999,13 +1006,6 @@ static int dock_remove(struct dock_stati
124 list)
125 kfree(dd);
126
127 - /* remove dock notify handler */
128 - status = acpi_remove_notify_handler(dock_station->handle,
129 - ACPI_SYSTEM_NOTIFY,
130 - dock_notify);
131 - if (ACPI_FAILURE(status))
132 - printk(KERN_ERR "Error removing notify handler\n");
133 -
134 /* cleanup sysfs */
135 device_remove_file(&dock_device->dev, &dev_attr_docked);
136 device_remove_file(&dock_device->dev, &dev_attr_undock);
137 @@ -1067,6 +1067,7 @@ static int __init dock_init(void)
138 return 0;
139 }
140
141 + register_acpi_bus_notifier(&dock_acpi_notifier);
142 printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
143 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
144 return 0;
145 @@ -1076,6 +1077,7 @@ static void __exit dock_exit(void)
146 {
147 struct dock_station *dock_station;
148
149 + unregister_acpi_bus_notifier(&dock_acpi_notifier);
150 list_for_each_entry(dock_station, &dock_stations, sibiling)
151 dock_remove(dock_station);
152 }
153 --- a/include/acpi/acpi_bus.h
154 +++ b/include/acpi/acpi_bus.h
155 @@ -327,6 +327,9 @@ int acpi_bus_get_private_data(acpi_handl
156 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
157 extern int register_acpi_notifier(struct notifier_block *);
158 extern int unregister_acpi_notifier(struct notifier_block *);
159 +
160 +extern int register_acpi_bus_notifier(struct notifier_block *nb);
161 +extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
162 /*
163 * External Functions
164 */