aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-02-20 13:08:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:37:26 -0500
commitffc7689ddae5cbe12bde437ae0f2b386d568b5cd (patch)
tree638e7dcf083c88cf45763953aa244504d357a220 /drivers/ssb
parent004c872e78d433f84f0a5cd4db7a6c780c0946e1 (diff)
ssb: Add support for 8bit register access
This adds support for 8bit wide register reads/writes. This is needed in order to support the gigabit ethernet core. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/main.c18
-rw-r--r--drivers/ssb/pci.c28
-rw-r--r--drivers/ssb/pcmcia.c32
3 files changed, 78 insertions, 0 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index bedb2b4ee9d2..8db40c4b86e9 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -505,6 +505,14 @@ error:
505 return err; 505 return err;
506} 506}
507 507
508static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
509{
510 struct ssb_bus *bus = dev->bus;
511
512 offset += dev->core_index * SSB_CORE_SIZE;
513 return readb(bus->mmio + offset);
514}
515
508static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) 516static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
509{ 517{
510 struct ssb_bus *bus = dev->bus; 518 struct ssb_bus *bus = dev->bus;
@@ -521,6 +529,14 @@ static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
521 return readl(bus->mmio + offset); 529 return readl(bus->mmio + offset);
522} 530}
523 531
532static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
533{
534 struct ssb_bus *bus = dev->bus;
535
536 offset += dev->core_index * SSB_CORE_SIZE;
537 writeb(value, bus->mmio + offset);
538}
539
524static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) 540static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
525{ 541{
526 struct ssb_bus *bus = dev->bus; 542 struct ssb_bus *bus = dev->bus;
@@ -539,8 +555,10 @@ static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
539 555
540/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ 556/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
541static const struct ssb_bus_ops ssb_ssb_ops = { 557static const struct ssb_bus_ops ssb_ssb_ops = {
558 .read8 = ssb_ssb_read8,
542 .read16 = ssb_ssb_read16, 559 .read16 = ssb_ssb_read16,
543 .read32 = ssb_ssb_read32, 560 .read32 = ssb_ssb_read32,
561 .write8 = ssb_ssb_write8,
544 .write16 = ssb_ssb_write16, 562 .write16 = ssb_ssb_write16,
545 .write32 = ssb_ssb_write32, 563 .write32 = ssb_ssb_write32,
546}; 564};
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index b434df75047f..1facc7620fc8 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -572,6 +572,19 @@ static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
572} 572}
573#endif /* DEBUG */ 573#endif /* DEBUG */
574 574
575static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
576{
577 struct ssb_bus *bus = dev->bus;
578
579 if (unlikely(ssb_pci_assert_buspower(bus)))
580 return 0xFF;
581 if (unlikely(bus->mapped_device != dev)) {
582 if (unlikely(ssb_pci_switch_core(bus, dev)))
583 return 0xFF;
584 }
585 return ioread8(bus->mmio + offset);
586}
587
575static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) 588static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
576{ 589{
577 struct ssb_bus *bus = dev->bus; 590 struct ssb_bus *bus = dev->bus;
@@ -598,6 +611,19 @@ static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
598 return ioread32(bus->mmio + offset); 611 return ioread32(bus->mmio + offset);
599} 612}
600 613
614static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
615{
616 struct ssb_bus *bus = dev->bus;
617
618 if (unlikely(ssb_pci_assert_buspower(bus)))
619 return;
620 if (unlikely(bus->mapped_device != dev)) {
621 if (unlikely(ssb_pci_switch_core(bus, dev)))
622 return;
623 }
624 iowrite8(value, bus->mmio + offset);
625}
626
601static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) 627static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
602{ 628{
603 struct ssb_bus *bus = dev->bus; 629 struct ssb_bus *bus = dev->bus;
@@ -626,8 +652,10 @@ static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
626 652
627/* Not "static", as it's used in main.c */ 653/* Not "static", as it's used in main.c */
628const struct ssb_bus_ops ssb_pci_ops = { 654const struct ssb_bus_ops ssb_pci_ops = {
655 .read8 = ssb_pci_read8,
629 .read16 = ssb_pci_read16, 656 .read16 = ssb_pci_read16,
630 .read32 = ssb_pci_read32, 657 .read32 = ssb_pci_read32,
658 .write8 = ssb_pci_write8,
631 .write16 = ssb_pci_write16, 659 .write16 = ssb_pci_write16,
632 .write32 = ssb_pci_write32, 660 .write32 = ssb_pci_write32,
633}; 661};
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index 46816cda8b98..84b3a845a8a8 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -172,6 +172,22 @@ static int select_core_and_segment(struct ssb_device *dev,
172 return 0; 172 return 0;
173} 173}
174 174
175static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
176{
177 struct ssb_bus *bus = dev->bus;
178 unsigned long flags;
179 int err;
180 u8 value = 0xFF;
181
182 spin_lock_irqsave(&bus->bar_lock, flags);
183 err = select_core_and_segment(dev, &offset);
184 if (likely(!err))
185 value = readb(bus->mmio + offset);
186 spin_unlock_irqrestore(&bus->bar_lock, flags);
187
188 return value;
189}
190
175static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) 191static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
176{ 192{
177 struct ssb_bus *bus = dev->bus; 193 struct ssb_bus *bus = dev->bus;
@@ -206,6 +222,20 @@ static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
206 return (lo | (hi << 16)); 222 return (lo | (hi << 16));
207} 223}
208 224
225static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
226{
227 struct ssb_bus *bus = dev->bus;
228 unsigned long flags;
229 int err;
230
231 spin_lock_irqsave(&bus->bar_lock, flags);
232 err = select_core_and_segment(dev, &offset);
233 if (likely(!err))
234 writeb(value, bus->mmio + offset);
235 mmiowb();
236 spin_unlock_irqrestore(&bus->bar_lock, flags);
237}
238
209static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) 239static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
210{ 240{
211 struct ssb_bus *bus = dev->bus; 241 struct ssb_bus *bus = dev->bus;
@@ -238,8 +268,10 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
238 268
239/* Not "static", as it's used in main.c */ 269/* Not "static", as it's used in main.c */
240const struct ssb_bus_ops ssb_pcmcia_ops = { 270const struct ssb_bus_ops ssb_pcmcia_ops = {
271 .read8 = ssb_pcmcia_read8,
241 .read16 = ssb_pcmcia_read16, 272 .read16 = ssb_pcmcia_read16,
242 .read32 = ssb_pcmcia_read32, 273 .read32 = ssb_pcmcia_read32,
274 .write8 = ssb_pcmcia_write8,
243 .write16 = ssb_pcmcia_write16, 275 .write16 = ssb_pcmcia_write16,
244 .write32 = ssb_pcmcia_write32, 276 .write32 = ssb_pcmcia_write32,
245}; 277};