aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/pci.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-04-02 13:46:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 16:44:40 -0400
commitd625a29ba649a4df6027520ffc378f23c0e6883e (patch)
tree07b895d38717e24e655948c963f4287f551df42f /drivers/ssb/pci.c
parent93af2614513103216038afa708718295e7016dbb (diff)
ssb: Add support for block-I/O
This adds support for block based I/O to SSB. This is needed in order to efficiently support PIO data transfers to the card. The block-I/O support is only compiled, if it's selected by the weird driver that needs it. So there's no overhead for sane devices. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r--drivers/ssb/pci.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index f1514b33cfae..904b1a8d0885 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -613,6 +613,41 @@ static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
613 return ioread32(bus->mmio + offset); 613 return ioread32(bus->mmio + offset);
614} 614}
615 615
616#ifdef CONFIG_SSB_BLOCKIO
617static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
618 size_t count, u16 offset, u8 reg_width)
619{
620 struct ssb_bus *bus = dev->bus;
621 void __iomem *addr = bus->mmio + offset;
622
623 if (unlikely(ssb_pci_assert_buspower(bus)))
624 goto error;
625 if (unlikely(bus->mapped_device != dev)) {
626 if (unlikely(ssb_pci_switch_core(bus, dev)))
627 goto error;
628 }
629 switch (reg_width) {
630 case sizeof(u8):
631 ioread8_rep(addr, buffer, count);
632 break;
633 case sizeof(u16):
634 SSB_WARN_ON(count & 1);
635 ioread16_rep(addr, buffer, count >> 1);
636 break;
637 case sizeof(u32):
638 SSB_WARN_ON(count & 3);
639 ioread32_rep(addr, buffer, count >> 2);
640 break;
641 default:
642 SSB_WARN_ON(1);
643 }
644
645 return;
646error:
647 memset(buffer, 0xFF, count);
648}
649#endif /* CONFIG_SSB_BLOCKIO */
650
616static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value) 651static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
617{ 652{
618 struct ssb_bus *bus = dev->bus; 653 struct ssb_bus *bus = dev->bus;
@@ -652,6 +687,37 @@ static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
652 iowrite32(value, bus->mmio + offset); 687 iowrite32(value, bus->mmio + offset);
653} 688}
654 689
690#ifdef CONFIG_SSB_BLOCKIO
691static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
692 size_t count, u16 offset, u8 reg_width)
693{
694 struct ssb_bus *bus = dev->bus;
695 void __iomem *addr = bus->mmio + offset;
696
697 if (unlikely(ssb_pci_assert_buspower(bus)))
698 return;
699 if (unlikely(bus->mapped_device != dev)) {
700 if (unlikely(ssb_pci_switch_core(bus, dev)))
701 return;
702 }
703 switch (reg_width) {
704 case sizeof(u8):
705 iowrite8_rep(addr, buffer, count);
706 break;
707 case sizeof(u16):
708 SSB_WARN_ON(count & 1);
709 iowrite16_rep(addr, buffer, count >> 1);
710 break;
711 case sizeof(u32):
712 SSB_WARN_ON(count & 3);
713 iowrite32_rep(addr, buffer, count >> 2);
714 break;
715 default:
716 SSB_WARN_ON(1);
717 }
718}
719#endif /* CONFIG_SSB_BLOCKIO */
720
655/* Not "static", as it's used in main.c */ 721/* Not "static", as it's used in main.c */
656const struct ssb_bus_ops ssb_pci_ops = { 722const struct ssb_bus_ops ssb_pci_ops = {
657 .read8 = ssb_pci_read8, 723 .read8 = ssb_pci_read8,
@@ -660,6 +726,10 @@ const struct ssb_bus_ops ssb_pci_ops = {
660 .write8 = ssb_pci_write8, 726 .write8 = ssb_pci_write8,
661 .write16 = ssb_pci_write16, 727 .write16 = ssb_pci_write16,
662 .write32 = ssb_pci_write32, 728 .write32 = ssb_pci_write32,
729#ifdef CONFIG_SSB_BLOCKIO
730 .block_read = ssb_pci_block_read,
731 .block_write = ssb_pci_block_write,
732#endif
663}; 733};
664 734
665static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev, 735static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,