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