summaryrefslogtreecommitdiff
path: root/drivers/hv/vmbus_drv.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-01-12 11:53:55 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-01-12 11:53:55 -0500
commitd3b7737f2b70ed2fb7cef985e70d04fb5dee7b7c (patch)
tree190e42f90d152ebad1c077809422c366cdf0577b /drivers/hv/vmbus_drv.c
parentdc6821e0cfe74802aefd2067b40fcdc03fc4599e (diff)
parent070680218379e15c1901f4bf21b98e3cbf12b527 (diff)
Merge commit '070680218379e15c1901f4bf21b98e3cbf12b527' into stable/for-linus-fixes-3.3
* commit '070680218379e15c1901f4bf21b98e3cbf12b527': (50 commits) xen-balloon: convert sysdev_class to a regular subsystem clocksource: convert sysdev_class to a regular subsystem ibm_rtl: convert sysdev_class to a regular subsystem edac: convert sysdev_class to a regular subsystem rtmutex-tester: convert sysdev_class to a regular subsystem driver-core: implement 'sysdev' functionality for regular devices and buses kref: fix up the kfree build problems kref: Remove the memory barriers kref: Implement kref_put in terms of kref_sub kref: Inline all functions Drivers: hv: Get rid of an unnecessary check in hv.c Drivers: hv: Make the vmbus driver unloadable Drivers: hv: Fix a memory leak Documentation: Update stable address MAINTAINERS: stable: Update address w1: add fast search for single slave bus driver-core: skip uevent generation when nobody is listening drivers: hv: Don't OOPS when you cannot init vmbus firmware: google: fix gsmi.c build warning drivers_base: make argument to platform_device_register_full const ...
Diffstat (limited to 'drivers/hv/vmbus_drv.c')
-rw-r--r--drivers/hv/vmbus_drv.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 0c048dd8013f..c3875f72b5bf 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -62,6 +62,14 @@ struct hv_device_info {
struct hv_dev_port_info outbound;
};
+static int vmbus_exists(void)
+{
+ if (hv_acpi_dev == NULL)
+ return -ENODEV;
+
+ return 0;
+}
+
static void get_channel_info(struct hv_device *device,
struct hv_device_info *info)
@@ -590,6 +598,10 @@ int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, c
pr_info("registering driver %s\n", hv_driver->name);
+ ret = vmbus_exists();
+ if (ret < 0)
+ return ret;
+
hv_driver->driver.name = hv_driver->name;
hv_driver->driver.owner = owner;
hv_driver->driver.mod_name = mod_name;
@@ -614,6 +626,9 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver)
{
pr_info("unregistering driver %s\n", hv_driver->name);
+ if (!vmbus_exists())
+ return;
+
driver_unregister(&hv_driver->driver);
}
@@ -776,11 +791,23 @@ static int __init hv_acpi_init(void)
cleanup:
acpi_bus_unregister_driver(&vmbus_acpi_driver);
+ hv_acpi_dev = NULL;
return ret;
}
+static void __exit vmbus_exit(void)
+{
+
+ free_irq(irq, hv_acpi_dev);
+ vmbus_free_channels();
+ bus_unregister(&hv_bus);
+ hv_cleanup();
+ acpi_bus_unregister_driver(&vmbus_acpi_driver);
+}
+
MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
-module_init(hv_acpi_init);
+subsys_initcall(hv_acpi_init);
+module_exit(vmbus_exit);