|
@@ -18,6 +18,7 @@
|
|
|
#include <linux/pm_domain.h>
|
|
|
#include <linux/amba/bus.h>
|
|
|
#include <linux/sizes.h>
|
|
|
+#include <linux/limits.h>
|
|
|
|
|
|
#include <asm/irq.h>
|
|
|
|
|
@@ -43,6 +44,10 @@ static int amba_match(struct device *dev, struct device_driver *drv)
|
|
|
struct amba_device *pcdev = to_amba_device(dev);
|
|
|
struct amba_driver *pcdrv = to_amba_driver(drv);
|
|
|
|
|
|
+ /* When driver_override is set, only bind to the matching driver */
|
|
|
+ if (pcdev->driver_override)
|
|
|
+ return !strcmp(pcdev->driver_override, drv->name);
|
|
|
+
|
|
|
return amba_lookup(pcdrv->id_table, pcdev) != NULL;
|
|
|
}
|
|
|
|
|
@@ -59,6 +64,47 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
+static ssize_t driver_override_show(struct device *_dev,
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
+{
|
|
|
+ struct amba_device *dev = to_amba_device(_dev);
|
|
|
+
|
|
|
+ if (!dev->driver_override)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return sprintf(buf, "%s\n", dev->driver_override);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t driver_override_store(struct device *_dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ const char *buf, size_t count)
|
|
|
+{
|
|
|
+ struct amba_device *dev = to_amba_device(_dev);
|
|
|
+ char *driver_override, *old = dev->driver_override, *cp;
|
|
|
+
|
|
|
+ if (count > PATH_MAX)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ driver_override = kstrndup(buf, count, GFP_KERNEL);
|
|
|
+ if (!driver_override)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ cp = strchr(driver_override, '\n');
|
|
|
+ if (cp)
|
|
|
+ *cp = '\0';
|
|
|
+
|
|
|
+ if (strlen(driver_override)) {
|
|
|
+ dev->driver_override = driver_override;
|
|
|
+ } else {
|
|
|
+ kfree(driver_override);
|
|
|
+ dev->driver_override = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ kfree(old);
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
#define amba_attr_func(name,fmt,arg...) \
|
|
|
static ssize_t name##_show(struct device *_dev, \
|
|
|
struct device_attribute *attr, char *buf) \
|
|
@@ -81,6 +127,7 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
|
|
|
static struct device_attribute amba_dev_attrs[] = {
|
|
|
__ATTR_RO(id),
|
|
|
__ATTR_RO(resource),
|
|
|
+ __ATTR_RW(driver_override),
|
|
|
__ATTR_NULL,
|
|
|
};
|
|
|
|