diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-2.6.25/680-ssb-support-8bit-writes.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-2.6.25/680-ssb-support-8bit-writes.patch | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-2.6.25/680-ssb-support-8bit-writes.patch b/target/linux/brcm47xx/patches-2.6.25/680-ssb-support-8bit-writes.patch new file mode 100644 index 0000000..82b64a3 --- /dev/null +++ b/target/linux/brcm47xx/patches-2.6.25/680-ssb-support-8bit-writes.patch @@ -0,0 +1,197 @@ +Add support for 8bit reads/writes to SSB. +Index: linux-2.6.23.16/drivers/ssb/main.c +=================================================================== +--- linux-2.6.23.16.orig/drivers/ssb/main.c 2008-02-20 14:10:07.000000000 +0100 ++++ linux-2.6.23.16/drivers/ssb/main.c 2008-02-20 18:34:48.000000000 +0100 +@@ -507,6 +507,14 @@ error: + return err; + } + ++static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset) ++{ ++ struct ssb_bus *bus = dev->bus; ++ ++ offset += dev->core_index * SSB_CORE_SIZE; ++ return readb(bus->mmio + offset); ++} ++ + static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) + { + struct ssb_bus *bus = dev->bus; +@@ -523,6 +531,14 @@ static u32 ssb_ssb_read32(struct ssb_dev + return readl(bus->mmio + offset); + } + ++static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value) ++{ ++ struct ssb_bus *bus = dev->bus; ++ ++ offset += dev->core_index * SSB_CORE_SIZE; ++ writeb(value, bus->mmio + offset); ++} ++ + static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) + { + struct ssb_bus *bus = dev->bus; +@@ -541,8 +557,10 @@ static void ssb_ssb_write32(struct ssb_d + + /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ + static const struct ssb_bus_ops ssb_ssb_ops = { ++ .read8 = ssb_ssb_read8, + .read16 = ssb_ssb_read16, + .read32 = ssb_ssb_read32, ++ .write8 = ssb_ssb_write8, + .write16 = ssb_ssb_write16, + .write32 = ssb_ssb_write32, + }; +Index: linux-2.6.23.16/drivers/ssb/pci.c +=================================================================== +--- linux-2.6.23.16.orig/drivers/ssb/pci.c 2008-02-20 14:10:03.000000000 +0100 ++++ linux-2.6.23.16/drivers/ssb/pci.c 2008-02-20 14:10:07.000000000 +0100 +@@ -572,6 +572,19 @@ static inline int ssb_pci_assert_buspowe + } + #endif /* DEBUG */ + ++static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset) ++{ ++ struct ssb_bus *bus = dev->bus; ++ ++ if (unlikely(ssb_pci_assert_buspower(bus))) ++ return 0xFF; ++ if (unlikely(bus->mapped_device != dev)) { ++ if (unlikely(ssb_pci_switch_core(bus, dev))) ++ return 0xFF; ++ } ++ return ioread8(bus->mmio + offset); ++} ++ + static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) + { + struct ssb_bus *bus = dev->bus; +@@ -598,6 +611,19 @@ static u32 ssb_pci_read32(struct ssb_dev + return ioread32(bus->mmio + offset); + } + ++static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value) ++{ ++ struct ssb_bus *bus = dev->bus; ++ ++ if (unlikely(ssb_pci_assert_buspower(bus))) ++ return; ++ if (unlikely(bus->mapped_device != dev)) { ++ if (unlikely(ssb_pci_switch_core(bus, dev))) ++ return; ++ } ++ iowrite8(value, bus->mmio + offset); ++} ++ + static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) + { + struct ssb_bus *bus = dev->bus; +@@ -626,8 +652,10 @@ static void ssb_pci_write32(struct ssb_d + + /* Not "static", as it's used in main.c */ + const struct ssb_bus_ops ssb_pci_ops = { ++ .read8 = ssb_pci_read8, + .read16 = ssb_pci_read16, + .read32 = ssb_pci_read32, ++ .write8 = ssb_pci_write8, + .write16 = ssb_pci_write16, + .write32 = ssb_pci_write32, + }; +Index: linux-2.6.23.16/drivers/ssb/pcmcia.c +=================================================================== +--- linux-2.6.23.16.orig/drivers/ssb/pcmcia.c 2008-02-20 14:10:03.000000000 +0100 ++++ linux-2.6.23.16/drivers/ssb/pcmcia.c 2008-02-20 14:10:07.000000000 +0100 +@@ -172,6 +172,22 @@ static int select_core_and_segment(struc + return 0; + } + ++static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset) ++{ ++ struct ssb_bus *bus = dev->bus; ++ unsigned long flags; ++ int err; ++ u8 value = 0xFF; ++ ++ spin_lock_irqsave(&bus->bar_lock, flags); ++ err = select_core_and_segment(dev, &offset); ++ if (likely(!err)) ++ value = readb(bus->mmio + offset); ++ spin_unlock_irqrestore(&bus->bar_lock, flags); ++ ++ return value; ++} ++ + static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) + { + struct ssb_bus *bus = dev->bus; +@@ -206,6 +222,20 @@ static u32 ssb_pcmcia_read32(struct ssb_ + return (lo | (hi << 16)); + } + ++static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value) ++{ ++ struct ssb_bus *bus = dev->bus; ++ unsigned long flags; ++ int err; ++ ++ spin_lock_irqsave(&bus->bar_lock, flags); ++ err = select_core_and_segment(dev, &offset); ++ if (likely(!err)) ++ writeb(value, bus->mmio + offset); ++ mmiowb(); ++ spin_unlock_irqrestore(&bus->bar_lock, flags); ++} ++ + static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) + { + struct ssb_bus *bus = dev->bus; +@@ -238,8 +268,10 @@ static void ssb_pcmcia_write32(struct ss + + /* Not "static", as it's used in main.c */ + const struct ssb_bus_ops ssb_pcmcia_ops = { ++ .read8 = ssb_pcmcia_read8, + .read16 = ssb_pcmcia_read16, + .read32 = ssb_pcmcia_read32, ++ .write8 = ssb_pcmcia_write8, + .write16 = ssb_pcmcia_write16, + .write32 = ssb_pcmcia_write32, + }; +Index: linux-2.6.23.16/include/linux/ssb/ssb.h +=================================================================== +--- linux-2.6.23.16.orig/include/linux/ssb/ssb.h 2008-02-20 14:10:07.000000000 +0100 ++++ linux-2.6.23.16/include/linux/ssb/ssb.h 2008-02-20 18:33:21.000000000 +0100 +@@ -72,8 +72,10 @@ struct ssb_device; + /* Lowlevel read/write operations on the device MMIO. + * Internal, don't use that outside of ssb. */ + struct ssb_bus_ops { ++ u8 (*read8)(struct ssb_device *dev, u16 offset); + u16 (*read16)(struct ssb_device *dev, u16 offset); + u32 (*read32)(struct ssb_device *dev, u16 offset); ++ void (*write8)(struct ssb_device *dev, u16 offset, u8 value); + void (*write16)(struct ssb_device *dev, u16 offset, u16 value); + void (*write32)(struct ssb_device *dev, u16 offset, u32 value); + }; +@@ -344,6 +346,10 @@ void ssb_device_disable(struct ssb_devic + + + /* Device MMIO register read/write functions. */ ++static inline u8 ssb_read8(struct ssb_device *dev, u16 offset) ++{ ++ return dev->ops->read8(dev, offset); ++} + static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) + { + return dev->ops->read16(dev, offset); +@@ -352,6 +358,10 @@ static inline u32 ssb_read32(struct ssb_ + { + return dev->ops->read32(dev, offset); + } ++static inline void ssb_write8(struct ssb_device *dev, u16 offset, u8 value) ++{ ++ dev->ops->write8(dev, offset, value); ++} + static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) + { + dev->ops->write16(dev, offset, value); |