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, ®); 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, ®); 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 --- |