pcmcia.c (e697b8d13ede3893724898d983eff3f8c9183643) pcmcia.c (993e1c780b323736a2cdc24564f35e80ce8d3337)
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007 Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.

--- 80 unchanged lines hidden (view full) ---

89 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
90 return -ENODEV;
91}
92
93int ssb_pcmcia_switch_core(struct ssb_bus *bus,
94 struct ssb_device *dev)
95{
96 int err;
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007 Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.

--- 80 unchanged lines hidden (view full) ---

89 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
90 return -ENODEV;
91}
92
93int ssb_pcmcia_switch_core(struct ssb_bus *bus,
94 struct ssb_device *dev)
95{
96 int err;
97 unsigned long flags;
98
99#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
100 ssb_printk(KERN_INFO PFX
101 "Switching to %s core, index %d\n",
102 ssb_core_name(dev->id.coreid),
103 dev->core_index);
104#endif
105
97
98#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
99 ssb_printk(KERN_INFO PFX
100 "Switching to %s core, index %d\n",
101 ssb_core_name(dev->id.coreid),
102 dev->core_index);
103#endif
104
106 spin_lock_irqsave(&bus->bar_lock, flags);
107 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
108 if (!err)
109 bus->mapped_device = dev;
105 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
106 if (!err)
107 bus->mapped_device = dev;
110 spin_unlock_irqrestore(&bus->bar_lock, flags);
111
112 return err;
113}
114
115int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
116{
117 int attempts = 0;
108
109 return err;
110}
111
112int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
113{
114 int attempts = 0;
118 unsigned long flags;
119 conf_reg_t reg;
115 conf_reg_t reg;
120 int res, err = 0;
116 int res;
121
122 SSB_WARN_ON((seg != 0) && (seg != 1));
123 reg.Offset = 0x34;
124 reg.Function = 0;
117
118 SSB_WARN_ON((seg != 0) && (seg != 1));
119 reg.Offset = 0x34;
120 reg.Function = 0;
125 spin_lock_irqsave(&bus->bar_lock, flags);
126 while (1) {
127 reg.Action = CS_WRITE;
128 reg.Value = seg;
129 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
130 if (unlikely(res != CS_SUCCESS))
131 goto error;
132 reg.Value = 0xFF;
133 reg.Action = CS_READ;

--- 4 unchanged lines hidden (view full) ---

138 if (reg.Value == seg)
139 break;
140
141 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
142 goto error;
143 udelay(10);
144 }
145 bus->mapped_pcmcia_seg = seg;
121 while (1) {
122 reg.Action = CS_WRITE;
123 reg.Value = seg;
124 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
125 if (unlikely(res != CS_SUCCESS))
126 goto error;
127 reg.Value = 0xFF;
128 reg.Action = CS_READ;

--- 4 unchanged lines hidden (view full) ---

133 if (reg.Value == seg)
134 break;
135
136 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
137 goto error;
138 udelay(10);
139 }
140 bus->mapped_pcmcia_seg = seg;
146out_unlock:
147 spin_unlock_irqrestore(&bus->bar_lock, flags);
148 return err;
141
142 return 0;
149error:
150 ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
143error:
144 ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
151 err = -ENODEV;
152 goto out_unlock;
145 return -ENODEV;
153}
154
155static int select_core_and_segment(struct ssb_device *dev,
156 u16 *offset)
157{
158 struct ssb_bus *bus = dev->bus;
159 int err;
160 u8 need_segment;

--- 16 unchanged lines hidden (view full) ---

177 }
178
179 return 0;
180}
181
182static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
183{
184 struct ssb_bus *bus = dev->bus;
146}
147
148static int select_core_and_segment(struct ssb_device *dev,
149 u16 *offset)
150{
151 struct ssb_bus *bus = dev->bus;
152 int err;
153 u8 need_segment;

--- 16 unchanged lines hidden (view full) ---

170 }
171
172 return 0;
173}
174
175static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
176{
177 struct ssb_bus *bus = dev->bus;
178 unsigned long flags;
179 int err;
180 u16 value = 0xFFFF;
185
181
186 if (unlikely(select_core_and_segment(dev, &offset)))
187 return 0xFFFF;
182 spin_lock_irqsave(&bus->bar_lock, flags);
183 err = select_core_and_segment(dev, &offset);
184 if (likely(!err))
185 value = readw(bus->mmio + offset);
186 spin_unlock_irqrestore(&bus->bar_lock, flags);
188
187
189 return readw(bus->mmio + offset);
188 return value;
190}
191
192static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
193{
194 struct ssb_bus *bus = dev->bus;
189}
190
191static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
192{
193 struct ssb_bus *bus = dev->bus;
195 u32 lo, hi;
194 unsigned long flags;
195 int err;
196 u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
196
197
197 if (unlikely(select_core_and_segment(dev, &offset)))
198 return 0xFFFFFFFF;
199 lo = readw(bus->mmio + offset);
200 hi = readw(bus->mmio + offset + 2);
198 spin_lock_irqsave(&bus->bar_lock, flags);
199 err = select_core_and_segment(dev, &offset);
200 if (likely(!err)) {
201 lo = readw(bus->mmio + offset);
202 hi = readw(bus->mmio + offset + 2);
203 }
204 spin_unlock_irqrestore(&bus->bar_lock, flags);
201
202 return (lo | (hi << 16));
203}
204
205static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
206{
207 struct ssb_bus *bus = dev->bus;
205
206 return (lo | (hi << 16));
207}
208
209static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
210{
211 struct ssb_bus *bus = dev->bus;
212 unsigned long flags;
213 int err;
208
214
209 if (unlikely(select_core_and_segment(dev, &offset)))
210 return;
211 writew(value, bus->mmio + offset);
215 spin_lock_irqsave(&bus->bar_lock, flags);
216 err = select_core_and_segment(dev, &offset);
217 if (likely(!err))
218 writew(value, bus->mmio + offset);
219 mmiowb();
220 spin_unlock_irqrestore(&bus->bar_lock, flags);
212}
213
214static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
215{
216 struct ssb_bus *bus = dev->bus;
221}
222
223static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
224{
225 struct ssb_bus *bus = dev->bus;
226 unsigned long flags;
227 int err;
217
228
218 if (unlikely(select_core_and_segment(dev, &offset)))
219 return;
220 writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3);
221 writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2);
222 writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1);
223 writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0);
229 spin_lock_irqsave(&bus->bar_lock, flags);
230 err = select_core_and_segment(dev, &offset);
231 if (likely(!err)) {
232 writew((value & 0x0000FFFF), bus->mmio + offset);
233 writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
234 }
235 mmiowb();
236 spin_unlock_irqrestore(&bus->bar_lock, flags);
224}
225
226/* Not "static", as it's used in main.c */
227const struct ssb_bus_ops ssb_pcmcia_ops = {
228 .read16 = ssb_pcmcia_read16,
229 .read32 = ssb_pcmcia_read32,
230 .write16 = ssb_pcmcia_write16,
231 .write32 = ssb_pcmcia_write32,
232};
233
237}
238
239/* Not "static", as it's used in main.c */
240const struct ssb_bus_ops ssb_pcmcia_ops = {
241 .read16 = ssb_pcmcia_read16,
242 .read32 = ssb_pcmcia_read32,
243 .write16 = ssb_pcmcia_write16,
244 .write32 = ssb_pcmcia_write32,
245};
246
247#include <linux/etherdevice.h>
234int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
235 struct ssb_init_invariants *iv)
236{
237 //TODO
248int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
249 struct ssb_init_invariants *iv)
250{
251 //TODO
252 random_ether_addr(iv->sprom.il0mac);
238 return 0;
239}
240
241int ssb_pcmcia_init(struct ssb_bus *bus)
242{
243 conf_reg_t reg;
244 int err;
245

--- 27 unchanged lines hidden ---
253 return 0;
254}
255
256int ssb_pcmcia_init(struct ssb_bus *bus)
257{
258 conf_reg_t reg;
259 int err;
260

--- 27 unchanged lines hidden ---