aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/Makefile3
-rw-r--r--drivers/pci/hotplug/acpiphp.h36
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c19
-rw-r--r--drivers/pci/hotplug/acpiphp_dock.c438
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c123
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c3
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c1
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c1
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c6
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c3
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c1
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c1
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c1
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c1
-rw-r--r--drivers/pci/hotplug/fakephp.c1
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c2
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c1
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c1
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pci/msi.c1
-rw-r--r--drivers/pci/pci-sysfs.c1
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/pci/rom.c1
24 files changed, 103 insertions, 546 deletions
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 421cfffb1756..34a1891191fd 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -40,8 +40,7 @@ ibmphp-objs := ibmphp_core.o \
40 ibmphp_hpc.o 40 ibmphp_hpc.o
41 41
42acpiphp-objs := acpiphp_core.o \ 42acpiphp-objs := acpiphp_core.o \
43 acpiphp_glue.o \ 43 acpiphp_glue.o
44 acpiphp_dock.o
45 44
46rpaphp-objs := rpaphp_core.o \ 45rpaphp-objs := rpaphp_core.o \
47 rpaphp_pci.o \ 46 rpaphp_pci.o \
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 17a93f890dba..be104eced34c 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -130,7 +130,7 @@ struct acpiphp_func {
130 130
131 struct list_head sibling; 131 struct list_head sibling;
132 struct pci_dev *pci_dev; 132 struct pci_dev *pci_dev;
133 133 struct notifier_block nb;
134 acpi_handle handle; 134 acpi_handle handle;
135 135
136 u8 function; /* pci function# */ 136 u8 function; /* pci function# */
@@ -151,24 +151,6 @@ struct acpiphp_attention_info
151}; 151};
152 152
153 153
154struct dependent_device {
155 struct list_head device_list;
156 struct list_head pci_list;
157 acpi_handle handle;
158 struct acpiphp_func *func;
159};
160
161
162struct acpiphp_dock_station {
163 acpi_handle handle;
164 u32 last_dock_time;
165 u32 flags;
166 struct acpiphp_func *dock_bridge;
167 struct list_head dependent_devices;
168 struct list_head pci_dependent_devices;
169};
170
171
172/* PCI bus bridge HID */ 154/* PCI bus bridge HID */
173#define ACPI_PCI_HOST_HID "PNP0A03" 155#define ACPI_PCI_HOST_HID "PNP0A03"
174 156
@@ -207,11 +189,6 @@ struct acpiphp_dock_station {
207#define FUNC_HAS_PS2 (0x00000040) 189#define FUNC_HAS_PS2 (0x00000040)
208#define FUNC_HAS_PS3 (0x00000080) 190#define FUNC_HAS_PS3 (0x00000080)
209#define FUNC_HAS_DCK (0x00000100) 191#define FUNC_HAS_DCK (0x00000100)
210#define FUNC_IS_DD (0x00000200)
211
212/* dock station flags */
213#define DOCK_DOCKING (0x00000001)
214#define DOCK_HAS_BRIDGE (0x00000002)
215 192
216/* function prototypes */ 193/* function prototypes */
217 194
@@ -226,7 +203,6 @@ extern int acpiphp_glue_init (void);
226extern void acpiphp_glue_exit (void); 203extern void acpiphp_glue_exit (void);
227extern int acpiphp_get_num_slots (void); 204extern int acpiphp_get_num_slots (void);
228typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); 205typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
229void handle_hotplug_event_func(acpi_handle, u32, void*);
230 206
231extern int acpiphp_enable_slot (struct acpiphp_slot *slot); 207extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
232extern int acpiphp_disable_slot (struct acpiphp_slot *slot); 208extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
@@ -236,16 +212,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
236extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); 212extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
237extern u32 acpiphp_get_address (struct acpiphp_slot *slot); 213extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
238 214
239/* acpiphp_dock.c */
240extern int find_dock_station(void);
241extern void remove_dock_station(void);
242extern void add_dependent_device(struct dependent_device *new_dd);
243extern void add_pci_dependent_device(struct dependent_device *new_dd);
244extern struct dependent_device *get_dependent_device(acpi_handle handle);
245extern int is_dependent_device(acpi_handle handle);
246extern int detect_dependent_devices(acpi_handle *bridge_handle);
247extern struct dependent_device *alloc_dependent_device(acpi_handle handle);
248
249/* variables */ 215/* variables */
250extern int acpiphp_debug; 216extern int acpiphp_debug;
251 217
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 4f1b0da8e47e..34de5697983d 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -416,27 +416,12 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
416 416
417static int __init acpiphp_init(void) 417static int __init acpiphp_init(void)
418{ 418{
419 int retval;
420 int docking_station;
421
422 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 419 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
423 420
424 acpiphp_debug = debug; 421 acpiphp_debug = debug;
425 422
426 docking_station = find_dock_station();
427
428 /* read all the ACPI info from the system */ 423 /* read all the ACPI info from the system */
429 retval = init_acpi(); 424 return init_acpi();
430
431 /* if we have found a docking station, we should
432 * go ahead and load even if init_acpi has found
433 * no slots. This handles the case when the _DCK
434 * method not defined under the actual dock bridge
435 */
436 if (docking_station)
437 return 0;
438 else
439 return retval;
440} 425}
441 426
442 427
@@ -444,8 +429,6 @@ static void __exit acpiphp_exit(void)
444{ 429{
445 /* deallocate internal data structures etc. */ 430 /* deallocate internal data structures etc. */
446 acpiphp_glue_exit(); 431 acpiphp_glue_exit();
447
448 remove_dock_station();
449} 432}
450 433
451module_init(acpiphp_init); 434module_init(acpiphp_init);
diff --git a/drivers/pci/hotplug/acpiphp_dock.c b/drivers/pci/hotplug/acpiphp_dock.c
deleted file mode 100644
index 4f1aaf128312..000000000000
--- a/drivers/pci/hotplug/acpiphp_dock.c
+++ /dev/null
@@ -1,438 +0,0 @@
1/*
2 * ACPI PCI HotPlug dock functions to ACPI CA subsystem
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi (kristen.c.accardi@intel.com)
5 * Copyright (C) 2006 Intel Corporation
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <kristen.c.accardi@intel.com>
25 *
26 */
27#include <linux/init.h>
28#include <linux/module.h>
29
30#include <linux/kernel.h>
31#include <linux/pci.h>
32#include <linux/smp_lock.h>
33#include <linux/mutex.h>
34
35#include "../pci.h"
36#include "pci_hotplug.h"
37#include "acpiphp.h"
38
39static struct acpiphp_dock_station *ds;
40#define MY_NAME "acpiphp_dock"
41
42
43int is_dependent_device(acpi_handle handle)
44{
45 return (get_dependent_device(handle) ? 1 : 0);
46}
47
48
49static acpi_status
50find_dependent_device(acpi_handle handle, u32 lvl, void *context, void **rv)
51{
52 int *count = (int *)context;
53
54 if (is_dependent_device(handle)) {
55 (*count)++;
56 return AE_CTRL_TERMINATE;
57 } else {
58 return AE_OK;
59 }
60}
61
62
63
64
65void add_dependent_device(struct dependent_device *new_dd)
66{
67 list_add_tail(&new_dd->device_list, &ds->dependent_devices);
68}
69
70
71void add_pci_dependent_device(struct dependent_device *new_dd)
72{
73 list_add_tail(&new_dd->pci_list, &ds->pci_dependent_devices);
74}
75
76
77
78struct dependent_device * get_dependent_device(acpi_handle handle)
79{
80 struct dependent_device *dd;
81
82 if (!ds)
83 return NULL;
84
85 list_for_each_entry(dd, &ds->dependent_devices, device_list) {
86 if (handle == dd->handle)
87 return dd;
88 }
89 return NULL;
90}
91
92
93
94struct dependent_device *alloc_dependent_device(acpi_handle handle)
95{
96 struct dependent_device *dd;
97
98 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
99 if (dd) {
100 INIT_LIST_HEAD(&dd->pci_list);
101 INIT_LIST_HEAD(&dd->device_list);
102 dd->handle = handle;
103 }
104 return dd;
105}
106
107
108
109static int is_dock(acpi_handle handle)
110{
111 acpi_status status;
112 acpi_handle tmp;
113
114 status = acpi_get_handle(handle, "_DCK", &tmp);
115 if (ACPI_FAILURE(status)) {
116 return 0;
117 }
118 return 1;
119}
120
121
122
123static int dock_present(void)
124{
125 unsigned long sta;
126 acpi_status status;
127
128 if (ds) {
129 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
130 if (ACPI_SUCCESS(status) && sta)
131 return 1;
132 }
133 return 0;
134}
135
136
137
138static void eject_dock(void)
139{
140 struct acpi_object_list arg_list;
141 union acpi_object arg;
142
143 arg_list.count = 1;
144 arg_list.pointer = &arg;
145 arg.type = ACPI_TYPE_INTEGER;
146 arg.integer.value = 1;
147
148 if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
149 &arg_list, NULL)) || dock_present())
150 warn("%s: failed to eject dock!\n", __FUNCTION__);
151
152 return;
153}
154
155
156
157
158static acpi_status handle_dock(int dock)
159{
160 acpi_status status;
161 struct acpi_object_list arg_list;
162 union acpi_object arg;
163 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
164
165 dbg("%s: %s\n", __FUNCTION__, dock ? "docking" : "undocking");
166
167 /* _DCK method has one argument */
168 arg_list.count = 1;
169 arg_list.pointer = &arg;
170 arg.type = ACPI_TYPE_INTEGER;
171 arg.integer.value = dock;
172 status = acpi_evaluate_object(ds->handle, "_DCK",
173 &arg_list, &buffer);
174 if (ACPI_FAILURE(status))
175 err("%s: failed to execute _DCK\n", __FUNCTION__);
176 acpi_os_free(buffer.pointer);
177
178 return status;
179}
180
181
182
183static inline void dock(void)
184{
185 handle_dock(1);
186}
187
188
189
190static inline void undock(void)
191{
192 handle_dock(0);
193}
194
195
196
197/*
198 * the _DCK method can do funny things... and sometimes not
199 * hah-hah funny.
200 *
201 * TBD - figure out a way to only call fixups for
202 * systems that require them.
203 */
204static void post_dock_fixups(void)
205{
206 struct pci_bus *bus;
207 u32 buses;
208 struct dependent_device *dd;
209
210 list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list) {
211 bus = dd->func->slot->bridge->pci_bus;
212
213 /* fixup bad _DCK function that rewrites
214 * secondary bridge on slot
215 */
216 pci_read_config_dword(bus->self,
217 PCI_PRIMARY_BUS,
218 &buses);
219
220 if (((buses >> 8) & 0xff) != bus->secondary) {
221 buses = (buses & 0xff000000)
222 | ((unsigned int)(bus->primary) << 0)
223 | ((unsigned int)(bus->secondary) << 8)
224 | ((unsigned int)(bus->subordinate) << 16);
225 pci_write_config_dword(bus->self,
226 PCI_PRIMARY_BUS,
227 buses);
228 }
229 }
230}
231
232
233
234static void hotplug_pci(u32 type)
235{
236 struct dependent_device *dd;
237
238 list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list)
239 handle_hotplug_event_func(dd->handle, type, dd->func);
240}
241
242
243
244static inline void begin_dock(void)
245{
246 ds->flags |= DOCK_DOCKING;
247}
248
249
250static inline void complete_dock(void)
251{
252 ds->flags &= ~(DOCK_DOCKING);
253 ds->last_dock_time = jiffies;
254}
255
256
257static int dock_in_progress(void)
258{
259 if (ds->flags & DOCK_DOCKING ||
260 ds->last_dock_time == jiffies) {
261 dbg("dock in progress\n");
262 return 1;
263 }
264 return 0;
265}
266
267
268
269static void
270handle_hotplug_event_dock(acpi_handle handle, u32 type, void *context)
271{
272 dbg("%s: enter\n", __FUNCTION__);
273
274 switch (type) {
275 case ACPI_NOTIFY_BUS_CHECK:
276 dbg("BUS Check\n");
277 if (!dock_in_progress() && dock_present()) {
278 begin_dock();
279 dock();
280 if (!dock_present()) {
281 err("Unable to dock!\n");
282 break;
283 }
284 post_dock_fixups();
285 hotplug_pci(type);
286 complete_dock();
287 }
288 break;
289 case ACPI_NOTIFY_EJECT_REQUEST:
290 dbg("EJECT request\n");
291 if (!dock_in_progress() && dock_present()) {
292 hotplug_pci(type);
293 undock();
294 eject_dock();
295 if (dock_present())
296 err("Unable to undock!\n");
297 }
298 break;
299 }
300}
301
302
303
304
305static acpi_status
306find_dock_ejd(acpi_handle handle, u32 lvl, void *context, void **rv)
307{
308 acpi_status status;
309 acpi_handle tmp;
310 acpi_handle dck_handle = (acpi_handle) context;
311 char objname[64];
312 struct acpi_buffer buffer = { .length = sizeof(objname),
313 .pointer = objname };
314 struct acpi_buffer ejd_buffer = {ACPI_ALLOCATE_BUFFER, NULL};
315 union acpi_object *ejd_obj;
316
317 status = acpi_get_handle(handle, "_EJD", &tmp);
318 if (ACPI_FAILURE(status))
319 return AE_OK;
320
321 /* make sure we are dependent on the dock device,
322 * by executing the _EJD method, then getting a handle
323 * to the device referenced by that name. If that
324 * device handle is the same handle as the dock station
325 * handle, then we are a device dependent on the dock station
326 */
327 acpi_get_name(dck_handle, ACPI_FULL_PATHNAME, &buffer);
328 status = acpi_evaluate_object(handle, "_EJD", NULL, &ejd_buffer);
329 if (ACPI_FAILURE(status)) {
330 err("Unable to execute _EJD!\n");
331 goto find_ejd_out;
332 }
333 ejd_obj = ejd_buffer.pointer;
334 status = acpi_get_handle(NULL, ejd_obj->string.pointer, &tmp);
335 if (ACPI_FAILURE(status))
336 goto find_ejd_out;
337
338 if (tmp == dck_handle) {
339 struct dependent_device *dd;
340 dbg("%s: found device dependent on dock\n", __FUNCTION__);
341 dd = alloc_dependent_device(handle);
342 if (!dd) {
343 err("Can't allocate memory for dependent device!\n");
344 goto find_ejd_out;
345 }
346 add_dependent_device(dd);
347 }
348
349find_ejd_out:
350 acpi_os_free(ejd_buffer.pointer);
351 return AE_OK;
352}
353
354
355
356int detect_dependent_devices(acpi_handle *bridge_handle)
357{
358 acpi_status status;
359 int count;
360
361 count = 0;
362
363 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
364 (u32)1, find_dependent_device,
365 (void *)&count, NULL);
366
367 return count;
368}
369
370
371
372
373
374static acpi_status
375find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
376{
377 int *count = (int *)context;
378
379 if (is_dock(handle)) {
380 dbg("%s: found dock\n", __FUNCTION__);
381 ds = kzalloc(sizeof(*ds), GFP_KERNEL);
382 ds->handle = handle;
383 INIT_LIST_HEAD(&ds->dependent_devices);
384 INIT_LIST_HEAD(&ds->pci_dependent_devices);
385
386 /* look for devices dependent on dock station */
387 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
388 ACPI_UINT32_MAX, find_dock_ejd, handle, NULL);
389
390 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
391 handle_hotplug_event_dock, ds);
392 (*count)++;
393 }
394
395 return AE_OK;
396}
397
398
399
400
401int find_dock_station(void)
402{
403 int num = 0;
404
405 ds = NULL;
406
407 /* start from the root object, because some laptops define
408 * _DCK methods outside the scope of PCI (IBM x-series laptop)
409 */
410 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
411 ACPI_UINT32_MAX, find_dock, &num, NULL);
412
413 return num;
414}
415
416
417
418void remove_dock_station(void)
419{
420 struct dependent_device *dd, *tmp;
421 if (ds) {
422 if (ACPI_FAILURE(acpi_remove_notify_handler(ds->handle,
423 ACPI_SYSTEM_NOTIFY, handle_hotplug_event_dock)))
424 err("failed to remove dock notify handler\n");
425
426 /* free all dependent devices */
427 list_for_each_entry_safe(dd, tmp, &ds->dependent_devices,
428 device_list)
429 kfree(dd);
430
431 /* no need to touch the pci_dependent_device list,
432 * cause all memory was freed above
433 */
434 kfree(ds);
435 }
436}
437
438
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index d370f999782e..ef95d12fb32c 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -59,6 +59,7 @@ static LIST_HEAD(bridge_list);
59static void handle_hotplug_event_bridge (acpi_handle, u32, void *); 59static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
60static void acpiphp_sanitize_bus(struct pci_bus *bus); 60static void acpiphp_sanitize_bus(struct pci_bus *bus);
61static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); 61static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
62static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
62 63
63 64
64/* 65/*
@@ -116,6 +117,59 @@ is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
116 } 117 }
117} 118}
118 119
120/* callback routine to check for the existance of a pci dock device */
121static acpi_status
122is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv)
123{
124 int *count = (int *)context;
125
126 if (is_dock_device(handle)) {
127 (*count)++;
128 return AE_CTRL_TERMINATE;
129 } else {
130 return AE_OK;
131 }
132}
133
134
135
136
137/*
138 * the _DCK method can do funny things... and sometimes not
139 * hah-hah funny.
140 *
141 * TBD - figure out a way to only call fixups for
142 * systems that require them.
143 */
144static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
145 void *v)
146{
147 struct acpiphp_func *func = container_of(nb, struct acpiphp_func, nb);
148 struct pci_bus *bus = func->slot->bridge->pci_bus;
149 u32 buses;
150
151 if (!bus->self)
152 return NOTIFY_OK;
153
154 /* fixup bad _DCK function that rewrites
155 * secondary bridge on slot
156 */
157 pci_read_config_dword(bus->self,
158 PCI_PRIMARY_BUS,
159 &buses);
160
161 if (((buses >> 8) & 0xff) != bus->secondary) {
162 buses = (buses & 0xff000000)
163 | ((unsigned int)(bus->primary) << 0)
164 | ((unsigned int)(bus->secondary) << 8)
165 | ((unsigned int)(bus->subordinate) << 16);
166 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
167 }
168 return NOTIFY_OK;
169}
170
171
172
119 173
120/* callback routine to register each ACPI PCI slot object */ 174/* callback routine to register each ACPI PCI slot object */
121static acpi_status 175static acpi_status
@@ -124,7 +178,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
124 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context; 178 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
125 struct acpiphp_slot *slot; 179 struct acpiphp_slot *slot;
126 struct acpiphp_func *newfunc; 180 struct acpiphp_func *newfunc;
127 struct dependent_device *dd;
128 acpi_handle tmp; 181 acpi_handle tmp;
129 acpi_status status = AE_OK; 182 acpi_status status = AE_OK;
130 unsigned long adr, sun; 183 unsigned long adr, sun;
@@ -137,7 +190,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
137 190
138 status = acpi_get_handle(handle, "_EJ0", &tmp); 191 status = acpi_get_handle(handle, "_EJ0", &tmp);
139 192
140 if (ACPI_FAILURE(status) && !(is_dependent_device(handle))) 193 if (ACPI_FAILURE(status) && !(is_dock_device(handle)))
141 return AE_OK; 194 return AE_OK;
142 195
143 device = (adr >> 16) & 0xffff; 196 device = (adr >> 16) & 0xffff;
@@ -162,22 +215,17 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
162 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp))) 215 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
163 newfunc->flags |= FUNC_HAS_PS3; 216 newfunc->flags |= FUNC_HAS_PS3;
164 217
165 if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) { 218 if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp)))
166 newfunc->flags |= FUNC_HAS_DCK; 219 newfunc->flags |= FUNC_HAS_DCK;
167 /* add to devices dependent on dock station,
168 * because this may actually be the dock bridge
169 */
170 dd = alloc_dependent_device(handle);
171 if (!dd)
172 err("Can't allocate memory for "
173 "new dependent device!\n");
174 else
175 add_dependent_device(dd);
176 }
177 220
178 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun); 221 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
179 if (ACPI_FAILURE(status)) 222 if (ACPI_FAILURE(status)) {
180 sun = -1; 223 /*
224 * use the count of the number of slots we've found
225 * for the number of the slot
226 */
227 sun = bridge->nr_slots+1;
228 }
181 229
182 /* search for objects that share the same slot */ 230 /* search for objects that share the same slot */
183 for (slot = bridge->slots; slot; slot = slot->next) 231 for (slot = bridge->slots; slot; slot = slot->next)
@@ -225,20 +273,23 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
225 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); 273 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
226 } 274 }
227 275
228 /* if this is a device dependent on a dock station, 276 if (is_dock_device(handle)) {
229 * associate the acpiphp_func to the dependent_device 277 /* we don't want to call this device's _EJ0
230 * struct. 278 * because we want the dock notify handler
231 */ 279 * to call it after it calls _DCK
232 if ((dd = get_dependent_device(handle))) {
233 newfunc->flags |= FUNC_IS_DD;
234 /*
235 * we don't want any devices which is dependent
236 * on the dock to have it's _EJ0 method executed.
237 * because we need to run _DCK first.
238 */ 280 */
239 newfunc->flags &= ~FUNC_HAS_EJ0; 281 newfunc->flags &= ~FUNC_HAS_EJ0;
240 dd->func = newfunc; 282 if (register_hotplug_dock_device(handle,
241 add_pci_dependent_device(dd); 283 handle_hotplug_event_func, newfunc))
284 dbg("failed to register dock device\n");
285
286 /* we need to be notified when dock events happen
287 * outside of the hotplug operation, since we may
288 * need to do fixups before we can hotplug.
289 */
290 newfunc->nb.notifier_call = post_dock_fixups;
291 if (register_dock_notifier(&newfunc->nb))
292 dbg("failed to register a dock notifier");
242 } 293 }
243 294
244 /* install notify handler */ 295 /* install notify handler */
@@ -277,6 +328,15 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
277 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, 328 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
278 is_ejectable_slot, (void *)&count, NULL); 329 is_ejectable_slot, (void *)&count, NULL);
279 330
331 /*
332 * we also need to add this bridge if there is a dock bridge or
333 * other pci device on a dock station (removable)
334 */
335 if (!count)
336 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
337 (u32)1, is_pci_dock_device, (void *)&count,
338 NULL);
339
280 return count; 340 return count;
281} 341}
282 342
@@ -487,8 +547,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
487 goto out; 547 goto out;
488 548
489 /* check if this bridge has ejectable slots */ 549 /* check if this bridge has ejectable slots */
490 if ((detect_ejectable_slots(handle) > 0) || 550 if ((detect_ejectable_slots(handle) > 0)) {
491 (detect_dependent_devices(handle) > 0)) {
492 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); 551 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
493 add_p2p_bridge(handle, dev); 552 add_p2p_bridge(handle, dev);
494 } 553 }
@@ -605,6 +664,10 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
605 list_for_each_safe (list, tmp, &slot->funcs) { 664 list_for_each_safe (list, tmp, &slot->funcs) {
606 struct acpiphp_func *func; 665 struct acpiphp_func *func;
607 func = list_entry(list, struct acpiphp_func, sibling); 666 func = list_entry(list, struct acpiphp_func, sibling);
667 if (is_dock_device(func->handle)) {
668 unregister_hotplug_dock_device(func->handle);
669 unregister_dock_notifier(&func->nb);
670 }
608 if (!(func->flags & FUNC_HAS_DCK)) { 671 if (!(func->flags & FUNC_HAS_DCK)) {
609 status = acpi_remove_notify_handler(func->handle, 672 status = acpi_remove_notify_handler(func->handle,
610 ACPI_SYSTEM_NOTIFY, 673 ACPI_SYSTEM_NOTIFY,
@@ -1440,7 +1503,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1440 * handles ACPI event notification on slots 1503 * handles ACPI event notification on slots
1441 * 1504 *
1442 */ 1505 */
1443void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) 1506static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
1444{ 1507{
1445 struct acpiphp_func *func; 1508 struct acpiphp_func *func;
1446 char objname[64]; 1509 char objname[64];
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 037ce4c91687..d5df5871cfa2 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -25,7 +25,6 @@
25 * Send feedback to <scottm@somanetworks.com> 25 * Send feedback to <scottm@somanetworks.com>
26 */ 26 */
27 27
28#include <linux/config.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
@@ -348,7 +347,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
348 dbg("entered cpci_hp_intr"); 347 dbg("entered cpci_hp_intr");
349 348
350 /* Check to see if it was our interrupt */ 349 /* Check to see if it was our interrupt */
351 if ((controller->irq_flags & SA_SHIRQ) && 350 if ((controller->irq_flags & IRQF_SHARED) &&
352 !controller->ops->check_irq(controller->dev_id)) { 351 !controller->ops->check_irq(controller->dev_id)) {
353 dbg("exited cpci_hp_intr, not our interrupt"); 352 dbg("exited cpci_hp_intr, not our interrupt");
354 return IRQ_NONE; 353 return IRQ_NONE;
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index 225b5e551dd6..02be74caa89f 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -23,7 +23,6 @@
23 * Send feedback to <scottm@somanetworks.com> 23 * Send feedback to <scottm@somanetworks.com>
24 */ 24 */
25 25
26#include <linux/config.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/kernel.h> 27#include <linux/kernel.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index 2d4639d6841f..e847f0d6c7fe 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -34,7 +34,6 @@
34 * Send feedback to <scottm@somanetworks.com> 34 * Send feedback to <scottm@somanetworks.com>
35 */ 35 */
36 36
37#include <linux/config.h>
38#include <linux/module.h> 37#include <linux/module.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/errno.h> 39#include <linux/errno.h>
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 1ec165df8522..1c12e9171097 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -30,13 +30,13 @@
30 * Send feedback to <scottm@somanetworks.com> 30 * Send feedback to <scottm@somanetworks.com>
31 */ 31 */
32 32
33#include <linux/config.h>
34#include <linux/module.h> 33#include <linux/module.h>
35#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
39#include <linux/signal.h> /* SA_SHIRQ */ 38#include <linux/interrupt.h>
39#include <linux/signal.h> /* IRQF_SHARED */
40#include "cpci_hotplug.h" 40#include "cpci_hotplug.h"
41#include "cpcihp_zt5550.h" 41#include "cpcihp_zt5550.h"
42 42
@@ -220,7 +220,7 @@ static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id
220 zt5550_hpc.ops = &zt5550_hpc_ops; 220 zt5550_hpc.ops = &zt5550_hpc_ops;
221 if(!poll) { 221 if(!poll) {
222 zt5550_hpc.irq = hc_dev->irq; 222 zt5550_hpc.irq = hc_dev->irq;
223 zt5550_hpc.irq_flags = SA_SHIRQ; 223 zt5550_hpc.irq_flags = IRQF_SHARED;
224 zt5550_hpc.dev_id = hc_dev; 224 zt5550_hpc.dev_id = hc_dev;
225 225
226 zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq; 226 zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index f8658d63f077..1fc259913b68 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -29,7 +29,6 @@
29 * 29 *
30 */ 30 */
31 31
32#include <linux/config.h>
33#include <linux/module.h> 32#include <linux/module.h>
34#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
35#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -1189,7 +1188,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1189 /* set up the interrupt */ 1188 /* set up the interrupt */
1190 dbg("HPC interrupt = %d \n", ctrl->interrupt); 1189 dbg("HPC interrupt = %d \n", ctrl->interrupt);
1191 if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr, 1190 if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
1192 SA_SHIRQ, MY_NAME, ctrl)) { 1191 IRQF_SHARED, MY_NAME, ctrl)) {
1193 err("Can't get irq %d for the hotplug pci controller\n", 1192 err("Can't get irq %d for the hotplug pci controller\n",
1194 ctrl->interrupt); 1193 ctrl->interrupt);
1195 rc = -ENODEV; 1194 rc = -ENODEV;
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 55d2dc7e39ca..ae2dd36efef2 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -26,7 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29#include <linux/config.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/types.h> 31#include <linux/types.h>
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
index ac98a11bd1eb..cf0878917537 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.c
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -26,7 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29#include <linux/config.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/types.h> 31#include <linux/types.h>
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 00b81a7bdd26..0d9688952f4a 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -26,7 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29#include <linux/config.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/types.h> 31#include <linux/types.h>
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index bbfeed767ff1..8b3da007e859 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -26,7 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29#include <linux/config.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/types.h> 31#include <linux/types.h>
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 71b80c23e8ce..dd2b762777c4 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -32,7 +32,6 @@
32 * Enabling PCI devices is left as an exercise for the reader... 32 * Enabling PCI devices is left as an exercise for the reader...
33 * 33 *
34 */ 34 */
35#include <linux/config.h>
36#include <linux/kernel.h> 35#include <linux/kernel.h>
37#include <linux/module.h> 36#include <linux/module.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index c4282902cb52..b7b378df89e3 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -27,7 +27,6 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 11f7858f0064..0d8fb6e607a1 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1458,7 +1458,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1458 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ 1458 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
1459 } else { 1459 } else {
1460 /* Installs the interrupt handler */ 1460 /* Installs the interrupt handler */
1461 rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); 1461 rc = request_irq(php_ctlr->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
1462 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); 1462 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1463 if (rc) { 1463 if (rc) {
1464 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); 1464 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 0a46f549676a..8ad446605f75 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -28,7 +28,6 @@
28 * 28 *
29 */ 29 */
30 30
31#include <linux/config.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
34#include <linux/kernel.h> 33#include <linux/kernel.h>
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 638004546700..076bd6dcafae 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -22,7 +22,6 @@
22 * Send feedback to <lxie@us.ibm.com> 22 * Send feedback to <lxie@us.ibm.com>
23 * 23 *
24 */ 24 */
25#include <linux/config.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 45facaad39bd..0f9798df4704 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1246,7 +1246,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1246 } else 1246 } else
1247 php_ctlr->irq = pdev->irq; 1247 php_ctlr->irq = pdev->irq;
1248 1248
1249 rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); 1249 rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
1250 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); 1250 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1251 if (rc) { 1251 if (rc) {
1252 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); 1252 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 76d023d8a33b..36bc7c415af7 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -10,7 +10,6 @@
10#include <linux/irq.h> 10#include <linux/irq.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/config.h>
14#include <linux/ioport.h> 13#include <linux/ioport.h>
15#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
16#include <linux/pci.h> 15#include <linux/pci.h>
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 606f9b6f70eb..fdefa7dcd156 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17 17
18#include <linux/config.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/pci.h> 19#include <linux/pci.h>
21#include <linux/stat.h> 20#include <linux/stat.h>
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4364d793f73b..d1d7333bb71b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -15,7 +15,6 @@
15 * use the PowerTweak utility (see http://powertweak.sourceforge.net). 15 * use the PowerTweak utility (see http://powertweak.sourceforge.net).
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/types.h> 18#include <linux/types.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/pci.h> 20#include <linux/pci.h>
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index cbb69cf41311..f5ee7ce16fa6 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -6,7 +6,6 @@
6 * 6 *
7 * PCI ROM access routines 7 * PCI ROM access routines
8 */ 8 */
9#include <linux/config.h>
10#include <linux/kernel.h> 9#include <linux/kernel.h>
11#include <linux/pci.h> 10#include <linux/pci.h>
12#include <linux/slab.h> 11#include <linux/slab.h>