aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/ioc4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/ioc4.c')
-rw-r--r--drivers/misc/ioc4.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 6f76573e7c8..06f6ad29cef 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/ioc4.h>
#include <linux/ktime.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/time.h>
#include <asm/io.h>
@@ -269,6 +270,14 @@ ioc4_variant(struct ioc4_driver_data *idd)
return IOC4_VARIANT_PCI_RT;
}
+static void
+ioc4_load_modules(struct work_struct *work)
+{
+ request_module("sgiioc4");
+}
+
+static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules);
+
/* Adds a new instance of an IOC4 card */
static int
ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
@@ -378,6 +387,21 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
}
mutex_unlock(&ioc4_mutex);
+ /* Request sgiioc4 IDE driver on boards that bring that functionality
+ * off of IOC4. The root filesystem may be hosted on a drive connected
+ * to IOC4, so we need to make sure the sgiioc4 driver is loaded as it
+ * won't be picked up by modprobes due to the ioc4 module owning the
+ * PCI device.
+ */
+ if (idd->idd_variant != IOC4_VARIANT_PCI_RT) {
+ /* Request the module from a work procedure as the modprobe
+ * goes out to a userland helper and that will hang if done
+ * directly from ioc4_probe().
+ */
+ printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n");
+ schedule_work(&ioc4_load_modules_work);
+ }
+
return 0;
out_misc_region:
@@ -452,16 +476,18 @@ MODULE_DEVICE_TABLE(pci, ioc4_id_table);
*********************/
/* Module load */
-static int __devinit
+static int __init
ioc4_init(void)
{
return pci_register_driver(&ioc4_driver);
}
/* Module unload */
-static void __devexit
+static void __exit
ioc4_exit(void)
{
+ /* Ensure ioc4_load_modules() has completed before exiting */
+ flush_work(&ioc4_load_modules_work);
pci_unregister_driver(&ioc4_driver);
}