| From 02e92b21edb4df7285f27ea5f0403377dcabe22d Mon Sep 17 00:00:00 2001 |
| From: Ioana Ciornei <ioana.ciornei@nxp.com> |
| Date: Tue, 29 Oct 2019 22:48:55 +0200 |
| Subject: [PATCH] bus: fsl-mc: add autorescan sysfs |
| |
| Add the autorescan sysfs in order to enable/disable the DPRC IRQs on |
| which automatic rescan of the bus is performed. This is important when |
| dynamic creation of objects is needed to happen in a timely manner because |
| object creation can be bundled together. |
| |
| Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> |
| --- |
| drivers/bus/fsl-mc/dprc-driver.c | 17 ++++++++++-- |
| drivers/bus/fsl-mc/fsl-mc-bus.c | 55 +++++++++++++++++++++++++++++++++++++ |
| drivers/bus/fsl-mc/fsl-mc-private.h | 4 +++ |
| include/linux/fsl/mc.h | 1 + |
| 4 files changed, 75 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/bus/fsl-mc/dprc-driver.c |
| +++ b/drivers/bus/fsl-mc/dprc-driver.c |
| @@ -484,8 +484,9 @@ out: |
| /* |
| * Disable and clear interrupt for a given DPRC object |
| */ |
| -static int disable_dprc_irq(struct fsl_mc_device *mc_dev) |
| +int disable_dprc_irq(struct fsl_mc_device *mc_dev) |
| { |
| + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); |
| int error; |
| struct fsl_mc_io *mc_io = mc_dev->mc_io; |
| |
| @@ -522,9 +523,18 @@ static int disable_dprc_irq(struct fsl_m |
| return error; |
| } |
| |
| + mc_bus->irq_enabled = 0; |
| + |
| return 0; |
| } |
| |
| +int get_dprc_irq_state(struct fsl_mc_device *mc_dev) |
| +{ |
| + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); |
| + |
| + return mc_bus->irq_enabled; |
| +} |
| + |
| static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) |
| { |
| int error; |
| @@ -551,8 +561,9 @@ static int register_dprc_irq_handler(str |
| return 0; |
| } |
| |
| -static int enable_dprc_irq(struct fsl_mc_device *mc_dev) |
| +int enable_dprc_irq(struct fsl_mc_device *mc_dev) |
| { |
| + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); |
| int error; |
| |
| /* |
| @@ -580,6 +591,8 @@ static int enable_dprc_irq(struct fsl_mc |
| return error; |
| } |
| |
| + mc_bus->irq_enabled = 1; |
| + |
| return 0; |
| } |
| |
| --- a/drivers/bus/fsl-mc/fsl-mc-bus.c |
| +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c |
| @@ -237,8 +237,63 @@ static ssize_t rescan_store(struct bus_t |
| } |
| static BUS_ATTR_WO(rescan); |
| |
| +static int fsl_mc_bus_set_autorescan(struct device *dev, void *data) |
| +{ |
| + struct fsl_mc_device *root_mc_dev; |
| + unsigned long val; |
| + char *buf = data; |
| + |
| + if (!fsl_mc_is_root_dprc(dev)) |
| + goto exit; |
| + |
| + root_mc_dev = to_fsl_mc_device(dev); |
| + |
| + if (kstrtoul(buf, 0, &val) < 0) |
| + return -EINVAL; |
| + |
| + if (val) |
| + enable_dprc_irq(root_mc_dev); |
| + else |
| + disable_dprc_irq(root_mc_dev); |
| + |
| +exit: |
| + return 0; |
| +} |
| + |
| +static int fsl_mc_bus_get_autorescan(struct device *dev, void *data) |
| +{ |
| + struct fsl_mc_device *root_mc_dev; |
| + char *buf = data; |
| + |
| + if (!fsl_mc_is_root_dprc(dev)) |
| + goto exit; |
| + |
| + root_mc_dev = to_fsl_mc_device(dev); |
| + |
| + sprintf(buf, "%d\n", get_dprc_irq_state(root_mc_dev)); |
| +exit: |
| + return 0; |
| +} |
| + |
| +static ssize_t autorescan_store(struct bus_type *bus, |
| + const char *buf, size_t count) |
| +{ |
| + bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_set_autorescan); |
| + |
| + return count; |
| +} |
| + |
| +static ssize_t autorescan_show(struct bus_type *bus, char *buf) |
| +{ |
| + bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_get_autorescan); |
| + return strlen(buf); |
| +} |
| + |
| +static BUS_ATTR_RW(autorescan); |
| + |
| static struct attribute *fsl_mc_bus_attrs[] = { |
| &bus_attr_rescan.attr, |
| + &bus_attr_autorescan.attr, |
| NULL, |
| }; |
| |
| --- a/drivers/bus/fsl-mc/fsl-mc-private.h |
| +++ b/drivers/bus/fsl-mc/fsl-mc-private.h |
| @@ -203,4 +203,8 @@ static inline void fsl_mc_uapi_remove_de |
| |
| #endif |
| |
| +int disable_dprc_irq(struct fsl_mc_device *mc_dev); |
| +int enable_dprc_irq(struct fsl_mc_device *mc_dev); |
| +int get_dprc_irq_state(struct fsl_mc_device *mc_dev); |
| + |
| #endif /* _FSL_MC_PRIVATE_H_ */ |
| --- a/include/linux/fsl/mc.h |
| +++ b/include/linux/fsl/mc.h |
| @@ -1006,6 +1006,7 @@ struct fsl_mc_bus { |
| struct mutex scan_mutex; /* serializes bus scanning */ |
| struct dprc_attributes dprc_attr; |
| struct fsl_mc_uapi uapi_misc; |
| + int irq_enabled; |
| }; |
| |
| int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, |