diff options
-rw-r--r-- | drivers/bcma/Kconfig | 5 | ||||
-rw-r--r-- | drivers/bcma/host_pci.c | 52 | ||||
-rw-r--r-- | include/linux/bcma/bcma.h | 18 |
3 files changed, 75 insertions, 0 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 353781b5b78b..83e9adf46441 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
@@ -13,6 +13,11 @@ config BCMA | |||
13 | Bus driver for Broadcom specific Advanced Microcontroller Bus | 13 | Bus driver for Broadcom specific Advanced Microcontroller Bus |
14 | Architecture. | 14 | Architecture. |
15 | 15 | ||
16 | # Support for Block-I/O. SELECT this from the driver that needs it. | ||
17 | config BCMA_BLOCKIO | ||
18 | bool | ||
19 | depends on BCMA | ||
20 | |||
16 | config BCMA_HOST_PCI_POSSIBLE | 21 | config BCMA_HOST_PCI_POSSIBLE |
17 | bool | 22 | bool |
18 | depends on BCMA && PCI = y | 23 | depends on BCMA && PCI = y |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index ffd8797faf4f..279bf50f6d8e 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -64,6 +64,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset, | |||
64 | iowrite32(value, core->bus->mmio + offset); | 64 | iowrite32(value, core->bus->mmio + offset); |
65 | } | 65 | } |
66 | 66 | ||
67 | #ifdef CONFIG_BCMA_BLOCKIO | ||
68 | void bcma_host_pci_block_read(struct bcma_device *core, void *buffer, | ||
69 | size_t count, u16 offset, u8 reg_width) | ||
70 | { | ||
71 | void __iomem *addr = core->bus->mmio + offset; | ||
72 | if (core->bus->mapped_core != core) | ||
73 | bcma_host_pci_switch_core(core); | ||
74 | switch (reg_width) { | ||
75 | case sizeof(u8): | ||
76 | ioread8_rep(addr, buffer, count); | ||
77 | break; | ||
78 | case sizeof(u16): | ||
79 | WARN_ON(count & 1); | ||
80 | ioread16_rep(addr, buffer, count >> 1); | ||
81 | break; | ||
82 | case sizeof(u32): | ||
83 | WARN_ON(count & 3); | ||
84 | ioread32_rep(addr, buffer, count >> 2); | ||
85 | break; | ||
86 | default: | ||
87 | WARN_ON(1); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer, | ||
92 | size_t count, u16 offset, u8 reg_width) | ||
93 | { | ||
94 | void __iomem *addr = core->bus->mmio + offset; | ||
95 | if (core->bus->mapped_core != core) | ||
96 | bcma_host_pci_switch_core(core); | ||
97 | switch (reg_width) { | ||
98 | case sizeof(u8): | ||
99 | iowrite8_rep(addr, buffer, count); | ||
100 | break; | ||
101 | case sizeof(u16): | ||
102 | WARN_ON(count & 1); | ||
103 | iowrite16_rep(addr, buffer, count >> 1); | ||
104 | break; | ||
105 | case sizeof(u32): | ||
106 | WARN_ON(count & 3); | ||
107 | iowrite32_rep(addr, buffer, count >> 2); | ||
108 | break; | ||
109 | default: | ||
110 | WARN_ON(1); | ||
111 | } | ||
112 | } | ||
113 | #endif | ||
114 | |||
67 | static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) | 115 | static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) |
68 | { | 116 | { |
69 | if (core->bus->mapped_core != core) | 117 | if (core->bus->mapped_core != core) |
@@ -86,6 +134,10 @@ const struct bcma_host_ops bcma_host_pci_ops = { | |||
86 | .write8 = bcma_host_pci_write8, | 134 | .write8 = bcma_host_pci_write8, |
87 | .write16 = bcma_host_pci_write16, | 135 | .write16 = bcma_host_pci_write16, |
88 | .write32 = bcma_host_pci_write32, | 136 | .write32 = bcma_host_pci_write32, |
137 | #ifdef CONFIG_BCMA_BLOCKIO | ||
138 | .block_read = bcma_host_pci_block_read, | ||
139 | .block_write = bcma_host_pci_block_write, | ||
140 | #endif | ||
89 | .aread32 = bcma_host_pci_aread32, | 141 | .aread32 = bcma_host_pci_aread32, |
90 | .awrite32 = bcma_host_pci_awrite32, | 142 | .awrite32 = bcma_host_pci_awrite32, |
91 | }; | 143 | }; |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 8b0cef9fd692..27a27a79bea3 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -31,6 +31,12 @@ struct bcma_host_ops { | |||
31 | void (*write8)(struct bcma_device *core, u16 offset, u8 value); | 31 | void (*write8)(struct bcma_device *core, u16 offset, u8 value); |
32 | void (*write16)(struct bcma_device *core, u16 offset, u16 value); | 32 | void (*write16)(struct bcma_device *core, u16 offset, u16 value); |
33 | void (*write32)(struct bcma_device *core, u16 offset, u32 value); | 33 | void (*write32)(struct bcma_device *core, u16 offset, u32 value); |
34 | #ifdef CONFIG_BCMA_BLOCKIO | ||
35 | void (*block_read)(struct bcma_device *core, void *buffer, | ||
36 | size_t count, u16 offset, u8 reg_width); | ||
37 | void (*block_write)(struct bcma_device *core, const void *buffer, | ||
38 | size_t count, u16 offset, u8 reg_width); | ||
39 | #endif | ||
34 | /* Agent ops */ | 40 | /* Agent ops */ |
35 | u32 (*aread32)(struct bcma_device *core, u16 offset); | 41 | u32 (*aread32)(struct bcma_device *core, u16 offset); |
36 | void (*awrite32)(struct bcma_device *core, u16 offset, u32 value); | 42 | void (*awrite32)(struct bcma_device *core, u16 offset, u32 value); |
@@ -210,6 +216,18 @@ void bcma_write32(struct bcma_device *core, u16 offset, u32 value) | |||
210 | { | 216 | { |
211 | core->bus->ops->write32(core, offset, value); | 217 | core->bus->ops->write32(core, offset, value); |
212 | } | 218 | } |
219 | #ifdef CONFIG_BCMA_BLOCKIO | ||
220 | extern inline void bcma_block_read(struct bcma_device *core, void *buffer, | ||
221 | size_t count, u16 offset, u8 reg_width) | ||
222 | { | ||
223 | core->bus->ops->block_read(core, buffer, count, offset, reg_width); | ||
224 | } | ||
225 | extern inline void bcma_block_write(struct bcma_device *core, const void *buffer, | ||
226 | size_t count, u16 offset, u8 reg_width) | ||
227 | { | ||
228 | core->bus->ops->block_write(core, buffer, count, offset, reg_width); | ||
229 | } | ||
230 | #endif | ||
213 | extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset) | 231 | extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset) |
214 | { | 232 | { |
215 | return core->bus->ops->aread32(core, offset); | 233 | return core->bus->ops->aread32(core, offset); |