diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 12:30:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 12:30:25 -0400 |
commit | 96a3e8af5a54c324535472ca946215d5bafe6539 (patch) | |
tree | e59b48aa3fa2b8c6c1f59f76b7b4c71f9c694093 /drivers/pci/hotplug | |
parent | a87451052fb914744571fc3ab39fcbf4fa4ef944 (diff) | |
parent | d4f09c5d7fbabd1389a5f03f5c9329d790f544e3 (diff) |
Merge tag 'pci-v3.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"PCI changes for the v3.10 merge window:
PCI device hotplug
- Remove ACPI PCI subdrivers (Jiang Liu, Myron Stowe)
- Make acpiphp builtin only, not modular (Jiang Liu)
- Add acpiphp mutual exclusion (Jiang Liu)
Power management
- Skip "PME enabled/disabled" messages when not supported (Rafael
Wysocki)
- Fix fallback to PCI_D0 (Rafael Wysocki)
Miscellaneous
- Factor quirk_io_region (Yinghai Lu)
- Cache MSI capability offsets & cleanup (Gavin Shan, Bjorn Helgaas)
- Clean up EISA resource initialization and logging (Bjorn Helgaas)
- Fix prototype warnings (Andy Shevchenko, Bjorn Helgaas)
- MIPS: Initialize of_node before scanning bus (Gabor Juhos)
- Fix pcibios_get_phb_of_node() declaration "weak" annotation (Gabor
Juhos)
- Add MSI INTX_DISABLE quirks for AR8161/AR8162/etc (Xiong Huang)
- Fix aer_inject return values (Prarit Bhargava)
- Remove PME/ACPI dependency (Andrew Murray)
- Use shared PCI_BUS_NUM() and PCI_DEVID() (Shuah Khan)"
* tag 'pci-v3.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (63 commits)
vfio-pci: Use cached MSI/MSI-X capabilities
vfio-pci: Use PCI_MSIX_TABLE_BIR, not PCI_MSIX_FLAGS_BIRMASK
PCI: Remove "extern" from function declarations
PCI: Use PCI_MSIX_TABLE_BIR, not PCI_MSIX_FLAGS_BIRMASK
PCI: Drop msi_mask_reg() and remove drivers/pci/msi.h
PCI: Use msix_table_size() directly, drop multi_msix_capable()
PCI: Drop msix_table_offset_reg() and msix_pba_offset_reg() macros
PCI: Drop is_64bit_address() and is_mask_bit_support() macros
PCI: Drop msi_data_reg() macro
PCI: Drop msi_lower_address_reg() and msi_upper_address_reg() macros
PCI: Drop msi_control_reg() macro and use PCI_MSI_FLAGS directly
PCI: Use cached MSI/MSI-X offsets from dev, not from msi_desc
PCI: Clean up MSI/MSI-X capability #defines
PCI: Use cached MSI-X cap while enabling MSI-X
PCI: Use cached MSI cap while enabling MSI interrupts
PCI: Remove MSI/MSI-X cap check in pci_msi_check_device()
PCI: Cache MSI/MSI-X capability offsets in struct pci_dev
PCI: Use u8, not int, for PM capability offset
[SCSI] megaraid_sas: Use correct #define for MSI-X capability
PCI: Remove "extern" from function declarations
...
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 7 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 35 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 30 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 415 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug.h | 44 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp.h | 70 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_nvram.h | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp.h | 66 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 15 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 22 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_acpi.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpadlpar.h | 8 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp.h | 16 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 26 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_sysfs.c | 2 |
15 files changed, 306 insertions, 464 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 13e9e63a7266..9fcb87f353d4 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -52,15 +52,12 @@ config HOTPLUG_PCI_IBM | |||
52 | When in doubt, say N. | 52 | When in doubt, say N. |
53 | 53 | ||
54 | config HOTPLUG_PCI_ACPI | 54 | config HOTPLUG_PCI_ACPI |
55 | tristate "ACPI PCI Hotplug driver" | 55 | bool "ACPI PCI Hotplug driver" |
56 | depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) | 56 | depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK)) |
57 | help | 57 | help |
58 | Say Y here if you have a system that supports PCI Hotplug using | 58 | Say Y here if you have a system that supports PCI Hotplug using |
59 | ACPI. | 59 | ACPI. |
60 | 60 | ||
61 | To compile this driver as a module, choose M here: the | ||
62 | module will be called acpiphp. | ||
63 | |||
64 | When in doubt, say N. | 61 | When in doubt, say N. |
65 | 62 | ||
66 | config HOTPLUG_PCI_ACPI_IBM | 63 | config HOTPLUG_PCI_ACPI_IBM |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index b70ac00a117e..6fdd49c6f0b9 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -73,8 +73,9 @@ static inline const char *slot_name(struct slot *slot) | |||
73 | */ | 73 | */ |
74 | struct acpiphp_bridge { | 74 | struct acpiphp_bridge { |
75 | struct list_head list; | 75 | struct list_head list; |
76 | struct list_head slots; | ||
77 | struct kref ref; | ||
76 | acpi_handle handle; | 78 | acpi_handle handle; |
77 | struct acpiphp_slot *slots; | ||
78 | 79 | ||
79 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ | 80 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ |
80 | struct acpiphp_func *func; | 81 | struct acpiphp_func *func; |
@@ -97,7 +98,7 @@ struct acpiphp_bridge { | |||
97 | * PCI slot information for each *physical* PCI slot | 98 | * PCI slot information for each *physical* PCI slot |
98 | */ | 99 | */ |
99 | struct acpiphp_slot { | 100 | struct acpiphp_slot { |
100 | struct acpiphp_slot *next; | 101 | struct list_head node; |
101 | struct acpiphp_bridge *bridge; /* parent */ | 102 | struct acpiphp_bridge *bridge; /* parent */ |
102 | struct list_head funcs; /* one slot may have different | 103 | struct list_head funcs; /* one slot may have different |
103 | objects (i.e. for each function) */ | 104 | objects (i.e. for each function) */ |
@@ -119,7 +120,6 @@ struct acpiphp_slot { | |||
119 | */ | 120 | */ |
120 | struct acpiphp_func { | 121 | struct acpiphp_func { |
121 | struct acpiphp_slot *slot; /* parent */ | 122 | struct acpiphp_slot *slot; /* parent */ |
122 | struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ | ||
123 | 123 | ||
124 | struct list_head sibling; | 124 | struct list_head sibling; |
125 | struct notifier_block nb; | 125 | struct notifier_block nb; |
@@ -146,10 +146,6 @@ struct acpiphp_attention_info | |||
146 | #define ACPI_PCI_HOST_HID "PNP0A03" | 146 | #define ACPI_PCI_HOST_HID "PNP0A03" |
147 | 147 | ||
148 | /* ACPI _STA method value (ignore bit 4; battery present) */ | 148 | /* ACPI _STA method value (ignore bit 4; battery present) */ |
149 | #define ACPI_STA_PRESENT (0x00000001) | ||
150 | #define ACPI_STA_ENABLED (0x00000002) | ||
151 | #define ACPI_STA_SHOW_IN_UI (0x00000004) | ||
152 | #define ACPI_STA_FUNCTIONING (0x00000008) | ||
153 | #define ACPI_STA_ALL (0x0000000f) | 149 | #define ACPI_STA_ALL (0x0000000f) |
154 | 150 | ||
155 | /* bridge flags */ | 151 | /* bridge flags */ |
@@ -174,25 +170,24 @@ struct acpiphp_attention_info | |||
174 | /* function prototypes */ | 170 | /* function prototypes */ |
175 | 171 | ||
176 | /* acpiphp_core.c */ | 172 | /* acpiphp_core.c */ |
177 | extern int acpiphp_register_attention(struct acpiphp_attention_info*info); | 173 | int acpiphp_register_attention(struct acpiphp_attention_info*info); |
178 | extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); | 174 | int acpiphp_unregister_attention(struct acpiphp_attention_info *info); |
179 | extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); | 175 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); |
180 | extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | 176 | void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); |
181 | 177 | ||
182 | /* acpiphp_glue.c */ | 178 | /* acpiphp_glue.c */ |
183 | extern int acpiphp_glue_init (void); | ||
184 | extern void acpiphp_glue_exit (void); | ||
185 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 179 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
186 | 180 | ||
187 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 181 | int acpiphp_enable_slot(struct acpiphp_slot *slot); |
188 | extern int acpiphp_disable_slot (struct acpiphp_slot *slot); | 182 | int acpiphp_disable_slot(struct acpiphp_slot *slot); |
189 | extern int acpiphp_eject_slot (struct acpiphp_slot *slot); | 183 | int acpiphp_eject_slot(struct acpiphp_slot *slot); |
190 | extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); | 184 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot); |
191 | extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); | 185 | u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); |
192 | extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); | 186 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); |
193 | extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); | 187 | u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot); |
194 | 188 | ||
195 | /* variables */ | 189 | /* variables */ |
196 | extern bool acpiphp_debug; | 190 | extern bool acpiphp_debug; |
191 | extern bool acpiphp_disabled; | ||
197 | 192 | ||
198 | #endif /* _ACPIPHP_H */ | 193 | #endif /* _ACPIPHP_H */ |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index c2fd3095701f..ca8127950fcd 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci-acpi.h> | ||
40 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/smp.h> | 43 | #include <linux/smp.h> |
@@ -48,6 +49,7 @@ | |||
48 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ | 49 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ |
49 | 50 | ||
50 | bool acpiphp_debug; | 51 | bool acpiphp_debug; |
52 | bool acpiphp_disabled; | ||
51 | 53 | ||
52 | /* local variables */ | 54 | /* local variables */ |
53 | static struct acpiphp_attention_info *attention_info; | 55 | static struct acpiphp_attention_info *attention_info; |
@@ -60,7 +62,9 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
60 | MODULE_DESCRIPTION(DRIVER_DESC); | 62 | MODULE_DESCRIPTION(DRIVER_DESC); |
61 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
62 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 64 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
65 | MODULE_PARM_DESC(disable, "disable acpiphp driver"); | ||
63 | module_param_named(debug, acpiphp_debug, bool, 0644); | 66 | module_param_named(debug, acpiphp_debug, bool, 0644); |
67 | module_param_named(disable, acpiphp_disabled, bool, 0444); | ||
64 | 68 | ||
65 | /* export the attention callback registration methods */ | 69 | /* export the attention callback registration methods */ |
66 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); | 70 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); |
@@ -351,27 +355,9 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
351 | } | 355 | } |
352 | 356 | ||
353 | 357 | ||
354 | static int __init acpiphp_init(void) | 358 | void __init acpiphp_init(void) |
355 | { | 359 | { |
356 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 360 | info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", |
357 | 361 | acpiphp_disabled ? ", disabled by user; please report a bug" | |
358 | if (acpi_pci_disabled) | 362 | : ""); |
359 | return 0; | ||
360 | |||
361 | /* read all the ACPI info from the system */ | ||
362 | /* initialize internal data structure etc. */ | ||
363 | return acpiphp_glue_init(); | ||
364 | } | ||
365 | |||
366 | |||
367 | static void __exit acpiphp_exit(void) | ||
368 | { | ||
369 | if (acpi_pci_disabled) | ||
370 | return; | ||
371 | |||
372 | /* deallocate internal data structures etc. */ | ||
373 | acpiphp_glue_exit(); | ||
374 | } | 363 | } |
375 | |||
376 | module_init(acpiphp_init); | ||
377 | module_exit(acpiphp_exit); | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 270fdbadc19c..96fed19c6d90 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "acpiphp.h" | 54 | #include "acpiphp.h" |
55 | 55 | ||
56 | static LIST_HEAD(bridge_list); | 56 | static LIST_HEAD(bridge_list); |
57 | static DEFINE_MUTEX(bridge_mutex); | ||
57 | 58 | ||
58 | #define MY_NAME "acpiphp_glue" | 59 | #define MY_NAME "acpiphp_glue" |
59 | 60 | ||
@@ -61,6 +62,7 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | |||
61 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
62 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
63 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
65 | static void free_bridge(struct kref *kref); | ||
64 | 66 | ||
65 | /* callback routine to check for the existence of a pci dock device */ | 67 | /* callback routine to check for the existence of a pci dock device */ |
66 | static acpi_status | 68 | static acpi_status |
@@ -76,6 +78,39 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
76 | } | 78 | } |
77 | } | 79 | } |
78 | 80 | ||
81 | static inline void get_bridge(struct acpiphp_bridge *bridge) | ||
82 | { | ||
83 | kref_get(&bridge->ref); | ||
84 | } | ||
85 | |||
86 | static inline void put_bridge(struct acpiphp_bridge *bridge) | ||
87 | { | ||
88 | kref_put(&bridge->ref, free_bridge); | ||
89 | } | ||
90 | |||
91 | static void free_bridge(struct kref *kref) | ||
92 | { | ||
93 | struct acpiphp_bridge *bridge; | ||
94 | struct acpiphp_slot *slot, *next; | ||
95 | struct acpiphp_func *func, *tmp; | ||
96 | |||
97 | bridge = container_of(kref, struct acpiphp_bridge, ref); | ||
98 | |||
99 | list_for_each_entry_safe(slot, next, &bridge->slots, node) { | ||
100 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
101 | kfree(func); | ||
102 | } | ||
103 | kfree(slot); | ||
104 | } | ||
105 | |||
106 | /* Release reference acquired by acpiphp_bridge_handle_to_function() */ | ||
107 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) | ||
108 | put_bridge(bridge->func->slot->bridge); | ||
109 | put_device(&bridge->pci_bus->dev); | ||
110 | pci_dev_put(bridge->pci_dev); | ||
111 | kfree(bridge); | ||
112 | } | ||
113 | |||
79 | /* | 114 | /* |
80 | * the _DCK method can do funny things... and sometimes not | 115 | * the _DCK method can do funny things... and sometimes not |
81 | * hah-hah funny. | 116 | * hah-hah funny. |
@@ -154,9 +189,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
154 | acpi_handle tmp; | 189 | acpi_handle tmp; |
155 | acpi_status status = AE_OK; | 190 | acpi_status status = AE_OK; |
156 | unsigned long long adr, sun; | 191 | unsigned long long adr, sun; |
157 | int device, function, retval; | 192 | int device, function, retval, found = 0; |
158 | struct pci_bus *pbus = bridge->pci_bus; | 193 | struct pci_bus *pbus = bridge->pci_bus; |
159 | struct pci_dev *pdev; | 194 | struct pci_dev *pdev; |
195 | u32 val; | ||
160 | 196 | ||
161 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 197 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
162 | return AE_OK; | 198 | return AE_OK; |
@@ -170,7 +206,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
170 | device = (adr >> 16) & 0xffff; | 206 | device = (adr >> 16) & 0xffff; |
171 | function = adr & 0xffff; | 207 | function = adr & 0xffff; |
172 | 208 | ||
173 | pdev = pbus->self; | 209 | pdev = bridge->pci_dev; |
174 | if (pdev && device_is_managed_by_native_pciehp(pdev)) | 210 | if (pdev && device_is_managed_by_native_pciehp(pdev)) |
175 | return AE_OK; | 211 | return AE_OK; |
176 | 212 | ||
@@ -178,7 +214,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
178 | if (!newfunc) | 214 | if (!newfunc) |
179 | return AE_NO_MEMORY; | 215 | return AE_NO_MEMORY; |
180 | 216 | ||
181 | INIT_LIST_HEAD(&newfunc->sibling); | ||
182 | newfunc->handle = handle; | 217 | newfunc->handle = handle; |
183 | newfunc->function = function; | 218 | newfunc->function = function; |
184 | 219 | ||
@@ -207,14 +242,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
207 | } | 242 | } |
208 | 243 | ||
209 | /* search for objects that share the same slot */ | 244 | /* search for objects that share the same slot */ |
210 | for (slot = bridge->slots; slot; slot = slot->next) | 245 | list_for_each_entry(slot, &bridge->slots, node) |
211 | if (slot->device == device) { | 246 | if (slot->device == device) { |
212 | if (slot->sun != sun) | 247 | if (slot->sun != sun) |
213 | warn("sibling found, but _SUN doesn't match!\n"); | 248 | warn("sibling found, but _SUN doesn't match!\n"); |
249 | found = 1; | ||
214 | break; | 250 | break; |
215 | } | 251 | } |
216 | 252 | ||
217 | if (!slot) { | 253 | if (!found) { |
218 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); | 254 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); |
219 | if (!slot) { | 255 | if (!slot) { |
220 | kfree(newfunc); | 256 | kfree(newfunc); |
@@ -227,9 +263,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
227 | INIT_LIST_HEAD(&slot->funcs); | 263 | INIT_LIST_HEAD(&slot->funcs); |
228 | mutex_init(&slot->crit_sect); | 264 | mutex_init(&slot->crit_sect); |
229 | 265 | ||
230 | slot->next = bridge->slots; | 266 | mutex_lock(&bridge_mutex); |
231 | bridge->slots = slot; | 267 | list_add_tail(&slot->node, &bridge->slots); |
232 | 268 | mutex_unlock(&bridge_mutex); | |
233 | bridge->nr_slots++; | 269 | bridge->nr_slots++; |
234 | 270 | ||
235 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", | 271 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", |
@@ -247,13 +283,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
247 | } | 283 | } |
248 | 284 | ||
249 | newfunc->slot = slot; | 285 | newfunc->slot = slot; |
286 | mutex_lock(&bridge_mutex); | ||
250 | list_add_tail(&newfunc->sibling, &slot->funcs); | 287 | list_add_tail(&newfunc->sibling, &slot->funcs); |
288 | mutex_unlock(&bridge_mutex); | ||
251 | 289 | ||
252 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); | 290 | if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), |
253 | if (pdev) { | 291 | &val, 60*1000)) |
254 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 292 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
255 | pci_dev_put(pdev); | ||
256 | } | ||
257 | 293 | ||
258 | if (is_dock_device(handle)) { | 294 | if (is_dock_device(handle)) { |
259 | /* we don't want to call this device's _EJ0 | 295 | /* we don't want to call this device's _EJ0 |
@@ -290,7 +326,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
290 | 326 | ||
291 | err_exit: | 327 | err_exit: |
292 | bridge->nr_slots--; | 328 | bridge->nr_slots--; |
293 | bridge->slots = slot->next; | 329 | mutex_lock(&bridge_mutex); |
330 | list_del(&slot->node); | ||
331 | mutex_unlock(&bridge_mutex); | ||
294 | kfree(slot); | 332 | kfree(slot); |
295 | kfree(newfunc); | 333 | kfree(newfunc); |
296 | 334 | ||
@@ -315,13 +353,17 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
315 | acpi_status status; | 353 | acpi_status status; |
316 | 354 | ||
317 | /* must be added to the list prior to calling register_slot */ | 355 | /* must be added to the list prior to calling register_slot */ |
356 | mutex_lock(&bridge_mutex); | ||
318 | list_add(&bridge->list, &bridge_list); | 357 | list_add(&bridge->list, &bridge_list); |
358 | mutex_unlock(&bridge_mutex); | ||
319 | 359 | ||
320 | /* register all slot objects under this bridge */ | 360 | /* register all slot objects under this bridge */ |
321 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | 361 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, |
322 | register_slot, NULL, bridge, NULL); | 362 | register_slot, NULL, bridge, NULL); |
323 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
364 | mutex_lock(&bridge_mutex); | ||
324 | list_del(&bridge->list); | 365 | list_del(&bridge->list); |
366 | mutex_unlock(&bridge_mutex); | ||
325 | return; | 367 | return; |
326 | } | 368 | } |
327 | 369 | ||
@@ -351,178 +393,46 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle | |||
351 | { | 393 | { |
352 | struct acpiphp_bridge *bridge; | 394 | struct acpiphp_bridge *bridge; |
353 | struct acpiphp_slot *slot; | 395 | struct acpiphp_slot *slot; |
354 | struct acpiphp_func *func; | 396 | struct acpiphp_func *func = NULL; |
355 | 397 | ||
398 | mutex_lock(&bridge_mutex); | ||
356 | list_for_each_entry(bridge, &bridge_list, list) { | 399 | list_for_each_entry(bridge, &bridge_list, list) { |
357 | for (slot = bridge->slots; slot; slot = slot->next) { | 400 | list_for_each_entry(slot, &bridge->slots, node) { |
358 | list_for_each_entry(func, &slot->funcs, sibling) { | 401 | list_for_each_entry(func, &slot->funcs, sibling) { |
359 | if (func->handle == handle) | 402 | if (func->handle == handle) { |
403 | get_bridge(func->slot->bridge); | ||
404 | mutex_unlock(&bridge_mutex); | ||
360 | return func; | 405 | return func; |
406 | } | ||
361 | } | 407 | } |
362 | } | 408 | } |
363 | } | 409 | } |
410 | mutex_unlock(&bridge_mutex); | ||
364 | 411 | ||
365 | return NULL; | 412 | return NULL; |
366 | } | 413 | } |
367 | 414 | ||
368 | 415 | ||
369 | static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) | ||
370 | { | ||
371 | acpi_handle dummy_handle; | ||
372 | struct acpiphp_func *func; | ||
373 | |||
374 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
375 | "_EJ0", &dummy_handle))) { | ||
376 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
377 | |||
378 | dbg("found ejectable p2p bridge\n"); | ||
379 | |||
380 | /* make link between PCI bridge and PCI function */ | ||
381 | func = acpiphp_bridge_handle_to_function(bridge->handle); | ||
382 | if (!func) | ||
383 | return; | ||
384 | bridge->func = func; | ||
385 | func->bridge = bridge; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | |||
390 | /* allocate and initialize host bridge data structure */ | ||
391 | static void add_host_bridge(struct acpi_pci_root *root) | ||
392 | { | ||
393 | struct acpiphp_bridge *bridge; | ||
394 | acpi_handle handle = root->device->handle; | ||
395 | |||
396 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
397 | if (bridge == NULL) | ||
398 | return; | ||
399 | |||
400 | bridge->handle = handle; | ||
401 | |||
402 | bridge->pci_bus = root->bus; | ||
403 | |||
404 | init_bridge_misc(bridge); | ||
405 | } | ||
406 | |||
407 | |||
408 | /* allocate and initialize PCI-to-PCI bridge data structure */ | ||
409 | static void add_p2p_bridge(acpi_handle *handle) | ||
410 | { | ||
411 | struct acpiphp_bridge *bridge; | ||
412 | |||
413 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
414 | if (bridge == NULL) { | ||
415 | err("out of memory\n"); | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | bridge->handle = handle; | ||
420 | config_p2p_bridge_flags(bridge); | ||
421 | |||
422 | bridge->pci_dev = acpi_get_pci_dev(handle); | ||
423 | bridge->pci_bus = bridge->pci_dev->subordinate; | ||
424 | if (!bridge->pci_bus) { | ||
425 | err("This is not a PCI-to-PCI bridge!\n"); | ||
426 | goto err; | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
431 | * removed via PCI core logical hotplug. The ref pins the bus | ||
432 | * (which we access during module unload). | ||
433 | */ | ||
434 | get_device(&bridge->pci_bus->dev); | ||
435 | |||
436 | init_bridge_misc(bridge); | ||
437 | return; | ||
438 | err: | ||
439 | pci_dev_put(bridge->pci_dev); | ||
440 | kfree(bridge); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | |||
445 | /* callback routine to find P2P bridges */ | ||
446 | static acpi_status | ||
447 | find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
448 | { | ||
449 | acpi_status status; | ||
450 | struct pci_dev *dev; | ||
451 | |||
452 | dev = acpi_get_pci_dev(handle); | ||
453 | if (!dev || !dev->subordinate) | ||
454 | goto out; | ||
455 | |||
456 | /* check if this bridge has ejectable slots */ | ||
457 | if ((detect_ejectable_slots(handle) > 0)) { | ||
458 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); | ||
459 | add_p2p_bridge(handle); | ||
460 | } | ||
461 | |||
462 | /* search P2P bridges under this p2p bridge */ | ||
463 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
464 | find_p2p_bridge, NULL, NULL, NULL); | ||
465 | if (ACPI_FAILURE(status)) | ||
466 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
467 | |||
468 | out: | ||
469 | pci_dev_put(dev); | ||
470 | return AE_OK; | ||
471 | } | ||
472 | |||
473 | |||
474 | /* find hot-pluggable slots, and then find P2P bridge */ | ||
475 | static int add_bridge(struct acpi_pci_root *root) | ||
476 | { | ||
477 | acpi_status status; | ||
478 | unsigned long long tmp; | ||
479 | acpi_handle dummy_handle; | ||
480 | acpi_handle handle = root->device->handle; | ||
481 | |||
482 | /* if the bridge doesn't have _STA, we assume it is always there */ | ||
483 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | ||
484 | if (ACPI_SUCCESS(status)) { | ||
485 | status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); | ||
486 | if (ACPI_FAILURE(status)) { | ||
487 | dbg("%s: _STA evaluation failure\n", __func__); | ||
488 | return 0; | ||
489 | } | ||
490 | if ((tmp & ACPI_STA_FUNCTIONING) == 0) | ||
491 | /* don't register this object */ | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* check if this bridge has ejectable slots */ | ||
496 | if (detect_ejectable_slots(handle) > 0) { | ||
497 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); | ||
498 | add_host_bridge(root); | ||
499 | } | ||
500 | |||
501 | /* search P2P bridges under this host bridge */ | ||
502 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
503 | find_p2p_bridge, NULL, NULL, NULL); | ||
504 | |||
505 | if (ACPI_FAILURE(status)) | ||
506 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 416 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
512 | { | 417 | { |
513 | struct acpiphp_bridge *bridge; | 418 | struct acpiphp_bridge *bridge; |
514 | 419 | ||
420 | mutex_lock(&bridge_mutex); | ||
515 | list_for_each_entry(bridge, &bridge_list, list) | 421 | list_for_each_entry(bridge, &bridge_list, list) |
516 | if (bridge->handle == handle) | 422 | if (bridge->handle == handle) { |
423 | get_bridge(bridge); | ||
424 | mutex_unlock(&bridge_mutex); | ||
517 | return bridge; | 425 | return bridge; |
426 | } | ||
427 | mutex_unlock(&bridge_mutex); | ||
518 | 428 | ||
519 | return NULL; | 429 | return NULL; |
520 | } | 430 | } |
521 | 431 | ||
522 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 432 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
523 | { | 433 | { |
524 | struct acpiphp_slot *slot, *next; | 434 | struct acpiphp_slot *slot; |
525 | struct acpiphp_func *func, *tmp; | 435 | struct acpiphp_func *func; |
526 | acpi_status status; | 436 | acpi_status status; |
527 | acpi_handle handle = bridge->handle; | 437 | acpi_handle handle = bridge->handle; |
528 | 438 | ||
@@ -543,10 +453,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
543 | err("failed to install interrupt notify handler\n"); | 453 | err("failed to install interrupt notify handler\n"); |
544 | } | 454 | } |
545 | 455 | ||
546 | slot = bridge->slots; | 456 | list_for_each_entry(slot, &bridge->slots, node) { |
547 | while (slot) { | 457 | list_for_each_entry(func, &slot->funcs, sibling) { |
548 | next = slot->next; | ||
549 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
550 | if (is_dock_device(func->handle)) { | 458 | if (is_dock_device(func->handle)) { |
551 | unregister_hotplug_dock_device(func->handle); | 459 | unregister_hotplug_dock_device(func->handle); |
552 | unregister_dock_notifier(&func->nb); | 460 | unregister_dock_notifier(&func->nb); |
@@ -558,63 +466,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
558 | if (ACPI_FAILURE(status)) | 466 | if (ACPI_FAILURE(status)) |
559 | err("failed to remove notify handler\n"); | 467 | err("failed to remove notify handler\n"); |
560 | } | 468 | } |
561 | list_del(&func->sibling); | ||
562 | kfree(func); | ||
563 | } | 469 | } |
564 | acpiphp_unregister_hotplug_slot(slot); | 470 | acpiphp_unregister_hotplug_slot(slot); |
565 | list_del(&slot->funcs); | ||
566 | kfree(slot); | ||
567 | slot = next; | ||
568 | } | 471 | } |
569 | 472 | ||
570 | /* | 473 | mutex_lock(&bridge_mutex); |
571 | * Only P2P bridges have a pci_dev | ||
572 | */ | ||
573 | if (bridge->pci_dev) | ||
574 | put_device(&bridge->pci_bus->dev); | ||
575 | |||
576 | pci_dev_put(bridge->pci_dev); | ||
577 | list_del(&bridge->list); | 474 | list_del(&bridge->list); |
578 | kfree(bridge); | 475 | mutex_unlock(&bridge_mutex); |
579 | } | ||
580 | |||
581 | static acpi_status | ||
582 | cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
583 | { | ||
584 | struct acpiphp_bridge *bridge; | ||
585 | |||
586 | /* cleanup p2p bridges under this P2P bridge | ||
587 | in a depth-first manner */ | ||
588 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
589 | cleanup_p2p_bridge, NULL, NULL, NULL); | ||
590 | |||
591 | bridge = acpiphp_handle_to_bridge(handle); | ||
592 | if (bridge) | ||
593 | cleanup_bridge(bridge); | ||
594 | |||
595 | return AE_OK; | ||
596 | } | ||
597 | |||
598 | static void remove_bridge(struct acpi_pci_root *root) | ||
599 | { | ||
600 | struct acpiphp_bridge *bridge; | ||
601 | acpi_handle handle = root->device->handle; | ||
602 | |||
603 | /* cleanup p2p bridges under this host bridge | ||
604 | in a depth-first manner */ | ||
605 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
606 | (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); | ||
607 | |||
608 | /* | ||
609 | * On root bridges with hotplug slots directly underneath (ie, | ||
610 | * no p2p bridge between), we call cleanup_bridge(). | ||
611 | * | ||
612 | * The else clause cleans up root bridges that either had no | ||
613 | * hotplug slots at all, or had a p2p bridge underneath. | ||
614 | */ | ||
615 | bridge = acpiphp_handle_to_bridge(handle); | ||
616 | if (bridge) | ||
617 | cleanup_bridge(bridge); | ||
618 | } | 476 | } |
619 | 477 | ||
620 | static int power_on_slot(struct acpiphp_slot *slot) | 478 | static int power_on_slot(struct acpiphp_slot *slot) |
@@ -798,6 +656,7 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | |||
798 | } | 656 | } |
799 | } | 657 | } |
800 | } | 658 | } |
659 | |||
801 | /** | 660 | /** |
802 | * enable_device - enable, configure a slot | 661 | * enable_device - enable, configure a slot |
803 | * @slot: slot to be enabled | 662 | * @slot: slot to be enabled |
@@ -810,9 +669,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
810 | struct pci_dev *dev; | 669 | struct pci_dev *dev; |
811 | struct pci_bus *bus = slot->bridge->pci_bus; | 670 | struct pci_bus *bus = slot->bridge->pci_bus; |
812 | struct acpiphp_func *func; | 671 | struct acpiphp_func *func; |
813 | int retval = 0; | ||
814 | int num, max, pass; | 672 | int num, max, pass; |
815 | acpi_status status; | ||
816 | 673 | ||
817 | if (slot->flags & SLOT_ENABLED) | 674 | if (slot->flags & SLOT_ENABLED) |
818 | goto err_exit; | 675 | goto err_exit; |
@@ -867,23 +724,11 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
867 | slot->flags &= (~SLOT_ENABLED); | 724 | slot->flags &= (~SLOT_ENABLED); |
868 | continue; | 725 | continue; |
869 | } | 726 | } |
870 | |||
871 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | ||
872 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { | ||
873 | pci_dev_put(dev); | ||
874 | continue; | ||
875 | } | ||
876 | |||
877 | status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); | ||
878 | if (ACPI_FAILURE(status)) | ||
879 | warn("find_p2p_bridge failed (error code = 0x%x)\n", | ||
880 | status); | ||
881 | pci_dev_put(dev); | ||
882 | } | 727 | } |
883 | 728 | ||
884 | 729 | ||
885 | err_exit: | 730 | err_exit: |
886 | return retval; | 731 | return 0; |
887 | } | 732 | } |
888 | 733 | ||
889 | /* return first device in slot, acquiring a reference on it */ | 734 | /* return first device in slot, acquiring a reference on it */ |
@@ -912,23 +757,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
912 | { | 757 | { |
913 | struct acpiphp_func *func; | 758 | struct acpiphp_func *func; |
914 | struct pci_dev *pdev; | 759 | struct pci_dev *pdev; |
915 | struct pci_bus *bus = slot->bridge->pci_bus; | ||
916 | |||
917 | /* The slot will be enabled when func 0 is added, so check | ||
918 | func 0 before disable the slot. */ | ||
919 | pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
920 | if (!pdev) | ||
921 | goto err_exit; | ||
922 | pci_dev_put(pdev); | ||
923 | |||
924 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
925 | if (func->bridge) { | ||
926 | /* cleanup p2p bridges under this P2P bridge */ | ||
927 | cleanup_p2p_bridge(func->bridge->handle, | ||
928 | (u32)1, NULL, NULL); | ||
929 | func->bridge = NULL; | ||
930 | } | ||
931 | } | ||
932 | 760 | ||
933 | /* | 761 | /* |
934 | * enable_device() enumerates all functions in this device via | 762 | * enable_device() enumerates all functions in this device via |
@@ -947,7 +775,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
947 | 775 | ||
948 | slot->flags &= (~SLOT_ENABLED); | 776 | slot->flags &= (~SLOT_ENABLED); |
949 | 777 | ||
950 | err_exit: | ||
951 | return 0; | 778 | return 0; |
952 | } | 779 | } |
953 | 780 | ||
@@ -1037,7 +864,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
1037 | 864 | ||
1038 | enabled = disabled = 0; | 865 | enabled = disabled = 0; |
1039 | 866 | ||
1040 | for (slot = bridge->slots; slot; slot = slot->next) { | 867 | list_for_each_entry(slot, &bridge->slots, node) { |
1041 | unsigned int status = get_slot_status(slot); | 868 | unsigned int status = get_slot_status(slot); |
1042 | if (slot->flags & SLOT_ENABLED) { | 869 | if (slot->flags & SLOT_ENABLED) { |
1043 | if (status == ACPI_STA_ALL) | 870 | if (status == ACPI_STA_ALL) |
@@ -1082,11 +909,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus) | |||
1082 | */ | 909 | */ |
1083 | static void acpiphp_sanitize_bus(struct pci_bus *bus) | 910 | static void acpiphp_sanitize_bus(struct pci_bus *bus) |
1084 | { | 911 | { |
1085 | struct pci_dev *dev; | 912 | struct pci_dev *dev, *tmp; |
1086 | int i; | 913 | int i; |
1087 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 914 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
1088 | 915 | ||
1089 | list_for_each_entry(dev, &bus->devices, bus_list) { | 916 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
1090 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 917 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
1091 | struct resource *res = &dev->resource[i]; | 918 | struct resource *res = &dev->resource[i]; |
1092 | if ((res->flags & type_mask) && !res->start && | 919 | if ((res->flags & type_mask) && !res->start && |
@@ -1118,6 +945,7 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1118 | dbg("%s: re-enumerating slots under %s\n", | 945 | dbg("%s: re-enumerating slots under %s\n", |
1119 | __func__, objname); | 946 | __func__, objname); |
1120 | acpiphp_check_bridge(bridge); | 947 | acpiphp_check_bridge(bridge); |
948 | put_bridge(bridge); | ||
1121 | } | 949 | } |
1122 | return AE_OK ; | 950 | return AE_OK ; |
1123 | } | 951 | } |
@@ -1195,6 +1023,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1195 | 1023 | ||
1196 | acpi_scan_lock_release(); | 1024 | acpi_scan_lock_release(); |
1197 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | 1025 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ |
1026 | put_bridge(bridge); | ||
1198 | } | 1027 | } |
1199 | 1028 | ||
1200 | /** | 1029 | /** |
@@ -1208,6 +1037,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1208 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | 1037 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, |
1209 | void *context) | 1038 | void *context) |
1210 | { | 1039 | { |
1040 | struct acpiphp_bridge *bridge = context; | ||
1041 | |||
1211 | /* | 1042 | /* |
1212 | * Currently the code adds all hotplug events to the kacpid_wq | 1043 | * Currently the code adds all hotplug events to the kacpid_wq |
1213 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1044 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
@@ -1216,6 +1047,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
1216 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1047 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1217 | * don't deadlock on hotplug actions. | 1048 | * don't deadlock on hotplug actions. |
1218 | */ | 1049 | */ |
1050 | get_bridge(bridge); | ||
1219 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | 1051 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
1220 | } | 1052 | } |
1221 | 1053 | ||
@@ -1270,6 +1102,7 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1270 | 1102 | ||
1271 | acpi_scan_lock_release(); | 1103 | acpi_scan_lock_release(); |
1272 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 1104 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ |
1105 | put_bridge(func->slot->bridge); | ||
1273 | } | 1106 | } |
1274 | 1107 | ||
1275 | /** | 1108 | /** |
@@ -1283,6 +1116,8 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1283 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, | 1116 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, |
1284 | void *context) | 1117 | void *context) |
1285 | { | 1118 | { |
1119 | struct acpiphp_func *func = context; | ||
1120 | |||
1286 | /* | 1121 | /* |
1287 | * Currently the code adds all hotplug events to the kacpid_wq | 1122 | * Currently the code adds all hotplug events to the kacpid_wq |
1288 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1123 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
@@ -1291,33 +1126,69 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
1291 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1126 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1292 | * don't deadlock on hotplug actions. | 1127 | * don't deadlock on hotplug actions. |
1293 | */ | 1128 | */ |
1129 | get_bridge(func->slot->bridge); | ||
1294 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); | 1130 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); |
1295 | } | 1131 | } |
1296 | 1132 | ||
1297 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1133 | /* |
1298 | .add = add_bridge, | 1134 | * Create hotplug slots for the PCI bus. |
1299 | .remove = remove_bridge, | 1135 | * It should always return 0 to avoid skipping following notifiers. |
1300 | }; | ||
1301 | |||
1302 | /** | ||
1303 | * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures | ||
1304 | */ | 1136 | */ |
1305 | int __init acpiphp_glue_init(void) | 1137 | void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) |
1306 | { | 1138 | { |
1307 | acpi_pci_register_driver(&acpi_pci_hp_driver); | 1139 | acpi_handle dummy_handle; |
1140 | struct acpiphp_bridge *bridge; | ||
1308 | 1141 | ||
1309 | return 0; | 1142 | if (acpiphp_disabled) |
1310 | } | 1143 | return; |
1311 | 1144 | ||
1145 | if (detect_ejectable_slots(handle) <= 0) | ||
1146 | return; | ||
1312 | 1147 | ||
1313 | /** | 1148 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
1314 | * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures | 1149 | if (bridge == NULL) { |
1315 | * | 1150 | err("out of memory\n"); |
1316 | * This function frees all data allocated in acpiphp_glue_init(). | 1151 | return; |
1317 | */ | 1152 | } |
1318 | void acpiphp_glue_exit(void) | 1153 | |
1154 | INIT_LIST_HEAD(&bridge->slots); | ||
1155 | kref_init(&bridge->ref); | ||
1156 | bridge->handle = handle; | ||
1157 | bridge->pci_dev = pci_dev_get(bus->self); | ||
1158 | bridge->pci_bus = bus; | ||
1159 | |||
1160 | /* | ||
1161 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
1162 | * removed via PCI core logical hotplug. The ref pins the bus | ||
1163 | * (which we access during module unload). | ||
1164 | */ | ||
1165 | get_device(&bus->dev); | ||
1166 | |||
1167 | if (!pci_is_root_bus(bridge->pci_bus) && | ||
1168 | ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
1169 | "_EJ0", &dummy_handle))) { | ||
1170 | dbg("found ejectable p2p bridge\n"); | ||
1171 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
1172 | bridge->func = acpiphp_bridge_handle_to_function(handle); | ||
1173 | } | ||
1174 | |||
1175 | init_bridge_misc(bridge); | ||
1176 | } | ||
1177 | |||
1178 | /* Destroy hotplug slots associated with the PCI bus */ | ||
1179 | void acpiphp_remove_slots(struct pci_bus *bus) | ||
1319 | { | 1180 | { |
1320 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1181 | struct acpiphp_bridge *bridge, *tmp; |
1182 | |||
1183 | if (acpiphp_disabled) | ||
1184 | return; | ||
1185 | |||
1186 | list_for_each_entry_safe(bridge, tmp, &bridge_list, list) | ||
1187 | if (bridge->pci_bus == bus) { | ||
1188 | cleanup_bridge(bridge); | ||
1189 | put_bridge(bridge); | ||
1190 | break; | ||
1191 | } | ||
1321 | } | 1192 | } |
1322 | 1193 | ||
1323 | /** | 1194 | /** |
@@ -1396,7 +1267,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | |||
1396 | 1267 | ||
1397 | sta = get_slot_status(slot); | 1268 | sta = get_slot_status(slot); |
1398 | 1269 | ||
1399 | return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; | 1270 | return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; |
1400 | } | 1271 | } |
1401 | 1272 | ||
1402 | 1273 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 9fff878cf026..1356211431d0 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h | |||
@@ -75,28 +75,36 @@ static inline const char *slot_name(struct slot *slot) | |||
75 | return hotplug_slot_name(slot->hotplug_slot); | 75 | return hotplug_slot_name(slot->hotplug_slot); |
76 | } | 76 | } |
77 | 77 | ||
78 | extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); | 78 | int cpci_hp_register_controller(struct cpci_hp_controller *controller); |
79 | extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); | 79 | int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); |
80 | extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); | 80 | int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); |
81 | extern int cpci_hp_unregister_bus(struct pci_bus *bus); | 81 | int cpci_hp_unregister_bus(struct pci_bus *bus); |
82 | extern int cpci_hp_start(void); | 82 | int cpci_hp_start(void); |
83 | extern int cpci_hp_stop(void); | 83 | int cpci_hp_stop(void); |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * Internal function prototypes, these functions should not be used by | 86 | * Internal function prototypes, these functions should not be used by |
87 | * board/chassis drivers. | 87 | * board/chassis drivers. |
88 | */ | 88 | */ |
89 | extern u8 cpci_get_attention_status(struct slot *slot); | 89 | u8 cpci_get_attention_status(struct slot *slot); |
90 | extern u8 cpci_get_latch_status(struct slot *slot); | 90 | u8 cpci_get_latch_status(struct slot *slot); |
91 | extern u8 cpci_get_adapter_status(struct slot *slot); | 91 | u8 cpci_get_adapter_status(struct slot *slot); |
92 | extern u16 cpci_get_hs_csr(struct slot * slot); | 92 | u16 cpci_get_hs_csr(struct slot * slot); |
93 | extern int cpci_set_attention_status(struct slot *slot, int status); | 93 | int cpci_set_attention_status(struct slot *slot, int status); |
94 | extern int cpci_check_and_clear_ins(struct slot * slot); | 94 | int cpci_check_and_clear_ins(struct slot * slot); |
95 | extern int cpci_check_ext(struct slot * slot); | 95 | int cpci_check_ext(struct slot * slot); |
96 | extern int cpci_clear_ext(struct slot * slot); | 96 | int cpci_clear_ext(struct slot * slot); |
97 | extern int cpci_led_on(struct slot * slot); | 97 | int cpci_led_on(struct slot * slot); |
98 | extern int cpci_led_off(struct slot * slot); | 98 | int cpci_led_off(struct slot * slot); |
99 | extern int cpci_configure_slot(struct slot *slot); | 99 | int cpci_configure_slot(struct slot *slot); |
100 | extern int cpci_unconfigure_slot(struct slot *slot); | 100 | int cpci_unconfigure_slot(struct slot *slot); |
101 | |||
102 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
103 | int cpci_hotplug_init(int debug); | ||
104 | void cpci_hotplug_exit(void); | ||
105 | #else | ||
106 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
107 | static inline void cpci_hotplug_exit(void) { } | ||
108 | #endif | ||
101 | 109 | ||
102 | #endif /* _CPCI_HOTPLUG_H */ | 110 | #endif /* _CPCI_HOTPLUG_H */ |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index d8ffc7366801..516b87738b6e 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -404,50 +404,44 @@ struct resource_lists { | |||
404 | 404 | ||
405 | 405 | ||
406 | /* debugfs functions for the hotplug controller info */ | 406 | /* debugfs functions for the hotplug controller info */ |
407 | extern void cpqhp_initialize_debugfs(void); | 407 | void cpqhp_initialize_debugfs(void); |
408 | extern void cpqhp_shutdown_debugfs(void); | 408 | void cpqhp_shutdown_debugfs(void); |
409 | extern void cpqhp_create_debugfs_files(struct controller *ctrl); | 409 | void cpqhp_create_debugfs_files(struct controller *ctrl); |
410 | extern void cpqhp_remove_debugfs_files(struct controller *ctrl); | 410 | void cpqhp_remove_debugfs_files(struct controller *ctrl); |
411 | 411 | ||
412 | /* controller functions */ | 412 | /* controller functions */ |
413 | extern void cpqhp_pushbutton_thread(unsigned long event_pointer); | 413 | void cpqhp_pushbutton_thread(unsigned long event_pointer); |
414 | extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); | 414 | irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); |
415 | extern int cpqhp_find_available_resources(struct controller *ctrl, | 415 | int cpqhp_find_available_resources(struct controller *ctrl, |
416 | void __iomem *rom_start); | 416 | void __iomem *rom_start); |
417 | extern int cpqhp_event_start_thread(void); | 417 | int cpqhp_event_start_thread(void); |
418 | extern void cpqhp_event_stop_thread(void); | 418 | void cpqhp_event_stop_thread(void); |
419 | extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); | 419 | struct pci_func *cpqhp_slot_create(unsigned char busnumber); |
420 | extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, | 420 | struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, |
421 | unsigned char index); | 421 | unsigned char index); |
422 | extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); | 422 | int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); |
423 | extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); | 423 | int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); |
424 | extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); | 424 | int cpqhp_hardware_test(struct controller *ctrl, int test_num); |
425 | 425 | ||
426 | /* resource functions */ | 426 | /* resource functions */ |
427 | extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); | 427 | int cpqhp_resource_sort_and_combine (struct pci_resource **head); |
428 | 428 | ||
429 | /* pci functions */ | 429 | /* pci functions */ |
430 | extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); | 430 | int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); |
431 | extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, | 431 | int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, |
432 | u8 slot); | 432 | u8 slot); |
433 | extern int cpqhp_save_config(struct controller *ctrl, int busnumber, | 433 | int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); |
434 | int is_hot_plug); | 434 | int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); |
435 | extern int cpqhp_save_base_addr_length(struct controller *ctrl, | 435 | int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); |
436 | struct pci_func *func); | 436 | int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); |
437 | extern int cpqhp_save_used_resources(struct controller *ctrl, | 437 | int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); |
438 | struct pci_func *func); | 438 | int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); |
439 | extern int cpqhp_configure_board(struct controller *ctrl, | 439 | void cpqhp_destroy_board_resources(struct pci_func *func); |
440 | struct pci_func *func); | 440 | int cpqhp_return_board_resources(struct pci_func *func, |
441 | extern int cpqhp_save_slot_config(struct controller *ctrl, | 441 | struct resource_lists *resources); |
442 | struct pci_func *new_slot); | 442 | void cpqhp_destroy_resource_list(struct resource_lists *resources); |
443 | extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); | 443 | int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); |
444 | extern void cpqhp_destroy_board_resources(struct pci_func *func); | 444 | int cpqhp_unconfigure_device(struct pci_func *func); |
445 | extern int cpqhp_return_board_resources (struct pci_func *func, | ||
446 | struct resource_lists *resources); | ||
447 | extern void cpqhp_destroy_resource_list(struct resource_lists *resources); | ||
448 | extern int cpqhp_configure_device(struct controller *ctrl, | ||
449 | struct pci_func *func); | ||
450 | extern int cpqhp_unconfigure_device(struct pci_func *func); | ||
451 | 445 | ||
452 | /* Global variables */ | 446 | /* Global variables */ |
453 | extern int cpqhp_debug; | 447 | extern int cpqhp_debug; |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h index e89c0702119d..34e4e54fcf15 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.h +++ b/drivers/pci/hotplug/cpqphp_nvram.h | |||
@@ -30,26 +30,26 @@ | |||
30 | 30 | ||
31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM | 31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM |
32 | 32 | ||
33 | static inline void compaq_nvram_init (void __iomem *rom_start) | 33 | static inline void compaq_nvram_init(void __iomem *rom_start) |
34 | { | 34 | { |
35 | return; | 35 | return; |
36 | } | 36 | } |
37 | 37 | ||
38 | static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | 38 | static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) |
39 | { | 39 | { |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline int compaq_nvram_store (void __iomem *rom_start) | 43 | static inline int compaq_nvram_store(void __iomem *rom_start) |
44 | { | 44 | { |
45 | return 0; | 45 | return 0; |
46 | } | 46 | } |
47 | 47 | ||
48 | #else | 48 | #else |
49 | 49 | ||
50 | extern void compaq_nvram_init (void __iomem *rom_start); | 50 | void compaq_nvram_init(void __iomem *rom_start); |
51 | extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); | 51 | int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); |
52 | extern int compaq_nvram_store (void __iomem *rom_start); | 52 | int compaq_nvram_store(void __iomem *rom_start); |
53 | 53 | ||
54 | #endif | 54 | #endif |
55 | 55 | ||
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index a8d391a4957d..8c5b25871d02 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
@@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head; | |||
275 | * FUNCTION PROTOTYPES * | 275 | * FUNCTION PROTOTYPES * |
276 | ***********************************************************/ | 276 | ***********************************************************/ |
277 | 277 | ||
278 | extern void ibmphp_free_ebda_hpc_queue (void); | 278 | void ibmphp_free_ebda_hpc_queue(void); |
279 | extern int ibmphp_access_ebda (void); | 279 | int ibmphp_access_ebda(void); |
280 | extern struct slot *ibmphp_get_slot_from_physical_num (u8); | 280 | struct slot *ibmphp_get_slot_from_physical_num(u8); |
281 | extern int ibmphp_get_total_hp_slots (void); | 281 | int ibmphp_get_total_hp_slots(void); |
282 | extern void ibmphp_free_ibm_slot (struct slot *); | 282 | void ibmphp_free_ibm_slot(struct slot *); |
283 | extern void ibmphp_free_bus_info_queue (void); | 283 | void ibmphp_free_bus_info_queue(void); |
284 | extern void ibmphp_free_ebda_pci_rsrc_queue (void); | 284 | void ibmphp_free_ebda_pci_rsrc_queue(void); |
285 | extern struct bus_info *ibmphp_find_same_bus_num (u32); | 285 | struct bus_info *ibmphp_find_same_bus_num(u32); |
286 | extern int ibmphp_get_bus_index (u8); | 286 | int ibmphp_get_bus_index(u8); |
287 | extern u16 ibmphp_get_total_controllers (void); | 287 | u16 ibmphp_get_total_controllers(void); |
288 | extern int ibmphp_register_pci (void); | 288 | int ibmphp_register_pci(void); |
289 | 289 | ||
290 | /* passed parameters */ | 290 | /* passed parameters */ |
291 | #define MEM 0 | 291 | #define MEM 0 |
@@ -381,24 +381,24 @@ struct res_needed { | |||
381 | 381 | ||
382 | /* functions */ | 382 | /* functions */ |
383 | 383 | ||
384 | extern int ibmphp_rsrc_init (void); | 384 | int ibmphp_rsrc_init(void); |
385 | extern int ibmphp_add_resource (struct resource_node *); | 385 | int ibmphp_add_resource(struct resource_node *); |
386 | extern int ibmphp_remove_resource (struct resource_node *); | 386 | int ibmphp_remove_resource(struct resource_node *); |
387 | extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); | 387 | int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); |
388 | extern int ibmphp_check_resource (struct resource_node *, u8); | 388 | int ibmphp_check_resource(struct resource_node *, u8); |
389 | extern int ibmphp_remove_bus (struct bus_node *, u8); | 389 | int ibmphp_remove_bus(struct bus_node *, u8); |
390 | extern void ibmphp_free_resources (void); | 390 | void ibmphp_free_resources(void); |
391 | extern int ibmphp_add_pfmem_from_mem (struct resource_node *); | 391 | int ibmphp_add_pfmem_from_mem(struct resource_node *); |
392 | extern struct bus_node *ibmphp_find_res_bus (u8); | 392 | struct bus_node *ibmphp_find_res_bus(u8); |
393 | extern void ibmphp_print_test (void); /* for debugging purposes */ | 393 | void ibmphp_print_test(void); /* for debugging purposes */ |
394 | 394 | ||
395 | extern void ibmphp_hpc_initvars (void); | 395 | void ibmphp_hpc_initvars(void); |
396 | extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); | 396 | int ibmphp_hpc_readslot(struct slot *, u8, u8 *); |
397 | extern int ibmphp_hpc_writeslot (struct slot *, u8); | 397 | int ibmphp_hpc_writeslot(struct slot *, u8); |
398 | extern void ibmphp_lock_operations (void); | 398 | void ibmphp_lock_operations(void); |
399 | extern void ibmphp_unlock_operations (void); | 399 | void ibmphp_unlock_operations(void); |
400 | extern int ibmphp_hpc_start_poll_thread (void); | 400 | int ibmphp_hpc_start_poll_thread(void); |
401 | extern void ibmphp_hpc_stop_poll_thread (void); | 401 | void ibmphp_hpc_stop_poll_thread(void); |
402 | 402 | ||
403 | //---------------------------------------------------------------------------- | 403 | //---------------------------------------------------------------------------- |
404 | 404 | ||
@@ -749,11 +749,11 @@ struct controller { | |||
749 | 749 | ||
750 | /* Functions */ | 750 | /* Functions */ |
751 | 751 | ||
752 | extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ | 752 | int ibmphp_init_devno(struct slot **); /* This function is called from EBDA, so we need it not be static */ |
753 | extern int ibmphp_do_disable_slot (struct slot *slot_cur); | 753 | int ibmphp_do_disable_slot(struct slot *slot_cur); |
754 | extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ | 754 | int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ |
755 | extern int ibmphp_configure_card (struct pci_func *, u8); | 755 | int ibmphp_configure_card(struct pci_func *, u8); |
756 | extern int ibmphp_unconfigure_card (struct slot **, int); | 756 | int ibmphp_unconfigure_card(struct slot **, int); |
757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; | 757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; |
758 | 758 | ||
759 | #endif //__IBMPHP_H | 759 | #endif //__IBMPHP_H |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 202f4a969eb5..ec20f74c8981 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include "../pci.h" | 43 | #include "../pci.h" |
44 | #include "cpci_hotplug.h" | ||
44 | 45 | ||
45 | #define MY_NAME "pci_hotplug" | 46 | #define MY_NAME "pci_hotplug" |
46 | 47 | ||
@@ -63,14 +64,6 @@ static bool debug; | |||
63 | static LIST_HEAD(pci_hotplug_slot_list); | 64 | static LIST_HEAD(pci_hotplug_slot_list); |
64 | static DEFINE_MUTEX(pci_hp_mutex); | 65 | static DEFINE_MUTEX(pci_hp_mutex); |
65 | 66 | ||
66 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
67 | extern int cpci_hotplug_init(int debug); | ||
68 | extern void cpci_hotplug_exit(void); | ||
69 | #else | ||
70 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
71 | static inline void cpci_hotplug_exit(void) { } | ||
72 | #endif | ||
73 | |||
74 | /* Weee, fun with macros... */ | 67 | /* Weee, fun with macros... */ |
75 | #define GET_STATUS(name,type) \ | 68 | #define GET_STATUS(name,type) \ |
76 | static int get_##name (struct hotplug_slot *slot, type *value) \ | 69 | static int get_##name (struct hotplug_slot *slot, type *value) \ |
@@ -524,13 +517,11 @@ int pci_hp_deregister(struct hotplug_slot *hotplug) | |||
524 | * | 517 | * |
525 | * Returns 0 if successful, anything else for an error. | 518 | * Returns 0 if successful, anything else for an error. |
526 | */ | 519 | */ |
527 | int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, | 520 | int pci_hp_change_slot_info(struct hotplug_slot *hotplug, |
528 | struct hotplug_slot_info *info) | 521 | struct hotplug_slot_info *info) |
529 | { | 522 | { |
530 | struct pci_slot *slot; | ||
531 | if (!hotplug || !info) | 523 | if (!hotplug || !info) |
532 | return -ENODEV; | 524 | return -ENODEV; |
533 | slot = hotplug->pci_slot; | ||
534 | 525 | ||
535 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); | 526 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); |
536 | 527 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 2c113de94323..7fb326983ed6 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -127,15 +127,15 @@ struct controller { | |||
127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) | 127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) |
128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) | 128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) |
129 | 129 | ||
130 | extern int pciehp_sysfs_enable_slot(struct slot *slot); | 130 | int pciehp_sysfs_enable_slot(struct slot *slot); |
131 | extern int pciehp_sysfs_disable_slot(struct slot *slot); | 131 | int pciehp_sysfs_disable_slot(struct slot *slot); |
132 | extern u8 pciehp_handle_attention_button(struct slot *p_slot); | 132 | u8 pciehp_handle_attention_button(struct slot *p_slot); |
133 | extern u8 pciehp_handle_switch_change(struct slot *p_slot); | 133 | u8 pciehp_handle_switch_change(struct slot *p_slot); |
134 | extern u8 pciehp_handle_presence_change(struct slot *p_slot); | 134 | u8 pciehp_handle_presence_change(struct slot *p_slot); |
135 | extern u8 pciehp_handle_power_fault(struct slot *p_slot); | 135 | u8 pciehp_handle_power_fault(struct slot *p_slot); |
136 | extern int pciehp_configure_device(struct slot *p_slot); | 136 | int pciehp_configure_device(struct slot *p_slot); |
137 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 137 | int pciehp_unconfigure_device(struct slot *p_slot); |
138 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 138 | void pciehp_queue_pushbutton_work(struct work_struct *work); |
139 | struct controller *pcie_init(struct pcie_device *dev); | 139 | struct controller *pcie_init(struct pcie_device *dev); |
140 | int pcie_init_notification(struct controller *ctrl); | 140 | int pcie_init_notification(struct controller *ctrl); |
141 | int pciehp_enable_slot(struct slot *p_slot); | 141 | int pciehp_enable_slot(struct slot *p_slot); |
@@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot) | |||
166 | #include <acpi/acpi_bus.h> | 166 | #include <acpi/acpi_bus.h> |
167 | #include <linux/pci-acpi.h> | 167 | #include <linux/pci-acpi.h> |
168 | 168 | ||
169 | extern void __init pciehp_acpi_slot_detection_init(void); | 169 | void __init pciehp_acpi_slot_detection_init(void); |
170 | extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); | 170 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev); |
171 | 171 | ||
172 | static inline void pciehp_firmware_init(void) | 172 | static inline void pciehp_firmware_init(void) |
173 | { | 173 | { |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 24d709b7388c..ead7c534095e 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
91 | if (!slot) | 91 | if (!slot) |
92 | return -ENOMEM; | 92 | return -ENOMEM; |
93 | slot->number = slot_cap >> 19; | 93 | slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; |
94 | list_for_each_entry(tmp, &dummy_slots, list) { | 94 | list_for_each_entry(tmp, &dummy_slots, list) { |
95 | if (tmp->number == slot->number) | 95 | if (tmp->number == slot->number) |
96 | dup_slot_id++; | 96 | dup_slot_id++; |
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h index 4a0a59b82eae..81df93931ad0 100644 --- a/drivers/pci/hotplug/rpadlpar.h +++ b/drivers/pci/hotplug/rpadlpar.h | |||
@@ -15,10 +15,10 @@ | |||
15 | #ifndef _RPADLPAR_IO_H_ | 15 | #ifndef _RPADLPAR_IO_H_ |
16 | #define _RPADLPAR_IO_H_ | 16 | #define _RPADLPAR_IO_H_ |
17 | 17 | ||
18 | extern int dlpar_sysfs_init(void); | 18 | int dlpar_sysfs_init(void); |
19 | extern void dlpar_sysfs_exit(void); | 19 | void dlpar_sysfs_exit(void); |
20 | 20 | ||
21 | extern int dlpar_add_slot(char *drc_name); | 21 | int dlpar_add_slot(char *drc_name); |
22 | extern int dlpar_remove_slot(char *drc_name); | 22 | int dlpar_remove_slot(char *drc_name); |
23 | 23 | ||
24 | #endif | 24 | #endif |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index df5677440a08..3135856e5e1c 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head; | |||
86 | /* function prototypes */ | 86 | /* function prototypes */ |
87 | 87 | ||
88 | /* rpaphp_pci.c */ | 88 | /* rpaphp_pci.c */ |
89 | extern int rpaphp_enable_slot(struct slot *slot); | 89 | int rpaphp_enable_slot(struct slot *slot); |
90 | extern int rpaphp_get_sensor_state(struct slot *slot, int *state); | 90 | int rpaphp_get_sensor_state(struct slot *slot, int *state); |
91 | 91 | ||
92 | /* rpaphp_core.c */ | 92 | /* rpaphp_core.c */ |
93 | extern int rpaphp_add_slot(struct device_node *dn); | 93 | int rpaphp_add_slot(struct device_node *dn); |
94 | extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, | 94 | int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, |
95 | char **drc_name, char **drc_type, int *drc_power_domain); | 95 | char **drc_name, char **drc_type, int *drc_power_domain); |
96 | 96 | ||
97 | /* rpaphp_slot.c */ | 97 | /* rpaphp_slot.c */ |
98 | extern void dealloc_slot_struct(struct slot *slot); | 98 | void dealloc_slot_struct(struct slot *slot); |
99 | extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); | 99 | struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); |
100 | extern int rpaphp_register_slot(struct slot *slot); | 100 | int rpaphp_register_slot(struct slot *slot); |
101 | extern int rpaphp_deregister_slot(struct slot *slot); | 101 | int rpaphp_deregister_slot(struct slot *slot); |
102 | 102 | ||
103 | #endif /* _PPC64PHP_H */ | 103 | #endif /* _PPC64PHP_H */ |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index b849f995075a..e260f207a90e 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -168,19 +168,19 @@ struct controller { | |||
168 | #define WRONG_BUS_FREQUENCY 0x0000000D | 168 | #define WRONG_BUS_FREQUENCY 0x0000000D |
169 | #define POWER_FAILURE 0x0000000E | 169 | #define POWER_FAILURE 0x0000000E |
170 | 170 | ||
171 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); | 171 | int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
172 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | 172 | void shpchp_remove_ctrl_files(struct controller *ctrl); |
173 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 173 | int shpchp_sysfs_enable_slot(struct slot *slot); |
174 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 174 | int shpchp_sysfs_disable_slot(struct slot *slot); |
175 | extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | 175 | u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); |
176 | extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); | 176 | u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
177 | extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); | 177 | u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
178 | extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); | 178 | u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); |
179 | extern int shpchp_configure_device(struct slot *p_slot); | 179 | int shpchp_configure_device(struct slot *p_slot); |
180 | extern int shpchp_unconfigure_device(struct slot *p_slot); | 180 | int shpchp_unconfigure_device(struct slot *p_slot); |
181 | extern void cleanup_slots(struct controller *ctrl); | 181 | void cleanup_slots(struct controller *ctrl); |
182 | extern void shpchp_queue_pushbutton_work(struct work_struct *work); | 182 | void shpchp_queue_pushbutton_work(struct work_struct *work); |
183 | extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); | 183 | int shpc_init( struct controller *ctrl, struct pci_dev *pdev); |
184 | 184 | ||
185 | static inline const char *slot_name(struct slot *slot) | 185 | static inline const char *slot_name(struct slot *slot) |
186 | { | 186 | { |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index eeb23ceae4a8..e8c31fe20566 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
85 | } | 85 | } |
86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); | 86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); |
87 | 87 | ||
88 | int __must_check shpchp_create_ctrl_files (struct controller *ctrl) | 88 | int shpchp_create_ctrl_files (struct controller *ctrl) |
89 | { | 89 | { |
90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); | 90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); |
91 | } | 91 | } |