diff options
Diffstat (limited to 'drivers/misc/ioc4.c')
-rw-r--r-- | drivers/misc/ioc4.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 193206602d88..668d41e594a9 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c | |||
@@ -273,13 +273,11 @@ ioc4_variant(struct ioc4_driver_data *idd) | |||
273 | static void __devinit | 273 | static void __devinit |
274 | ioc4_load_modules(struct work_struct *work) | 274 | ioc4_load_modules(struct work_struct *work) |
275 | { | 275 | { |
276 | /* arg just has to be freed */ | ||
277 | |||
278 | request_module("sgiioc4"); | 276 | request_module("sgiioc4"); |
279 | |||
280 | kfree(work); | ||
281 | } | 277 | } |
282 | 278 | ||
279 | static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules); | ||
280 | |||
283 | /* Adds a new instance of an IOC4 card */ | 281 | /* Adds a new instance of an IOC4 card */ |
284 | static int __devinit | 282 | static int __devinit |
285 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | 283 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) |
@@ -396,21 +394,12 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
396 | * PCI device. | 394 | * PCI device. |
397 | */ | 395 | */ |
398 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { | 396 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { |
399 | struct work_struct *work; | 397 | /* Request the module from a work procedure as the modprobe |
400 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | 398 | * goes out to a userland helper and that will hang if done |
401 | if (!work) { | 399 | * directly from ioc4_probe(). |
402 | printk(KERN_WARNING | 400 | */ |
403 | "%s: IOC4 unable to allocate memory for " | 401 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); |
404 | "load of sub-modules.\n", __func__); | 402 | schedule_work(&ioc4_load_modules_work); |
405 | } else { | ||
406 | /* Request the module from a work procedure as the | ||
407 | * modprobe goes out to a userland helper and that | ||
408 | * will hang if done directly from ioc4_probe(). | ||
409 | */ | ||
410 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); | ||
411 | INIT_WORK(work, ioc4_load_modules); | ||
412 | schedule_work(work); | ||
413 | } | ||
414 | } | 403 | } |
415 | 404 | ||
416 | return 0; | 405 | return 0; |
@@ -498,7 +487,7 @@ static void __exit | |||
498 | ioc4_exit(void) | 487 | ioc4_exit(void) |
499 | { | 488 | { |
500 | /* Ensure ioc4_load_modules() has completed before exiting */ | 489 | /* Ensure ioc4_load_modules() has completed before exiting */ |
501 | flush_scheduled_work(); | 490 | flush_work_sync(&ioc4_load_modules_work); |
502 | pci_unregister_driver(&ioc4_driver); | 491 | pci_unregister_driver(&ioc4_driver); |
503 | } | 492 | } |
504 | 493 | ||