summaryrefslogtreecommitdiffstats
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
commit125450f814418b9f889c9885831467d1b2e25a7d (patch)
tree4acbbedcd4446d00cd5f5122b56aa7d2d7646815
parenta7da21613c4efcd4cc0235e6a30bec96ae47c619 (diff)
PCI: hotplug: Embed hotplug_slot
When the PCI hotplug core and its first user, cpqphp, were introduced in February 2002 with historic commit a8a2069f432c, cpqphp allocated a slot struct for its internal use plus a hotplug_slot struct to be registered with the hotplug core and linked the two with pointers: https://git.kernel.org/tglx/history/c/a8a2069f432c Nowadays, the predominant pattern in the tree is to embed ("subclass") such structures in one another and cast to the containing struct with container_of(). But it wasn't until July 2002 that container_of() was introduced with historic commit ec4f214232cf: https://git.kernel.org/tglx/history/c/ec4f214232cf pnv_php, introduced in 2016, did the right thing and embedded struct hotplug_slot in its internal struct pnv_php_slot, but all other drivers cargo-culted cpqphp's design and linked separate structs with pointers. Embedding structs is preferrable to linking them with pointers because it requires fewer allocations, thereby reducing overhead and simplifying error paths. Casting an embedded struct to the containing struct becomes a cheap subtraction rather than a dereference. And having fewer pointers reduces the risk of them pointing nowhere either accidentally or due to an attack. Convert all drivers to embed struct hotplug_slot in their internal slot struct. The "private" pointer in struct hotplug_slot thereby becomes unused, so drop it. 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--drivers/pci/hotplug/acpiphp.h9
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c28
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c2
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h9
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c37
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c6
-rw-r--r--drivers/pci/hotplug/cpqphp.h9
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c37
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c2
-rw-r--r--drivers/pci/hotplug/ibmphp.h7
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c92
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c37
-rw-r--r--drivers/pci/hotplug/pciehp.h11
-rw-r--r--drivers/pci/hotplug/pciehp_core.c37
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c4
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c8
-rw-r--r--drivers/pci/hotplug/pnv_php.c9
-rw-r--r--drivers/pci/hotplug/rpaphp.h7
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c14
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c15
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c30
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c52
-rw-r--r--drivers/pci/hotplug/shpchp.h6
-rw-r--r--drivers/pci/hotplug/shpchp_core.c17
-rw-r--r--drivers/platform/x86/asus-wmi.c26
-rw-r--r--drivers/platform/x86/eeepc-laptop.c30
-rw-r--r--include/linux/pci_hotplug.h3
27 files changed, 223 insertions, 321 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 8377e736ea69..cf3058404f41 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -33,14 +33,19 @@ struct acpiphp_slot;
33 * struct slot - slot information for each *physical* slot 33 * struct slot - slot information for each *physical* slot
34 */ 34 */
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 unsigned int sun; /* ACPI _SUN (Slot User Number) value */ 38 unsigned int sun; /* ACPI _SUN (Slot User Number) value */
39}; 39};
40 40
41static inline const char *slot_name(struct slot *slot) 41static inline const char *slot_name(struct slot *slot)
42{ 42{
43 return hotplug_slot_name(slot->hotplug_slot); 43 return hotplug_slot_name(&slot->hotplug_slot);
44}
45
46static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
47{
48 return container_of(hotplug_slot, struct slot, hotplug_slot);
44} 49}
45 50
46/* 51/*
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index abd4f8d7e16a..c9e2bd40c038 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(acpiphp_unregister_attention);
118 */ 118 */
119static int enable_slot(struct hotplug_slot *hotplug_slot) 119static int enable_slot(struct hotplug_slot *hotplug_slot)
120{ 120{
121 struct slot *slot = hotplug_slot->private; 121 struct slot *slot = to_slot(hotplug_slot);
122 122
123 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 123 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
124 124
@@ -135,7 +135,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
135 */ 135 */
136static int disable_slot(struct hotplug_slot *hotplug_slot) 136static int disable_slot(struct hotplug_slot *hotplug_slot)
137{ 137{
138 struct slot *slot = hotplug_slot->private; 138 struct slot *slot = to_slot(hotplug_slot);
139 139
140 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 140 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
141 141
@@ -179,7 +179,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
179 */ 179 */
180static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 180static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
181{ 181{
182 struct slot *slot = hotplug_slot->private; 182 struct slot *slot = to_slot(hotplug_slot);
183 183
184 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 184 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
185 185
@@ -225,7 +225,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
225 */ 225 */
226static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 226static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
227{ 227{
228 struct slot *slot = hotplug_slot->private; 228 struct slot *slot = to_slot(hotplug_slot);
229 229
230 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 230 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
231 231
@@ -245,7 +245,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
245 */ 245 */
246static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 246static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
247{ 247{
248 struct slot *slot = hotplug_slot->private; 248 struct slot *slot = to_slot(hotplug_slot);
249 249
250 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 250 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
251 251
@@ -266,12 +266,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,
266 if (!slot) 266 if (!slot)
267 goto error; 267 goto error;
268 268
269 slot->hotplug_slot = kzalloc(sizeof(*slot->hotplug_slot), GFP_KERNEL); 269 slot->hotplug_slot.ops = &acpi_hotplug_slot_ops;
270 if (!slot->hotplug_slot)
271 goto error_slot;
272
273 slot->hotplug_slot->private = slot;
274 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
275 270
276 slot->acpi_slot = acpiphp_slot; 271 slot->acpi_slot = acpiphp_slot;
277 272
@@ -279,20 +274,18 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,
279 slot->sun = sun; 274 slot->sun = sun;
280 snprintf(name, SLOT_NAME_SIZE, "%u", sun); 275 snprintf(name, SLOT_NAME_SIZE, "%u", sun);
281 276
282 retval = pci_hp_register(slot->hotplug_slot, acpiphp_slot->bus, 277 retval = pci_hp_register(&slot->hotplug_slot, acpiphp_slot->bus,
283 acpiphp_slot->device, name); 278 acpiphp_slot->device, name);
284 if (retval == -EBUSY) 279 if (retval == -EBUSY)
285 goto error_hpslot; 280 goto error_slot;
286 if (retval) { 281 if (retval) {
287 pr_err("pci_hp_register failed with error %d\n", retval); 282 pr_err("pci_hp_register failed with error %d\n", retval);
288 goto error_hpslot; 283 goto error_slot;
289 } 284 }
290 285
291 pr_info("Slot [%s] registered\n", slot_name(slot)); 286 pr_info("Slot [%s] registered\n", slot_name(slot));
292 287
293 return 0; 288 return 0;
294error_hpslot:
295 kfree(slot->hotplug_slot);
296error_slot: 289error_slot:
297 kfree(slot); 290 kfree(slot);
298error: 291error:
@@ -306,8 +299,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
306 299
307 pr_info("Slot [%s] unregistered\n", slot_name(slot)); 300 pr_info("Slot [%s] unregistered\n", slot_name(slot));
308 301
309 pci_hp_deregister(slot->hotplug_slot); 302 pci_hp_deregister(&slot->hotplug_slot);
310 kfree(slot->hotplug_slot);
311 kfree(slot); 303 kfree(slot);
312} 304}
313 305
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 41713f16ff97..df48b3b03ab4 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -41,7 +41,7 @@ MODULE_VERSION(DRIVER_VERSION);
41#define IBM_HARDWARE_ID1 "IBM37D0" 41#define IBM_HARDWARE_ID1 "IBM37D0"
42#define IBM_HARDWARE_ID2 "IBM37D4" 42#define IBM_HARDWARE_ID2 "IBM37D4"
43 43
44#define hpslot_to_sun(A) (((struct slot *)((A)->private))->sun) 44#define hpslot_to_sun(A) (to_slot(A)->sun)
45 45
46/* union apci_descriptor - allows access to the 46/* union apci_descriptor - allows access to the
47 * various device descriptors that are embedded in the 47 * various device descriptors that are embedded in the
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index a35f40a2290c..f33ff2bca414 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -35,7 +35,7 @@ struct slot {
35 unsigned int latch_status:1; 35 unsigned int latch_status:1;
36 unsigned int adapter_status:1; 36 unsigned int adapter_status:1;
37 unsigned int extracting; 37 unsigned int extracting;
38 struct hotplug_slot *hotplug_slot; 38 struct hotplug_slot hotplug_slot;
39 struct list_head slot_list; 39 struct list_head slot_list;
40}; 40};
41 41
@@ -60,7 +60,12 @@ struct cpci_hp_controller {
60 60
61static inline const char *slot_name(struct slot *slot) 61static inline const char *slot_name(struct slot *slot)
62{ 62{
63 return hotplug_slot_name(slot->hotplug_slot); 63 return hotplug_slot_name(&slot->hotplug_slot);
64}
65
66static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
67{
68 return container_of(hotplug_slot, struct slot, hotplug_slot);
64} 69}
65 70
66int cpci_hp_register_controller(struct cpci_hp_controller *controller); 71int cpci_hp_register_controller(struct cpci_hp_controller *controller);
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index a17fb24c28cd..603eadf3d965 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -70,7 +70,7 @@ static const struct hotplug_slot_ops cpci_hotplug_slot_ops = {
70static int 70static int
71enable_slot(struct hotplug_slot *hotplug_slot) 71enable_slot(struct hotplug_slot *hotplug_slot)
72{ 72{
73 struct slot *slot = hotplug_slot->private; 73 struct slot *slot = to_slot(hotplug_slot);
74 int retval = 0; 74 int retval = 0;
75 75
76 dbg("%s - physical_slot = %s", __func__, slot_name(slot)); 76 dbg("%s - physical_slot = %s", __func__, slot_name(slot));
@@ -83,7 +83,7 @@ enable_slot(struct hotplug_slot *hotplug_slot)
83static int 83static int
84disable_slot(struct hotplug_slot *hotplug_slot) 84disable_slot(struct hotplug_slot *hotplug_slot)
85{ 85{
86 struct slot *slot = hotplug_slot->private; 86 struct slot *slot = to_slot(hotplug_slot);
87 int retval = 0; 87 int retval = 0;
88 88
89 dbg("%s - physical_slot = %s", __func__, slot_name(slot)); 89 dbg("%s - physical_slot = %s", __func__, slot_name(slot));
@@ -139,7 +139,7 @@ cpci_get_power_status(struct slot *slot)
139static int 139static int
140get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 140get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
141{ 141{
142 struct slot *slot = hotplug_slot->private; 142 struct slot *slot = to_slot(hotplug_slot);
143 143
144 *value = cpci_get_power_status(slot); 144 *value = cpci_get_power_status(slot);
145 return 0; 145 return 0;
@@ -148,7 +148,7 @@ get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
148static int 148static int
149get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 149get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
150{ 150{
151 struct slot *slot = hotplug_slot->private; 151 struct slot *slot = to_slot(hotplug_slot);
152 152
153 *value = cpci_get_attention_status(slot); 153 *value = cpci_get_attention_status(slot);
154 return 0; 154 return 0;
@@ -157,13 +157,13 @@ get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
157static int 157static int
158set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 158set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
159{ 159{
160 return cpci_set_attention_status(hotplug_slot->private, status); 160 return cpci_set_attention_status(to_slot(hotplug_slot), status);
161} 161}
162 162
163static int 163static int
164get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 164get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
165{ 165{
166 struct slot *slot = hotplug_slot->private; 166 struct slot *slot = to_slot(hotplug_slot);
167 167
168 *value = slot->adapter_status; 168 *value = slot->adapter_status;
169 return 0; 169 return 0;
@@ -172,7 +172,7 @@ get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
172static int 172static int
173get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 173get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
174{ 174{
175 struct slot *slot = hotplug_slot->private; 175 struct slot *slot = to_slot(hotplug_slot);
176 176
177 *value = slot->latch_status; 177 *value = slot->latch_status;
178 return 0; 178 return 0;
@@ -180,7 +180,6 @@ get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
180 180
181static void release_slot(struct slot *slot) 181static void release_slot(struct slot *slot)
182{ 182{
183 kfree(slot->hotplug_slot);
184 pci_dev_put(slot->dev); 183 pci_dev_put(slot->dev);
185 kfree(slot); 184 kfree(slot);
186} 185}
@@ -191,7 +190,6 @@ int
191cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) 190cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
192{ 191{
193 struct slot *slot; 192 struct slot *slot;
194 struct hotplug_slot *hotplug_slot;
195 char name[SLOT_NAME_SIZE]; 193 char name[SLOT_NAME_SIZE];
196 int status; 194 int status;
197 int i; 195 int i;
@@ -210,28 +208,19 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
210 goto error; 208 goto error;
211 } 209 }
212 210
213 hotplug_slot =
214 kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
215 if (!hotplug_slot) {
216 status = -ENOMEM;
217 goto error_slot;
218 }
219 slot->hotplug_slot = hotplug_slot;
220
221 slot->bus = bus; 211 slot->bus = bus;
222 slot->number = i; 212 slot->number = i;
223 slot->devfn = PCI_DEVFN(i, 0); 213 slot->devfn = PCI_DEVFN(i, 0);
224 214
225 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i); 215 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
226 216
227 hotplug_slot->private = slot; 217 slot->hotplug_slot.ops = &cpci_hotplug_slot_ops;
228 hotplug_slot->ops = &cpci_hotplug_slot_ops;
229 218
230 dbg("registering slot %s", name); 219 dbg("registering slot %s", name);
231 status = pci_hp_register(slot->hotplug_slot, bus, i, name); 220 status = pci_hp_register(&slot->hotplug_slot, bus, i, name);
232 if (status) { 221 if (status) {
233 err("pci_hp_register failed with error %d", status); 222 err("pci_hp_register failed with error %d", status);
234 goto error_hpslot; 223 goto error_slot;
235 } 224 }
236 dbg("slot registered with name: %s", slot_name(slot)); 225 dbg("slot registered with name: %s", slot_name(slot));
237 226
@@ -242,8 +231,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
242 up_write(&list_rwsem); 231 up_write(&list_rwsem);
243 } 232 }
244 return 0; 233 return 0;
245error_hpslot:
246 kfree(hotplug_slot);
247error_slot: 234error_slot:
248 kfree(slot); 235 kfree(slot);
249error: 236error:
@@ -269,7 +256,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
269 slots--; 256 slots--;
270 257
271 dbg("deregistering slot %s", slot_name(slot)); 258 dbg("deregistering slot %s", slot_name(slot));
272 pci_hp_deregister(slot->hotplug_slot); 259 pci_hp_deregister(&slot->hotplug_slot);
273 release_slot(slot); 260 release_slot(slot);
274 } 261 }
275 } 262 }
@@ -571,7 +558,7 @@ cleanup_slots(void)
571 goto cleanup_null; 558 goto cleanup_null;
572 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 559 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
573 list_del(&slot->slot_list); 560 list_del(&slot->slot_list);
574 pci_hp_deregister(slot->hotplug_slot); 561 pci_hp_deregister(&slot->hotplug_slot);
575 release_slot(slot); 562 release_slot(slot);
576 } 563 }
577cleanup_null: 564cleanup_null:
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index 389b8fb50cd9..2c16adb7f4ec 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -194,8 +194,7 @@ int cpci_led_on(struct slot *slot)
194 slot->devfn, 194 slot->devfn,
195 hs_cap + 2, 195 hs_cap + 2,
196 hs_csr)) { 196 hs_csr)) {
197 err("Could not set LOO for slot %s", 197 err("Could not set LOO for slot %s", slot_name(slot));
198 hotplug_slot_name(slot->hotplug_slot));
199 return -ENODEV; 198 return -ENODEV;
200 } 199 }
201 } 200 }
@@ -223,8 +222,7 @@ int cpci_led_off(struct slot *slot)
223 slot->devfn, 222 slot->devfn,
224 hs_cap + 2, 223 hs_cap + 2,
225 hs_csr)) { 224 hs_csr)) {
226 err("Could not clear LOO for slot %s", 225 err("Could not clear LOO for slot %s", slot_name(slot));
227 hotplug_slot_name(slot->hotplug_slot));
228 return -ENODEV; 226 return -ENODEV;
229 } 227 }
230 } 228 }
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index db78b394a075..77e4e0142fbc 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -260,7 +260,7 @@ struct slot {
260 u8 hp_slot; 260 u8 hp_slot;
261 struct controller *ctrl; 261 struct controller *ctrl;
262 void __iomem *p_sm_slot; 262 void __iomem *p_sm_slot;
263 struct hotplug_slot *hotplug_slot; 263 struct hotplug_slot hotplug_slot;
264}; 264};
265 265
266struct pci_resource { 266struct pci_resource {
@@ -445,7 +445,12 @@ extern u8 cpqhp_disk_irq;
445 445
446static inline const char *slot_name(struct slot *slot) 446static inline const char *slot_name(struct slot *slot)
447{ 447{
448 return hotplug_slot_name(slot->hotplug_slot); 448 return hotplug_slot_name(&slot->hotplug_slot);
449}
450
451static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
452{
453 return container_of(hotplug_slot, struct slot, hotplug_slot);
449} 454}
450 455
451/* 456/*
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index bb354a7fc112..95b7d60cf119 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -275,8 +275,7 @@ static int ctrl_slot_cleanup(struct controller *ctrl)
275 275
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);
280 kfree(old_slot); 279 kfree(old_slot);
281 old_slot = next_slot; 280 old_slot = next_slot;
282 } 281 }
@@ -418,7 +417,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
418static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 417static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
419{ 418{
420 struct pci_func *slot_func; 419 struct pci_func *slot_func;
421 struct slot *slot = hotplug_slot->private; 420 struct slot *slot = to_slot(hotplug_slot);
422 struct controller *ctrl = slot->ctrl; 421 struct controller *ctrl = slot->ctrl;
423 u8 bus; 422 u8 bus;
424 u8 devfn; 423 u8 devfn;
@@ -445,7 +444,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
445static int process_SI(struct hotplug_slot *hotplug_slot) 444static int process_SI(struct hotplug_slot *hotplug_slot)
446{ 445{
447 struct pci_func *slot_func; 446 struct pci_func *slot_func;
448 struct slot *slot = hotplug_slot->private; 447 struct slot *slot = to_slot(hotplug_slot);
449 struct controller *ctrl = slot->ctrl; 448 struct controller *ctrl = slot->ctrl;
450 u8 bus; 449 u8 bus;
451 u8 devfn; 450 u8 devfn;
@@ -477,7 +476,7 @@ static int process_SI(struct hotplug_slot *hotplug_slot)
477static int process_SS(struct hotplug_slot *hotplug_slot) 476static int process_SS(struct hotplug_slot *hotplug_slot)
478{ 477{
479 struct pci_func *slot_func; 478 struct pci_func *slot_func;
480 struct slot *slot = hotplug_slot->private; 479 struct slot *slot = to_slot(hotplug_slot);
481 struct controller *ctrl = slot->ctrl; 480 struct controller *ctrl = slot->ctrl;
482 u8 bus; 481 u8 bus;
483 u8 devfn; 482 u8 devfn;
@@ -504,7 +503,7 @@ static int process_SS(struct hotplug_slot *hotplug_slot)
504 503
505static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value) 504static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
506{ 505{
507 struct slot *slot = hotplug_slot->private; 506 struct slot *slot = to_slot(hotplug_slot);
508 struct controller *ctrl = slot->ctrl; 507 struct controller *ctrl = slot->ctrl;
509 508
510 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); 509 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
@@ -515,7 +514,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
515 514
516static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 515static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
517{ 516{
518 struct slot *slot = hotplug_slot->private; 517 struct slot *slot = to_slot(hotplug_slot);
519 struct controller *ctrl = slot->ctrl; 518 struct controller *ctrl = slot->ctrl;
520 519
521 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); 520 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
@@ -526,7 +525,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
526 525
527static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 526static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
528{ 527{
529 struct slot *slot = hotplug_slot->private; 528 struct slot *slot = to_slot(hotplug_slot);
530 struct controller *ctrl = slot->ctrl; 529 struct controller *ctrl = slot->ctrl;
531 530
532 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); 531 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
@@ -537,7 +536,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
537 536
538static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 537static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
539{ 538{
540 struct slot *slot = hotplug_slot->private; 539 struct slot *slot = to_slot(hotplug_slot);
541 struct controller *ctrl = slot->ctrl; 540 struct controller *ctrl = slot->ctrl;
542 541
543 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); 542 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
@@ -549,7 +548,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
549 548
550static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 549static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
551{ 550{
552 struct slot *slot = hotplug_slot->private; 551 struct slot *slot = to_slot(hotplug_slot);
553 struct controller *ctrl = slot->ctrl; 552 struct controller *ctrl = slot->ctrl;
554 553
555 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); 554 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
@@ -577,7 +576,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
577 void __iomem *smbios_table) 576 void __iomem *smbios_table)
578{ 577{
579 struct slot *slot; 578 struct slot *slot;
580 struct hotplug_slot *hotplug_slot;
581 struct pci_bus *bus = ctrl->pci_bus; 579 struct pci_bus *bus = ctrl->pci_bus;
582 u8 number_of_slots; 580 u8 number_of_slots;
583 u8 slot_device; 581 u8 slot_device;
@@ -603,14 +601,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
603 goto error; 601 goto error;
604 } 602 }
605 603
606 slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
607 GFP_KERNEL);
608 if (!slot->hotplug_slot) {
609 result = -ENOMEM;
610 goto error_slot;
611 }
612 hotplug_slot = slot->hotplug_slot;
613
614 slot->ctrl = ctrl; 604 slot->ctrl = ctrl;
615 slot->bus = ctrl->bus; 605 slot->bus = ctrl->bus;
616 slot->device = slot_device; 606 slot->device = slot_device;
@@ -659,21 +649,20 @@ static int ctrl_slot_setup(struct controller *ctrl,
659 ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; 649 ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
660 650
661 /* register this slot with the hotplug pci core */ 651 /* register this slot with the hotplug pci core */
662 hotplug_slot->private = slot;
663 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); 652 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
664 hotplug_slot->ops = &cpqphp_hotplug_slot_ops; 653 slot->hotplug_slot.ops = &cpqphp_hotplug_slot_ops;
665 654
666 dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", 655 dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n",
667 slot->bus, slot->device, 656 slot->bus, slot->device,
668 slot->number, ctrl->slot_device_offset, 657 slot->number, ctrl->slot_device_offset,
669 slot_number); 658 slot_number);
670 result = pci_hp_register(hotplug_slot, 659 result = pci_hp_register(&slot->hotplug_slot,
671 ctrl->pci_dev->bus, 660 ctrl->pci_dev->bus,
672 slot->device, 661 slot->device,
673 name); 662 name);
674 if (result) { 663 if (result) {
675 err("pci_hp_register failed with error %d\n", result); 664 err("pci_hp_register failed with error %d\n", result);
676 goto error_hpslot; 665 goto error_slot;
677 } 666 }
678 667
679 slot->next = ctrl->slot; 668 slot->next = ctrl->slot;
@@ -685,8 +674,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
685 } 674 }
686 675
687 return 0; 676 return 0;
688error_hpslot:
689 kfree(hotplug_slot);
690error_slot: 677error_slot:
691 kfree(slot); 678 kfree(slot);
692error: 679error:
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 9c4826ac6a4f..b7f4e1f099d9 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1130,8 +1130,6 @@ 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)
1134 continue;
1135 if (get_presence_status(ctrl, slot) == 0) 1133 if (get_presence_status(ctrl, slot) == 0)
1136 continue; 1134 continue;
1137 /* If another adapter is running on the same segment but at a 1135 /* If another adapter is running on the same segment but at a
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index db387e10581e..b89f850c3a4e 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -698,7 +698,7 @@ struct slot {
698 u8 supported_bus_mode; 698 u8 supported_bus_mode;
699 u8 flag; /* this is for disable slot and polling */ 699 u8 flag; /* this is for disable slot and polling */
700 u8 ctlr_index; 700 u8 ctlr_index;
701 struct hotplug_slot *hotplug_slot; 701 struct hotplug_slot hotplug_slot;
702 struct controller *ctrl; 702 struct controller *ctrl;
703 struct pci_func *func; 703 struct pci_func *func;
704 u8 irq[4]; 704 u8 irq[4];
@@ -742,5 +742,10 @@ int ibmphp_configure_card(struct pci_func *, u8);
742int ibmphp_unconfigure_card(struct slot **, int); 742int ibmphp_unconfigure_card(struct slot **, int);
743extern const struct hotplug_slot_ops ibmphp_hotplug_slot_ops; 743extern const struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
744 744
745static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
746{
747 return container_of(hotplug_slot, struct slot, hotplug_slot);
748}
749
745#endif //__IBMPHP_H 750#endif //__IBMPHP_H
746 751
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 96e5b1f544ac..08a58e911fc2 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -247,11 +247,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
247 break; 247 break;
248 } 248 }
249 if (rc == 0) { 249 if (rc == 0) {
250 pslot = hotplug_slot->private; 250 pslot = to_slot(hotplug_slot);
251 if (pslot) 251 rc = ibmphp_hpc_writeslot(pslot, cmd);
252 rc = ibmphp_hpc_writeslot(pslot, cmd);
253 else
254 rc = -ENODEV;
255 } 252 }
256 } else 253 } else
257 rc = -ENODEV; 254 rc = -ENODEV;
@@ -273,19 +270,15 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
273 270
274 ibmphp_lock_operations(); 271 ibmphp_lock_operations();
275 if (hotplug_slot) { 272 if (hotplug_slot) {
276 pslot = hotplug_slot->private; 273 pslot = to_slot(hotplug_slot);
277 if (pslot) { 274 memcpy(&myslot, pslot, sizeof(struct slot));
278 memcpy(&myslot, pslot, sizeof(struct slot)); 275 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
279 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, 276 &myslot.status);
280 &(myslot.status)); 277 if (!rc)
281 if (!rc) 278 rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS,
282 rc = ibmphp_hpc_readslot(pslot, 279 &myslot.ext_status);
283 READ_EXTSLOTSTATUS, 280 if (!rc)
284 &(myslot.ext_status)); 281 *value = SLOT_ATTN(myslot.status, myslot.ext_status);
285 if (!rc)
286 *value = SLOT_ATTN(myslot.status,
287 myslot.ext_status);
288 }
289 } 282 }
290 283
291 ibmphp_unlock_operations(); 284 ibmphp_unlock_operations();
@@ -303,14 +296,12 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
303 (ulong) hotplug_slot, (ulong) value); 296 (ulong) hotplug_slot, (ulong) value);
304 ibmphp_lock_operations(); 297 ibmphp_lock_operations();
305 if (hotplug_slot) { 298 if (hotplug_slot) {
306 pslot = hotplug_slot->private; 299 pslot = to_slot(hotplug_slot);
307 if (pslot) { 300 memcpy(&myslot, pslot, sizeof(struct slot));
308 memcpy(&myslot, pslot, sizeof(struct slot)); 301 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
309 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, 302 &myslot.status);
310 &(myslot.status)); 303 if (!rc)
311 if (!rc) 304 *value = SLOT_LATCH(myslot.status);
312 *value = SLOT_LATCH(myslot.status);
313 }
314 } 305 }
315 306
316 ibmphp_unlock_operations(); 307 ibmphp_unlock_operations();
@@ -330,14 +321,12 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
330 (ulong) hotplug_slot, (ulong) value); 321 (ulong) hotplug_slot, (ulong) value);
331 ibmphp_lock_operations(); 322 ibmphp_lock_operations();
332 if (hotplug_slot) { 323 if (hotplug_slot) {
333 pslot = hotplug_slot->private; 324 pslot = to_slot(hotplug_slot);
334 if (pslot) { 325 memcpy(&myslot, pslot, sizeof(struct slot));
335 memcpy(&myslot, pslot, sizeof(struct slot)); 326 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
336 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, 327 &myslot.status);
337 &(myslot.status)); 328 if (!rc)
338 if (!rc) 329 *value = SLOT_PWRGD(myslot.status);
339 *value = SLOT_PWRGD(myslot.status);
340 }
341 } 330 }
342 331
343 ibmphp_unlock_operations(); 332 ibmphp_unlock_operations();
@@ -357,18 +346,16 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)
357 (ulong) hotplug_slot, (ulong) value); 346 (ulong) hotplug_slot, (ulong) value);
358 ibmphp_lock_operations(); 347 ibmphp_lock_operations();
359 if (hotplug_slot) { 348 if (hotplug_slot) {
360 pslot = hotplug_slot->private; 349 pslot = to_slot(hotplug_slot);
361 if (pslot) { 350 memcpy(&myslot, pslot, sizeof(struct slot));
362 memcpy(&myslot, pslot, sizeof(struct slot)); 351 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
363 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, 352 &myslot.status);
364 &(myslot.status)); 353 if (!rc) {
365 if (!rc) { 354 present = SLOT_PRESENT(myslot.status);
366 present = SLOT_PRESENT(myslot.status); 355 if (present == HPC_SLOT_EMPTY)
367 if (present == HPC_SLOT_EMPTY) 356 *value = 0;
368 *value = 0; 357 else
369 else 358 *value = 1;
370 *value = 1;
371 }
372 } 359 }
373 } 360 }
374 361
@@ -382,7 +369,7 @@ static int get_max_bus_speed(struct slot *slot)
382 int rc = 0; 369 int rc = 0;
383 u8 mode = 0; 370 u8 mode = 0;
384 enum pci_bus_speed speed; 371 enum pci_bus_speed speed;
385 struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; 372 struct pci_bus *bus = slot->hotplug_slot.pci_slot->bus;
386 373
387 debug("%s - Entry slot[%p]\n", __func__, slot); 374 debug("%s - Entry slot[%p]\n", __func__, slot);
388 375
@@ -582,7 +569,7 @@ static int validate(struct slot *slot_cur, int opn)
582 ****************************************************************************/ 569 ****************************************************************************/
583int ibmphp_update_slot_info(struct slot *slot_cur) 570int ibmphp_update_slot_info(struct slot *slot_cur)
584{ 571{
585 struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; 572 struct pci_bus *bus = slot_cur->hotplug_slot.pci_slot->bus;
586 u8 bus_speed; 573 u8 bus_speed;
587 u8 mode; 574 u8 mode;
588 575
@@ -652,7 +639,7 @@ static void free_slots(void)
652 639
653 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head, 640 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
654 ibm_slot_list) { 641 ibm_slot_list) {
655 pci_hp_del(slot_cur->hotplug_slot); 642 pci_hp_del(&slot_cur->hotplug_slot);
656 slot_cur->ctrl = NULL; 643 slot_cur->ctrl = NULL;
657 slot_cur->bus_on = NULL; 644 slot_cur->bus_on = NULL;
658 645
@@ -662,8 +649,7 @@ static void free_slots(void)
662 */ 649 */
663 ibmphp_unconfigure_card(&slot_cur, -1); 650 ibmphp_unconfigure_card(&slot_cur, -1);
664 651
665 pci_hp_destroy(slot_cur->hotplug_slot); 652 pci_hp_destroy(&slot_cur->hotplug_slot);
666 kfree(slot_cur->hotplug_slot);
667 kfree(slot_cur); 653 kfree(slot_cur);
668 } 654 }
669 debug("%s -- exit\n", __func__); 655 debug("%s -- exit\n", __func__);
@@ -985,7 +971,7 @@ static int enable_slot(struct hotplug_slot *hs)
985 ibmphp_lock_operations(); 971 ibmphp_lock_operations();
986 972
987 debug("ENABLING SLOT........\n"); 973 debug("ENABLING SLOT........\n");
988 slot_cur = hs->private; 974 slot_cur = to_slot(hs);
989 975
990 rc = validate(slot_cur, ENABLE); 976 rc = validate(slot_cur, ENABLE);
991 if (rc) { 977 if (rc) {
@@ -1146,7 +1132,7 @@ error_power:
1146**************************************************************/ 1132**************************************************************/
1147static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot) 1133static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1148{ 1134{
1149 struct slot *slot = hotplug_slot->private; 1135 struct slot *slot = to_slot(hotplug_slot);
1150 int rc; 1136 int rc;
1151 1137
1152 ibmphp_lock_operations(); 1138 ibmphp_lock_operations();
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index c05d066ab0d5..11a2661dc062 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -666,10 +666,7 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot)
666 struct slot *slot; 666 struct slot *slot;
667 int rc = 0; 667 int rc = 0;
668 668
669 if (!hotplug_slot || !hotplug_slot->private) 669 slot = to_slot(hotplug_slot);
670 return -EINVAL;
671
672 slot = hotplug_slot->private;
673 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); 670 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL);
674 return rc; 671 return rc;
675} 672}
@@ -687,7 +684,6 @@ static int __init ebda_rsrc_controller(void)
687 u8 ctlr_id, temp, bus_index; 684 u8 ctlr_id, temp, bus_index;
688 u16 ctlr, slot, bus; 685 u16 ctlr, slot, bus;
689 u16 slot_num, bus_num, index; 686 u16 slot_num, bus_num, index;
690 struct hotplug_slot *hp_slot_ptr;
691 struct controller *hpc_ptr; 687 struct controller *hpc_ptr;
692 struct ebda_hpc_bus *bus_ptr; 688 struct ebda_hpc_bus *bus_ptr;
693 struct ebda_hpc_slot *slot_ptr; 689 struct ebda_hpc_slot *slot_ptr;
@@ -746,7 +742,7 @@ static int __init ebda_rsrc_controller(void)
746 bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL); 742 bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
747 if (!bus_info_ptr1) { 743 if (!bus_info_ptr1) {
748 rc = -ENOMEM; 744 rc = -ENOMEM;
749 goto error_no_hp_slot; 745 goto error_no_slot;
750 } 746 }
751 bus_info_ptr1->slot_min = slot_ptr->slot_num; 747 bus_info_ptr1->slot_min = slot_ptr->slot_num;
752 bus_info_ptr1->slot_max = slot_ptr->slot_num; 748 bus_info_ptr1->slot_max = slot_ptr->slot_num;
@@ -817,7 +813,7 @@ static int __init ebda_rsrc_controller(void)
817 (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), 813 (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
818 "ibmphp")) { 814 "ibmphp")) {
819 rc = -ENODEV; 815 rc = -ENODEV;
820 goto error_no_hp_slot; 816 goto error_no_slot;
821 } 817 }
822 hpc_ptr->irq = readb(io_mem + addr + 4); 818 hpc_ptr->irq = readb(io_mem + addr + 4);
823 addr += 5; 819 addr += 5;
@@ -832,7 +828,7 @@ static int __init ebda_rsrc_controller(void)
832 break; 828 break;
833 default: 829 default:
834 rc = -ENODEV; 830 rc = -ENODEV;
835 goto error_no_hp_slot; 831 goto error_no_slot;
836 } 832 }
837 833
838 //reorganize chassis' linked list 834 //reorganize chassis' linked list
@@ -845,13 +841,6 @@ static int __init ebda_rsrc_controller(void)
845 841
846 // register slots with hpc core as well as create linked list of ibm slot 842 // register slots with hpc core as well as create linked list of ibm slot
847 for (index = 0; index < hpc_ptr->slot_count; index++) { 843 for (index = 0; index < hpc_ptr->slot_count; index++) {
848
849 hp_slot_ptr = kzalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
850 if (!hp_slot_ptr) {
851 rc = -ENOMEM;
852 goto error_no_hp_slot;
853 }
854
855 tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); 844 tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
856 if (!tmp_slot) { 845 if (!tmp_slot) {
857 rc = -ENOMEM; 846 rc = -ENOMEM;
@@ -878,7 +867,6 @@ static int __init ebda_rsrc_controller(void)
878 867
879 bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num); 868 bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num);
880 if (!bus_info_ptr1) { 869 if (!bus_info_ptr1) {
881 kfree(tmp_slot);
882 rc = -ENODEV; 870 rc = -ENODEV;
883 goto error; 871 goto error;
884 } 872 }
@@ -888,22 +876,19 @@ static int __init ebda_rsrc_controller(void)
888 876
889 tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index; 877 tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
890 tmp_slot->number = hpc_ptr->slots[index].slot_num; 878 tmp_slot->number = hpc_ptr->slots[index].slot_num;
891 tmp_slot->hotplug_slot = hp_slot_ptr;
892
893 hp_slot_ptr->private = tmp_slot;
894 879
895 rc = fillslotinfo(hp_slot_ptr); 880 rc = fillslotinfo(&tmp_slot->hotplug_slot);
896 if (rc) 881 if (rc)
897 goto error; 882 goto error;
898 883
899 rc = ibmphp_init_devno((struct slot **) &hp_slot_ptr->private); 884 rc = ibmphp_init_devno(&tmp_slot);
900 if (rc) 885 if (rc)
901 goto error; 886 goto error;
902 hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; 887 tmp_slot->hotplug_slot.ops = &ibmphp_hotplug_slot_ops;
903 888
904 // end of registering ibm slot with hotplug core 889 // end of registering ibm slot with hotplug core
905 890
906 list_add(&((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head); 891 list_add(&tmp_slot->ibm_slot_list, &ibmphp_slot_head);
907 } 892 }
908 893
909 print_bus_info(); 894 print_bus_info();
@@ -913,7 +898,7 @@ static int __init ebda_rsrc_controller(void)
913 898
914 list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) { 899 list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
915 snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot)); 900 snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
916 pci_hp_register(tmp_slot->hotplug_slot, 901 pci_hp_register(&tmp_slot->hotplug_slot,
917 pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name); 902 pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
918 } 903 }
919 904
@@ -922,10 +907,8 @@ static int __init ebda_rsrc_controller(void)
922 return 0; 907 return 0;
923 908
924error: 909error:
925 kfree(hp_slot_ptr->private); 910 kfree(tmp_slot);
926error_no_slot: 911error_no_slot:
927 kfree(hp_slot_ptr);
928error_no_hp_slot:
929 free_ebda_hpc(hpc_ptr); 912 free_ebda_hpc(hpc_ptr);
930error_no_hpc: 913error_no_hpc:
931 iounmap(io_mem); 914 iounmap(io_mem);
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 3cc88f3e4368..3740f1a759c5 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -88,7 +88,7 @@ do { \
88 * protects scheduling, execution and cancellation of @button_work 88 * protects scheduling, execution and cancellation of @button_work
89 * @button_work: work item to turn the slot on or off after 5 seconds 89 * @button_work: work item to turn the slot on or off after 5 seconds
90 * in response to an Attention Button press 90 * in response to an Attention Button press
91 * @hotplug_slot: pointer to the structure registered with the PCI hotplug core 91 * @hotplug_slot: structure registered with the PCI hotplug core
92 * @reset_lock: prevents access to the Data Link Layer Link Active bit in the 92 * @reset_lock: prevents access to the Data Link Layer Link Active bit in the
93 * Link Status register and to the Presence Detect State bit in the Slot 93 * Link Status register and to the Presence Detect State bit in the Slot
94 * Status register during a slot reset which may cause them to flap 94 * Status register during a slot reset which may cause them to flap
@@ -120,7 +120,7 @@ struct controller {
120 struct mutex state_lock; 120 struct mutex state_lock;
121 struct delayed_work button_work; 121 struct delayed_work button_work;
122 122
123 struct hotplug_slot *hotplug_slot; /* hotplug core interface */ 123 struct hotplug_slot hotplug_slot; /* hotplug core interface */
124 struct rw_semaphore reset_lock; 124 struct rw_semaphore reset_lock;
125 int request_result; 125 int request_result;
126 wait_queue_head_t requester; 126 wait_queue_head_t requester;
@@ -207,7 +207,12 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
207 207
208static inline const char *slot_name(struct controller *ctrl) 208static inline const char *slot_name(struct controller *ctrl)
209{ 209{
210 return hotplug_slot_name(ctrl->hotplug_slot); 210 return hotplug_slot_name(&ctrl->hotplug_slot);
211}
212
213static inline struct controller *to_ctrl(struct hotplug_slot *hotplug_slot)
214{
215 return container_of(hotplug_slot, struct controller, hotplug_slot);
211} 216}
212 217
213#endif /* _PCIEHP_H */ 218#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index ac5baf887c5d..68b20e667764 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -51,19 +51,14 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
51 51
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_ops *ops;
55 struct hotplug_slot_ops *ops = NULL;
56 char name[SLOT_NAME_SIZE]; 55 char name[SLOT_NAME_SIZE];
57 int retval = -ENOMEM; 56 int retval;
58
59 hotplug = kzalloc(sizeof(*hotplug), GFP_KERNEL);
60 if (!hotplug)
61 goto out;
62 57
63 /* Setup hotplug slot ops */ 58 /* Setup hotplug slot ops */
64 ops = kzalloc(sizeof(*ops), GFP_KERNEL); 59 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
65 if (!ops) 60 if (!ops)
66 goto out; 61 return -ENOMEM;
67 62
68 ops->enable_slot = pciehp_sysfs_enable_slot; 63 ops->enable_slot = pciehp_sysfs_enable_slot;
69 ops->disable_slot = pciehp_sysfs_disable_slot; 64 ops->disable_slot = pciehp_sysfs_disable_slot;
@@ -81,30 +76,24 @@ static int init_slot(struct controller *ctrl)
81 } 76 }
82 77
83 /* register this slot with the hotplug pci core */ 78 /* register this slot with the hotplug pci core */
84 hotplug->private = ctrl; 79 ctrl->hotplug_slot.ops = ops;
85 hotplug->ops = ops;
86 ctrl->hotplug_slot = hotplug;
87 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); 80 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl));
88 81
89 retval = pci_hp_initialize(hotplug, 82 retval = pci_hp_initialize(&ctrl->hotplug_slot,
90 ctrl->pcie->port->subordinate, 0, name); 83 ctrl->pcie->port->subordinate, 0, name);
91 if (retval)
92 ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval);
93out:
94 if (retval) { 84 if (retval) {
85 ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval);
95 kfree(ops); 86 kfree(ops);
96 kfree(hotplug);
97 } 87 }
98 return retval; 88 return retval;
99} 89}
100 90
101static void cleanup_slot(struct controller *ctrl) 91static void cleanup_slot(struct controller *ctrl)
102{ 92{
103 struct hotplug_slot *hotplug_slot = ctrl->hotplug_slot; 93 struct hotplug_slot *hotplug_slot = &ctrl->hotplug_slot;
104 94
105 pci_hp_destroy(hotplug_slot); 95 pci_hp_destroy(hotplug_slot);
106 kfree(hotplug_slot->ops); 96 kfree(hotplug_slot->ops);
107 kfree(hotplug_slot);
108} 97}
109 98
110/* 99/*
@@ -112,7 +101,7 @@ static void cleanup_slot(struct controller *ctrl)
112 */ 101 */
113static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 102static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
114{ 103{
115 struct controller *ctrl = hotplug_slot->private; 104 struct controller *ctrl = to_ctrl(hotplug_slot);
116 struct pci_dev *pdev = ctrl->pcie->port; 105 struct pci_dev *pdev = ctrl->pcie->port;
117 106
118 pci_config_pm_runtime_get(pdev); 107 pci_config_pm_runtime_get(pdev);
@@ -123,7 +112,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
123 112
124static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 113static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
125{ 114{
126 struct controller *ctrl = hotplug_slot->private; 115 struct controller *ctrl = to_ctrl(hotplug_slot);
127 struct pci_dev *pdev = ctrl->pcie->port; 116 struct pci_dev *pdev = ctrl->pcie->port;
128 117
129 pci_config_pm_runtime_get(pdev); 118 pci_config_pm_runtime_get(pdev);
@@ -134,7 +123,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
134 123
135static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 124static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
136{ 125{
137 struct controller *ctrl = hotplug_slot->private; 126 struct controller *ctrl = to_ctrl(hotplug_slot);
138 struct pci_dev *pdev = ctrl->pcie->port; 127 struct pci_dev *pdev = ctrl->pcie->port;
139 128
140 pci_config_pm_runtime_get(pdev); 129 pci_config_pm_runtime_get(pdev);
@@ -145,7 +134,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
145 134
146static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 135static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
147{ 136{
148 struct controller *ctrl = hotplug_slot->private; 137 struct controller *ctrl = to_ctrl(hotplug_slot);
149 struct pci_dev *pdev = ctrl->pcie->port; 138 struct pci_dev *pdev = ctrl->pcie->port;
150 139
151 pci_config_pm_runtime_get(pdev); 140 pci_config_pm_runtime_get(pdev);
@@ -223,7 +212,7 @@ static int pciehp_probe(struct pcie_device *dev)
223 } 212 }
224 213
225 /* Publish to user space */ 214 /* Publish to user space */
226 rc = pci_hp_add(ctrl->hotplug_slot); 215 rc = pci_hp_add(&ctrl->hotplug_slot);
227 if (rc) { 216 if (rc) {
228 ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc); 217 ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc);
229 goto err_out_shutdown_notification; 218 goto err_out_shutdown_notification;
@@ -246,7 +235,7 @@ static void pciehp_remove(struct pcie_device *dev)
246{ 235{
247 struct controller *ctrl = get_service_data(dev); 236 struct controller *ctrl = get_service_data(dev);
248 237
249 pci_hp_del(ctrl->hotplug_slot); 238 pci_hp_del(&ctrl->hotplug_slot);
250 pcie_shutdown_notification(ctrl); 239 pcie_shutdown_notification(ctrl);
251 cleanup_slot(ctrl); 240 cleanup_slot(ctrl);
252 pciehp_release_ctrl(ctrl); 241 pciehp_release_ctrl(ctrl);
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 04f7ad9fffe1..3f3df4c29f6e 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -348,7 +348,7 @@ static int pciehp_disable_slot(struct controller *ctrl, bool safe_removal)
348 348
349int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot) 349int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot)
350{ 350{
351 struct controller *ctrl = hotplug_slot->private; 351 struct controller *ctrl = to_ctrl(hotplug_slot);
352 352
353 mutex_lock(&ctrl->state_lock); 353 mutex_lock(&ctrl->state_lock);
354 switch (ctrl->state) { 354 switch (ctrl->state) {
@@ -386,7 +386,7 @@ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot)
386 386
387int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot) 387int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot)
388{ 388{
389 struct controller *ctrl = hotplug_slot->private; 389 struct controller *ctrl = to_ctrl(hotplug_slot);
390 390
391 mutex_lock(&ctrl->state_lock); 391 mutex_lock(&ctrl->state_lock);
392 switch (ctrl->state) { 392 switch (ctrl->state) {
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 0289a3ae4d90..7b5f9db60d9a 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -315,7 +315,7 @@ static int pciehp_link_enable(struct controller *ctrl)
315int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, 315int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot,
316 u8 *status) 316 u8 *status)
317{ 317{
318 struct controller *ctrl = hotplug_slot->private; 318 struct controller *ctrl = to_ctrl(hotplug_slot);
319 struct pci_dev *pdev = ctrl_dev(ctrl); 319 struct pci_dev *pdev = ctrl_dev(ctrl);
320 u16 slot_ctrl; 320 u16 slot_ctrl;
321 321
@@ -328,7 +328,7 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot,
328 328
329int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status) 329int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status)
330{ 330{
331 struct controller *ctrl = hotplug_slot->private; 331 struct controller *ctrl = to_ctrl(hotplug_slot);
332 struct pci_dev *pdev = ctrl_dev(ctrl); 332 struct pci_dev *pdev = ctrl_dev(ctrl);
333 u16 slot_ctrl; 333 u16 slot_ctrl;
334 334
@@ -422,7 +422,7 @@ int pciehp_query_power_fault(struct controller *ctrl)
422int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, 422int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
423 u8 status) 423 u8 status)
424{ 424{
425 struct controller *ctrl = hotplug_slot->private; 425 struct controller *ctrl = to_ctrl(hotplug_slot);
426 struct pci_dev *pdev = ctrl_dev(ctrl); 426 struct pci_dev *pdev = ctrl_dev(ctrl);
427 427
428 pci_config_pm_runtime_get(pdev); 428 pci_config_pm_runtime_get(pdev);
@@ -758,7 +758,7 @@ void pcie_clear_hotplug_events(struct controller *ctrl)
758 */ 758 */
759int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe) 759int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe)
760{ 760{
761 struct controller *ctrl = hotplug_slot->private; 761 struct controller *ctrl = to_ctrl(hotplug_slot);
762 struct pci_dev *pdev = ctrl_dev(ctrl); 762 struct pci_dev *pdev = ctrl_dev(ctrl);
763 u16 stat_mask = 0, ctrl_mask = 0; 763 u16 stat_mask = 0, ctrl_mask = 0;
764 int rc; 764 int rc;
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 5bb63430262e..5070620a4f9f 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -336,7 +336,7 @@ static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot)
336int pnv_php_set_slot_power_state(struct hotplug_slot *slot, 336int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
337 uint8_t state) 337 uint8_t state)
338{ 338{
339 struct pnv_php_slot *php_slot = slot->private; 339 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
340 struct opal_msg msg; 340 struct opal_msg msg;
341 int ret; 341 int ret;
342 342
@@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state);
368 368
369static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) 369static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
370{ 370{
371 struct pnv_php_slot *php_slot = slot->private; 371 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
372 uint8_t power_state = OPAL_PCI_SLOT_POWER_ON; 372 uint8_t power_state = OPAL_PCI_SLOT_POWER_ON;
373 int ret; 373 int ret;
374 374
@@ -390,7 +390,7 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
390 390
391static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) 391static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
392{ 392{
393 struct pnv_php_slot *php_slot = slot->private; 393 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
394 uint8_t presence = OPAL_PCI_SLOT_EMPTY; 394 uint8_t presence = OPAL_PCI_SLOT_EMPTY;
395 int ret; 395 int ret;
396 396
@@ -521,7 +521,7 @@ static int pnv_php_enable_slot(struct hotplug_slot *slot)
521 521
522static int pnv_php_disable_slot(struct hotplug_slot *slot) 522static int pnv_php_disable_slot(struct hotplug_slot *slot)
523{ 523{
524 struct pnv_php_slot *php_slot = slot->private; 524 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
525 int ret; 525 int ret;
526 526
527 if (php_slot->state != PNV_PHP_STATE_POPULATED) 527 if (php_slot->state != PNV_PHP_STATE_POPULATED)
@@ -607,7 +607,6 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
607 php_slot->id = id; 607 php_slot->id = id;
608 php_slot->power_state_check = false; 608 php_slot->power_state_check = false;
609 php_slot->slot.ops = &php_slot_ops; 609 php_slot->slot.ops = &php_slot_ops;
610 php_slot->slot.private = php_slot;
611 610
612 INIT_LIST_HEAD(&php_slot->children); 611 INIT_LIST_HEAD(&php_slot->children);
613 INIT_LIST_HEAD(&php_slot->link); 612 INIT_LIST_HEAD(&php_slot->link);
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 26a3dd731b5e..bdc954d70869 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -68,12 +68,17 @@ struct slot {
68 struct device_node *dn; 68 struct device_node *dn;
69 struct pci_bus *bus; 69 struct pci_bus *bus;
70 struct list_head *pci_devs; 70 struct list_head *pci_devs;
71 struct hotplug_slot *hotplug_slot; 71 struct hotplug_slot hotplug_slot;
72}; 72};
73 73
74extern const struct hotplug_slot_ops rpaphp_hotplug_slot_ops; 74extern const struct hotplug_slot_ops rpaphp_hotplug_slot_ops;
75extern struct list_head rpaphp_slot_head; 75extern struct list_head rpaphp_slot_head;
76 76
77static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
78{
79 return container_of(hotplug_slot, struct slot, hotplug_slot);
80}
81
77/* function prototypes */ 82/* function prototypes */
78 83
79/* rpaphp_pci.c */ 84/* rpaphp_pci.c */
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 898e78dcd311..bcd5d357ca23 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -52,7 +52,7 @@ module_param_named(debug, rpaphp_debug, bool, 0644);
52static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) 52static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
53{ 53{
54 int rc; 54 int rc;
55 struct slot *slot = (struct slot *)hotplug_slot->private; 55 struct slot *slot = to_slot(hotplug_slot);
56 56
57 switch (value) { 57 switch (value) {
58 case 0: 58 case 0:
@@ -79,7 +79,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
79static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 79static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
80{ 80{
81 int retval, level; 81 int retval, level;
82 struct slot *slot = (struct slot *)hotplug_slot->private; 82 struct slot *slot = to_slot(hotplug_slot);
83 83
84 retval = rtas_get_power_level(slot->power_domain, &level); 84 retval = rtas_get_power_level(slot->power_domain, &level);
85 if (!retval) 85 if (!retval)
@@ -94,14 +94,14 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
94 */ 94 */
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 = to_slot(hotplug_slot);
98 *value = slot->attention_status; 98 *value = slot->attention_status;
99 return 0; 99 return 0;
100} 100}
101 101
102static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 102static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
103{ 103{
104 struct slot *slot = (struct slot *)hotplug_slot->private; 104 struct slot *slot = to_slot(hotplug_slot);
105 int rc, state; 105 int rc, state;
106 106
107 rc = rpaphp_get_sensor_state(slot, &state); 107 rc = rpaphp_get_sensor_state(slot, &state);
@@ -409,7 +409,7 @@ static void __exit cleanup_slots(void)
409 list_for_each_entry_safe(slot, next, &rpaphp_slot_head, 409 list_for_each_entry_safe(slot, next, &rpaphp_slot_head,
410 rpaphp_slot_list) { 410 rpaphp_slot_list) {
411 list_del(&slot->rpaphp_slot_list); 411 list_del(&slot->rpaphp_slot_list);
412 pci_hp_deregister(slot->hotplug_slot); 412 pci_hp_deregister(&slot->hotplug_slot);
413 dealloc_slot_struct(slot); 413 dealloc_slot_struct(slot);
414 } 414 }
415 return; 415 return;
@@ -434,7 +434,7 @@ static void __exit rpaphp_exit(void)
434 434
435static int enable_slot(struct hotplug_slot *hotplug_slot) 435static int enable_slot(struct hotplug_slot *hotplug_slot)
436{ 436{
437 struct slot *slot = (struct slot *)hotplug_slot->private; 437 struct slot *slot = to_slot(hotplug_slot);
438 int state; 438 int state;
439 int retval; 439 int retval;
440 440
@@ -464,7 +464,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
464 464
465static int disable_slot(struct hotplug_slot *hotplug_slot) 465static int disable_slot(struct hotplug_slot *hotplug_slot)
466{ 466{
467 struct slot *slot = (struct slot *)hotplug_slot->private; 467 struct slot *slot = to_slot(hotplug_slot);
468 if (slot->state == NOT_CONFIGURED) 468 if (slot->state == NOT_CONFIGURED)
469 return -EINVAL; 469 return -EINVAL;
470 470
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 6e2658ce300b..5282aa3e33c5 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -22,7 +22,6 @@
22void dealloc_slot_struct(struct slot *slot) 22void dealloc_slot_struct(struct slot *slot)
23{ 23{
24 kfree(slot->name); 24 kfree(slot->name);
25 kfree(slot->hotplug_slot);
26 kfree(slot); 25 kfree(slot);
27} 26}
28 27
@@ -34,22 +33,16 @@ struct slot *alloc_slot_struct(struct device_node *dn,
34 slot = kzalloc(sizeof(struct slot), GFP_KERNEL); 33 slot = kzalloc(sizeof(struct slot), GFP_KERNEL);
35 if (!slot) 34 if (!slot)
36 goto error_nomem; 35 goto error_nomem;
37 slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
38 if (!slot->hotplug_slot)
39 goto error_slot;
40 slot->name = kstrdup(drc_name, GFP_KERNEL); 36 slot->name = kstrdup(drc_name, GFP_KERNEL);
41 if (!slot->name) 37 if (!slot->name)
42 goto error_hpslot; 38 goto error_slot;
43 slot->dn = dn; 39 slot->dn = dn;
44 slot->index = drc_index; 40 slot->index = drc_index;
45 slot->power_domain = power_domain; 41 slot->power_domain = power_domain;
46 slot->hotplug_slot->private = slot; 42 slot->hotplug_slot.ops = &rpaphp_hotplug_slot_ops;
47 slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
48 43
49 return (slot); 44 return (slot);
50 45
51error_hpslot:
52 kfree(slot->hotplug_slot);
53error_slot: 46error_slot:
54 kfree(slot); 47 kfree(slot);
55error_nomem: 48error_nomem:
@@ -70,7 +63,7 @@ static int is_registered(struct slot *slot)
70int rpaphp_deregister_slot(struct slot *slot) 63int rpaphp_deregister_slot(struct slot *slot)
71{ 64{
72 int retval = 0; 65 int retval = 0;
73 struct hotplug_slot *php_slot = slot->hotplug_slot; 66 struct hotplug_slot *php_slot = &slot->hotplug_slot;
74 67
75 dbg("%s - Entry: deregistering slot=%s\n", 68 dbg("%s - Entry: deregistering slot=%s\n",
76 __func__, slot->name); 69 __func__, slot->name);
@@ -86,7 +79,7 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
86 79
87int rpaphp_register_slot(struct slot *slot) 80int rpaphp_register_slot(struct slot *slot)
88{ 81{
89 struct hotplug_slot *php_slot = slot->hotplug_slot; 82 struct hotplug_slot *php_slot = &slot->hotplug_slot;
90 struct device_node *child; 83 struct device_node *child;
91 u32 my_index; 84 u32 my_index;
92 int retval; 85 int retval;
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index d04634b0defe..30ee72268790 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -32,10 +32,15 @@ static int zpci_fn_configured(enum zpci_state state)
32 */ 32 */
33struct slot { 33struct slot {
34 struct list_head slot_list; 34 struct list_head slot_list;
35 struct hotplug_slot *hotplug_slot; 35 struct hotplug_slot hotplug_slot;
36 struct zpci_dev *zdev; 36 struct zpci_dev *zdev;
37}; 37};
38 38
39static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
40{
41 return container_of(hotplug_slot, struct slot, hotplug_slot);
42}
43
39static inline int slot_configure(struct slot *slot) 44static inline int slot_configure(struct slot *slot)
40{ 45{
41 int ret = sclp_pci_configure(slot->zdev->fid); 46 int ret = sclp_pci_configure(slot->zdev->fid);
@@ -60,7 +65,7 @@ static inline int slot_deconfigure(struct slot *slot)
60 65
61static int enable_slot(struct hotplug_slot *hotplug_slot) 66static int enable_slot(struct hotplug_slot *hotplug_slot)
62{ 67{
63 struct slot *slot = hotplug_slot->private; 68 struct slot *slot = to_slot(hotplug_slot);
64 int rc; 69 int rc;
65 70
66 if (slot->zdev->state != ZPCI_FN_STATE_STANDBY) 71 if (slot->zdev->state != ZPCI_FN_STATE_STANDBY)
@@ -88,7 +93,7 @@ out_deconfigure:
88 93
89static int disable_slot(struct hotplug_slot *hotplug_slot) 94static int disable_slot(struct hotplug_slot *hotplug_slot)
90{ 95{
91 struct slot *slot = hotplug_slot->private; 96 struct slot *slot = to_slot(hotplug_slot);
92 struct pci_dev *pdev; 97 struct pci_dev *pdev;
93 int rc; 98 int rc;
94 99
@@ -110,7 +115,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
110 115
111static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 116static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
112{ 117{
113 struct slot *slot = hotplug_slot->private; 118 struct slot *slot = to_slot(hotplug_slot);
114 119
115 switch (slot->zdev->state) { 120 switch (slot->zdev->state) {
116 case ZPCI_FN_STATE_STANDBY: 121 case ZPCI_FN_STATE_STANDBY:
@@ -139,7 +144,6 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = {
139 144
140int zpci_init_slot(struct zpci_dev *zdev) 145int zpci_init_slot(struct zpci_dev *zdev)
141{ 146{
142 struct hotplug_slot *hotplug_slot;
143 char name[SLOT_NAME_SIZE]; 147 char name[SLOT_NAME_SIZE];
144 struct slot *slot; 148 struct slot *slot;
145 int rc; 149 int rc;
@@ -151,18 +155,11 @@ int zpci_init_slot(struct zpci_dev *zdev)
151 if (!slot) 155 if (!slot)
152 goto error; 156 goto error;
153 157
154 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
155 if (!hotplug_slot)
156 goto error_hp;
157 hotplug_slot->private = slot;
158
159 slot->hotplug_slot = hotplug_slot;
160 slot->zdev = zdev; 158 slot->zdev = zdev;
161 159 slot->hotplug_slot.ops = &s390_hotplug_slot_ops;
162 hotplug_slot->ops = &s390_hotplug_slot_ops;
163 160
164 snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); 161 snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
165 rc = pci_hp_register(slot->hotplug_slot, zdev->bus, 162 rc = pci_hp_register(&slot->hotplug_slot, zdev->bus,
166 ZPCI_DEVFN, name); 163 ZPCI_DEVFN, name);
167 if (rc) 164 if (rc)
168 goto error_reg; 165 goto error_reg;
@@ -171,8 +168,6 @@ int zpci_init_slot(struct zpci_dev *zdev)
171 return 0; 168 return 0;
172 169
173error_reg: 170error_reg:
174 kfree(hotplug_slot);
175error_hp:
176 kfree(slot); 171 kfree(slot);
177error: 172error:
178 return -ENOMEM; 173 return -ENOMEM;
@@ -187,8 +182,7 @@ void zpci_exit_slot(struct zpci_dev *zdev)
187 if (slot->zdev != zdev) 182 if (slot->zdev != zdev)
188 continue; 183 continue;
189 list_del(&slot->slot_list); 184 list_del(&slot->slot_list);
190 pci_hp_deregister(slot->hotplug_slot); 185 pci_hp_deregister(&slot->hotplug_slot);
191 kfree(slot->hotplug_slot);
192 kfree(slot); 186 kfree(slot);
193 } 187 }
194} 188}
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index e103826c83e3..231f5bdd3d2d 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -56,7 +56,7 @@ struct slot {
56 int device_num; 56 int device_num;
57 struct pci_bus *pci_bus; 57 struct pci_bus *pci_bus;
58 /* this struct for glue internal only */ 58 /* this struct for glue internal only */
59 struct hotplug_slot *hotplug_slot; 59 struct hotplug_slot hotplug_slot;
60 struct list_head hp_list; 60 struct list_head hp_list;
61 char physical_path[SN_SLOT_NAME_SIZE]; 61 char physical_path[SN_SLOT_NAME_SIZE];
62}; 62};
@@ -88,10 +88,15 @@ static const struct hotplug_slot_ops sn_hotplug_slot_ops = {
88 88
89static DEFINE_MUTEX(sn_hotplug_mutex); 89static DEFINE_MUTEX(sn_hotplug_mutex);
90 90
91static struct slot *to_slot(struct hotplug_slot *bss_hotplug_slot)
92{
93 return container_of(bss_hotplug_slot, struct slot, hotplug_slot);
94}
95
91static ssize_t path_show(struct pci_slot *pci_slot, char *buf) 96static ssize_t path_show(struct pci_slot *pci_slot, char *buf)
92{ 97{
93 int retval = -ENOENT; 98 int retval = -ENOENT;
94 struct slot *slot = pci_slot->hotplug->private; 99 struct slot *slot = to_slot(pci_slot->hotplug);
95 100
96 if (!slot) 101 if (!slot)
97 return retval; 102 return retval;
@@ -156,7 +161,7 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
156 return -EIO; 161 return -EIO;
157} 162}
158 163
159static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, 164static int sn_hp_slot_private_alloc(struct hotplug_slot **bss_hotplug_slot,
160 struct pci_bus *pci_bus, int device, 165 struct pci_bus *pci_bus, int device,
161 char *name) 166 char *name)
162{ 167{
@@ -168,7 +173,6 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
168 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 173 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
169 if (!slot) 174 if (!slot)
170 return -ENOMEM; 175 return -ENOMEM;
171 bss_hotplug_slot->private = slot;
172 176
173 slot->device_num = device; 177 slot->device_num = device;
174 slot->pci_bus = pci_bus; 178 slot->pci_bus = pci_bus;
@@ -179,8 +183,8 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
179 183
180 sn_generate_path(pci_bus, slot->physical_path); 184 sn_generate_path(pci_bus, slot->physical_path);
181 185
182 slot->hotplug_slot = bss_hotplug_slot;
183 list_add(&slot->hp_list, &sn_hp_list); 186 list_add(&slot->hp_list, &sn_hp_list);
187 *bss_hotplug_slot = &slot->hotplug_slot;
184 188
185 return 0; 189 return 0;
186} 190}
@@ -192,10 +196,9 @@ static struct hotplug_slot *sn_hp_destroy(void)
192 struct hotplug_slot *bss_hotplug_slot = NULL; 196 struct hotplug_slot *bss_hotplug_slot = NULL;
193 197
194 list_for_each_entry(slot, &sn_hp_list, hp_list) { 198 list_for_each_entry(slot, &sn_hp_list, hp_list) {
195 bss_hotplug_slot = slot->hotplug_slot; 199 bss_hotplug_slot = &slot->hotplug_slot;
196 pci_slot = bss_hotplug_slot->pci_slot; 200 pci_slot = bss_hotplug_slot->pci_slot;
197 list_del(&((struct slot *)bss_hotplug_slot->private)-> 201 list_del(&slot->hp_list);
198 hp_list);
199 sysfs_remove_file(&pci_slot->kobj, 202 sysfs_remove_file(&pci_slot->kobj,
200 &sn_slot_path_attr.attr); 203 &sn_slot_path_attr.attr);
201 break; 204 break;
@@ -227,7 +230,7 @@ static void sn_bus_free_data(struct pci_dev *dev)
227static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, 230static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
228 int device_num, char **ssdt) 231 int device_num, char **ssdt)
229{ 232{
230 struct slot *slot = bss_hotplug_slot->private; 233 struct slot *slot = to_slot(bss_hotplug_slot);
231 struct pcibus_info *pcibus_info; 234 struct pcibus_info *pcibus_info;
232 struct pcibr_slot_enable_resp resp; 235 struct pcibr_slot_enable_resp resp;
233 int rc; 236 int rc;
@@ -267,7 +270,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
267static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, 270static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
268 int device_num, int action) 271 int device_num, int action)
269{ 272{
270 struct slot *slot = bss_hotplug_slot->private; 273 struct slot *slot = to_slot(bss_hotplug_slot);
271 struct pcibus_info *pcibus_info; 274 struct pcibus_info *pcibus_info;
272 struct pcibr_slot_disable_resp resp; 275 struct pcibr_slot_disable_resp resp;
273 int rc; 276 int rc;
@@ -323,7 +326,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
323 */ 326 */
324static int enable_slot(struct hotplug_slot *bss_hotplug_slot) 327static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
325{ 328{
326 struct slot *slot = bss_hotplug_slot->private; 329 struct slot *slot = to_slot(bss_hotplug_slot);
327 struct pci_bus *new_bus = NULL; 330 struct pci_bus *new_bus = NULL;
328 struct pci_dev *dev; 331 struct pci_dev *dev;
329 int num_funcs; 332 int num_funcs;
@@ -469,7 +472,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
469 472
470static int disable_slot(struct hotplug_slot *bss_hotplug_slot) 473static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
471{ 474{
472 struct slot *slot = bss_hotplug_slot->private; 475 struct slot *slot = to_slot(bss_hotplug_slot);
473 struct pci_dev *dev, *temp; 476 struct pci_dev *dev, *temp;
474 int rc; 477 int rc;
475 acpi_handle ssdt_hdl = NULL; 478 acpi_handle ssdt_hdl = NULL;
@@ -571,7 +574,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
571static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, 574static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
572 u8 *value) 575 u8 *value)
573{ 576{
574 struct slot *slot = bss_hotplug_slot->private; 577 struct slot *slot = to_slot(bss_hotplug_slot);
575 struct pcibus_info *pcibus_info; 578 struct pcibus_info *pcibus_info;
576 u32 power; 579 u32 power;
577 580
@@ -585,8 +588,7 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
585 588
586static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot) 589static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
587{ 590{
588 kfree(bss_hotplug_slot->private); 591 kfree(to_slot(bss_hotplug_slot));
589 kfree(bss_hotplug_slot);
590} 592}
591 593
592static int sn_hotplug_slot_register(struct pci_bus *pci_bus) 594static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
@@ -606,14 +608,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
606 if (sn_pci_slot_valid(pci_bus, device) != 1) 608 if (sn_pci_slot_valid(pci_bus, device) != 1)
607 continue; 609 continue;
608 610
609 bss_hotplug_slot = kzalloc(sizeof(*bss_hotplug_slot), 611 if (sn_hp_slot_private_alloc(&bss_hotplug_slot,
610 GFP_KERNEL);
611 if (!bss_hotplug_slot) {
612 rc = -ENOMEM;
613 goto alloc_err;
614 }
615
616 if (sn_hp_slot_private_alloc(bss_hotplug_slot,
617 pci_bus, device, name)) { 612 pci_bus, device, name)) {
618 rc = -ENOMEM; 613 rc = -ENOMEM;
619 goto alloc_err; 614 goto alloc_err;
@@ -628,7 +623,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
628 rc = sysfs_create_file(&pci_slot->kobj, 623 rc = sysfs_create_file(&pci_slot->kobj,
629 &sn_slot_path_attr.attr); 624 &sn_slot_path_attr.attr);
630 if (rc) 625 if (rc)
631 goto register_err; 626 goto alloc_err;
632 } 627 }
633 pci_dbg(pci_bus->self, "Registered bus with hotplug\n"); 628 pci_dbg(pci_bus->self, "Registered bus with hotplug\n");
634 return rc; 629 return rc;
@@ -637,14 +632,11 @@ register_err:
637 pci_dbg(pci_bus->self, "bus failed to register with err = %d\n", 632 pci_dbg(pci_bus->self, "bus failed to register with err = %d\n",
638 rc); 633 rc);
639 634
640alloc_err:
641 if (rc == -ENOMEM)
642 pci_dbg(pci_bus->self, "Memory allocation error\n");
643
644 /* destroy THIS element */ 635 /* destroy THIS element */
645 if (bss_hotplug_slot) 636 sn_hp_destroy();
646 sn_release_slot(bss_hotplug_slot); 637 sn_release_slot(bss_hotplug_slot);
647 638
639alloc_err:
648 /* destroy anything else on the list */ 640 /* destroy anything else on the list */
649 while ((bss_hotplug_slot = sn_hp_destroy())) { 641 while ((bss_hotplug_slot = sn_hp_destroy())) {
650 pci_hp_deregister(bss_hotplug_slot); 642 pci_hp_deregister(bss_hotplug_slot);
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index a7bb816e6f25..f7f13ee5d06e 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -73,7 +73,7 @@ struct slot {
73 u8 pwr_save; 73 u8 pwr_save;
74 struct controller *ctrl; 74 struct controller *ctrl;
75 const struct hpc_ops *hpc_ops; 75 const struct hpc_ops *hpc_ops;
76 struct hotplug_slot *hotplug_slot; 76 struct hotplug_slot hotplug_slot;
77 struct list_head slot_list; 77 struct list_head slot_list;
78 struct delayed_work work; /* work for button event */ 78 struct delayed_work work; /* work for button event */
79 struct mutex lock; 79 struct mutex lock;
@@ -171,7 +171,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev);
171 171
172static inline const char *slot_name(struct slot *slot) 172static inline const char *slot_name(struct slot *slot)
173{ 173{
174 return hotplug_slot_name(slot->hotplug_slot); 174 return hotplug_slot_name(&slot->hotplug_slot);
175} 175}
176 176
177struct ctrl_reg { 177struct ctrl_reg {
@@ -209,7 +209,7 @@ enum ctrl_offsets {
209 209
210static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) 210static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
211{ 211{
212 return hotplug_slot->private; 212 return container_of(hotplug_slot, struct slot, hotplug_slot);
213} 213}
214 214
215static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device) 215static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device)
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index b7181b7e7b98..81a918d47895 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -76,12 +76,7 @@ static int init_slots(struct controller *ctrl)
76 goto error; 76 goto error;
77 } 77 }
78 78
79 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); 79 hotplug_slot = &slot->hotplug_slot;
80 if (!hotplug_slot) {
81 retval = -ENOMEM;
82 goto error_slot;
83 }
84 slot->hotplug_slot = hotplug_slot;
85 80
86 slot->hp_slot = i; 81 slot->hp_slot = i;
87 slot->ctrl = ctrl; 82 slot->ctrl = ctrl;
@@ -93,14 +88,13 @@ static int init_slots(struct controller *ctrl)
93 slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number); 88 slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number);
94 if (!slot->wq) { 89 if (!slot->wq) {
95 retval = -ENOMEM; 90 retval = -ENOMEM;
96 goto error_hpslot; 91 goto error_slot;
97 } 92 }
98 93
99 mutex_init(&slot->lock); 94 mutex_init(&slot->lock);
100 INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); 95 INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work);
101 96
102 /* register this slot with the hotplug pci core */ 97 /* register this slot with the hotplug pci core */
103 hotplug_slot->private = slot;
104 snprintf(name, SLOT_NAME_SIZE, "%d", slot->number); 98 snprintf(name, SLOT_NAME_SIZE, "%d", slot->number);
105 hotplug_slot->ops = &shpchp_hotplug_slot_ops; 99 hotplug_slot->ops = &shpchp_hotplug_slot_ops;
106 100
@@ -108,7 +102,7 @@ static int init_slots(struct controller *ctrl)
108 pci_domain_nr(ctrl->pci_dev->subordinate), 102 pci_domain_nr(ctrl->pci_dev->subordinate),
109 slot->bus, slot->device, slot->hp_slot, slot->number, 103 slot->bus, slot->device, slot->hp_slot, slot->number,
110 ctrl->slot_device_offset); 104 ctrl->slot_device_offset);
111 retval = pci_hp_register(slot->hotplug_slot, 105 retval = pci_hp_register(hotplug_slot,
112 ctrl->pci_dev->subordinate, slot->device, name); 106 ctrl->pci_dev->subordinate, slot->device, name);
113 if (retval) { 107 if (retval) {
114 ctrl_err(ctrl, "pci_hp_register failed with error %d\n", 108 ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
@@ -127,8 +121,6 @@ static int init_slots(struct controller *ctrl)
127 return 0; 121 return 0;
128error_slotwq: 122error_slotwq:
129 destroy_workqueue(slot->wq); 123 destroy_workqueue(slot->wq);
130error_hpslot:
131 kfree(hotplug_slot);
132error_slot: 124error_slot:
133 kfree(slot); 125 kfree(slot);
134error: 126error:
@@ -143,8 +135,7 @@ void cleanup_slots(struct controller *ctrl)
143 list_del(&slot->slot_list); 135 list_del(&slot->slot_list);
144 cancel_delayed_work(&slot->work); 136 cancel_delayed_work(&slot->work);
145 destroy_workqueue(slot->wq); 137 destroy_workqueue(slot->wq);
146 pci_hp_deregister(slot->hotplug_slot); 138 pci_hp_deregister(&slot->hotplug_slot);
147 kfree(slot->hotplug_slot);
148 kfree(slot); 139 kfree(slot);
149 } 140 }
150} 141}
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 019b037319e3..93ee2d5466f8 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -254,7 +254,7 @@ struct asus_wmi {
254 int asus_hwmon_num_fans; 254 int asus_hwmon_num_fans;
255 int asus_hwmon_pwm; 255 int asus_hwmon_pwm;
256 256
257 struct hotplug_slot *hotplug_slot; 257 struct hotplug_slot hotplug_slot;
258 struct mutex hotplug_lock; 258 struct mutex hotplug_lock;
259 struct mutex wmi_lock; 259 struct mutex wmi_lock;
260 struct workqueue_struct *hotplug_workqueue; 260 struct workqueue_struct *hotplug_workqueue;
@@ -753,7 +753,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus)
753 if (asus->wlan.rfkill) 753 if (asus->wlan.rfkill)
754 rfkill_set_sw_state(asus->wlan.rfkill, blocked); 754 rfkill_set_sw_state(asus->wlan.rfkill, blocked);
755 755
756 if (asus->hotplug_slot) { 756 if (asus->hotplug_slot.ops) {
757 bus = pci_find_bus(0, 1); 757 bus = pci_find_bus(0, 1);
758 if (!bus) { 758 if (!bus) {
759 pr_warn("Unable to find PCI bus 1?\n"); 759 pr_warn("Unable to find PCI bus 1?\n");
@@ -858,7 +858,8 @@ static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
858static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, 858static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
859 u8 *value) 859 u8 *value)
860{ 860{
861 struct asus_wmi *asus = hotplug_slot->private; 861 struct asus_wmi *asus = container_of(hotplug_slot,
862 struct asus_wmi, hotplug_slot);
862 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); 863 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
863 864
864 if (result < 0) 865 if (result < 0)
@@ -898,14 +899,9 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus)
898 899
899 INIT_WORK(&asus->hotplug_work, asus_hotplug_work); 900 INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
900 901
901 asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); 902 asus->hotplug_slot.ops = &asus_hotplug_slot_ops;
902 if (!asus->hotplug_slot)
903 goto error_slot;
904 903
905 asus->hotplug_slot->private = asus; 904 ret = pci_hp_register(&asus->hotplug_slot, bus, 0, "asus-wifi");
906 asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
907
908 ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
909 if (ret) { 905 if (ret) {
910 pr_err("Unable to register hotplug slot - %d\n", ret); 906 pr_err("Unable to register hotplug slot - %d\n", ret);
911 goto error_register; 907 goto error_register;
@@ -914,9 +910,7 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus)
914 return 0; 910 return 0;
915 911
916error_register: 912error_register:
917 kfree(asus->hotplug_slot); 913 asus->hotplug_slot.ops = NULL;
918 asus->hotplug_slot = NULL;
919error_slot:
920 destroy_workqueue(asus->hotplug_workqueue); 914 destroy_workqueue(asus->hotplug_workqueue);
921error_workqueue: 915error_workqueue:
922 return ret; 916 return ret;
@@ -1044,10 +1038,8 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
1044 * asus_unregister_rfkill_notifier() 1038 * asus_unregister_rfkill_notifier()
1045 */ 1039 */
1046 asus_rfkill_hotplug(asus); 1040 asus_rfkill_hotplug(asus);
1047 if (asus->hotplug_slot) { 1041 if (asus->hotplug_slot.ops)
1048 pci_hp_deregister(asus->hotplug_slot); 1042 pci_hp_deregister(&asus->hotplug_slot);
1049 kfree(asus->hotplug_slot);
1050 }
1051 if (asus->hotplug_workqueue) 1043 if (asus->hotplug_workqueue)
1052 destroy_workqueue(asus->hotplug_workqueue); 1044 destroy_workqueue(asus->hotplug_workqueue);
1053 1045
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 028b20f82962..e6946a9beb5a 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -177,7 +177,7 @@ struct eeepc_laptop {
177 struct rfkill *wwan3g_rfkill; 177 struct rfkill *wwan3g_rfkill;
178 struct rfkill *wimax_rfkill; 178 struct rfkill *wimax_rfkill;
179 179
180 struct hotplug_slot *hotplug_slot; 180 struct hotplug_slot hotplug_slot;
181 struct mutex hotplug_lock; 181 struct mutex hotplug_lock;
182 182
183 struct led_classdev tpd_led; 183 struct led_classdev tpd_led;
@@ -582,7 +582,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
582 mutex_lock(&eeepc->hotplug_lock); 582 mutex_lock(&eeepc->hotplug_lock);
583 pci_lock_rescan_remove(); 583 pci_lock_rescan_remove();
584 584
585 if (!eeepc->hotplug_slot) 585 if (!eeepc->hotplug_slot.ops)
586 goto out_unlock; 586 goto out_unlock;
587 587
588 port = acpi_get_pci_dev(handle); 588 port = acpi_get_pci_dev(handle);
@@ -715,8 +715,11 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
715static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, 715static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
716 u8 *value) 716 u8 *value)
717{ 717{
718 struct eeepc_laptop *eeepc = hotplug_slot->private; 718 struct eeepc_laptop *eeepc;
719 int val = get_acpi(eeepc, CM_ASL_WLAN); 719 int val;
720
721 eeepc = container_of(hotplug_slot, struct eeepc_laptop, hotplug_slot);
722 val = get_acpi(eeepc, CM_ASL_WLAN);
720 723
721 if (val == 1 || val == 0) 724 if (val == 1 || val == 0)
722 *value = val; 725 *value = val;
@@ -741,14 +744,9 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
741 return -ENODEV; 744 return -ENODEV;
742 } 745 }
743 746
744 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); 747 eeepc->hotplug_slot.ops = &eeepc_hotplug_slot_ops;
745 if (!eeepc->hotplug_slot)
746 goto error_slot;
747 748
748 eeepc->hotplug_slot->private = eeepc; 749 ret = pci_hp_register(&eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
749 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
750
751 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
752 if (ret) { 750 if (ret) {
753 pr_err("Unable to register hotplug slot - %d\n", ret); 751 pr_err("Unable to register hotplug slot - %d\n", ret);
754 goto error_register; 752 goto error_register;
@@ -757,9 +755,7 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
757 return 0; 755 return 0;
758 756
759error_register: 757error_register:
760 kfree(eeepc->hotplug_slot); 758 eeepc->hotplug_slot.ops = NULL;
761 eeepc->hotplug_slot = NULL;
762error_slot:
763 return ret; 759 return ret;
764} 760}
765 761
@@ -820,10 +816,8 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
820 eeepc->wlan_rfkill = NULL; 816 eeepc->wlan_rfkill = NULL;
821 } 817 }
822 818
823 if (eeepc->hotplug_slot) { 819 if (eeepc->hotplug_slot.ops)
824 pci_hp_deregister(eeepc->hotplug_slot); 820 pci_hp_deregister(&eeepc->hotplug_slot);
825 kfree(eeepc->hotplug_slot);
826 }
827 821
828 if (eeepc->bluetooth_rfkill) { 822 if (eeepc->bluetooth_rfkill) {
829 rfkill_unregister(eeepc->bluetooth_rfkill); 823 rfkill_unregister(eeepc->bluetooth_rfkill);
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 6f07a4e1de8d..7acc9f91e72b 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -50,14 +50,11 @@ struct hotplug_slot_ops {
50/** 50/**
51 * 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
52 * @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
53 * @private: used by the hotplug pci controller driver to store whatever it
54 * needs.
55 * @owner: The module owner of this structure 53 * @owner: The module owner of this structure
56 * @mod_name: The module name (KBUILD_MODNAME) of this structure 54 * @mod_name: The module name (KBUILD_MODNAME) of this structure
57 */ 55 */
58struct hotplug_slot { 56struct hotplug_slot {
59 const struct hotplug_slot_ops *ops; 57 const struct hotplug_slot_ops *ops;
60 void *private;
61 58
62 /* Variables below this are for use only by the hotplug pci core. */ 59 /* Variables below this are for use only by the hotplug pci core. */
63 struct list_head slot_list; 60 struct list_head slot_list;