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.c260
1 files changed, 207 insertions, 53 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 72017bf2e577..6ce92e82b64e 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)
@@ -81,35 +120,12 @@ static void ssb_device_put(struct ssb_device *dev)
81 put_device(dev->dev); 120 put_device(dev->dev);
82} 121}
83 122
84static int ssb_bus_resume(struct ssb_bus *bus)
85{
86 int err;
87
88 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
89 err = ssb_pcmcia_init(bus);
90 if (err) {
91 /* No need to disable XTAL, as we don't have one on PCMCIA. */
92 return err;
93 }
94 ssb_chipco_resume(&bus->chipco);
95
96 return 0;
97}
98
99static int ssb_device_resume(struct device *dev) 123static int ssb_device_resume(struct device *dev)
100{ 124{
101 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); 125 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
102 struct ssb_driver *ssb_drv; 126 struct ssb_driver *ssb_drv;
103 struct ssb_bus *bus;
104 int err = 0; 127 int err = 0;
105 128
106 bus = ssb_dev->bus;
107 if (bus->suspend_cnt == bus->nr_devices) {
108 err = ssb_bus_resume(bus);
109 if (err)
110 return err;
111 }
112 bus->suspend_cnt--;
113 if (dev->driver) { 129 if (dev->driver) {
114 ssb_drv = drv_to_ssb_drv(dev->driver); 130 ssb_drv = drv_to_ssb_drv(dev->driver);
115 if (ssb_drv && ssb_drv->resume) 131 if (ssb_drv && ssb_drv->resume)
@@ -121,27 +137,10 @@ out:
121 return err; 137 return err;
122} 138}
123 139
124static void ssb_bus_suspend(struct ssb_bus *bus, pm_message_t state)
125{
126 ssb_chipco_suspend(&bus->chipco, state);
127 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
128
129 /* Reset HW state information in memory, so that HW is
130 * completely reinitialized on resume. */
131 bus->mapped_device = NULL;
132#ifdef CONFIG_SSB_DRIVER_PCICORE
133 bus->pcicore.setup_done = 0;
134#endif
135#ifdef CONFIG_SSB_DEBUG
136 bus->powered_up = 0;
137#endif
138}
139
140static int ssb_device_suspend(struct device *dev, pm_message_t state) 140static int ssb_device_suspend(struct device *dev, pm_message_t state)
141{ 141{
142 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); 142 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
143 struct ssb_driver *ssb_drv; 143 struct ssb_driver *ssb_drv;
144 struct ssb_bus *bus;
145 int err = 0; 144 int err = 0;
146 145
147 if (dev->driver) { 146 if (dev->driver) {
@@ -151,19 +150,46 @@ static int ssb_device_suspend(struct device *dev, pm_message_t state)
151 if (err) 150 if (err)
152 goto out; 151 goto out;
153 } 152 }
153out:
154 return err;
155}
156
157int ssb_bus_resume(struct ssb_bus *bus)
158{
159 int err;
160
161 /* Reset HW state information in memory, so that HW is
162 * completely reinitialized. */
163 bus->mapped_device = NULL;
164#ifdef CONFIG_SSB_DRIVER_PCICORE
165 bus->pcicore.setup_done = 0;
166#endif
154 167
155 bus = ssb_dev->bus; 168 err = ssb_bus_powerup(bus, 0);
156 bus->suspend_cnt++; 169 if (err)
157 if (bus->suspend_cnt == bus->nr_devices) { 170 return err;
158 /* All devices suspended. Shutdown the bus. */ 171 err = ssb_pcmcia_hardware_setup(bus);
159 ssb_bus_suspend(bus, state); 172 if (err) {
173 ssb_bus_may_powerdown(bus);
174 return err;
160 } 175 }
176 ssb_chipco_resume(&bus->chipco);
177 ssb_bus_may_powerdown(bus);
161 178
162out: 179 return 0;
163 return err;
164} 180}
181EXPORT_SYMBOL(ssb_bus_resume);
165 182
166#ifdef CONFIG_SSB_PCIHOST 183int ssb_bus_suspend(struct ssb_bus *bus)
184{
185 ssb_chipco_suspend(&bus->chipco);
186 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
187
188 return 0;
189}
190EXPORT_SYMBOL(ssb_bus_suspend);
191
192#ifdef CONFIG_SSB_SPROM
167int ssb_devices_freeze(struct ssb_bus *bus) 193int ssb_devices_freeze(struct ssb_bus *bus)
168{ 194{
169 struct ssb_device *dev; 195 struct ssb_device *dev;
@@ -249,7 +275,7 @@ int ssb_devices_thaw(struct ssb_bus *bus)
249 275
250 return 0; 276 return 0;
251} 277}
252#endif /* CONFIG_SSB_PCIHOST */ 278#endif /* CONFIG_SSB_SPROM */
253 279
254static void ssb_device_shutdown(struct device *dev) 280static void ssb_device_shutdown(struct device *dev)
255{ 281{
@@ -378,7 +404,7 @@ void ssb_bus_unregister(struct ssb_bus *bus)
378 list_del(&bus->list); 404 list_del(&bus->list);
379 ssb_buses_unlock(); 405 ssb_buses_unlock();
380 406
381 /* ssb_pcmcia_exit(bus); */ 407 ssb_pcmcia_exit(bus);
382 ssb_pci_exit(bus); 408 ssb_pci_exit(bus);
383 ssb_iounmap(bus); 409 ssb_iounmap(bus);
384} 410}
@@ -505,6 +531,14 @@ error:
505 return err; 531 return err;
506} 532}
507 533
534static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
535{
536 struct ssb_bus *bus = dev->bus;
537
538 offset += dev->core_index * SSB_CORE_SIZE;
539 return readb(bus->mmio + offset);
540}
541
508static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) 542static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
509{ 543{
510 struct ssb_bus *bus = dev->bus; 544 struct ssb_bus *bus = dev->bus;
@@ -521,6 +555,63 @@ static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
521 return readl(bus->mmio + offset); 555 return readl(bus->mmio + offset);
522} 556}
523 557
558#ifdef CONFIG_SSB_BLOCKIO
559static void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
560 size_t count, u16 offset, u8 reg_width)
561{
562 struct ssb_bus *bus = dev->bus;
563 void __iomem *addr;
564
565 offset += dev->core_index * SSB_CORE_SIZE;
566 addr = bus->mmio + offset;
567
568 switch (reg_width) {
569 case sizeof(u8): {
570 u8 *buf = buffer;
571
572 while (count) {
573 *buf = __raw_readb(addr);
574 buf++;
575 count--;
576 }
577 break;
578 }
579 case sizeof(u16): {
580 __le16 *buf = buffer;
581
582 SSB_WARN_ON(count & 1);
583 while (count) {
584 *buf = (__force __le16)__raw_readw(addr);
585 buf++;
586 count -= 2;
587 }
588 break;
589 }
590 case sizeof(u32): {
591 __le32 *buf = buffer;
592
593 SSB_WARN_ON(count & 3);
594 while (count) {
595 *buf = (__force __le32)__raw_readl(addr);
596 buf++;
597 count -= 4;
598 }
599 break;
600 }
601 default:
602 SSB_WARN_ON(1);
603 }
604}
605#endif /* CONFIG_SSB_BLOCKIO */
606
607static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
608{
609 struct ssb_bus *bus = dev->bus;
610
611 offset += dev->core_index * SSB_CORE_SIZE;
612 writeb(value, bus->mmio + offset);
613}
614
524static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) 615static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
525{ 616{
526 struct ssb_bus *bus = dev->bus; 617 struct ssb_bus *bus = dev->bus;
@@ -537,12 +628,67 @@ static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
537 writel(value, bus->mmio + offset); 628 writel(value, bus->mmio + offset);
538} 629}
539 630
631#ifdef CONFIG_SSB_BLOCKIO
632static void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
633 size_t count, u16 offset, u8 reg_width)
634{
635 struct ssb_bus *bus = dev->bus;
636 void __iomem *addr;
637
638 offset += dev->core_index * SSB_CORE_SIZE;
639 addr = bus->mmio + offset;
640
641 switch (reg_width) {
642 case sizeof(u8): {
643 const u8 *buf = buffer;
644
645 while (count) {
646 __raw_writeb(*buf, addr);
647 buf++;
648 count--;
649 }
650 break;
651 }
652 case sizeof(u16): {
653 const __le16 *buf = buffer;
654
655 SSB_WARN_ON(count & 1);
656 while (count) {
657 __raw_writew((__force u16)(*buf), addr);
658 buf++;
659 count -= 2;
660 }
661 break;
662 }
663 case sizeof(u32): {
664 const __le32 *buf = buffer;
665
666 SSB_WARN_ON(count & 3);
667 while (count) {
668 __raw_writel((__force u32)(*buf), addr);
669 buf++;
670 count -= 4;
671 }
672 break;
673 }
674 default:
675 SSB_WARN_ON(1);
676 }
677}
678#endif /* CONFIG_SSB_BLOCKIO */
679
540/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ 680/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
541static const struct ssb_bus_ops ssb_ssb_ops = { 681static const struct ssb_bus_ops ssb_ssb_ops = {
682 .read8 = ssb_ssb_read8,
542 .read16 = ssb_ssb_read16, 683 .read16 = ssb_ssb_read16,
543 .read32 = ssb_ssb_read32, 684 .read32 = ssb_ssb_read32,
685 .write8 = ssb_ssb_write8,
544 .write16 = ssb_ssb_write16, 686 .write16 = ssb_ssb_write16,
545 .write32 = ssb_ssb_write32, 687 .write32 = ssb_ssb_write32,
688#ifdef CONFIG_SSB_BLOCKIO
689 .block_read = ssb_ssb_block_read,
690 .block_write = ssb_ssb_block_write,
691#endif
546}; 692};
547 693
548static int ssb_fetch_invariants(struct ssb_bus *bus, 694static int ssb_fetch_invariants(struct ssb_bus *bus,
@@ -625,7 +771,7 @@ out:
625err_dequeue: 771err_dequeue:
626 list_del(&bus->list); 772 list_del(&bus->list);
627err_pcmcia_exit: 773err_pcmcia_exit:
628/* ssb_pcmcia_exit(bus); */ 774 ssb_pcmcia_exit(bus);
629err_pci_exit: 775err_pci_exit:
630 ssb_pci_exit(bus); 776 ssb_pci_exit(bus);
631err_unmap: 777err_unmap:
@@ -1007,9 +1153,9 @@ u32 ssb_dma_translation(struct ssb_device *dev)
1007{ 1153{
1008 switch (dev->bus->bustype) { 1154 switch (dev->bus->bustype) {
1009 case SSB_BUSTYPE_SSB: 1155 case SSB_BUSTYPE_SSB:
1156 case SSB_BUSTYPE_PCMCIA:
1010 return 0; 1157 return 0;
1011 case SSB_BUSTYPE_PCI: 1158 case SSB_BUSTYPE_PCI:
1012 case SSB_BUSTYPE_PCMCIA:
1013 return SSB_PCI_DMA; 1159 return SSB_PCI_DMA;
1014 } 1160 }
1015 return 0; 1161 return 0;
@@ -1159,7 +1305,14 @@ static int __init ssb_modinit(void)
1159 err = b43_pci_ssb_bridge_init(); 1305 err = b43_pci_ssb_bridge_init();
1160 if (err) { 1306 if (err) {
1161 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " 1307 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge "
1162 "initialization failed"); 1308 "initialization failed\n");
1309 /* don't fail SSB init because of this */
1310 err = 0;
1311 }
1312 err = ssb_gige_init();
1313 if (err) {
1314 ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet "
1315 "driver initialization failed\n");
1163 /* don't fail SSB init because of this */ 1316 /* don't fail SSB init because of this */
1164 err = 0; 1317 err = 0;
1165 } 1318 }
@@ -1173,6 +1326,7 @@ fs_initcall(ssb_modinit);
1173 1326
1174static void __exit ssb_modexit(void) 1327static void __exit ssb_modexit(void)
1175{ 1328{
1329 ssb_gige_exit();
1176 b43_pci_ssb_bridge_exit(); 1330 b43_pci_ssb_bridge_exit();
1177 bus_unregister(&ssb_bustype); 1331 bus_unregister(&ssb_bustype);
1178} 1332}