[PATCH 04/11] bcma: add SOC bus
Jonas Gorski
jonas.gorski at gmail.com
Wed Jul 13 15:36:09 EDT 2011
Hi,
some minor things I saw:
On 9 July 2011 13:05, Hauke Mehrtens <hauke at hauke-m.de> wrote:
> This patch adds support for using bcma on a Broadcom SoC as the system
> bus. An SoC like the bcm4716 could register this bus and use it to
> searches for the bcma cores and register the devices on this bus.
>
> Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
> ---
> drivers/bcma/Kconfig | 5 +
> drivers/bcma/Makefile | 1 +
> drivers/bcma/host_soc.c | 178 +++++++++++++++++++++++++++++++++++++++++
> drivers/bcma/main.c | 1 +
> drivers/bcma/scan.c | 24 +++++-
> include/linux/bcma/bcma.h | 4 +
> include/linux/bcma/bcma_soc.h | 16 ++++
> 7 files changed, 227 insertions(+), 2 deletions(-)
> create mode 100644 drivers/bcma/host_soc.c
> create mode 100644 include/linux/bcma/bcma_soc.h
>
> diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
> index 353781b..8d82f42 100644
> --- a/drivers/bcma/Kconfig
> +++ b/drivers/bcma/Kconfig
> @@ -22,6 +22,11 @@ config BCMA_HOST_PCI
> bool "Support for BCMA on PCI-host bus"
> depends on BCMA_HOST_PCI_POSSIBLE
>
> +config BCMA_HOST_SOC
> + bool
> + depends on BCMA && MIPS
> + default n
Default default is already "n", so this line is superfluous.
> +
> config BCMA_DEBUG
> bool "BCMA debugging"
> depends on BCMA
> diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
> index 0d56245..42d61dd 100644
> --- a/drivers/bcma/Makefile
> +++ b/drivers/bcma/Makefile
> @@ -2,6 +2,7 @@ bcma-y += main.o scan.o core.o
> bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
> bcma-y += driver_pci.o
> bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
> +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
> obj-$(CONFIG_BCMA) += bcma.o
>
> ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
> diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
> new file mode 100644
> index 0000000..a6fe724
> --- /dev/null
> +++ b/drivers/bcma/host_soc.c
> @@ -0,0 +1,178 @@
> +/*
> + * Broadcom specific AMBA
> + * System on Chip (SoC) Host
> + *
> + * Licensed under the GNU/GPL. See COPYING for details.
> + */
> +
> +#include "bcma_private.h"
> +#include "scan.h"
> +#include <linux/bcma/bcma.h>
> +#include <linux/bcma/bcma_soc.h>
> +
> +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
> +{
> + return readb(core->io_addr + offset);
> +}
> +
> +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
> +{
> + return readw(core->io_addr + offset);
> +}
> +
> +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
> +{
> + return readl(core->io_addr + offset);
> +}
> +
> +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
> + u8 value)
> +{
> + writeb(value, core->io_addr + offset);
> +}
> +
> +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
> + u16 value)
> +{
> + writew(value, core->io_addr + offset);
> +}
> +
> +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
> + u32 value)
> +{
> + writel(value, core->io_addr + offset);
> +}
> +
> +#ifdef CONFIG_BCMA_BLOCKIO
> +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
> + size_t count, u16 offset, u8 reg_width)
> +{
> + void __iomem *addr = core->io_addr + offset;
> +
> + switch (reg_width) {
> + case sizeof(u8): {
> + u8 *buf = buffer;
> +
> + while (count) {
> + *buf = __raw_readb(addr);
> + buf++;
> + count--;
> + }
> + break;
> + }
> + case sizeof(u16): {
> + __le16 *buf = buffer;
> +
> + WARN_ON(count & 1);
> + while (count) {
> + *buf = (__force __le16)__raw_readw(addr);
> + buf++;
> + count -= 2;
> + }
> + break;
> + }
> + case sizeof(u32): {
> + __le32 *buf = buffer;
> +
> + WARN_ON(count & 3);
> + while (count) {
> + *buf = (__force __le32)__raw_readl(addr);
> + buf++;
> + count -= 4;
> + }
> + break;
> + }
> + default:
> + WARN_ON(1);
> + }
> +}
> +
> +static void bcma_host_soc_block_write(struct bcma_device *core,
> + const void *buffer,
> + size_t count, u16 offset, u8 reg_width)
> +{
> + void __iomem *addr = core->io_addr + offset;
> +
> + switch (reg_width) {
> + case sizeof(u8): {
> + const u8 *buf = buffer;
> +
> + while (count) {
> + __raw_writeb(*buf, addr);
> + buf++;
> + count--;
> + }
> + break;
> + }
> + case sizeof(u16): {
> + const __le16 *buf = buffer;
> +
> + WARN_ON(count & 1);
> + while (count) {
> + __raw_writew((__force u16)(*buf), addr);
> + buf++;
> + count -= 2;
> + }
> + break;
> + }
> + case sizeof(u32): {
> + const __le32 *buf = buffer;
> +
> + WARN_ON(count & 3);
> + while (count) {
> + __raw_writel((__force u32)(*buf), addr);
> + buf++;
> + count -= 4;
> + }
> + break;
> + }
> + default:
> + WARN_ON(1);
> + }
> +}
> +#endif /* CONFIG_BCMA_BLOCKIO */
> +
> +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
> +{
> + return readl(core->io_wrap + offset);
> +}
> +
> +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
> + u32 value)
> +{
> + writel(value, core->io_wrap + offset);
> +}
> +
> +const struct bcma_host_ops bcma_host_soc_ops = {
> + .read8 = bcma_host_soc_read8,
> + .read16 = bcma_host_soc_read16,
> + .read32 = bcma_host_soc_read32,
> + .write8 = bcma_host_soc_write8,
> + .write16 = bcma_host_soc_write16,
> + .write32 = bcma_host_soc_write32,
> +#ifdef CONFIG_BCMA_BLOCKIO
> + .block_read = bcma_host_soc_block_read,
> + .block_write = bcma_host_soc_block_write,
> +#endif
> + .aread32 = bcma_host_soc_aread32,
> + .awrite32 = bcma_host_soc_awrite32,
> +};
> +
> +int __init bcma_host_soc_register(struct bcma_soc *soc)
> +{
> + struct bcma_bus *bus = &soc->bus;
> +
> + /* iomap only first core. We have to read some register on this core
> + * to scan the bus.
> + */
> + bus->mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
> + if (!bus->mmio)
> + return -ENOMEM;
> +
> + /* Host specific */
> + bus->hosttype = BCMA_HOSTTYPE_SOC;
> + bus->ops = &bcma_host_soc_ops;
> +
> + /* Register */
> + return bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
> +}
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index e6c308c..2ca5eeb 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -92,6 +92,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
> break;
> case BCMA_HOSTTYPE_NONE:
> case BCMA_HOSTTYPE_SDIO:
> + case BCMA_HOSTTYPE_SOC:
> break;
> }
>
> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
> index bf9f806..202edc8 100644
> --- a/drivers/bcma/scan.c
> +++ b/drivers/bcma/scan.c
> @@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
> }
> }
> }
> + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
> + core->io_addr = ioremap(core->addr, BCMA_CORE_SIZE);
> + if (!core->io_addr)
> + return -ENOMEM;
> + core->io_wrap = ioremap(core->wrap, BCMA_CORE_SIZE);
> + if (!core->io_wrap)
> + return -ENOMEM;
Shouldn't you unmap core->io_addr if remapping io_wrap fails?
> + }
> return 0;
> }
>
> @@ -369,7 +377,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
> bcma_init_bus(bus);
>
> erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
> - eromptr = bus->mmio;
> + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
> + eromptr = ioremap(erombase, BCMA_CORE_SIZE);
> + if (!eromptr)
> + return -ENOMEM;
> + } else
> + eromptr = bus->mmio;
Documentation/CodingStyle says use braces in both branches if one needs them.
> +
> eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>
> bcma_scan_switch_core(bus, erombase);
> @@ -417,7 +431,13 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
> int err, core_num = 0;
>
> erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
> - eromptr = bus->mmio;
> + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
> + eromptr = ioremap(erombase, BCMA_CORE_SIZE);
> + if (!eromptr)
> + return -ENOMEM;
> + } else
> + eromptr = bus->mmio;
Ditto.
> +
> eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>
> bcma_scan_switch_core(bus, erombase);
> diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
> index 6bd7b7f..73fda1c 100644
> --- a/include/linux/bcma/bcma.h
> +++ b/include/linux/bcma/bcma.h
> @@ -16,6 +16,7 @@ enum bcma_hosttype {
> BCMA_HOSTTYPE_NONE,
> BCMA_HOSTTYPE_PCI,
> BCMA_HOSTTYPE_SDIO,
> + BCMA_HOSTTYPE_SOC,
> };
>
> struct bcma_chipinfo {
> @@ -124,6 +125,9 @@ struct bcma_device {
> u32 addr;
> u32 wrap;
>
> + void __iomem *io_addr;
> + void __iomem *io_wrap;
> +
> void *drvdata;
> struct list_head list;
> };
> diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
> new file mode 100644
> index 0000000..4203c55
> --- /dev/null
> +++ b/include/linux/bcma/bcma_soc.h
> @@ -0,0 +1,16 @@
> +#ifndef LINUX_BCMA_SOC_H_
> +#define LINUX_BCMA_SOC_H_
> +
> +#include <linux/bcma/bcma.h>
> +
> +struct bcma_soc {
> + struct bcma_bus bus;
> + struct bcma_device core_cc;
> + struct bcma_device core_mips;
> +};
> +
> +int __init bcma_host_soc_register(struct bcma_soc *soc);
> +
> +int bcma_bus_register(struct bcma_bus *bus);
> +
> +#endif /* LINUX_BCMA_SOC_H_ */
> --
> 1.7.4.1
More information about the b43-dev
mailing list