[PATCH 04/11] bcma: add SOC bus

Hauke Mehrtens hauke at hauke-m.de
Thu Jul 14 16:37:26 EDT 2011


Hi Jonas,


On 07/13/2011 09:36 PM, Jonas Gorski wrote:
> 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.

Will remove this.

> 
>> +
>>  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?

Ok I will add iounmap() on the error path and when the core is freed.
> 
>> +       }
>>        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.
Will fix this.
> 
>> +
>>        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