aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/s390_pci_hpc.c
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-01-31 13:55:17 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-02-14 09:55:17 -0500
commit53923354d69e4748506bfee932b7c6b309a15c21 (patch)
tree3d6e2d0fac4f26f53cbff549ad31b0032006c99d /drivers/pci/hotplug/s390_pci_hpc.c
parentadd09d61fee72d7a346051332b6d99f18989504c (diff)
s390/pci: fix hotplug module init
Loading the pci hotplug module when no devices are present will fail but unfortunately some hotplug callbacks stay registered to the pci bus level. Fix this by not letting module loading fail when no pci devices are present and provide proper {de}registration functions for these callbacks. Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/pci/hotplug/s390_pci_hpc.c')
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 8fe2a8aa89a1..7db249a25016 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -172,25 +172,6 @@ error:
172 return -ENOMEM; 172 return -ENOMEM;
173} 173}
174 174
175static int __init init_pci_slots(void)
176{
177 struct zpci_dev *zdev;
178 int device = 0;
179
180 /*
181 * Create a structure for each slot, and register that slot
182 * with the pci_hotplug subsystem.
183 */
184 mutex_lock(&zpci_list_lock);
185 list_for_each_entry(zdev, &zpci_list, entry) {
186 init_pci_slot(zdev);
187 device++;
188 }
189
190 mutex_unlock(&zpci_list_lock);
191 return (device) ? 0 : -ENODEV;
192}
193
194static void exit_pci_slot(struct zpci_dev *zdev) 175static void exit_pci_slot(struct zpci_dev *zdev)
195{ 176{
196 struct list_head *tmp, *n; 177 struct list_head *tmp, *n;
@@ -205,6 +186,26 @@ static void exit_pci_slot(struct zpci_dev *zdev)
205 } 186 }
206} 187}
207 188
189static struct pci_hp_callback_ops hp_ops = {
190 .create_slot = init_pci_slot,
191 .remove_slot = exit_pci_slot,
192};
193
194static void __init init_pci_slots(void)
195{
196 struct zpci_dev *zdev;
197
198 /*
199 * Create a structure for each slot, and register that slot
200 * with the pci_hotplug subsystem.
201 */
202 mutex_lock(&zpci_list_lock);
203 list_for_each_entry(zdev, &zpci_list, entry) {
204 init_pci_slot(zdev);
205 }
206 mutex_unlock(&zpci_list_lock);
207}
208
208static void __exit exit_pci_slots(void) 209static void __exit exit_pci_slots(void)
209{ 210{
210 struct list_head *tmp, *n; 211 struct list_head *tmp, *n;
@@ -224,28 +225,19 @@ static void __exit exit_pci_slots(void)
224 225
225static int __init pci_hotplug_s390_init(void) 226static int __init pci_hotplug_s390_init(void)
226{ 227{
227 /*
228 * Do specific initialization stuff for your driver here
229 * like initializing your controller hardware (if any) and
230 * determining the number of slots you have in the system
231 * right now.
232 */
233
234 if (!s390_pci_probe) 228 if (!s390_pci_probe)
235 return -EOPNOTSUPP; 229 return -EOPNOTSUPP;
236 230
237 /* register callbacks for slot handling from arch code */ 231 zpci_register_hp_ops(&hp_ops);
238 mutex_lock(&zpci_list_lock); 232 init_pci_slots();
239 hotplug_ops.create_slot = init_pci_slot; 233
240 hotplug_ops.remove_slot = exit_pci_slot; 234 return 0;
241 mutex_unlock(&zpci_list_lock);
242 pr_info("registered hotplug slot callbacks\n");
243 return init_pci_slots();
244} 235}
245 236
246static void __exit pci_hotplug_s390_exit(void) 237static void __exit pci_hotplug_s390_exit(void)
247{ 238{
248 exit_pci_slots(); 239 exit_pci_slots();
240 zpci_deregister_hp_ops();
249} 241}
250 242
251module_init(pci_hotplug_s390_init); 243module_init(pci_hotplug_s390_init);