Add a runtime device tree overlay interface for device need dts file. With it its possible to use device tree overlays without having to use a per-platform overlay manager. Add a new device by command: $ cat test.dtbo > /sys/class/spi_master/spi0/overlay_fdto Remove the device by command: $ echo remove > /sys/class/spi_master/spi0/overlay_fdto Signed-off-by: Wei Yongjun <weiyongjun1@xxxxxxxxxx> --- drivers/spi/Kconfig | 2 ++ drivers/spi/spi-mockup.c | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e0f0fa2746ad..4b7c84ddb367 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1161,6 +1161,8 @@ config SPI_TLE62X0 config SPI_MOCKUP tristate "SPI controller Testing Driver" depends on OF + select OF_EARLY_FLATTREE + select OF_RESOLVE select BPF_EVENTS help This enables SPI controller testing driver, which provides a way to diff --git a/drivers/spi/spi-mockup.c b/drivers/spi/spi-mockup.c index 7a93b194ee53..404ad821bf6a 100644 --- a/drivers/spi/spi-mockup.c +++ b/drivers/spi/spi-mockup.c @@ -21,6 +21,9 @@ struct mockup_spi { struct mutex lock; struct spi_device *devs[MOCKUP_CHIPSELECT_MAX]; + + void *fdto; + int ovcs_id; }; static struct spi_master *to_spi_master(struct device *dev) @@ -145,9 +148,53 @@ delete_device_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_WO(delete_device); +static ssize_t +overlay_fdto_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct spi_master *master = to_spi_master(dev); + struct mockup_spi *mock = spi_master_get_devdata(master); + int ret; + + mutex_lock(&mock->lock); + + if (strncmp(buf, "remove\n", count) == 0) { + if (mock->ovcs_id < 0) { + ret = -ENOENT; + goto out_unlock; + } + of_overlay_remove(&mock->ovcs_id); + kfree(mock->fdto); + mock->ovcs_id = -1; + mock->fdto = NULL; + } else { + if (mock->ovcs_id >= 0) { + ret = -EINVAL; + goto out_unlock; + } + mock->fdto = kmemdup(buf, count, GFP_KERNEL); + if (!mock->fdto) { + ret = -ENOMEM; + goto out_unlock; + } + ret = of_overlay_fdt_apply(mock->fdto, count, &mock->ovcs_id); + if (ret < 0) + goto out_unlock; + } + + mutex_unlock(&mock->lock); + return count; + +out_unlock: + mutex_unlock(&mock->lock); + return ret; +} +static DEVICE_ATTR_WO(overlay_fdto); + static struct attribute *spi_mockup_attrs[] = { &dev_attr_new_device.attr, &dev_attr_delete_device.attr, + &dev_attr_overlay_fdto.attr, NULL }; ATTRIBUTE_GROUPS(spi_mockup); @@ -227,6 +274,7 @@ static int spi_mockup_probe(struct platform_device *pdev) mock = spi_master_get_devdata(master); mutex_init(&mock->lock); + mock->ovcs_id = -1; ret = spi_register_master(master); if (ret) { -- 2.34.1