aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2018-09-08 03:59:01 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-09-18 18:52:15 -0400
commita7da21613c4efcd4cc0235e6a30bec96ae47c619 (patch)
tree130c0fc6bc359509cb0c27ea6fe01d38a61b890c
parent81c4b5bf30de01a0f6b43ccaa1d220f4a0a5d99c (diff)
PCI: hotplug: Drop hotplug_slot_info
Ever since the PCI hotplug core was introduced in 2002, drivers had to allocate and register a struct hotplug_slot_info for every slot: https://git.kernel.org/tglx/history/c/a8a2069f432c Apparently the idea was that drivers furnish the hotplug core with an up-to-date card presence status, power status, latch status and attention indicator status as well as notify the hotplug core of changes thereof. However only 4 out of 12 hotplug drivers bother to notify the hotplug core with pci_hp_change_slot_info() and the hotplug core never made any use of the information: There is just a single macro in pci_hotplug_core.c, GET_STATUS(), which uses the hotplug_slot_info if the driver lacks the corresponding callback in hotplug_slot_ops. The macro is called when the user reads the attribute via sysfs. Now, if the callback isn't defined, the attribute isn't exposed in sysfs in the first place (see e.g. has_power_file()). There are only two situations when the hotplug_slot_info would actually be accessed: * If the driver defines ->enable_slot or ->disable_slot but not ->get_power_status. * If the driver defines ->set_attention_status but not ->get_attention_status. There is no driver doing the former and just a single driver doing the latter, namely pnv_php.c. Amend it with a ->get_attention_status callback. With that, the hotplug_slot_info becomes completely unused by the PCI hotplug core. But a few drivers use it internally as a cache: cpcihp uses it to cache the latch_status and adapter_status. cpqhp uses it to cache the adapter_status. pnv_php and rpaphp use it to cache the attention_status. shpchp uses it to cache all four values. Amend these drivers to cache the information in their private slot struct. shpchp's slot struct already contains members to cache the power_status and adapter_status, so additional members are only needed for the other two values. In the case of cpqphp, the cached value is only accessed in a single place, so instead of caching it, read the current value from the hardware. Caution: acpiphp, cpci, cpqhp, shpchp, asus-wmi and eeepc-laptop populate the hotplug_slot_info with initial values on probe. That code is herewith removed. There is a theoretical chance that the code has side effects without which the driver fails to function, e.g. if the ACPI method to read the adapter status needs to be executed at least once on probe. That seems unlikely to me, still maintainers should review the changes carefully for this possibility. Rafael adds: "I'm not aware of any case in which it will break anything, [...] but if that happens, it may be necessary to add the execution of the control methods in question directly to the initialization part." Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com> # drivers/pci/hotplug/rpa* Acked-by: Sebastian Ott <sebott@linux.ibm.com> # drivers/pci/hotplug/s390* Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com> # drivers/platform/x86 Cc: Len Brown <lenb@kernel.org> Cc: Scott Murray <scott@spiteful.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Oliver OHalloran <oliveroh@au1.ibm.com> Cc: Gavin Shan <gwshan@linux.vnet.ibm.com> Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com> Cc: Corentin Chary <corentin.chary@gmail.com> Cc: Darren Hart <dvhart@infradead.org>
-rw-r--r--arch/powerpc/include/asm/pnv-pci.h2
-rw-r--r--drivers/pci/hotplug/acpiphp.h1
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c6
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c72
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c22
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c31
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c27
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c33
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c26
-rw-r--r--drivers/pci/hotplug/pciehp_core.c8
-rw-r--r--drivers/pci/hotplug/pnv_php.c24
-rw-r--r--drivers/pci/hotplug/rpaphp.h1
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c4
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c11
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c9
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c12
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c9
-rw-r--r--drivers/pci/hotplug/shpchp.h2
-rw-r--r--drivers/pci/hotplug/shpchp_core.c31
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c21
-rw-r--r--drivers/platform/x86/asus-wmi.c10
-rw-r--r--drivers/platform/x86/eeepc-laptop.c10
-rw-r--r--include/linux/pci_hotplug.h30
24 files changed, 64 insertions, 340 deletions
diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h
index 7f627e3f4da4..630eb8b1b7ed 100644
--- a/arch/powerpc/include/asm/pnv-pci.h
+++ b/arch/powerpc/include/asm/pnv-pci.h
@@ -54,7 +54,6 @@ void pnv_cxl_release_hwirq_ranges(struct cxl_irq_ranges *irqs,
54 54
55struct pnv_php_slot { 55struct pnv_php_slot {
56 struct hotplug_slot slot; 56 struct hotplug_slot slot;
57 struct hotplug_slot_info slot_info;
58 uint64_t id; 57 uint64_t id;
59 char *name; 58 char *name;
60 int slot_no; 59 int slot_no;
@@ -72,6 +71,7 @@ struct pnv_php_slot {
72 struct pci_dev *pdev; 71 struct pci_dev *pdev;
73 struct pci_bus *bus; 72 struct pci_bus *bus;
74 bool power_state_check; 73 bool power_state_check;
74 u8 attention_state;
75 void *fdt; 75 void *fdt;
76 void *dt; 76 void *dt;
77 struct of_changeset ocs; 77 struct of_changeset ocs;
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index e438a2d734f2..8377e736ea69 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -35,7 +35,6 @@ struct acpiphp_slot;
35struct slot { 35struct slot {
36 struct hotplug_slot *hotplug_slot; 36 struct hotplug_slot *hotplug_slot;
37 struct acpiphp_slot *acpi_slot; 37 struct acpiphp_slot *acpi_slot;
38 struct hotplug_slot_info info;
39 unsigned int sun; /* ACPI _SUN (Slot User Number) value */ 38 unsigned int sun; /* ACPI _SUN (Slot User Number) value */
40}; 39};
41 40
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index e883cef0f3bc..abd4f8d7e16a 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -270,16 +270,10 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,
270 if (!slot->hotplug_slot) 270 if (!slot->hotplug_slot)
271 goto error_slot; 271 goto error_slot;
272 272
273 slot->hotplug_slot->info = &slot->info;
274
275 slot->hotplug_slot->private = slot; 273 slot->hotplug_slot->private = slot;
276 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; 274 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
277 275
278 slot->acpi_slot = acpiphp_slot; 276 slot->acpi_slot = acpiphp_slot;
279 slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
280 slot->hotplug_slot->info->attention_status = 0;
281 slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
282 slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
283 277
284 acpiphp_slot->slot = slot; 278 acpiphp_slot->slot = slot;
285 slot->sun = sun; 279 slot->sun = sun;
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index 4658557be01a..a35f40a2290c 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -32,6 +32,8 @@ struct slot {
32 unsigned int devfn; 32 unsigned int devfn;
33 struct pci_bus *bus; 33 struct pci_bus *bus;
34 struct pci_dev *dev; 34 struct pci_dev *dev;
35 unsigned int latch_status:1;
36 unsigned int adapter_status:1;
35 unsigned int extracting; 37 unsigned int extracting;
36 struct hotplug_slot *hotplug_slot; 38 struct hotplug_slot *hotplug_slot;
37 struct list_head slot_list; 39 struct list_head slot_list;
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 97c32e4c74c8..a17fb24c28cd 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -68,26 +68,6 @@ static const struct hotplug_slot_ops cpci_hotplug_slot_ops = {
68}; 68};
69 69
70static int 70static int
71update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
72{
73 struct hotplug_slot_info info;
74
75 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
76 info.latch_status = value;
77 return pci_hp_change_slot_info(hotplug_slot, &info);
78}
79
80static int
81update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
82{
83 struct hotplug_slot_info info;
84
85 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
86 info.adapter_status = value;
87 return pci_hp_change_slot_info(hotplug_slot, &info);
88}
89
90static int
91enable_slot(struct hotplug_slot *hotplug_slot) 71enable_slot(struct hotplug_slot *hotplug_slot)
92{ 72{
93 struct slot *slot = hotplug_slot->private; 73 struct slot *slot = hotplug_slot->private;
@@ -135,8 +115,7 @@ disable_slot(struct hotplug_slot *hotplug_slot)
135 goto disable_error; 115 goto disable_error;
136 } 116 }
137 117
138 if (update_adapter_status(slot->hotplug_slot, 0)) 118 slot->adapter_status = 0;
139 warn("failure to update adapter file");
140 119
141 if (slot->extracting) { 120 if (slot->extracting) {
142 slot->extracting = 0; 121 slot->extracting = 0;
@@ -184,20 +163,23 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
184static int 163static int
185get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 164get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
186{ 165{
187 *value = hotplug_slot->info->adapter_status; 166 struct slot *slot = hotplug_slot->private;
167
168 *value = slot->adapter_status;
188 return 0; 169 return 0;
189} 170}
190 171
191static int 172static int
192get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 173get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
193{ 174{
194 *value = hotplug_slot->info->latch_status; 175 struct slot *slot = hotplug_slot->private;
176
177 *value = slot->latch_status;
195 return 0; 178 return 0;
196} 179}
197 180
198static void release_slot(struct slot *slot) 181static void release_slot(struct slot *slot)
199{ 182{
200 kfree(slot->hotplug_slot->info);
201 kfree(slot->hotplug_slot); 183 kfree(slot->hotplug_slot);
202 pci_dev_put(slot->dev); 184 pci_dev_put(slot->dev);
203 kfree(slot); 185 kfree(slot);
@@ -210,7 +192,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
210{ 192{
211 struct slot *slot; 193 struct slot *slot;
212 struct hotplug_slot *hotplug_slot; 194 struct hotplug_slot *hotplug_slot;
213 struct hotplug_slot_info *info;
214 char name[SLOT_NAME_SIZE]; 195 char name[SLOT_NAME_SIZE];
215 int status; 196 int status;
216 int i; 197 int i;
@@ -237,13 +218,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
237 } 218 }
238 slot->hotplug_slot = hotplug_slot; 219 slot->hotplug_slot = hotplug_slot;
239 220
240 info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
241 if (!info) {
242 status = -ENOMEM;
243 goto error_hpslot;
244 }
245 hotplug_slot->info = info;
246
247 slot->bus = bus; 221 slot->bus = bus;
248 slot->number = i; 222 slot->number = i;
249 slot->devfn = PCI_DEVFN(i, 0); 223 slot->devfn = PCI_DEVFN(i, 0);
@@ -253,19 +227,11 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
253 hotplug_slot->private = slot; 227 hotplug_slot->private = slot;
254 hotplug_slot->ops = &cpci_hotplug_slot_ops; 228 hotplug_slot->ops = &cpci_hotplug_slot_ops;
255 229
256 /*
257 * Initialize the slot info structure with some known
258 * good values.
259 */
260 dbg("initializing slot %s", name);
261 info->power_status = cpci_get_power_status(slot);
262 info->attention_status = cpci_get_attention_status(slot);
263
264 dbg("registering slot %s", name); 230 dbg("registering slot %s", name);
265 status = pci_hp_register(slot->hotplug_slot, bus, i, name); 231 status = pci_hp_register(slot->hotplug_slot, bus, i, name);
266 if (status) { 232 if (status) {
267 err("pci_hp_register failed with error %d", status); 233 err("pci_hp_register failed with error %d", status);
268 goto error_info; 234 goto error_hpslot;
269 } 235 }
270 dbg("slot registered with name: %s", slot_name(slot)); 236 dbg("slot registered with name: %s", slot_name(slot));
271 237
@@ -276,8 +242,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
276 up_write(&list_rwsem); 242 up_write(&list_rwsem);
277 } 243 }
278 return 0; 244 return 0;
279error_info:
280 kfree(info);
281error_hpslot: 245error_hpslot:
282 kfree(hotplug_slot); 246 kfree(hotplug_slot);
283error_slot: 247error_slot:
@@ -359,10 +323,8 @@ init_slots(int clear_ins)
359 __func__, slot_name(slot)); 323 __func__, slot_name(slot));
360 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); 324 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
361 if (dev) { 325 if (dev) {
362 if (update_adapter_status(slot->hotplug_slot, 1)) 326 slot->adapter_status = 1;
363 warn("failure to update adapter file"); 327 slot->latch_status = 1;
364 if (update_latch_status(slot->hotplug_slot, 1))
365 warn("failure to update latch file");
366 slot->dev = dev; 328 slot->dev = dev;
367 } 329 }
368 } 330 }
@@ -424,11 +386,8 @@ check_slots(void)
424 dbg("%s - slot %s HS_CSR (2) = %04x", 386 dbg("%s - slot %s HS_CSR (2) = %04x",
425 __func__, slot_name(slot), hs_csr); 387 __func__, slot_name(slot), hs_csr);
426 388
427 if (update_latch_status(slot->hotplug_slot, 1)) 389 slot->latch_status = 1;
428 warn("failure to update latch file"); 390 slot->adapter_status = 1;
429
430 if (update_adapter_status(slot->hotplug_slot, 1))
431 warn("failure to update adapter file");
432 391
433 cpci_led_off(slot); 392 cpci_led_off(slot);
434 393
@@ -449,9 +408,7 @@ check_slots(void)
449 __func__, slot_name(slot), hs_csr); 408 __func__, slot_name(slot), hs_csr);
450 409
451 if (!slot->extracting) { 410 if (!slot->extracting) {
452 if (update_latch_status(slot->hotplug_slot, 0)) 411 slot->latch_status = 0;
453 warn("failure to update latch file");
454
455 slot->extracting = 1; 412 slot->extracting = 1;
456 atomic_inc(&extracting); 413 atomic_inc(&extracting);
457 } 414 }
@@ -465,8 +422,7 @@ check_slots(void)
465 */ 422 */
466 err("card in slot %s was improperly removed", 423 err("card in slot %s was improperly removed",
467 slot_name(slot)); 424 slot_name(slot));
468 if (update_adapter_status(slot->hotplug_slot, 0)) 425 slot->adapter_status = 0;
469 warn("failure to update adapter file");
470 slot->extracting = 0; 426 slot->extracting = 0;
471 atomic_dec(&extracting); 427 atomic_dec(&extracting);
472 } 428 }
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 3409b62fceac..bb354a7fc112 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -276,7 +276,6 @@ static int ctrl_slot_cleanup(struct controller *ctrl)
276 while (old_slot) { 276 while (old_slot) {
277 next_slot = old_slot->next; 277 next_slot = old_slot->next;
278 pci_hp_deregister(old_slot->hotplug_slot); 278 pci_hp_deregister(old_slot->hotplug_slot);
279 kfree(old_slot->hotplug_slot->info);
280 kfree(old_slot->hotplug_slot); 279 kfree(old_slot->hotplug_slot);
281 kfree(old_slot); 280 kfree(old_slot);
282 old_slot = next_slot; 281 old_slot = next_slot;
@@ -579,7 +578,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
579{ 578{
580 struct slot *slot; 579 struct slot *slot;
581 struct hotplug_slot *hotplug_slot; 580 struct hotplug_slot *hotplug_slot;
582 struct hotplug_slot_info *hotplug_slot_info;
583 struct pci_bus *bus = ctrl->pci_bus; 581 struct pci_bus *bus = ctrl->pci_bus;
584 u8 number_of_slots; 582 u8 number_of_slots;
585 u8 slot_device; 583 u8 slot_device;
@@ -613,14 +611,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
613 } 611 }
614 hotplug_slot = slot->hotplug_slot; 612 hotplug_slot = slot->hotplug_slot;
615 613
616 hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)),
617 GFP_KERNEL);
618 if (!hotplug_slot->info) {
619 result = -ENOMEM;
620 goto error_hpslot;
621 }
622 hotplug_slot_info = hotplug_slot->info;
623
624 slot->ctrl = ctrl; 614 slot->ctrl = ctrl;
625 slot->bus = ctrl->bus; 615 slot->bus = ctrl->bus;
626 slot->device = slot_device; 616 slot->device = slot_device;
@@ -673,14 +663,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
673 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); 663 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
674 hotplug_slot->ops = &cpqphp_hotplug_slot_ops; 664 hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
675 665
676 hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
677 hotplug_slot_info->attention_status =
678 cpq_get_attention_status(ctrl, slot);
679 hotplug_slot_info->latch_status =
680 cpq_get_latch_status(ctrl, slot);
681 hotplug_slot_info->adapter_status =
682 get_presence_status(ctrl, slot);
683
684 dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", 666 dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n",
685 slot->bus, slot->device, 667 slot->bus, slot->device,
686 slot->number, ctrl->slot_device_offset, 668 slot->number, ctrl->slot_device_offset,
@@ -691,7 +673,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
691 name); 673 name);
692 if (result) { 674 if (result) {
693 err("pci_hp_register failed with error %d\n", result); 675 err("pci_hp_register failed with error %d\n", result);
694 goto error_info; 676 goto error_hpslot;
695 } 677 }
696 678
697 slot->next = ctrl->slot; 679 slot->next = ctrl->slot;
@@ -703,8 +685,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
703 } 685 }
704 686
705 return 0; 687 return 0;
706error_info:
707 kfree(hotplug_slot_info);
708error_hpslot: 688error_hpslot:
709 kfree(hotplug_slot); 689 kfree(hotplug_slot);
710error_slot: 690error_slot:
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 616df442520b..9c4826ac6a4f 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1130,9 +1130,9 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
1130 for (slot = ctrl->slot; slot; slot = slot->next) { 1130 for (slot = ctrl->slot; slot; slot = slot->next) {
1131 if (slot->device == (hp_slot + ctrl->slot_device_offset)) 1131 if (slot->device == (hp_slot + ctrl->slot_device_offset))
1132 continue; 1132 continue;
1133 if (!slot->hotplug_slot || !slot->hotplug_slot->info) 1133 if (!slot->hotplug_slot)
1134 continue; 1134 continue;
1135 if (slot->hotplug_slot->info->adapter_status == 0) 1135 if (get_presence_status(ctrl, slot) == 0)
1136 continue; 1136 continue;
1137 /* If another adapter is running on the same segment but at a 1137 /* If another adapter is running on the same segment but at a
1138 * lower speed/mode, we allow the new adapter to function at 1138 * lower speed/mode, we allow the new adapter to function at
@@ -1767,24 +1767,6 @@ void cpqhp_event_stop_thread(void)
1767} 1767}
1768 1768
1769 1769
1770static int update_slot_info(struct controller *ctrl, struct slot *slot)
1771{
1772 struct hotplug_slot_info *info;
1773 int result;
1774
1775 info = kmalloc(sizeof(*info), GFP_KERNEL);
1776 if (!info)
1777 return -ENOMEM;
1778
1779 info->power_status = get_slot_enabled(ctrl, slot);
1780 info->attention_status = cpq_get_attention_status(ctrl, slot);
1781 info->latch_status = cpq_get_latch_status(ctrl, slot);
1782 info->adapter_status = get_presence_status(ctrl, slot);
1783 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1784 kfree(info);
1785 return result;
1786}
1787
1788static void interrupt_event_handler(struct controller *ctrl) 1770static void interrupt_event_handler(struct controller *ctrl)
1789{ 1771{
1790 int loop = 0; 1772 int loop = 0;
@@ -1884,9 +1866,6 @@ static void interrupt_event_handler(struct controller *ctrl)
1884 /***********POWER FAULT */ 1866 /***********POWER FAULT */
1885 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { 1867 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1886 dbg("power fault\n"); 1868 dbg("power fault\n");
1887 } else {
1888 /* refresh notification */
1889 update_slot_info(ctrl, p_slot);
1890 } 1869 }
1891 1870
1892 ctrl->event_queue[loop].event_type = 0; 1871 ctrl->event_queue[loop].event_type = 0;
@@ -2057,9 +2036,6 @@ int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func)
2057 if (rc) 2036 if (rc)
2058 dbg("%s: rc = %d\n", __func__, rc); 2037 dbg("%s: rc = %d\n", __func__, rc);
2059 2038
2060 if (p_slot)
2061 update_slot_info(ctrl, p_slot);
2062
2063 return rc; 2039 return rc;
2064} 2040}
2065 2041
@@ -2125,9 +2101,6 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
2125 rc = 1; 2101 rc = 1;
2126 } 2102 }
2127 2103
2128 if (p_slot)
2129 update_slot_info(ctrl, p_slot);
2130
2131 return rc; 2104 return rc;
2132} 2105}
2133 2106
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index b82fdc17040d..96e5b1f544ac 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -582,29 +582,10 @@ static int validate(struct slot *slot_cur, int opn)
582 ****************************************************************************/ 582 ****************************************************************************/
583int ibmphp_update_slot_info(struct slot *slot_cur) 583int ibmphp_update_slot_info(struct slot *slot_cur)
584{ 584{
585 struct hotplug_slot_info *info;
586 struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; 585 struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus;
587 int rc;
588 u8 bus_speed; 586 u8 bus_speed;
589 u8 mode; 587 u8 mode;
590 588
591 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
592 if (!info)
593 return -ENOMEM;
594
595 info->power_status = SLOT_PWRGD(slot_cur->status);
596 info->attention_status = SLOT_ATTN(slot_cur->status,
597 slot_cur->ext_status);
598 info->latch_status = SLOT_LATCH(slot_cur->status);
599 if (!SLOT_PRESENT(slot_cur->status)) {
600 info->adapter_status = 0;
601/* info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
602 } else {
603 info->adapter_status = 1;
604/* get_max_adapter_speed_1(slot_cur->hotplug_slot,
605 &info->max_adapter_speed_status, 0); */
606 }
607
608 bus_speed = slot_cur->bus_on->current_speed; 589 bus_speed = slot_cur->bus_on->current_speed;
609 mode = slot_cur->bus_on->current_bus_mode; 590 mode = slot_cur->bus_on->current_bus_mode;
610 591
@@ -630,9 +611,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)
630 bus->cur_bus_speed = bus_speed; 611 bus->cur_bus_speed = bus_speed;
631 // To do: bus_names 612 // To do: bus_names
632 613
633 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); 614 return 0;
634 kfree(info);
635 return rc;
636} 615}
637 616
638 617
@@ -684,7 +663,6 @@ static void free_slots(void)
684 ibmphp_unconfigure_card(&slot_cur, -1); 663 ibmphp_unconfigure_card(&slot_cur, -1);
685 664
686 pci_hp_destroy(slot_cur->hotplug_slot); 665 pci_hp_destroy(slot_cur->hotplug_slot);
687 kfree(slot_cur->hotplug_slot->info);
688 kfree(slot_cur->hotplug_slot); 666 kfree(slot_cur->hotplug_slot);
689 kfree(slot_cur); 667 kfree(slot_cur);
690 } 668 }
@@ -1095,8 +1073,7 @@ static int enable_slot(struct hotplug_slot *hs)
1095 1073
1096 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); 1074 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1097 if (!slot_cur->func) { 1075 if (!slot_cur->func) {
1098 /* We cannot do update_slot_info here, since no memory for 1076 /* do update_slot_info here? */
1099 * kmalloc n.e.ways, and update_slot_info allocates some */
1100 rc = -ENOMEM; 1077 rc = -ENOMEM;
1101 goto error_power; 1078 goto error_power;
1102 } 1079 }
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 6f8e90e3ec08..c05d066ab0d5 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -671,31 +671,6 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot)
671 671
672 slot = hotplug_slot->private; 672 slot = hotplug_slot->private;
673 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); 673 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL);
674 if (rc)
675 return rc;
676
677 // power - enabled:1 not:0
678 hotplug_slot->info->power_status = SLOT_POWER(slot->status);
679
680 // attention - off:0, on:1, blinking:2
681 hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status);
682
683 // latch - open:1 closed:0
684 hotplug_slot->info->latch_status = SLOT_LATCH(slot->status);
685
686 // pci board - present:1 not:0
687 if (SLOT_PRESENT(slot->status))
688 hotplug_slot->info->adapter_status = 1;
689 else
690 hotplug_slot->info->adapter_status = 0;
691/*
692 if (slot->bus_on->supported_bus_mode
693 && (slot->bus_on->supported_speed == BUS_SPEED_66))
694 hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
695 else
696 hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed;
697*/
698
699 return rc; 674 return rc;
700} 675}
701 676
@@ -877,12 +852,6 @@ static int __init ebda_rsrc_controller(void)
877 goto error_no_hp_slot; 852 goto error_no_hp_slot;
878 } 853 }
879 854
880 hp_slot_ptr->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
881 if (!hp_slot_ptr->info) {
882 rc = -ENOMEM;
883 goto error_no_hp_info;
884 }
885
886 tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); 855 tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
887 if (!tmp_slot) { 856 if (!tmp_slot) {
888 rc = -ENOMEM; 857 rc = -ENOMEM;
@@ -955,8 +924,6 @@ static int __init ebda_rsrc_controller(void)
955error: 924error:
956 kfree(hp_slot_ptr->private); 925 kfree(hp_slot_ptr->private);
957error_no_slot: 926error_no_slot:
958 kfree(hp_slot_ptr->info);
959error_no_hp_info:
960 kfree(hp_slot_ptr); 927 kfree(hp_slot_ptr);
961error_no_hp_slot: 928error_no_hp_slot:
962 free_ebda_hpc(hpc_ptr); 929 free_ebda_hpc(hpc_ptr);
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index ede2ed6f4ce0..5ac31f683b85 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -55,8 +55,6 @@ static int get_##name(struct hotplug_slot *slot, type *value) \
55 return -ENODEV; \ 55 return -ENODEV; \
56 if (ops->get_##name) \ 56 if (ops->get_##name) \
57 retval = ops->get_##name(slot, value); \ 57 retval = ops->get_##name(slot, value); \
58 else \
59 *value = slot->info->name; \
60 module_put(slot->owner); \ 58 module_put(slot->owner); \
61 return retval; \ 59 return retval; \
62} 60}
@@ -445,7 +443,7 @@ int __pci_hp_initialize(struct hotplug_slot *slot, struct pci_bus *bus,
445 443
446 if (slot == NULL) 444 if (slot == NULL)
447 return -ENODEV; 445 return -ENODEV;
448 if ((slot->info == NULL) || (slot->ops == NULL)) 446 if (slot->ops == NULL)
449 return -EINVAL; 447 return -EINVAL;
450 448
451 slot->owner = owner; 449 slot->owner = owner;
@@ -560,28 +558,6 @@ void pci_hp_destroy(struct hotplug_slot *slot)
560} 558}
561EXPORT_SYMBOL_GPL(pci_hp_destroy); 559EXPORT_SYMBOL_GPL(pci_hp_destroy);
562 560
563/**
564 * pci_hp_change_slot_info - changes the slot's information structure in the core
565 * @slot: pointer to the slot whose info has changed
566 * @info: pointer to the info copy into the slot's info structure
567 *
568 * @slot must have been registered with the pci
569 * hotplug subsystem previously with a call to pci_hp_register().
570 *
571 * Returns 0 if successful, anything else for an error.
572 */
573int pci_hp_change_slot_info(struct hotplug_slot *slot,
574 struct hotplug_slot_info *info)
575{
576 if (!slot || !info)
577 return -ENODEV;
578
579 memcpy(slot->info, info, sizeof(struct hotplug_slot_info));
580
581 return 0;
582}
583EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
584
585static int __init pci_hotplug_init(void) 561static int __init pci_hotplug_init(void)
586{ 562{
587 int result; 563 int result;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 80cc7ba534bf..ac5baf887c5d 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -52,7 +52,6 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
52static int init_slot(struct controller *ctrl) 52static int init_slot(struct controller *ctrl)
53{ 53{
54 struct hotplug_slot *hotplug = NULL; 54 struct hotplug_slot *hotplug = NULL;
55 struct hotplug_slot_info *info = NULL;
56 struct hotplug_slot_ops *ops = NULL; 55 struct hotplug_slot_ops *ops = NULL;
57 char name[SLOT_NAME_SIZE]; 56 char name[SLOT_NAME_SIZE];
58 int retval = -ENOMEM; 57 int retval = -ENOMEM;
@@ -61,10 +60,6 @@ static int init_slot(struct controller *ctrl)
61 if (!hotplug) 60 if (!hotplug)
62 goto out; 61 goto out;
63 62
64 info = kzalloc(sizeof(*info), GFP_KERNEL);
65 if (!info)
66 goto out;
67
68 /* Setup hotplug slot ops */ 63 /* Setup hotplug slot ops */
69 ops = kzalloc(sizeof(*ops), GFP_KERNEL); 64 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
70 if (!ops) 65 if (!ops)
@@ -86,7 +81,6 @@ static int init_slot(struct controller *ctrl)
86 } 81 }
87 82
88 /* register this slot with the hotplug pci core */ 83 /* register this slot with the hotplug pci core */
89 hotplug->info = info;
90 hotplug->private = ctrl; 84 hotplug->private = ctrl;
91 hotplug->ops = ops; 85 hotplug->ops = ops;
92 ctrl->hotplug_slot = hotplug; 86 ctrl->hotplug_slot = hotplug;
@@ -99,7 +93,6 @@ static int init_slot(struct controller *ctrl)
99out: 93out:
100 if (retval) { 94 if (retval) {
101 kfree(ops); 95 kfree(ops);
102 kfree(info);
103 kfree(hotplug); 96 kfree(hotplug);
104 } 97 }
105 return retval; 98 return retval;
@@ -111,7 +104,6 @@ static void cleanup_slot(struct controller *ctrl)
111 104
112 pci_hp_destroy(hotplug_slot); 105 pci_hp_destroy(hotplug_slot);
113 kfree(hotplug_slot->ops); 106 kfree(hotplug_slot->ops);
114 kfree(hotplug_slot->info);
115 kfree(hotplug_slot); 107 kfree(hotplug_slot);
116} 108}
117 109
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 12b92a0ff688..5bb63430262e 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -328,6 +328,11 @@ out:
328 return ret; 328 return ret;
329} 329}
330 330
331static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot)
332{
333 return container_of(slot, struct pnv_php_slot, slot);
334}
335
331int pnv_php_set_slot_power_state(struct hotplug_slot *slot, 336int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
332 uint8_t state) 337 uint8_t state)
333{ 338{
@@ -378,7 +383,6 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
378 ret); 383 ret);
379 } else { 384 } else {
380 *state = power_state; 385 *state = power_state;
381 slot->info->power_status = power_state;
382 } 386 }
383 387
384 return 0; 388 return 0;
@@ -397,7 +401,6 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
397 ret = pnv_pci_get_presence_state(php_slot->id, &presence); 401 ret = pnv_pci_get_presence_state(php_slot->id, &presence);
398 if (ret >= 0) { 402 if (ret >= 0) {
399 *state = presence; 403 *state = presence;
400 slot->info->adapter_status = presence;
401 ret = 0; 404 ret = 0;
402 } else { 405 } else {
403 pci_warn(php_slot->pdev, "Error %d getting presence\n", ret); 406 pci_warn(php_slot->pdev, "Error %d getting presence\n", ret);
@@ -406,10 +409,20 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
406 return ret; 409 return ret;
407} 410}
408 411
412static int pnv_php_get_attention_state(struct hotplug_slot *slot, u8 *state)
413{
414 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
415
416 *state = php_slot->attention_state;
417 return 0;
418}
419
409static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state) 420static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state)
410{ 421{
422 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
423
411 /* FIXME: Make it real once firmware supports it */ 424 /* FIXME: Make it real once firmware supports it */
412 slot->info->attention_status = state; 425 php_slot->attention_state = state;
413 426
414 return 0; 427 return 0;
415} 428}
@@ -501,8 +514,7 @@ scan:
501 514
502static int pnv_php_enable_slot(struct hotplug_slot *slot) 515static int pnv_php_enable_slot(struct hotplug_slot *slot)
503{ 516{
504 struct pnv_php_slot *php_slot = container_of(slot, 517 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
505 struct pnv_php_slot, slot);
506 518
507 return pnv_php_enable(php_slot, true); 519 return pnv_php_enable(php_slot, true);
508} 520}
@@ -533,6 +545,7 @@ static int pnv_php_disable_slot(struct hotplug_slot *slot)
533static const struct hotplug_slot_ops php_slot_ops = { 545static const struct hotplug_slot_ops php_slot_ops = {
534 .get_power_status = pnv_php_get_power_state, 546 .get_power_status = pnv_php_get_power_state,
535 .get_adapter_status = pnv_php_get_adapter_state, 547 .get_adapter_status = pnv_php_get_adapter_state,
548 .get_attention_status = pnv_php_get_attention_state,
536 .set_attention_status = pnv_php_set_attention_state, 549 .set_attention_status = pnv_php_set_attention_state,
537 .enable_slot = pnv_php_enable_slot, 550 .enable_slot = pnv_php_enable_slot,
538 .disable_slot = pnv_php_disable_slot, 551 .disable_slot = pnv_php_disable_slot,
@@ -594,7 +607,6 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
594 php_slot->id = id; 607 php_slot->id = id;
595 php_slot->power_state_check = false; 608 php_slot->power_state_check = false;
596 php_slot->slot.ops = &php_slot_ops; 609 php_slot->slot.ops = &php_slot_ops;
597 php_slot->slot.info = &php_slot->slot_info;
598 php_slot->slot.private = php_slot; 610 php_slot->slot.private = php_slot;
599 611
600 INIT_LIST_HEAD(&php_slot->children); 612 INIT_LIST_HEAD(&php_slot->children);
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index f83347819f7b..26a3dd731b5e 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -63,6 +63,7 @@ struct slot {
63 u32 index; 63 u32 index;
64 u32 type; 64 u32 type;
65 u32 power_domain; 65 u32 power_domain;
66 u8 attention_status;
66 char *name; 67 char *name;
67 struct device_node *dn; 68 struct device_node *dn;
68 struct pci_bus *bus; 69 struct pci_bus *bus;
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 8620a3f8c987..898e78dcd311 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -66,7 +66,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
66 66
67 rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); 67 rc = rtas_set_indicator(DR_INDICATOR, slot->index, value);
68 if (!rc) 68 if (!rc)
69 hotplug_slot->info->attention_status = value; 69 slot->attention_status = value;
70 70
71 return rc; 71 return rc;
72} 72}
@@ -95,7 +95,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
95static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 95static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
96{ 96{
97 struct slot *slot = (struct slot *)hotplug_slot->private; 97 struct slot *slot = (struct slot *)hotplug_slot->private;
98 *value = slot->hotplug_slot->info->attention_status; 98 *value = slot->attention_status;
99 return 0; 99 return 0;
100} 100}
101 101
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 0aac33e15dab..beca61badeea 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -54,25 +54,21 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state)
54 * rpaphp_enable_slot - record slot state, config pci device 54 * rpaphp_enable_slot - record slot state, config pci device
55 * @slot: target &slot 55 * @slot: target &slot
56 * 56 *
57 * Initialize values in the slot, and the hotplug_slot info 57 * Initialize values in the slot structure to indicate if there is a pci card
58 * structures to indicate if there is a pci card plugged into 58 * plugged into the slot. If the slot is not empty, run the pcibios routine
59 * the slot. If the slot is not empty, run the pcibios routine
60 * to get pcibios stuff correctly set up. 59 * to get pcibios stuff correctly set up.
61 */ 60 */
62int rpaphp_enable_slot(struct slot *slot) 61int rpaphp_enable_slot(struct slot *slot)
63{ 62{
64 int rc, level, state; 63 int rc, level, state;
65 struct pci_bus *bus; 64 struct pci_bus *bus;
66 struct hotplug_slot_info *info = slot->hotplug_slot->info;
67 65
68 info->adapter_status = NOT_VALID;
69 slot->state = EMPTY; 66 slot->state = EMPTY;
70 67
71 /* Find out if the power is turned on for the slot */ 68 /* Find out if the power is turned on for the slot */
72 rc = rtas_get_power_level(slot->power_domain, &level); 69 rc = rtas_get_power_level(slot->power_domain, &level);
73 if (rc) 70 if (rc)
74 return rc; 71 return rc;
75 info->power_status = level;
76 72
77 /* Figure out if there is an adapter in the slot */ 73 /* Figure out if there is an adapter in the slot */
78 rc = rpaphp_get_sensor_state(slot, &state); 74 rc = rpaphp_get_sensor_state(slot, &state);
@@ -85,13 +81,11 @@ int rpaphp_enable_slot(struct slot *slot)
85 return -EINVAL; 81 return -EINVAL;
86 } 82 }
87 83
88 info->adapter_status = EMPTY;
89 slot->bus = bus; 84 slot->bus = bus;
90 slot->pci_devs = &bus->devices; 85 slot->pci_devs = &bus->devices;
91 86
92 /* if there's an adapter in the slot, go add the pci devices */ 87 /* if there's an adapter in the slot, go add the pci devices */
93 if (state == PRESENT) { 88 if (state == PRESENT) {
94 info->adapter_status = NOT_CONFIGURED;
95 slot->state = NOT_CONFIGURED; 89 slot->state = NOT_CONFIGURED;
96 90
97 /* non-empty slot has to have child */ 91 /* non-empty slot has to have child */
@@ -105,7 +99,6 @@ int rpaphp_enable_slot(struct slot *slot)
105 pci_hp_add_devices(bus); 99 pci_hp_add_devices(bus);
106 100
107 if (!list_empty(&bus->devices)) { 101 if (!list_empty(&bus->devices)) {
108 info->adapter_status = CONFIGURED;
109 slot->state = CONFIGURED; 102 slot->state = CONFIGURED;
110 } 103 }
111 104
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index b916c8e4372d..6e2658ce300b 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -21,7 +21,6 @@
21/* free up the memory used by a slot */ 21/* free up the memory used by a slot */
22void dealloc_slot_struct(struct slot *slot) 22void dealloc_slot_struct(struct slot *slot)
23{ 23{
24 kfree(slot->hotplug_slot->info);
25 kfree(slot->name); 24 kfree(slot->name);
26 kfree(slot->hotplug_slot); 25 kfree(slot->hotplug_slot);
27 kfree(slot); 26 kfree(slot);
@@ -38,13 +37,9 @@ struct slot *alloc_slot_struct(struct device_node *dn,
38 slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); 37 slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
39 if (!slot->hotplug_slot) 38 if (!slot->hotplug_slot)
40 goto error_slot; 39 goto error_slot;
41 slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
42 GFP_KERNEL);
43 if (!slot->hotplug_slot->info)
44 goto error_hpslot;
45 slot->name = kstrdup(drc_name, GFP_KERNEL); 40 slot->name = kstrdup(drc_name, GFP_KERNEL);
46 if (!slot->name) 41 if (!slot->name)
47 goto error_info; 42 goto error_hpslot;
48 slot->dn = dn; 43 slot->dn = dn;
49 slot->index = drc_index; 44 slot->index = drc_index;
50 slot->power_domain = power_domain; 45 slot->power_domain = power_domain;
@@ -53,8 +48,6 @@ struct slot *alloc_slot_struct(struct device_node *dn,
53 48
54 return (slot); 49 return (slot);
55 50
56error_info:
57 kfree(slot->hotplug_slot->info);
58error_hpslot: 51error_hpslot:
59 kfree(slot->hotplug_slot); 52 kfree(slot->hotplug_slot);
60error_slot: 53error_slot:
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 5bd45fd4a92a..d04634b0defe 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -140,7 +140,6 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = {
140int zpci_init_slot(struct zpci_dev *zdev) 140int zpci_init_slot(struct zpci_dev *zdev)
141{ 141{
142 struct hotplug_slot *hotplug_slot; 142 struct hotplug_slot *hotplug_slot;
143 struct hotplug_slot_info *info;
144 char name[SLOT_NAME_SIZE]; 143 char name[SLOT_NAME_SIZE];
145 struct slot *slot; 144 struct slot *slot;
146 int rc; 145 int rc;
@@ -160,16 +159,8 @@ int zpci_init_slot(struct zpci_dev *zdev)
160 slot->hotplug_slot = hotplug_slot; 159 slot->hotplug_slot = hotplug_slot;
161 slot->zdev = zdev; 160 slot->zdev = zdev;
162 161
163 info = kzalloc(sizeof(*info), GFP_KERNEL);
164 if (!info)
165 goto error_info;
166 hotplug_slot->info = info;
167
168 hotplug_slot->ops = &s390_hotplug_slot_ops; 162 hotplug_slot->ops = &s390_hotplug_slot_ops;
169 163
170 get_power_status(hotplug_slot, &info->power_status);
171 get_adapter_status(hotplug_slot, &info->adapter_status);
172
173 snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); 164 snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
174 rc = pci_hp_register(slot->hotplug_slot, zdev->bus, 165 rc = pci_hp_register(slot->hotplug_slot, zdev->bus,
175 ZPCI_DEVFN, name); 166 ZPCI_DEVFN, name);
@@ -180,8 +171,6 @@ int zpci_init_slot(struct zpci_dev *zdev)
180 return 0; 171 return 0;
181 172
182error_reg: 173error_reg:
183 kfree(info);
184error_info:
185 kfree(hotplug_slot); 174 kfree(hotplug_slot);
186error_hp: 175error_hp:
187 kfree(slot); 176 kfree(slot);
@@ -199,7 +188,6 @@ void zpci_exit_slot(struct zpci_dev *zdev)
199 continue; 188 continue;
200 list_del(&slot->slot_list); 189 list_del(&slot->slot_list);
201 pci_hp_deregister(slot->hotplug_slot); 190 pci_hp_deregister(slot->hotplug_slot);
202 kfree(slot->hotplug_slot->info);
203 kfree(slot->hotplug_slot); 191 kfree(slot->hotplug_slot);
204 kfree(slot); 192 kfree(slot);
205 } 193 }
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index af4c28c574dd..e103826c83e3 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -585,7 +585,6 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
585 585
586static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot) 586static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
587{ 587{
588 kfree(bss_hotplug_slot->info);
589 kfree(bss_hotplug_slot->private); 588 kfree(bss_hotplug_slot->private);
590 kfree(bss_hotplug_slot); 589 kfree(bss_hotplug_slot);
591} 590}
@@ -614,14 +613,6 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
614 goto alloc_err; 613 goto alloc_err;
615 } 614 }
616 615
617 bss_hotplug_slot->info =
618 kzalloc(sizeof(struct hotplug_slot_info),
619 GFP_KERNEL);
620 if (!bss_hotplug_slot->info) {
621 rc = -ENOMEM;
622 goto alloc_err;
623 }
624
625 if (sn_hp_slot_private_alloc(bss_hotplug_slot, 616 if (sn_hp_slot_private_alloc(bss_hotplug_slot,
626 pci_bus, device, name)) { 617 pci_bus, device, name)) {
627 rc = -ENOMEM; 618 rc = -ENOMEM;
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 516e4835019c..a7bb816e6f25 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -67,7 +67,9 @@ struct slot {
67 u32 number; 67 u32 number;
68 u8 is_a_board; 68 u8 is_a_board;
69 u8 state; 69 u8 state;
70 u8 attention_save;
70 u8 presence_save; 71 u8 presence_save;
72 u8 latch_save;
71 u8 pwr_save; 73 u8 pwr_save;
72 struct controller *ctrl; 74 struct controller *ctrl;
73 const struct hpc_ops *hpc_ops; 75 const struct hpc_ops *hpc_ops;
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 26cbea04237c..b7181b7e7b98 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -65,7 +65,6 @@ static int init_slots(struct controller *ctrl)
65{ 65{
66 struct slot *slot; 66 struct slot *slot;
67 struct hotplug_slot *hotplug_slot; 67 struct hotplug_slot *hotplug_slot;
68 struct hotplug_slot_info *info;
69 char name[SLOT_NAME_SIZE]; 68 char name[SLOT_NAME_SIZE];
70 int retval; 69 int retval;
71 int i; 70 int i;
@@ -84,13 +83,6 @@ static int init_slots(struct controller *ctrl)
84 } 83 }
85 slot->hotplug_slot = hotplug_slot; 84 slot->hotplug_slot = hotplug_slot;
86 85
87 info = kzalloc(sizeof(*info), GFP_KERNEL);
88 if (!info) {
89 retval = -ENOMEM;
90 goto error_hpslot;
91 }
92 hotplug_slot->info = info;
93
94 slot->hp_slot = i; 86 slot->hp_slot = i;
95 slot->ctrl = ctrl; 87 slot->ctrl = ctrl;
96 slot->bus = ctrl->pci_dev->subordinate->number; 88 slot->bus = ctrl->pci_dev->subordinate->number;
@@ -101,7 +93,7 @@ static int init_slots(struct controller *ctrl)
101 slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number); 93 slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number);
102 if (!slot->wq) { 94 if (!slot->wq) {
103 retval = -ENOMEM; 95 retval = -ENOMEM;
104 goto error_info; 96 goto error_hpslot;
105 } 97 }
106 98
107 mutex_init(&slot->lock); 99 mutex_init(&slot->lock);
@@ -124,10 +116,10 @@ static int init_slots(struct controller *ctrl)
124 goto error_slotwq; 116 goto error_slotwq;
125 } 117 }
126 118
127 get_power_status(hotplug_slot, &info->power_status); 119 get_power_status(hotplug_slot, &slot->pwr_save);
128 get_attention_status(hotplug_slot, &info->attention_status); 120 get_attention_status(hotplug_slot, &slot->attention_save);
129 get_latch_status(hotplug_slot, &info->latch_status); 121 get_latch_status(hotplug_slot, &slot->latch_save);
130 get_adapter_status(hotplug_slot, &info->adapter_status); 122 get_adapter_status(hotplug_slot, &slot->presence_save);
131 123
132 list_add(&slot->slot_list, &ctrl->slot_list); 124 list_add(&slot->slot_list, &ctrl->slot_list);
133 } 125 }
@@ -135,8 +127,6 @@ static int init_slots(struct controller *ctrl)
135 return 0; 127 return 0;
136error_slotwq: 128error_slotwq:
137 destroy_workqueue(slot->wq); 129 destroy_workqueue(slot->wq);
138error_info:
139 kfree(info);
140error_hpslot: 130error_hpslot:
141 kfree(hotplug_slot); 131 kfree(hotplug_slot);
142error_slot: 132error_slot:
@@ -154,7 +144,6 @@ void cleanup_slots(struct controller *ctrl)
154 cancel_delayed_work(&slot->work); 144 cancel_delayed_work(&slot->work);
155 destroy_workqueue(slot->wq); 145 destroy_workqueue(slot->wq);
156 pci_hp_deregister(slot->hotplug_slot); 146 pci_hp_deregister(slot->hotplug_slot);
157 kfree(slot->hotplug_slot->info);
158 kfree(slot->hotplug_slot); 147 kfree(slot->hotplug_slot);
159 kfree(slot); 148 kfree(slot);
160 } 149 }
@@ -170,7 +159,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
170 ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", 159 ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
171 __func__, slot_name(slot)); 160 __func__, slot_name(slot));
172 161
173 hotplug_slot->info->attention_status = status; 162 slot->attention_save = status;
174 slot->hpc_ops->set_attention_status(slot, status); 163 slot->hpc_ops->set_attention_status(slot, status);
175 164
176 return 0; 165 return 0;
@@ -206,7 +195,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
206 195
207 retval = slot->hpc_ops->get_power_status(slot, value); 196 retval = slot->hpc_ops->get_power_status(slot, value);
208 if (retval < 0) 197 if (retval < 0)
209 *value = hotplug_slot->info->power_status; 198 *value = slot->pwr_save;
210 199
211 return 0; 200 return 0;
212} 201}
@@ -221,7 +210,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
221 210
222 retval = slot->hpc_ops->get_attention_status(slot, value); 211 retval = slot->hpc_ops->get_attention_status(slot, value);
223 if (retval < 0) 212 if (retval < 0)
224 *value = hotplug_slot->info->attention_status; 213 *value = slot->attention_save;
225 214
226 return 0; 215 return 0;
227} 216}
@@ -236,7 +225,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
236 225
237 retval = slot->hpc_ops->get_latch_status(slot, value); 226 retval = slot->hpc_ops->get_latch_status(slot, value);
238 if (retval < 0) 227 if (retval < 0)
239 *value = hotplug_slot->info->latch_status; 228 *value = slot->latch_save;
240 229
241 return 0; 230 return 0;
242} 231}
@@ -251,7 +240,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
251 240
252 retval = slot->hpc_ops->get_adapter_status(slot, value); 241 retval = slot->hpc_ops->get_adapter_status(slot, value);
253 if (retval < 0) 242 if (retval < 0)
254 *value = hotplug_slot->info->adapter_status; 243 *value = slot->presence_save;
255 244
256 return 0; 245 return 0;
257} 246}
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 1267dcc5a531..078003dcde5b 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -446,23 +446,12 @@ void shpchp_queue_pushbutton_work(struct work_struct *work)
446 mutex_unlock(&p_slot->lock); 446 mutex_unlock(&p_slot->lock);
447} 447}
448 448
449static int update_slot_info (struct slot *slot) 449static void update_slot_info(struct slot *slot)
450{ 450{
451 struct hotplug_slot_info *info; 451 slot->hpc_ops->get_power_status(slot, &slot->pwr_save);
452 int result; 452 slot->hpc_ops->get_attention_status(slot, &slot->attention_save);
453 453 slot->hpc_ops->get_latch_status(slot, &slot->latch_save);
454 info = kmalloc(sizeof(*info), GFP_KERNEL); 454 slot->hpc_ops->get_adapter_status(slot, &slot->presence_save);
455 if (!info)
456 return -ENOMEM;
457
458 slot->hpc_ops->get_power_status(slot, &(info->power_status));
459 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
460 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
461 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
462
463 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
464 kfree (info);
465 return result;
466} 455}
467 456
468/* 457/*
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index a8aa2eadfd82..019b037319e3 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -902,15 +902,8 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus)
902 if (!asus->hotplug_slot) 902 if (!asus->hotplug_slot)
903 goto error_slot; 903 goto error_slot;
904 904
905 asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
906 GFP_KERNEL);
907 if (!asus->hotplug_slot->info)
908 goto error_info;
909
910 asus->hotplug_slot->private = asus; 905 asus->hotplug_slot->private = asus;
911 asus->hotplug_slot->ops = &asus_hotplug_slot_ops; 906 asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
912 asus_get_adapter_status(asus->hotplug_slot,
913 &asus->hotplug_slot->info->adapter_status);
914 907
915 ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi"); 908 ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
916 if (ret) { 909 if (ret) {
@@ -921,8 +914,6 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus)
921 return 0; 914 return 0;
922 915
923error_register: 916error_register:
924 kfree(asus->hotplug_slot->info);
925error_info:
926 kfree(asus->hotplug_slot); 917 kfree(asus->hotplug_slot);
927 asus->hotplug_slot = NULL; 918 asus->hotplug_slot = NULL;
928error_slot: 919error_slot:
@@ -1055,7 +1046,6 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
1055 asus_rfkill_hotplug(asus); 1046 asus_rfkill_hotplug(asus);
1056 if (asus->hotplug_slot) { 1047 if (asus->hotplug_slot) {
1057 pci_hp_deregister(asus->hotplug_slot); 1048 pci_hp_deregister(asus->hotplug_slot);
1058 kfree(asus->hotplug_slot->info);
1059 kfree(asus->hotplug_slot); 1049 kfree(asus->hotplug_slot);
1060 } 1050 }
1061 if (asus->hotplug_workqueue) 1051 if (asus->hotplug_workqueue)
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 41a364376e91..028b20f82962 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -745,15 +745,8 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
745 if (!eeepc->hotplug_slot) 745 if (!eeepc->hotplug_slot)
746 goto error_slot; 746 goto error_slot;
747 747
748 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
749 GFP_KERNEL);
750 if (!eeepc->hotplug_slot->info)
751 goto error_info;
752
753 eeepc->hotplug_slot->private = eeepc; 748 eeepc->hotplug_slot->private = eeepc;
754 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops; 749 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
755 eeepc_get_adapter_status(eeepc->hotplug_slot,
756 &eeepc->hotplug_slot->info->adapter_status);
757 750
758 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi"); 751 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
759 if (ret) { 752 if (ret) {
@@ -764,8 +757,6 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
764 return 0; 757 return 0;
765 758
766error_register: 759error_register:
767 kfree(eeepc->hotplug_slot->info);
768error_info:
769 kfree(eeepc->hotplug_slot); 760 kfree(eeepc->hotplug_slot);
770 eeepc->hotplug_slot = NULL; 761 eeepc->hotplug_slot = NULL;
771error_slot: 762error_slot:
@@ -831,7 +822,6 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
831 822
832 if (eeepc->hotplug_slot) { 823 if (eeepc->hotplug_slot) {
833 pci_hp_deregister(eeepc->hotplug_slot); 824 pci_hp_deregister(eeepc->hotplug_slot);
834 kfree(eeepc->hotplug_slot->info);
835 kfree(eeepc->hotplug_slot); 825 kfree(eeepc->hotplug_slot);
836 } 826 }
837 827
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 372dbe95c207..6f07a4e1de8d 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -23,17 +23,9 @@
23 * @hardware_test: Called to run a specified hardware test on the specified 23 * @hardware_test: Called to run a specified hardware test on the specified
24 * slot. 24 * slot.
25 * @get_power_status: Called to get the current power status of a slot. 25 * @get_power_status: Called to get the current power status of a slot.
26 * If this field is NULL, the value passed in the struct hotplug_slot_info
27 * will be used when this value is requested by a user.
28 * @get_attention_status: Called to get the current attention status of a slot. 26 * @get_attention_status: Called to get the current attention status of a slot.
29 * If this field is NULL, the value passed in the struct hotplug_slot_info
30 * will be used when this value is requested by a user.
31 * @get_latch_status: Called to get the current latch status of a slot. 27 * @get_latch_status: Called to get the current latch status of a slot.
32 * If this field is NULL, the value passed in the struct hotplug_slot_info
33 * will be used when this value is requested by a user.
34 * @get_adapter_status: Called to get see if an adapter is present in the slot or not. 28 * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
35 * If this field is NULL, the value passed in the struct hotplug_slot_info
36 * will be used when this value is requested by a user.
37 * @reset_slot: Optional interface to allow override of a bus reset for the 29 * @reset_slot: Optional interface to allow override of a bus reset for the
38 * slot for cases where a secondary bus reset can result in spurious 30 * slot for cases where a secondary bus reset can result in spurious
39 * hotplug events or where a slot can be reset independent of the bus. 31 * hotplug events or where a slot can be reset independent of the bus.
@@ -56,26 +48,8 @@ struct hotplug_slot_ops {
56}; 48};
57 49
58/** 50/**
59 * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
60 * @power_status: if power is enabled or not (1/0)
61 * @attention_status: if the attention light is enabled or not (1/0)
62 * @latch_status: if the latch (if any) is open or closed (1/0)
63 * @adapter_status: if there is a pci board present in the slot or not (1/0)
64 *
65 * Used to notify the hotplug pci core of the status of a specific slot.
66 */
67struct hotplug_slot_info {
68 u8 power_status;
69 u8 attention_status;
70 u8 latch_status;
71 u8 adapter_status;
72};
73
74/**
75 * struct hotplug_slot - used to register a physical slot with the hotplug pci core 51 * struct hotplug_slot - used to register a physical slot with the hotplug pci core
76 * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot 52 * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
77 * @info: pointer to the &struct hotplug_slot_info for the initial values for
78 * this slot.
79 * @private: used by the hotplug pci controller driver to store whatever it 53 * @private: used by the hotplug pci controller driver to store whatever it
80 * needs. 54 * needs.
81 * @owner: The module owner of this structure 55 * @owner: The module owner of this structure
@@ -83,7 +57,6 @@ struct hotplug_slot_info {
83 */ 57 */
84struct hotplug_slot { 58struct hotplug_slot {
85 const struct hotplug_slot_ops *ops; 59 const struct hotplug_slot_ops *ops;
86 struct hotplug_slot_info *info;
87 void *private; 60 void *private;
88 61
89 /* Variables below this are for use only by the hotplug pci core. */ 62 /* Variables below this are for use only by the hotplug pci core. */
@@ -110,9 +83,6 @@ void pci_hp_del(struct hotplug_slot *slot);
110void pci_hp_destroy(struct hotplug_slot *slot); 83void pci_hp_destroy(struct hotplug_slot *slot);
111void pci_hp_deregister(struct hotplug_slot *slot); 84void pci_hp_deregister(struct hotplug_slot *slot);
112 85
113int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot,
114 struct hotplug_slot_info *info);
115
116/* use a define to avoid include chaining to get THIS_MODULE & friends */ 86/* use a define to avoid include chaining to get THIS_MODULE & friends */
117#define pci_hp_register(slot, pbus, devnr, name) \ 87#define pci_hp_register(slot, pbus, devnr, name) \
118 __pci_hp_register(slot, pbus, devnr, name, THIS_MODULE, KBUILD_MODNAME) 88 __pci_hp_register(slot, pbus, devnr, name, THIS_MODULE, KBUILD_MODNAME)