mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-06 12:44:14 +08:00
bus/fsl-mc: add support for 'driver_override' in the mc-bus
This patch is required for vfio-fsl-mc meta driver to successfully bind layerscape container devices for device passthrough. This patch adds a mechanism to allow a layerscape device to specify a driver rather than a layerscape driver provide a device match. Example to allow a device (dprc.1) to specifically bind with driver (vfio-fsl-mc):- - echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override - echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind - echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind Reviewed-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Acked-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com> Link: https://lore.kernel.org/r/20200929085441.17448-4-diana.craciun@oss.nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
35df88208c
commit
1f86a00c11
@ -3,6 +3,7 @@
|
||||
* Freescale Management Complex (MC) bus driver
|
||||
*
|
||||
* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2019-2020 NXP
|
||||
* Author: German Rivera <German.Rivera@freescale.com>
|
||||
*
|
||||
*/
|
||||
@ -78,6 +79,12 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
|
||||
struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
|
||||
bool found = false;
|
||||
|
||||
/* When driver_override is set, only bind to the matching driver */
|
||||
if (mc_dev->driver_override) {
|
||||
found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!mc_drv->match_id_table)
|
||||
goto out;
|
||||
|
||||
@ -147,8 +154,52 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
static DEVICE_ATTR_RO(modalias);
|
||||
|
||||
static ssize_t driver_override_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
char *driver_override, *old = mc_dev->driver_override;
|
||||
char *cp;
|
||||
|
||||
if (WARN_ON(dev->bus != &fsl_mc_bus_type))
|
||||
return -EINVAL;
|
||||
|
||||
if (count >= (PAGE_SIZE - 1))
|
||||
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)) {
|
||||
mc_dev->driver_override = driver_override;
|
||||
} else {
|
||||
kfree(driver_override);
|
||||
mc_dev->driver_override = NULL;
|
||||
}
|
||||
|
||||
kfree(old);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t driver_override_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
|
||||
}
|
||||
static DEVICE_ATTR_RW(driver_override);
|
||||
|
||||
static struct attribute *fsl_mc_dev_attrs[] = {
|
||||
&dev_attr_modalias.attr,
|
||||
&dev_attr_driver_override.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -748,6 +799,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add);
|
||||
*/
|
||||
void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
|
||||
{
|
||||
kfree(mc_dev->driver_override);
|
||||
mc_dev->driver_override = NULL;
|
||||
|
||||
/*
|
||||
* The device-specific remove callback will get invoked by device_del()
|
||||
*/
|
||||
|
@ -161,6 +161,7 @@ struct fsl_mc_obj_desc {
|
||||
* @regions: pointer to array of MMIO region entries
|
||||
* @irqs: pointer to array of pointers to interrupts allocated to this device
|
||||
* @resource: generic resource associated with this MC object device, if any.
|
||||
* @driver_override: driver name to force a match
|
||||
*
|
||||
* Generic device object for MC object devices that are "attached" to a
|
||||
* MC bus.
|
||||
@ -194,6 +195,7 @@ struct fsl_mc_device {
|
||||
struct fsl_mc_device_irq **irqs;
|
||||
struct fsl_mc_resource *resource;
|
||||
struct device_link *consumer_link;
|
||||
char *driver_override;
|
||||
};
|
||||
|
||||
#define to_fsl_mc_device(_dev) \
|
||||
|
Loading…
Reference in New Issue
Block a user