Root/drivers/bcma/host_soc.c

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
146const 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

Archive Download this file



interactive