diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-01-28 14:43:00 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-01-28 14:43:00 -0500 |
commit | 4205e6ef4ee747aa81930537b6035086ba5f1e28 (patch) | |
tree | b2ebe2b4621f5f531f283cb9bf0005cd3c04ca7b /drivers/bcma | |
parent | cef401de7be8c4e155c6746bfccf721a4fa5fab9 (diff) | |
parent | 9ebea3829fac7505e0cd2642fbd13cfa9c038831 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/bcma_private.h | 2 | ||||
-rw-r--r-- | drivers/bcma/driver_chipcommon.c | 2 | ||||
-rw-r--r-- | drivers/bcma/driver_mips.c | 157 | ||||
-rw-r--r-- | drivers/bcma/driver_pci_host.c | 62 | ||||
-rw-r--r-- | drivers/bcma/main.c | 4 |
5 files changed, 155 insertions, 72 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 19e3fbfd5757..04f7c86ea3d8 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -31,6 +31,8 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, | |||
31 | int bcma_bus_suspend(struct bcma_bus *bus); | 31 | int bcma_bus_suspend(struct bcma_bus *bus); |
32 | int bcma_bus_resume(struct bcma_bus *bus); | 32 | int bcma_bus_resume(struct bcma_bus *bus); |
33 | #endif | 33 | #endif |
34 | struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, | ||
35 | u8 unit); | ||
34 | 36 | ||
35 | /* scan.c */ | 37 | /* scan.c */ |
36 | int bcma_bus_scan(struct bcma_bus *bus); | 38 | int bcma_bus_scan(struct bcma_bus *bus); |
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index e461ad25fda4..28fa50ad87be 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c | |||
@@ -329,7 +329,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) | |||
329 | return; | 329 | return; |
330 | } | 330 | } |
331 | 331 | ||
332 | irq = bcma_core_mips_irq(cc->core); | 332 | irq = bcma_core_irq(cc->core); |
333 | 333 | ||
334 | /* Determine the registers of the UARTs */ | 334 | /* Determine the registers of the UARTs */ |
335 | cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); | 335 | cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); |
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 792daad28cbc..9fe86ee16c66 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
@@ -74,28 +74,41 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev) | |||
74 | return dev->core_index; | 74 | return dev->core_index; |
75 | flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); | 75 | flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); |
76 | 76 | ||
77 | return flag & 0x1F; | 77 | if (flag) |
78 | return flag & 0x1F; | ||
79 | else | ||
80 | return 0x3f; | ||
78 | } | 81 | } |
79 | 82 | ||
80 | /* Get the MIPS IRQ assignment for a specified device. | 83 | /* Get the MIPS IRQ assignment for a specified device. |
81 | * If unassigned, 0 is returned. | 84 | * If unassigned, 0 is returned. |
85 | * If disabled, 5 is returned. | ||
86 | * If not supported, 6 is returned. | ||
82 | */ | 87 | */ |
83 | unsigned int bcma_core_mips_irq(struct bcma_device *dev) | 88 | static unsigned int bcma_core_mips_irq(struct bcma_device *dev) |
84 | { | 89 | { |
85 | struct bcma_device *mdev = dev->bus->drv_mips.core; | 90 | struct bcma_device *mdev = dev->bus->drv_mips.core; |
86 | u32 irqflag; | 91 | u32 irqflag; |
87 | unsigned int irq; | 92 | unsigned int irq; |
88 | 93 | ||
89 | irqflag = bcma_core_mips_irqflag(dev); | 94 | irqflag = bcma_core_mips_irqflag(dev); |
95 | if (irqflag == 0x3f) | ||
96 | return 6; | ||
90 | 97 | ||
91 | for (irq = 1; irq <= 4; irq++) | 98 | for (irq = 0; irq <= 4; irq++) |
92 | if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) & | 99 | if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) & |
93 | (1 << irqflag)) | 100 | (1 << irqflag)) |
94 | return irq; | 101 | return irq; |
95 | 102 | ||
96 | return 0; | 103 | return 5; |
104 | } | ||
105 | |||
106 | unsigned int bcma_core_irq(struct bcma_device *dev) | ||
107 | { | ||
108 | unsigned int mips_irq = bcma_core_mips_irq(dev); | ||
109 | return mips_irq <= 4 ? mips_irq + 2 : 0; | ||
97 | } | 110 | } |
98 | EXPORT_SYMBOL(bcma_core_mips_irq); | 111 | EXPORT_SYMBOL(bcma_core_irq); |
99 | 112 | ||
100 | static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | 113 | static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) |
101 | { | 114 | { |
@@ -114,7 +127,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | |||
114 | bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), | 127 | bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), |
115 | bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) & | 128 | bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) & |
116 | ~(1 << irqflag)); | 129 | ~(1 << irqflag)); |
117 | else | 130 | else if (oldirq != 5) |
118 | bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0); | 131 | bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0); |
119 | 132 | ||
120 | /* assign the new one */ | 133 | /* assign the new one */ |
@@ -123,9 +136,9 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | |||
123 | bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | | 136 | bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | |
124 | (1 << irqflag)); | 137 | (1 << irqflag)); |
125 | } else { | 138 | } else { |
126 | u32 oldirqflag = bcma_read32(mdev, | 139 | u32 irqinitmask = bcma_read32(mdev, |
127 | BCMA_MIPS_MIPS74K_INTMASK(irq)); | 140 | BCMA_MIPS_MIPS74K_INTMASK(irq)); |
128 | if (oldirqflag) { | 141 | if (irqinitmask) { |
129 | struct bcma_device *core; | 142 | struct bcma_device *core; |
130 | 143 | ||
131 | /* backplane irq line is in use, find out who uses | 144 | /* backplane irq line is in use, find out who uses |
@@ -133,7 +146,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | |||
133 | */ | 146 | */ |
134 | list_for_each_entry(core, &bus->cores, list) { | 147 | list_for_each_entry(core, &bus->cores, list) { |
135 | if ((1 << bcma_core_mips_irqflag(core)) == | 148 | if ((1 << bcma_core_mips_irqflag(core)) == |
136 | oldirqflag) { | 149 | irqinitmask) { |
137 | bcma_core_mips_set_irq(core, 0); | 150 | bcma_core_mips_set_irq(core, 0); |
138 | break; | 151 | break; |
139 | } | 152 | } |
@@ -143,15 +156,31 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | |||
143 | 1 << irqflag); | 156 | 1 << irqflag); |
144 | } | 157 | } |
145 | 158 | ||
146 | bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n", | 159 | bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n", |
147 | dev->id.id, oldirq + 2, irq + 2); | 160 | dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2); |
161 | } | ||
162 | |||
163 | static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq, | ||
164 | u16 coreid, u8 unit) | ||
165 | { | ||
166 | struct bcma_device *core; | ||
167 | |||
168 | core = bcma_find_core_unit(bus, coreid, unit); | ||
169 | if (!core) { | ||
170 | bcma_warn(bus, | ||
171 | "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n", | ||
172 | coreid, unit); | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | bcma_core_mips_set_irq(core, irq); | ||
148 | } | 177 | } |
149 | 178 | ||
150 | static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq) | 179 | static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq) |
151 | { | 180 | { |
152 | int i; | 181 | int i; |
153 | static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; | 182 | static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; |
154 | printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); | 183 | printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); |
155 | for (i = 0; i <= 6; i++) | 184 | for (i = 0; i <= 6; i++) |
156 | printk(" %s%s", irq_name[i], i == irq ? "*" : " "); | 185 | printk(" %s%s", irq_name[i], i == irq ? "*" : " "); |
157 | printk("\n"); | 186 | printk("\n"); |
@@ -227,6 +256,32 @@ void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) | |||
227 | mcore->early_setup_done = true; | 256 | mcore->early_setup_done = true; |
228 | } | 257 | } |
229 | 258 | ||
259 | static void bcma_fix_i2s_irqflag(struct bcma_bus *bus) | ||
260 | { | ||
261 | struct bcma_device *cpu, *pcie, *i2s; | ||
262 | |||
263 | /* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK) | ||
264 | * (IRQ flags > 7 are ignored when setting the interrupt masks) | ||
265 | */ | ||
266 | if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 && | ||
267 | bus->chipinfo.id != BCMA_CHIP_ID_BCM4748) | ||
268 | return; | ||
269 | |||
270 | cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K); | ||
271 | pcie = bcma_find_core(bus, BCMA_CORE_PCIE); | ||
272 | i2s = bcma_find_core(bus, BCMA_CORE_I2S); | ||
273 | if (cpu && pcie && i2s && | ||
274 | bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 && | ||
275 | bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 && | ||
276 | bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) { | ||
277 | bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504); | ||
278 | bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504); | ||
279 | bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87); | ||
280 | bcma_debug(bus, | ||
281 | "Moved i2s interrupt to oob line 7 instead of 8\n"); | ||
282 | } | ||
283 | } | ||
284 | |||
230 | void bcma_core_mips_init(struct bcma_drv_mips *mcore) | 285 | void bcma_core_mips_init(struct bcma_drv_mips *mcore) |
231 | { | 286 | { |
232 | struct bcma_bus *bus; | 287 | struct bcma_bus *bus; |
@@ -236,43 +291,55 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) | |||
236 | if (mcore->setup_done) | 291 | if (mcore->setup_done) |
237 | return; | 292 | return; |
238 | 293 | ||
239 | bcma_info(bus, "Initializing MIPS core...\n"); | 294 | bcma_debug(bus, "Initializing MIPS core...\n"); |
240 | 295 | ||
241 | bcma_core_mips_early_init(mcore); | 296 | bcma_core_mips_early_init(mcore); |
242 | 297 | ||
243 | mcore->assigned_irqs = 1; | 298 | bcma_fix_i2s_irqflag(bus); |
244 | 299 | ||
245 | /* Assign IRQs to all cores on the bus */ | 300 | switch (bus->chipinfo.id) { |
246 | list_for_each_entry(core, &bus->cores, list) { | 301 | case BCMA_CHIP_ID_BCM4716: |
247 | int mips_irq; | 302 | case BCMA_CHIP_ID_BCM4748: |
248 | if (core->irq) | 303 | bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); |
249 | continue; | 304 | bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); |
250 | 305 | bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0); | |
251 | mips_irq = bcma_core_mips_irq(core); | 306 | bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0); |
252 | if (mips_irq > 4) | 307 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); |
253 | core->irq = 0; | 308 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0); |
254 | else | 309 | break; |
255 | core->irq = mips_irq + 2; | 310 | case BCMA_CHIP_ID_BCM5356: |
256 | if (core->irq > 5) | 311 | case BCMA_CHIP_ID_BCM47162: |
257 | continue; | 312 | case BCMA_CHIP_ID_BCM53572: |
258 | switch (core->id.id) { | 313 | bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); |
259 | case BCMA_CORE_PCI: | 314 | bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); |
260 | case BCMA_CORE_PCIE: | 315 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); |
261 | case BCMA_CORE_ETHERNET: | 316 | break; |
262 | case BCMA_CORE_ETHERNET_GBIT: | 317 | case BCMA_CHIP_ID_BCM5357: |
263 | case BCMA_CORE_MAC_GBIT: | 318 | case BCMA_CHIP_ID_BCM4749: |
264 | case BCMA_CORE_80211: | 319 | bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); |
265 | case BCMA_CORE_USB20_HOST: | 320 | bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); |
266 | /* These devices get their own IRQ line if available, | 321 | bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0); |
267 | * the rest goes on IRQ0 | 322 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); |
268 | */ | 323 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0); |
269 | if (mcore->assigned_irqs <= 4) | 324 | break; |
270 | bcma_core_mips_set_irq(core, | 325 | case BCMA_CHIP_ID_BCM4706: |
271 | mcore->assigned_irqs++); | 326 | bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0); |
272 | break; | 327 | bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT, |
328 | 0); | ||
329 | bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1); | ||
330 | bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0); | ||
331 | bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON, | ||
332 | 0); | ||
333 | break; | ||
334 | default: | ||
335 | list_for_each_entry(core, &bus->cores, list) { | ||
336 | core->irq = bcma_core_irq(core); | ||
273 | } | 337 | } |
338 | bcma_err(bus, | ||
339 | "Unknown device (0x%x) found, can not configure IRQs\n", | ||
340 | bus->chipinfo.id); | ||
274 | } | 341 | } |
275 | bcma_info(bus, "IRQ reconfiguration done\n"); | 342 | bcma_debug(bus, "IRQ reconfiguration done\n"); |
276 | bcma_core_mips_dump_irq(bus); | 343 | bcma_core_mips_dump_irq(bus); |
277 | 344 | ||
278 | mcore->setup_done = true; | 345 | mcore->setup_done = true; |
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index af0c9fabee54..d3bde6cec927 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c | |||
@@ -94,19 +94,19 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
94 | if (dev == 0) { | 94 | if (dev == 0) { |
95 | /* we support only two functions on device 0 */ | 95 | /* we support only two functions on device 0 */ |
96 | if (func > 1) | 96 | if (func > 1) |
97 | return -EINVAL; | 97 | goto out; |
98 | 98 | ||
99 | /* accesses to config registers with offsets >= 256 | 99 | /* accesses to config registers with offsets >= 256 |
100 | * requires indirect access. | 100 | * requires indirect access. |
101 | */ | 101 | */ |
102 | if (off >= PCI_CONFIG_SPACE_SIZE) { | 102 | if (off >= PCI_CONFIG_SPACE_SIZE) { |
103 | addr = (func << 12); | 103 | addr = (func << 12); |
104 | addr |= (off & 0x0FFF); | 104 | addr |= (off & 0x0FFC); |
105 | val = bcma_pcie_read_config(pc, addr); | 105 | val = bcma_pcie_read_config(pc, addr); |
106 | } else { | 106 | } else { |
107 | addr = BCMA_CORE_PCI_PCICFG0; | 107 | addr = BCMA_CORE_PCI_PCICFG0; |
108 | addr |= (func << 8); | 108 | addr |= (func << 8); |
109 | addr |= (off & 0xfc); | 109 | addr |= (off & 0xFC); |
110 | val = pcicore_read32(pc, addr); | 110 | val = pcicore_read32(pc, addr); |
111 | } | 111 | } |
112 | } else { | 112 | } else { |
@@ -119,11 +119,9 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
119 | goto out; | 119 | goto out; |
120 | 120 | ||
121 | if (mips_busprobe32(val, mmio)) { | 121 | if (mips_busprobe32(val, mmio)) { |
122 | val = 0xffffffff; | 122 | val = 0xFFFFFFFF; |
123 | goto unmap; | 123 | goto unmap; |
124 | } | 124 | } |
125 | |||
126 | val = readl(mmio); | ||
127 | } | 125 | } |
128 | val >>= (8 * (off & 3)); | 126 | val >>= (8 * (off & 3)); |
129 | 127 | ||
@@ -151,7 +149,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
151 | const void *buf, int len) | 149 | const void *buf, int len) |
152 | { | 150 | { |
153 | int err = -EINVAL; | 151 | int err = -EINVAL; |
154 | u32 addr = 0, val = 0; | 152 | u32 addr, val; |
155 | void __iomem *mmio = 0; | 153 | void __iomem *mmio = 0; |
156 | u16 chipid = pc->core->bus->chipinfo.id; | 154 | u16 chipid = pc->core->bus->chipinfo.id; |
157 | 155 | ||
@@ -159,16 +157,22 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
159 | if (unlikely(len != 1 && len != 2 && len != 4)) | 157 | if (unlikely(len != 1 && len != 2 && len != 4)) |
160 | goto out; | 158 | goto out; |
161 | if (dev == 0) { | 159 | if (dev == 0) { |
160 | /* we support only two functions on device 0 */ | ||
161 | if (func > 1) | ||
162 | goto out; | ||
163 | |||
162 | /* accesses to config registers with offsets >= 256 | 164 | /* accesses to config registers with offsets >= 256 |
163 | * requires indirect access. | 165 | * requires indirect access. |
164 | */ | 166 | */ |
165 | if (off < PCI_CONFIG_SPACE_SIZE) { | 167 | if (off >= PCI_CONFIG_SPACE_SIZE) { |
166 | addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; | 168 | addr = (func << 12); |
169 | addr |= (off & 0x0FFC); | ||
170 | val = bcma_pcie_read_config(pc, addr); | ||
171 | } else { | ||
172 | addr = BCMA_CORE_PCI_PCICFG0; | ||
167 | addr |= (func << 8); | 173 | addr |= (func << 8); |
168 | addr |= (off & 0xfc); | 174 | addr |= (off & 0xFC); |
169 | mmio = ioremap_nocache(addr, sizeof(val)); | 175 | val = pcicore_read32(pc, addr); |
170 | if (!mmio) | ||
171 | goto out; | ||
172 | } | 176 | } |
173 | } else { | 177 | } else { |
174 | addr = bcma_get_cfgspace_addr(pc, dev, func, off); | 178 | addr = bcma_get_cfgspace_addr(pc, dev, func, off); |
@@ -180,19 +184,17 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
180 | goto out; | 184 | goto out; |
181 | 185 | ||
182 | if (mips_busprobe32(val, mmio)) { | 186 | if (mips_busprobe32(val, mmio)) { |
183 | val = 0xffffffff; | 187 | val = 0xFFFFFFFF; |
184 | goto unmap; | 188 | goto unmap; |
185 | } | 189 | } |
186 | } | 190 | } |
187 | 191 | ||
188 | switch (len) { | 192 | switch (len) { |
189 | case 1: | 193 | case 1: |
190 | val = readl(mmio); | ||
191 | val &= ~(0xFF << (8 * (off & 3))); | 194 | val &= ~(0xFF << (8 * (off & 3))); |
192 | val |= *((const u8 *)buf) << (8 * (off & 3)); | 195 | val |= *((const u8 *)buf) << (8 * (off & 3)); |
193 | break; | 196 | break; |
194 | case 2: | 197 | case 2: |
195 | val = readl(mmio); | ||
196 | val &= ~(0xFFFF << (8 * (off & 3))); | 198 | val &= ~(0xFFFF << (8 * (off & 3))); |
197 | val |= *((const u16 *)buf) << (8 * (off & 3)); | 199 | val |= *((const u16 *)buf) << (8 * (off & 3)); |
198 | break; | 200 | break; |
@@ -200,13 +202,14 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, | |||
200 | val = *((const u32 *)buf); | 202 | val = *((const u32 *)buf); |
201 | break; | 203 | break; |
202 | } | 204 | } |
203 | if (dev == 0 && !addr) { | 205 | if (dev == 0) { |
204 | /* accesses to config registers with offsets >= 256 | 206 | /* accesses to config registers with offsets >= 256 |
205 | * requires indirect access. | 207 | * requires indirect access. |
206 | */ | 208 | */ |
207 | addr = (func << 12); | 209 | if (off >= PCI_CONFIG_SPACE_SIZE) |
208 | addr |= (off & 0x0FFF); | 210 | bcma_pcie_write_config(pc, addr, val); |
209 | bcma_pcie_write_config(pc, addr, val); | 211 | else |
212 | pcicore_write32(pc, addr, val); | ||
210 | } else { | 213 | } else { |
211 | writel(val, mmio); | 214 | writel(val, mmio); |
212 | 215 | ||
@@ -276,7 +279,7 @@ static u8 bcma_find_pci_capability(struct bcma_drv_pci *pc, unsigned int dev, | |||
276 | /* check for Header type 0 */ | 279 | /* check for Header type 0 */ |
277 | bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, | 280 | bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, |
278 | sizeof(u8)); | 281 | sizeof(u8)); |
279 | if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) | 282 | if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL) |
280 | return cap_ptr; | 283 | return cap_ptr; |
281 | 284 | ||
282 | /* check if the capability pointer field exists */ | 285 | /* check if the capability pointer field exists */ |
@@ -426,7 +429,7 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) | |||
426 | /* Reset RC */ | 429 | /* Reset RC */ |
427 | usleep_range(3000, 5000); | 430 | usleep_range(3000, 5000); |
428 | pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); | 431 | pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); |
429 | usleep_range(1000, 2000); | 432 | msleep(50); |
430 | pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | | 433 | pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | |
431 | BCMA_CORE_PCI_CTL_RST_OE); | 434 | BCMA_CORE_PCI_CTL_RST_OE); |
432 | 435 | ||
@@ -488,6 +491,17 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) | |||
488 | 491 | ||
489 | bcma_core_pci_enable_crs(pc); | 492 | bcma_core_pci_enable_crs(pc); |
490 | 493 | ||
494 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 || | ||
495 | bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) { | ||
496 | u16 val16; | ||
497 | bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL, | ||
498 | &val16, sizeof(val16)); | ||
499 | val16 |= (2 << 5); /* Max payload size of 512 */ | ||
500 | val16 |= (2 << 12); /* MRRS 512 */ | ||
501 | bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL, | ||
502 | &val16, sizeof(val16)); | ||
503 | } | ||
504 | |||
491 | /* Enable PCI bridge BAR0 memory & master access */ | 505 | /* Enable PCI bridge BAR0 memory & master access */ |
492 | tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; | 506 | tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; |
493 | bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); | 507 | bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); |
@@ -576,7 +590,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev) | |||
576 | pr_info("PCI: Fixing up device %s\n", pci_name(dev)); | 590 | pr_info("PCI: Fixing up device %s\n", pci_name(dev)); |
577 | 591 | ||
578 | /* Fix up interrupt lines */ | 592 | /* Fix up interrupt lines */ |
579 | dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2; | 593 | dev->irq = bcma_core_irq(pc_host->pdev->core); |
580 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | 594 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); |
581 | 595 | ||
582 | return 0; | 596 | return 0; |
@@ -595,6 +609,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) | |||
595 | 609 | ||
596 | pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, | 610 | pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, |
597 | pci_ops); | 611 | pci_ops); |
598 | return bcma_core_mips_irq(pc_host->pdev->core) + 2; | 612 | return bcma_core_irq(pc_host->pdev->core); |
599 | } | 613 | } |
600 | EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); | 614 | EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 4a92f647b58b..ff8528925322 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -81,8 +81,8 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | |||
81 | } | 81 | } |
82 | EXPORT_SYMBOL_GPL(bcma_find_core); | 82 | EXPORT_SYMBOL_GPL(bcma_find_core); |
83 | 83 | ||
84 | static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, | 84 | struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, |
85 | u8 unit) | 85 | u8 unit) |
86 | { | 86 | { |
87 | struct bcma_device *core; | 87 | struct bcma_device *core; |
88 | 88 | ||