bcma: host pci: implement block R/W operations
authorRafał Miłecki <zajec5@gmail.com>
Fri, 20 May 2011 01:27:06 +0000 (03:27 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 1 Jun 2011 19:12:28 +0000 (15:12 -0400)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/bcma/Kconfig
drivers/bcma/host_pci.c
include/linux/bcma/bcma.h

index 353781b..83e9adf 100644 (file)
@@ -13,6 +13,11 @@ config BCMA
          Bus driver for Broadcom specific Advanced Microcontroller Bus
          Architecture.
 
+# Support for Block-I/O. SELECT this from the driver that needs it.
+config BCMA_BLOCKIO
+       bool
+       depends on BCMA
+
 config BCMA_HOST_PCI_POSSIBLE
        bool
        depends on BCMA && PCI = y
index ffd8797..279bf50 100644 (file)
@@ -64,6 +64,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
        iowrite32(value, core->bus->mmio + offset);
 }
 
+#ifdef CONFIG_BCMA_BLOCKIO
+void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
+                             size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->bus->mmio + offset;
+       if (core->bus->mapped_core != core)
+               bcma_host_pci_switch_core(core);
+       switch (reg_width) {
+       case sizeof(u8):
+               ioread8_rep(addr, buffer, count);
+               break;
+       case sizeof(u16):
+               WARN_ON(count & 1);
+               ioread16_rep(addr, buffer, count >> 1);
+               break;
+       case sizeof(u32):
+               WARN_ON(count & 3);
+               ioread32_rep(addr, buffer, count >> 2);
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+
+void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
+                              size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->bus->mmio + offset;
+       if (core->bus->mapped_core != core)
+               bcma_host_pci_switch_core(core);
+       switch (reg_width) {
+       case sizeof(u8):
+               iowrite8_rep(addr, buffer, count);
+               break;
+       case sizeof(u16):
+               WARN_ON(count & 1);
+               iowrite16_rep(addr, buffer, count >> 1);
+               break;
+       case sizeof(u32):
+               WARN_ON(count & 3);
+               iowrite32_rep(addr, buffer, count >> 2);
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+#endif
+
 static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
 {
        if (core->bus->mapped_core != core)
@@ -86,6 +134,10 @@ const struct bcma_host_ops bcma_host_pci_ops = {
        .write8         = bcma_host_pci_write8,
        .write16        = bcma_host_pci_write16,
        .write32        = bcma_host_pci_write32,
+#ifdef CONFIG_BCMA_BLOCKIO
+       .block_read     = bcma_host_pci_block_read,
+       .block_write    = bcma_host_pci_block_write,
+#endif
        .aread32        = bcma_host_pci_aread32,
        .awrite32       = bcma_host_pci_awrite32,
 };
index 8b0cef9..27a27a7 100644 (file)
@@ -31,6 +31,12 @@ struct bcma_host_ops {
        void (*write8)(struct bcma_device *core, u16 offset, u8 value);
        void (*write16)(struct bcma_device *core, u16 offset, u16 value);
        void (*write32)(struct bcma_device *core, u16 offset, u32 value);
+#ifdef CONFIG_BCMA_BLOCKIO
+       void (*block_read)(struct bcma_device *core, void *buffer,
+                          size_t count, u16 offset, u8 reg_width);
+       void (*block_write)(struct bcma_device *core, const void *buffer,
+                           size_t count, u16 offset, u8 reg_width);
+#endif
        /* Agent ops */
        u32 (*aread32)(struct bcma_device *core, u16 offset);
        void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
@@ -210,6 +216,18 @@ void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
 {
        core->bus->ops->write32(core, offset, value);
 }
+#ifdef CONFIG_BCMA_BLOCKIO
+extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
+                                  size_t count, u16 offset, u8 reg_width)
+{
+       core->bus->ops->block_read(core, buffer, count, offset, reg_width);
+}
+extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
+                                   size_t count, u16 offset, u8 reg_width)
+{
+       core->bus->ops->block_write(core, buffer, count, offset, reg_width);
+}
+#endif
 extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
 {
        return core->bus->ops->aread32(core, offset);