]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/acpi-dock-Fix-duplicate-notification-handler-register.patch
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / acpi-dock-Fix-duplicate-notification-handler-register.patch
CommitLineData
2cb7cef9
BS
1From: Shaohua Li <shaohua.li@intel.com>
2Subject: Fix duplicate notification handler register
3Patch-mainline: submitted 2008-08-28
4References: fate#304731,bnc#401740
5
6Battery driver already registers notification handler. To avoid register
7notification handler again, the patch introduced a notifier chain in
8global system notifier handler and use it in dock driver, so we can
9avoid register notification handler.
10
11Signed-off-by: Shaohua Li <shaohua.li@intel.com>
12Signed-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 */