bcm47xx: Add driver for the SSB Gigabit Ethernet core.
[openwrt.git] / target / linux / brcm47xx / patches-2.6.23 / 680-ssb-support-8bit-writes.patch
1 Add support for 8bit reads/writes to SSB.
2 Index: linux-2.6.23.16/drivers/ssb/main.c
3 ===================================================================
4 --- linux-2.6.23.16.orig/drivers/ssb/main.c     2008-02-20 14:10:07.000000000 +0100
5 +++ linux-2.6.23.16/drivers/ssb/main.c  2008-02-20 18:34:48.000000000 +0100
6 @@ -507,6 +507,14 @@ error:
7         return err;
8  }
9  
10 +static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
11 +{
12 +       struct ssb_bus *bus = dev->bus;
13 +
14 +       offset += dev->core_index * SSB_CORE_SIZE;
15 +       return readb(bus->mmio + offset);
16 +}
17 +
18  static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
19  {
20         struct ssb_bus *bus = dev->bus;
21 @@ -523,6 +531,14 @@ static u32 ssb_ssb_read32(struct ssb_dev
22         return readl(bus->mmio + offset);
23  }
24  
25 +static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
26 +{
27 +       struct ssb_bus *bus = dev->bus;
28 +
29 +       offset += dev->core_index * SSB_CORE_SIZE;
30 +       writeb(value, bus->mmio + offset);
31 +}
32 +
33  static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
34  {
35         struct ssb_bus *bus = dev->bus;
36 @@ -541,8 +557,10 @@ static void ssb_ssb_write32(struct ssb_d
37  
38  /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
39  static const struct ssb_bus_ops ssb_ssb_ops = {
40 +       .read8          = ssb_ssb_read8,
41         .read16         = ssb_ssb_read16,
42         .read32         = ssb_ssb_read32,
43 +       .write8         = ssb_ssb_write8,
44         .write16        = ssb_ssb_write16,
45         .write32        = ssb_ssb_write32,
46  };
47 Index: linux-2.6.23.16/drivers/ssb/pci.c
48 ===================================================================
49 --- linux-2.6.23.16.orig/drivers/ssb/pci.c      2008-02-20 14:10:03.000000000 +0100
50 +++ linux-2.6.23.16/drivers/ssb/pci.c   2008-02-20 14:10:07.000000000 +0100
51 @@ -572,6 +572,19 @@ static inline int ssb_pci_assert_buspowe
52  }
53  #endif /* DEBUG */
54  
55 +static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
56 +{
57 +       struct ssb_bus *bus = dev->bus;
58 +
59 +       if (unlikely(ssb_pci_assert_buspower(bus)))
60 +               return 0xFF;
61 +       if (unlikely(bus->mapped_device != dev)) {
62 +               if (unlikely(ssb_pci_switch_core(bus, dev)))
63 +                       return 0xFF;
64 +       }
65 +       return ioread8(bus->mmio + offset);
66 +}
67 +
68  static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
69  {
70         struct ssb_bus *bus = dev->bus;
71 @@ -598,6 +611,19 @@ static u32 ssb_pci_read32(struct ssb_dev
72         return ioread32(bus->mmio + offset);
73  }
74  
75 +static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
76 +{
77 +       struct ssb_bus *bus = dev->bus;
78 +
79 +       if (unlikely(ssb_pci_assert_buspower(bus)))
80 +               return;
81 +       if (unlikely(bus->mapped_device != dev)) {
82 +               if (unlikely(ssb_pci_switch_core(bus, dev)))
83 +                       return;
84 +       }
85 +       iowrite8(value, bus->mmio + offset);
86 +}
87 +
88  static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
89  {
90         struct ssb_bus *bus = dev->bus;
91 @@ -626,8 +652,10 @@ static void ssb_pci_write32(struct ssb_d
92  
93  /* Not "static", as it's used in main.c */
94  const struct ssb_bus_ops ssb_pci_ops = {
95 +       .read8          = ssb_pci_read8,
96         .read16         = ssb_pci_read16,
97         .read32         = ssb_pci_read32,
98 +       .write8         = ssb_pci_write8,
99         .write16        = ssb_pci_write16,
100         .write32        = ssb_pci_write32,
101  };
102 Index: linux-2.6.23.16/drivers/ssb/pcmcia.c
103 ===================================================================
104 --- linux-2.6.23.16.orig/drivers/ssb/pcmcia.c   2008-02-20 14:10:03.000000000 +0100
105 +++ linux-2.6.23.16/drivers/ssb/pcmcia.c        2008-02-20 14:10:07.000000000 +0100
106 @@ -172,6 +172,22 @@ static int select_core_and_segment(struc
107         return 0;
108  }
109  
110 +static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
111 +{
112 +       struct ssb_bus *bus = dev->bus;
113 +       unsigned long flags;
114 +       int err;
115 +       u8 value = 0xFF;
116 +
117 +       spin_lock_irqsave(&bus->bar_lock, flags);
118 +       err = select_core_and_segment(dev, &offset);
119 +       if (likely(!err))
120 +               value = readb(bus->mmio + offset);
121 +       spin_unlock_irqrestore(&bus->bar_lock, flags);
122 +
123 +       return value;
124 +}
125 +
126  static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
127  {
128         struct ssb_bus *bus = dev->bus;
129 @@ -206,6 +222,20 @@ static u32 ssb_pcmcia_read32(struct ssb_
130         return (lo | (hi << 16));
131  }
132  
133 +static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
134 +{
135 +       struct ssb_bus *bus = dev->bus;
136 +       unsigned long flags;
137 +       int err;
138 +
139 +       spin_lock_irqsave(&bus->bar_lock, flags);
140 +       err = select_core_and_segment(dev, &offset);
141 +       if (likely(!err))
142 +               writeb(value, bus->mmio + offset);
143 +       mmiowb();
144 +       spin_unlock_irqrestore(&bus->bar_lock, flags);
145 +}
146 +
147  static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
148  {
149         struct ssb_bus *bus = dev->bus;
150 @@ -238,8 +268,10 @@ static void ssb_pcmcia_write32(struct ss
151  
152  /* Not "static", as it's used in main.c */
153  const struct ssb_bus_ops ssb_pcmcia_ops = {
154 +       .read8          = ssb_pcmcia_read8,
155         .read16         = ssb_pcmcia_read16,
156         .read32         = ssb_pcmcia_read32,
157 +       .write8         = ssb_pcmcia_write8,
158         .write16        = ssb_pcmcia_write16,
159         .write32        = ssb_pcmcia_write32,
160  };
161 Index: linux-2.6.23.16/include/linux/ssb/ssb.h
162 ===================================================================
163 --- linux-2.6.23.16.orig/include/linux/ssb/ssb.h        2008-02-20 14:10:07.000000000 +0100
164 +++ linux-2.6.23.16/include/linux/ssb/ssb.h     2008-02-20 18:33:21.000000000 +0100
165 @@ -72,8 +72,10 @@ struct ssb_device;
166  /* Lowlevel read/write operations on the device MMIO.
167   * Internal, don't use that outside of ssb. */
168  struct ssb_bus_ops {
169 +       u8 (*read8)(struct ssb_device *dev, u16 offset);
170         u16 (*read16)(struct ssb_device *dev, u16 offset);
171         u32 (*read32)(struct ssb_device *dev, u16 offset);
172 +       void (*write8)(struct ssb_device *dev, u16 offset, u8 value);
173         void (*write16)(struct ssb_device *dev, u16 offset, u16 value);
174         void (*write32)(struct ssb_device *dev, u16 offset, u32 value);
175  };
176 @@ -344,6 +346,10 @@ void ssb_device_disable(struct ssb_devic
177  
178  
179  /* Device MMIO register read/write functions. */
180 +static inline u8 ssb_read8(struct ssb_device *dev, u16 offset)
181 +{
182 +       return dev->ops->read8(dev, offset);
183 +}
184  static inline u16 ssb_read16(struct ssb_device *dev, u16 offset)
185  {
186         return dev->ops->read16(dev, offset);
187 @@ -352,6 +358,10 @@ static inline u32 ssb_read32(struct ssb_
188  {
189         return dev->ops->read32(dev, offset);
190  }
191 +static inline void ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
192 +{
193 +       dev->ops->write8(dev, offset, value);
194 +}
195  static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
196  {
197         dev->ops->write16(dev, offset, value);