linux/drivers/bcma/host_soc.c
<<
>>
Prefs
   1/*
   2 * Broadcom specific AMBA
   3 * System on Chip (SoC) Host
   4 *
   5 * Licensed under the GNU/GPL. See COPYING for details.
   6 */
   7
   8#include "bcma_private.h"
   9#include "scan.h"
  10#include <linux/bcma/bcma.h>
  11#include <linux/bcma/bcma_soc.h>
  12
  13static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
  14{
  15        return readb(core->io_addr + offset);
  16}
  17
  18static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
  19{
  20        return readw(core->io_addr + offset);
  21}
  22
  23static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
  24{
  25        return readl(core->io_addr + offset);
  26}
  27
  28static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
  29                                 u8 value)
  30{
  31        writeb(value, core->io_addr + offset);
  32}
  33
  34static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
  35                                 u16 value)
  36{
  37        writew(value, core->io_addr + offset);
  38}
  39
  40static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
  41                                 u32 value)
  42{
  43        writel(value, core->io_addr + offset);
  44}
  45
  46#ifdef CONFIG_BCMA_BLOCKIO
  47static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
  48                                     size_t count, u16 offset, u8 reg_width)
  49{
  50        void __iomem *addr = core->io_addr + offset;
  51
  52        switch (reg_width) {
  53        case sizeof(u8): {
  54                u8 *buf = buffer;
  55
  56                while (count) {
  57                        *buf = __raw_readb(addr);
  58                        buf++;
  59                        count--;
  60                }
  61                break;
  62        }
  63        case sizeof(u16): {
  64                __le16 *buf = buffer;
  65
  66                WARN_ON(count & 1);
  67                while (count) {
  68                        *buf = (__force __le16)__raw_readw(addr);
  69                        buf++;
  70                        count -= 2;
  71                }
  72                break;
  73        }
  74        case sizeof(u32): {
  75                __le32 *buf = buffer;
  76
  77                WARN_ON(count & 3);
  78                while (count) {
  79                        *buf = (__force __le32)__raw_readl(addr);
  80                        buf++;
  81                        count -= 4;
  82                }
  83                break;
  84        }
  85        default:
  86                WARN_ON(1);
  87        }
  88}
  89
  90static void bcma_host_soc_block_write(struct bcma_device *core,
  91                                      const void *buffer,
  92                                      size_t count, u16 offset, u8 reg_width)
  93{
  94        void __iomem *addr = core->io_addr + offset;
  95
  96        switch (reg_width) {
  97        case sizeof(u8): {
  98                const u8 *buf = buffer;
  99
 100                while (count) {
 101                        __raw_writeb(*buf, addr);
 102                        buf++;
 103                        count--;
 104                }
 105                break;
 106        }
 107        case sizeof(u16): {
 108                const __le16 *buf = buffer;
 109
 110                WARN_ON(count & 1);
 111                while (count) {
 112                        __raw_writew((__force u16)(*buf), addr);
 113                        buf++;
 114                        count -= 2;
 115                }
 116                break;
 117        }
 118        case sizeof(u32): {
 119                const __le32 *buf = buffer;
 120
 121                WARN_ON(count & 3);
 122                while (count) {
 123                        __raw_writel((__force u32)(*buf), addr);
 124                        buf++;
 125                        count -= 4;
 126                }
 127                break;
 128        }
 129        default:
 130                WARN_ON(1);
 131        }
 132}
 133#endif /* CONFIG_BCMA_BLOCKIO */
 134
 135static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
 136{
 137        return readl(core->io_wrap + offset);
 138}
 139
 140static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
 141                                  u32 value)
 142{
 143        writel(value, core->io_wrap + offset);
 144}
 145
 146static const struct bcma_host_ops bcma_host_soc_ops = {
 147        .read8          = bcma_host_soc_read8,
 148        .read16         = bcma_host_soc_read16,
 149        .read32         = bcma_host_soc_read32,
 150        .write8         = bcma_host_soc_write8,
 151        .write16        = bcma_host_soc_write16,
 152        .write32        = bcma_host_soc_write32,
 153#ifdef CONFIG_BCMA_BLOCKIO
 154        .block_read     = bcma_host_soc_block_read,
 155        .block_write    = bcma_host_soc_block_write,
 156#endif
 157        .aread32        = bcma_host_soc_aread32,
 158        .awrite32       = bcma_host_soc_awrite32,
 159};
 160
 161int __init bcma_host_soc_register(struct bcma_soc *soc)
 162{
 163        struct bcma_bus *bus = &soc->bus;
 164        int err;
 165
 166        /* iomap only first core. We have to read some register on this core
 167         * to scan the bus.
 168         */
 169        bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
 170        if (!bus->mmio)
 171                return -ENOMEM;
 172
 173        /* Host specific */
 174        bus->hosttype = BCMA_HOSTTYPE_SOC;
 175        bus->ops = &bcma_host_soc_ops;
 176
 177        /* Register */
 178        err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
 179        if (err)
 180                iounmap(bus->mmio);
 181
 182        return err;
 183}
 184
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.