aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb/main.c')
-rw-r--r--drivers/ssb/main.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index bedb2b4ee9d2..e12371916444 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -14,6 +14,7 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/ssb/ssb.h> 15#include <linux/ssb/ssb.h>
16#include <linux/ssb/ssb_regs.h> 16#include <linux/ssb/ssb_regs.h>
17#include <linux/ssb/ssb_driver_gige.h>
17#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
18#include <linux/pci.h> 19#include <linux/pci.h>
19 20
@@ -68,6 +69,44 @@ found:
68} 69}
69#endif /* CONFIG_SSB_PCIHOST */ 70#endif /* CONFIG_SSB_PCIHOST */
70 71
72#ifdef CONFIG_SSB_PCMCIAHOST
73struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev)
74{
75 struct ssb_bus *bus;
76
77 ssb_buses_lock();
78 list_for_each_entry(bus, &buses, list) {
79 if (bus->bustype == SSB_BUSTYPE_PCMCIA &&
80 bus->host_pcmcia == pdev)
81 goto found;
82 }
83 bus = NULL;
84found:
85 ssb_buses_unlock();
86
87 return bus;
88}
89#endif /* CONFIG_SSB_PCMCIAHOST */
90
91int ssb_for_each_bus_call(unsigned long data,
92 int (*func)(struct ssb_bus *bus, unsigned long data))
93{
94 struct ssb_bus *bus;
95 int res;
96
97 ssb_buses_lock();
98 list_for_each_entry(bus, &buses, list) {
99 res = func(bus, data);
100 if (res >= 0) {
101 ssb_buses_unlock();
102 return res;
103 }
104 }
105 ssb_buses_unlock();
106
107 return -ENODEV;
108}
109
71static struct ssb_device *ssb_device_get(struct ssb_device *dev) 110static struct ssb_device *ssb_device_get(struct ssb_device *dev)
72{ 111{
73 if (dev) 112 if (dev)
@@ -378,7 +417,7 @@ void ssb_bus_unregister(struct ssb_bus *bus)
378 list_del(&bus->list); 417 list_del(&bus->list);
379 ssb_buses_unlock(); 418 ssb_buses_unlock();
380 419
381 /* ssb_pcmcia_exit(bus); */ 420 ssb_pcmcia_exit(bus);
382 ssb_pci_exit(bus); 421 ssb_pci_exit(bus);
383 ssb_iounmap(bus); 422 ssb_iounmap(bus);
384} 423}
@@ -505,6 +544,14 @@ error:
505 return err; 544 return err;
506} 545}
507 546
547static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
548{
549 struct ssb_bus *bus = dev->bus;
550
551 offset += dev->core_index * SSB_CORE_SIZE;
552 return readb(bus->mmio + offset);
553}
554
508static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) 555static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
509{ 556{
510 struct ssb_bus *bus = dev->bus; 557 struct ssb_bus *bus = dev->bus;
@@ -521,6 +568,14 @@ static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
521 return readl(bus->mmio + offset); 568 return readl(bus->mmio + offset);
522} 569}
523 570
571static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
572{
573 struct ssb_bus *bus = dev->bus;
574
575 offset += dev->core_index * SSB_CORE_SIZE;
576 writeb(value, bus->mmio + offset);
577}
578
524static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) 579static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
525{ 580{
526 struct ssb_bus *bus = dev->bus; 581 struct ssb_bus *bus = dev->bus;
@@ -539,8 +594,10 @@ static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
539 594
540/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ 595/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
541static const struct ssb_bus_ops ssb_ssb_ops = { 596static const struct ssb_bus_ops ssb_ssb_ops = {
597 .read8 = ssb_ssb_read8,
542 .read16 = ssb_ssb_read16, 598 .read16 = ssb_ssb_read16,
543 .read32 = ssb_ssb_read32, 599 .read32 = ssb_ssb_read32,
600 .write8 = ssb_ssb_write8,
544 .write16 = ssb_ssb_write16, 601 .write16 = ssb_ssb_write16,
545 .write32 = ssb_ssb_write32, 602 .write32 = ssb_ssb_write32,
546}; 603};
@@ -625,7 +682,7 @@ out:
625err_dequeue: 682err_dequeue:
626 list_del(&bus->list); 683 list_del(&bus->list);
627err_pcmcia_exit: 684err_pcmcia_exit:
628/* ssb_pcmcia_exit(bus); */ 685 ssb_pcmcia_exit(bus);
629err_pci_exit: 686err_pci_exit:
630 ssb_pci_exit(bus); 687 ssb_pci_exit(bus);
631err_unmap: 688err_unmap:
@@ -1153,7 +1210,14 @@ static int __init ssb_modinit(void)
1153 err = b43_pci_ssb_bridge_init(); 1210 err = b43_pci_ssb_bridge_init();
1154 if (err) { 1211 if (err) {
1155 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " 1212 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge "
1156 "initialization failed"); 1213 "initialization failed\n");
1214 /* don't fail SSB init because of this */
1215 err = 0;
1216 }
1217 err = ssb_gige_init();
1218 if (err) {
1219 ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet "
1220 "driver initialization failed\n");
1157 /* don't fail SSB init because of this */ 1221 /* don't fail SSB init because of this */
1158 err = 0; 1222 err = 0;
1159 } 1223 }
@@ -1167,6 +1231,7 @@ fs_initcall(ssb_modinit);
1167 1231
1168static void __exit ssb_modexit(void) 1232static void __exit ssb_modexit(void)
1169{ 1233{
1234 ssb_gige_exit();
1170 b43_pci_ssb_bridge_exit(); 1235 b43_pci_ssb_bridge_exit();
1171 bus_unregister(&ssb_bustype); 1236 bus_unregister(&ssb_bustype);
1172} 1237}