Message ID | 20210226140305.26356-3-nsaenzjulienne@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Generic way of dealing with broken 64-bit buses | expand |
On 2021-02-26 14:02, Nicolas Saenz Julienne wrote: > Some devices might inadvertently sit on buses that don't support 64bit > MMIO access, and need a mechanism to query these limitations without > prejudice to other buses in the system (i.e. defaulting to 32bit access > system wide isn't an option). > > Introduce a new bus callback, 'mmio_configure(),' which will take care > of populating the relevant device properties based on the bus' > limitations. Devil's advocate: there already exist workarounds for 8-bit and/or 16-bit accesses not working in various places, does it make sense for a 64-bit workaround to be so wildly different and disjoint? > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > --- > arch/Kconfig | 8 ++++++++ > drivers/base/dd.c | 6 ++++++ > include/linux/device.h | 3 +++ > include/linux/device/bus.h | 3 +++ > 4 files changed, 20 insertions(+) > > diff --git a/arch/Kconfig b/arch/Kconfig > index 2bb30673d8e6..ba7f246b6b9d 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -1191,6 +1191,14 @@ config ARCH_SPLIT_ARG64 > config ARCH_HAS_ELFCORE_COMPAT > bool > > +config ARCH_HAS_64BIT_MMIO_BROKEN > + bool > + depends on 64BIT As mentioned previously, 32-bit systems may not need the overrides for kernel I/O accessors, but they could still need the same workarounds for the memory-mapping implications (if this is to be a proper generic mechanism). > + default n Tip: it is always redundant to state that. Robin. > + help > + Arch might contain busses unable to perform 64bit mmio accessses on > + an otherwise 64bit system. > + > source "kernel/gcov/Kconfig" > > source "scripts/gcc-plugins/Kconfig" > diff --git a/drivers/base/dd.c b/drivers/base/dd.c > index 9179825ff646..8086ce8f17a6 100644 > --- a/drivers/base/dd.c > +++ b/drivers/base/dd.c > @@ -538,6 +538,12 @@ static int really_probe(struct device *dev, struct device_driver *drv) > goto probe_failed; > } > > + if (dev->bus->mmio_configure) { > + ret = dev->bus->mmio_configure(dev); > + if (ret) > + goto probe_failed; > + } > + > if (driver_sysfs_add(dev)) { > pr_err("%s: driver_sysfs_add(%s) failed\n", > __func__, dev_name(dev)); > diff --git a/include/linux/device.h b/include/linux/device.h > index ba660731bd25..bd94aa0cbd72 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -553,6 +553,9 @@ struct device { > #ifdef CONFIG_DMA_OPS_BYPASS > bool dma_ops_bypass : 1; > #endif > +#if defined(CONFIG_ARCH_HAS_64BIT_MMIO_BROKEN) > + bool mmio_64bit_broken:1; > +#endif > }; > > /** > diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h > index 1ea5e1d1545b..680dfc3b4744 100644 > --- a/include/linux/device/bus.h > +++ b/include/linux/device/bus.h > @@ -59,6 +59,8 @@ struct fwnode_handle; > * bus supports. > * @dma_configure: Called to setup DMA configuration on a device on > * this bus. > + * @mmio_configure: Called to setup MMIO configuration on a device on > + * this bus. > * @pm: Power management operations of this bus, callback the specific > * device driver's pm-ops. > * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU > @@ -103,6 +105,7 @@ struct bus_type { > int (*num_vf)(struct device *dev); > > int (*dma_configure)(struct device *dev); > + int (*mmio_configure)(struct device *dev); > > const struct dev_pm_ops *pm; > >
Hi Robin, On Tue, 2021-03-02 at 11:29 +0000, Robin Murphy wrote: > On 2021-02-26 14:02, Nicolas Saenz Julienne wrote: > > Some devices might inadvertently sit on buses that don't support 64bit > > MMIO access, and need a mechanism to query these limitations without > > prejudice to other buses in the system (i.e. defaulting to 32bit access > > system wide isn't an option). > > > > Introduce a new bus callback, 'mmio_configure(),' which will take care > > of populating the relevant device properties based on the bus' > > limitations. > > Devil's advocate: there already exist workarounds for 8-bit and/or > 16-bit accesses not working in various places, does it make sense for a > 64-bit workaround to be so wildly different and disjoint? Can you point out an example of the workarounds? > > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > > --- > > arch/Kconfig | 8 ++++++++ > > drivers/base/dd.c | 6 ++++++ > > include/linux/device.h | 3 +++ > > include/linux/device/bus.h | 3 +++ > > 4 files changed, 20 insertions(+) > > > > diff --git a/arch/Kconfig b/arch/Kconfig > > index 2bb30673d8e6..ba7f246b6b9d 100644 > > --- a/arch/Kconfig > > +++ b/arch/Kconfig > > @@ -1191,6 +1191,14 @@ config ARCH_SPLIT_ARG64 > > config ARCH_HAS_ELFCORE_COMPAT > > bool > > > > > > +config ARCH_HAS_64BIT_MMIO_BROKEN > > + bool > > + depends on 64BIT > > As mentioned previously, 32-bit systems may not need the overrides for > kernel I/O accessors, but they could still need the same workarounds for > the memory-mapping implications (if this is to be a proper generic > mechanism). I'll keep it in mind. > > + default n > > Tip: it is always redundant to state that. Noted! Regards, Nicolas
diff --git a/arch/Kconfig b/arch/Kconfig index 2bb30673d8e6..ba7f246b6b9d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1191,6 +1191,14 @@ config ARCH_SPLIT_ARG64 config ARCH_HAS_ELFCORE_COMPAT bool +config ARCH_HAS_64BIT_MMIO_BROKEN + bool + depends on 64BIT + default n + help + Arch might contain busses unable to perform 64bit mmio accessses on + an otherwise 64bit system. + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 9179825ff646..8086ce8f17a6 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -538,6 +538,12 @@ static int really_probe(struct device *dev, struct device_driver *drv) goto probe_failed; } + if (dev->bus->mmio_configure) { + ret = dev->bus->mmio_configure(dev); + if (ret) + goto probe_failed; + } + if (driver_sysfs_add(dev)) { pr_err("%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); diff --git a/include/linux/device.h b/include/linux/device.h index ba660731bd25..bd94aa0cbd72 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -553,6 +553,9 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif +#if defined(CONFIG_ARCH_HAS_64BIT_MMIO_BROKEN) + bool mmio_64bit_broken:1; +#endif }; /** diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 1ea5e1d1545b..680dfc3b4744 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -59,6 +59,8 @@ struct fwnode_handle; * bus supports. * @dma_configure: Called to setup DMA configuration on a device on * this bus. + * @mmio_configure: Called to setup MMIO configuration on a device on + * this bus. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU @@ -103,6 +105,7 @@ struct bus_type { int (*num_vf)(struct device *dev); int (*dma_configure)(struct device *dev); + int (*mmio_configure)(struct device *dev); const struct dev_pm_ops *pm;
Some devices might inadvertently sit on buses that don't support 64bit MMIO access, and need a mechanism to query these limitations without prejudice to other buses in the system (i.e. defaulting to 32bit access system wide isn't an option). Introduce a new bus callback, 'mmio_configure(),' which will take care of populating the relevant device properties based on the bus' limitations. Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> --- arch/Kconfig | 8 ++++++++ drivers/base/dd.c | 6 ++++++ include/linux/device.h | 3 +++ include/linux/device/bus.h | 3 +++ 4 files changed, 20 insertions(+)