Skip to content

Commit 3cf3857

Browse files
Antonios MotakisRussell King
authored andcommitted
ARM: 8256/1: driver coamba: add device binding path 'driver_override'
As already demonstrated with PCI [1] and the platform bus [2], a driver_override property in sysfs can be used to bypass the id matching of a device to a AMBA driver. This can be used by VFIO to bind to any AMBA device requested by the user. [1] http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html [2] https://www.redhat.com/archives/libvir-list/2014-April/msg00382.html Signed-off-by: Antonios Motakis <[email protected]> Reviewed-by: Kim Phillips <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent 8684014 commit 3cf3857

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
What: /sys/bus/amba/devices/.../driver_override
2+
Date: September 2014
3+
Contact: Antonios Motakis <[email protected]>
4+
Description:
5+
This file allows the driver for a device to be specified which
6+
will override standard OF, ACPI, ID table, and name matching.
7+
When specified, only a driver with a name matching the value
8+
written to driver_override will have an opportunity to bind to
9+
the device. The override is specified by writing a string to the
10+
driver_override file (echo vfio-amba > driver_override) and may
11+
be cleared with an empty string (echo > driver_override).
12+
This returns the device to standard matching rules binding.
13+
Writing to driver_override does not automatically unbind the
14+
device from its current driver or make any attempt to
15+
automatically load the specified driver. If no driver with a
16+
matching name is currently loaded in the kernel, the device will
17+
not bind to any driver. This also allows devices to opt-out of
18+
driver binding using a driver_override name such as "none".
19+
Only a single driver may be specified in the override, there is
20+
no support for parsing delimiters.

drivers/amba/bus.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/pm_domain.h>
1919
#include <linux/amba/bus.h>
2020
#include <linux/sizes.h>
21+
#include <linux/limits.h>
2122

2223
#include <asm/irq.h>
2324

@@ -43,6 +44,10 @@ static int amba_match(struct device *dev, struct device_driver *drv)
4344
struct amba_device *pcdev = to_amba_device(dev);
4445
struct amba_driver *pcdrv = to_amba_driver(drv);
4546

47+
/* When driver_override is set, only bind to the matching driver */
48+
if (pcdev->driver_override)
49+
return !strcmp(pcdev->driver_override, drv->name);
50+
4651
return amba_lookup(pcdrv->id_table, pcdev) != NULL;
4752
}
4853

@@ -59,6 +64,47 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
5964
return retval;
6065
}
6166

67+
static ssize_t driver_override_show(struct device *_dev,
68+
struct device_attribute *attr, char *buf)
69+
{
70+
struct amba_device *dev = to_amba_device(_dev);
71+
72+
if (!dev->driver_override)
73+
return 0;
74+
75+
return sprintf(buf, "%s\n", dev->driver_override);
76+
}
77+
78+
static ssize_t driver_override_store(struct device *_dev,
79+
struct device_attribute *attr,
80+
const char *buf, size_t count)
81+
{
82+
struct amba_device *dev = to_amba_device(_dev);
83+
char *driver_override, *old = dev->driver_override, *cp;
84+
85+
if (count > PATH_MAX)
86+
return -EINVAL;
87+
88+
driver_override = kstrndup(buf, count, GFP_KERNEL);
89+
if (!driver_override)
90+
return -ENOMEM;
91+
92+
cp = strchr(driver_override, '\n');
93+
if (cp)
94+
*cp = '\0';
95+
96+
if (strlen(driver_override)) {
97+
dev->driver_override = driver_override;
98+
} else {
99+
kfree(driver_override);
100+
dev->driver_override = NULL;
101+
}
102+
103+
kfree(old);
104+
105+
return count;
106+
}
107+
62108
#define amba_attr_func(name,fmt,arg...) \
63109
static ssize_t name##_show(struct device *_dev, \
64110
struct device_attribute *attr, char *buf) \
@@ -81,6 +127,7 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
81127
static struct device_attribute amba_dev_attrs[] = {
82128
__ATTR_RO(id),
83129
__ATTR_RO(resource),
130+
__ATTR_RW(driver_override),
84131
__ATTR_NULL,
85132
};
86133

include/linux/amba/bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct amba_device {
3333
struct clk *pclk;
3434
unsigned int periphid;
3535
unsigned int irq[AMBA_NR_IRQS];
36+
char *driver_override;
3637
};
3738

3839
struct amba_driver {

0 commit comments

Comments
 (0)