summaryrefslogtreecommitdiff
path: root/drivers/vbus
diff options
context:
space:
mode:
authorGregory Haskins <ghaskins@novell.com>2009-12-07 11:46:45 -0500
committerGregory Haskins <ghaskins@novell.com>2010-05-20 09:12:05 -0400
commitd86efb46b8cf33cf57702a2629f848c91149fbde (patch)
tree27fbd5492623e46d45c5a72040e82cb8b4e739ac /drivers/vbus
parent5a61684fd5ecd09439a76fcc6bc0333e72a368ca (diff)
vbus: add autoprobe capability to guest
This enables the guest to automatically load the appropriate driver when vbus devices are detected. Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Diffstat (limited to 'drivers/vbus')
-rw-r--r--drivers/vbus/bus-proxy.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/vbus/bus-proxy.c b/drivers/vbus/bus-proxy.c
index 5d349427661a..a318c6754b4b 100644
--- a/drivers/vbus/bus-proxy.c
+++ b/drivers/vbus/bus-proxy.c
@@ -48,6 +48,16 @@ static int vbus_dev_proxy_match(struct device *_dev, struct device_driver *_drv)
return !strcmp(dev->type, drv->type);
}
+static int vbus_dev_proxy_uevent(struct device *_dev, struct kobj_uevent_env *env)
+{
+ struct vbus_device_proxy *dev = to_dev(_dev);
+
+ if (add_uevent_var(env, "MODALIAS=vbus-proxy:%s", dev->type))
+ return -ENOMEM;
+
+ return 0;
+}
+
/*
* This function is invoked after the bus infrastructure has already made a
* match. The device will contain a reference to the paired driver which
@@ -68,6 +78,7 @@ static int vbus_dev_proxy_probe(struct device *_dev)
static struct bus_type vbus_proxy = {
.name = VBUS_PROXY_NAME,
.match = vbus_dev_proxy_match,
+ .uevent = vbus_dev_proxy_uevent,
};
static struct device vbus_proxy_rootdev = {
@@ -99,18 +110,38 @@ static void device_release(struct device *dev)
_dev->ops->release(_dev);
}
+static ssize_t _show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "vbus-proxy:%s\n", to_dev(dev)->type);
+}
+static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, _show_modalias, NULL);
+
int vbus_device_proxy_register(struct vbus_device_proxy *new)
{
+ int ret;
+
new->dev.parent = &vbus_proxy_rootdev;
new->dev.bus = &vbus_proxy;
new->dev.release = &device_release;
- return device_register(&new->dev);
+ ret = device_register(&new->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = device_create_file(&new->dev, &dev_attr_modalias);
+ if (ret < 0) {
+ device_unregister(&new->dev);
+ return ret;
+ }
+
+ return 0;
}
EXPORT_SYMBOL_GPL(vbus_device_proxy_register);
void vbus_device_proxy_unregister(struct vbus_device_proxy *dev)
{
+ device_remove_file(&dev->dev, &dev_attr_modalias);
device_unregister(&dev->dev);
}
EXPORT_SYMBOL_GPL(vbus_device_proxy_unregister);