Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc3 183 lines 3.7 kB view raw
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}