Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcmcia.c
Go to the documentation of this file.
1 /*
2  * Sonics Silicon Backplane
3  * PCMCIA-Hostbus related functions
4  *
5  * Copyright 2006 Johannes Berg <[email protected]>
6  * Copyright 2007-2008 Michael Buesch <[email protected]>
7  *
8  * Licensed under the GNU/GPL. See COPYING for details.
9  */
10 
11 #include <linux/ssb/ssb.h>
12 #include <linux/delay.h>
13 #include <linux/io.h>
14 #include <linux/etherdevice.h>
15 
16 #include <pcmcia/cistpl.h>
17 #include <pcmcia/ciscode.h>
18 #include <pcmcia/ds.h>
19 #include <pcmcia/cisreg.h>
20 
21 #include "ssb_private.h"
22 
23 
24 /* Define the following to 1 to enable a printk on each coreswitch. */
25 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
26 
27 
28 /* PCMCIA configuration registers */
29 #define SSB_PCMCIA_ADDRESS0 0x2E
30 #define SSB_PCMCIA_ADDRESS1 0x30
31 #define SSB_PCMCIA_ADDRESS2 0x32
32 #define SSB_PCMCIA_MEMSEG 0x34
33 #define SSB_PCMCIA_SPROMCTL 0x36
34 #define SSB_PCMCIA_SPROMCTL_IDLE 0
35 #define SSB_PCMCIA_SPROMCTL_WRITE 1
36 #define SSB_PCMCIA_SPROMCTL_READ 2
37 #define SSB_PCMCIA_SPROMCTL_WRITEEN 4
38 #define SSB_PCMCIA_SPROMCTL_WRITEDIS 7
39 #define SSB_PCMCIA_SPROMCTL_DONE 8
40 #define SSB_PCMCIA_SPROM_DATALO 0x38
41 #define SSB_PCMCIA_SPROM_DATAHI 0x3A
42 #define SSB_PCMCIA_SPROM_ADDRLO 0x3C
43 #define SSB_PCMCIA_SPROM_ADDRHI 0x3E
44 
45 /* Hardware invariants CIS tuples */
46 #define SSB_PCMCIA_CIS 0x80
47 #define SSB_PCMCIA_CIS_ID 0x01
48 #define SSB_PCMCIA_CIS_BOARDREV 0x02
49 #define SSB_PCMCIA_CIS_PA 0x03
50 #define SSB_PCMCIA_CIS_PA_PA0B0_LO 0
51 #define SSB_PCMCIA_CIS_PA_PA0B0_HI 1
52 #define SSB_PCMCIA_CIS_PA_PA0B1_LO 2
53 #define SSB_PCMCIA_CIS_PA_PA0B1_HI 3
54 #define SSB_PCMCIA_CIS_PA_PA0B2_LO 4
55 #define SSB_PCMCIA_CIS_PA_PA0B2_HI 5
56 #define SSB_PCMCIA_CIS_PA_ITSSI 6
57 #define SSB_PCMCIA_CIS_PA_MAXPOW 7
58 #define SSB_PCMCIA_CIS_OEMNAME 0x04
59 #define SSB_PCMCIA_CIS_CCODE 0x05
60 #define SSB_PCMCIA_CIS_ANTENNA 0x06
61 #define SSB_PCMCIA_CIS_ANTGAIN 0x07
62 #define SSB_PCMCIA_CIS_BFLAGS 0x08
63 #define SSB_PCMCIA_CIS_LEDS 0x09
64 
65 /* PCMCIA SPROM size. */
66 #define SSB_PCMCIA_SPROM_SIZE 256
67 #define SSB_PCMCIA_SPROM_SIZE_BYTES (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
68 
69 
70 /* Write to a PCMCIA configuration register. */
71 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
72 {
73  int res;
74 
75  res = pcmcia_write_config_byte(bus->host_pcmcia, offset, value);
76  if (unlikely(res != 0))
77  return -EBUSY;
78 
79  return 0;
80 }
81 
82 /* Read from a PCMCIA configuration register. */
83 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
84 {
85  int res;
86 
87  res = pcmcia_read_config_byte(bus->host_pcmcia, offset, value);
88  if (unlikely(res != 0))
89  return -EBUSY;
90 
91  return 0;
92 }
93 
95  u8 coreidx)
96 {
97  int err;
98  int attempts = 0;
99  u32 cur_core;
100  u32 addr;
101  u32 read_addr;
102  u8 val;
103 
104  addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
105  while (1) {
106  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
107  (addr & 0x0000F000) >> 12);
108  if (err)
109  goto error;
110  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
111  (addr & 0x00FF0000) >> 16);
112  if (err)
113  goto error;
114  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
115  (addr & 0xFF000000) >> 24);
116  if (err)
117  goto error;
118 
119  read_addr = 0;
120 
121  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
122  if (err)
123  goto error;
124  read_addr |= ((u32)(val & 0x0F)) << 12;
125  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
126  if (err)
127  goto error;
128  read_addr |= ((u32)val) << 16;
129  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
130  if (err)
131  goto error;
132  read_addr |= ((u32)val) << 24;
133 
134  cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
135  if (cur_core == coreidx)
136  break;
137 
138  err = -ETIMEDOUT;
139  if (attempts++ > SSB_BAR0_MAX_RETRIES)
140  goto error;
141  udelay(10);
142  }
143 
144  return 0;
145 error:
146  ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
147  return err;
148 }
149 
151  struct ssb_device *dev)
152 {
153  int err;
154 
155 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
157  "Switching to %s core, index %d\n",
158  ssb_core_name(dev->id.coreid),
159  dev->core_index);
160 #endif
161 
162  err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
163  if (!err)
164  bus->mapped_device = dev;
165 
166  return err;
167 }
168 
170 {
171  int attempts = 0;
172  int err;
173  u8 val;
174 
175  SSB_WARN_ON((seg != 0) && (seg != 1));
176  while (1) {
177  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
178  if (err)
179  goto error;
180  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
181  if (err)
182  goto error;
183  if (val == seg)
184  break;
185 
186  err = -ETIMEDOUT;
187  if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
188  goto error;
189  udelay(10);
190  }
191  bus->mapped_pcmcia_seg = seg;
192 
193  return 0;
194 error:
195  ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
196  return err;
197 }
198 
199 static int select_core_and_segment(struct ssb_device *dev,
200  u16 *offset)
201 {
202  struct ssb_bus *bus = dev->bus;
203  int err;
204  u8 need_segment;
205 
206  if (*offset >= 0x800) {
207  *offset -= 0x800;
208  need_segment = 1;
209  } else
210  need_segment = 0;
211 
212  if (unlikely(dev != bus->mapped_device)) {
213  err = ssb_pcmcia_switch_core(bus, dev);
214  if (unlikely(err))
215  return err;
216  }
217  if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
218  err = ssb_pcmcia_switch_segment(bus, need_segment);
219  if (unlikely(err))
220  return err;
221  }
222 
223  return 0;
224 }
225 
226 static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
227 {
228  struct ssb_bus *bus = dev->bus;
229  unsigned long flags;
230  int err;
231  u8 value = 0xFF;
232 
233  spin_lock_irqsave(&bus->bar_lock, flags);
234  err = select_core_and_segment(dev, &offset);
235  if (likely(!err))
236  value = readb(bus->mmio + offset);
237  spin_unlock_irqrestore(&bus->bar_lock, flags);
238 
239  return value;
240 }
241 
242 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
243 {
244  struct ssb_bus *bus = dev->bus;
245  unsigned long flags;
246  int err;
247  u16 value = 0xFFFF;
248 
249  spin_lock_irqsave(&bus->bar_lock, flags);
250  err = select_core_and_segment(dev, &offset);
251  if (likely(!err))
252  value = readw(bus->mmio + offset);
253  spin_unlock_irqrestore(&bus->bar_lock, flags);
254 
255  return value;
256 }
257 
258 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
259 {
260  struct ssb_bus *bus = dev->bus;
261  unsigned long flags;
262  int err;
263  u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
264 
265  spin_lock_irqsave(&bus->bar_lock, flags);
266  err = select_core_and_segment(dev, &offset);
267  if (likely(!err)) {
268  lo = readw(bus->mmio + offset);
269  hi = readw(bus->mmio + offset + 2);
270  }
271  spin_unlock_irqrestore(&bus->bar_lock, flags);
272 
273  return (lo | (hi << 16));
274 }
275 
276 #ifdef CONFIG_SSB_BLOCKIO
277 static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer,
278  size_t count, u16 offset, u8 reg_width)
279 {
280  struct ssb_bus *bus = dev->bus;
281  unsigned long flags;
282  void __iomem *addr = bus->mmio + offset;
283  int err;
284 
285  spin_lock_irqsave(&bus->bar_lock, flags);
286  err = select_core_and_segment(dev, &offset);
287  if (unlikely(err)) {
288  memset(buffer, 0xFF, count);
289  goto unlock;
290  }
291  switch (reg_width) {
292  case sizeof(u8): {
293  u8 *buf = buffer;
294 
295  while (count) {
296  *buf = __raw_readb(addr);
297  buf++;
298  count--;
299  }
300  break;
301  }
302  case sizeof(u16): {
303  __le16 *buf = buffer;
304 
305  SSB_WARN_ON(count & 1);
306  while (count) {
307  *buf = (__force __le16)__raw_readw(addr);
308  buf++;
309  count -= 2;
310  }
311  break;
312  }
313  case sizeof(u32): {
314  __le16 *buf = buffer;
315 
316  SSB_WARN_ON(count & 3);
317  while (count) {
318  *buf = (__force __le16)__raw_readw(addr);
319  buf++;
320  *buf = (__force __le16)__raw_readw(addr + 2);
321  buf++;
322  count -= 4;
323  }
324  break;
325  }
326  default:
327  SSB_WARN_ON(1);
328  }
329 unlock:
330  spin_unlock_irqrestore(&bus->bar_lock, flags);
331 }
332 #endif /* CONFIG_SSB_BLOCKIO */
333 
334 static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
335 {
336  struct ssb_bus *bus = dev->bus;
337  unsigned long flags;
338  int err;
339 
340  spin_lock_irqsave(&bus->bar_lock, flags);
341  err = select_core_and_segment(dev, &offset);
342  if (likely(!err))
343  writeb(value, bus->mmio + offset);
344  mmiowb();
345  spin_unlock_irqrestore(&bus->bar_lock, flags);
346 }
347 
348 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
349 {
350  struct ssb_bus *bus = dev->bus;
351  unsigned long flags;
352  int err;
353 
354  spin_lock_irqsave(&bus->bar_lock, flags);
355  err = select_core_and_segment(dev, &offset);
356  if (likely(!err))
357  writew(value, bus->mmio + offset);
358  mmiowb();
359  spin_unlock_irqrestore(&bus->bar_lock, flags);
360 }
361 
362 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
363 {
364  struct ssb_bus *bus = dev->bus;
365  unsigned long flags;
366  int err;
367 
368  spin_lock_irqsave(&bus->bar_lock, flags);
369  err = select_core_and_segment(dev, &offset);
370  if (likely(!err)) {
371  writew((value & 0x0000FFFF), bus->mmio + offset);
372  writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
373  }
374  mmiowb();
375  spin_unlock_irqrestore(&bus->bar_lock, flags);
376 }
377 
378 #ifdef CONFIG_SSB_BLOCKIO
379 static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer,
380  size_t count, u16 offset, u8 reg_width)
381 {
382  struct ssb_bus *bus = dev->bus;
383  unsigned long flags;
384  void __iomem *addr = bus->mmio + offset;
385  int err;
386 
387  spin_lock_irqsave(&bus->bar_lock, flags);
388  err = select_core_and_segment(dev, &offset);
389  if (unlikely(err))
390  goto unlock;
391  switch (reg_width) {
392  case sizeof(u8): {
393  const u8 *buf = buffer;
394 
395  while (count) {
396  __raw_writeb(*buf, addr);
397  buf++;
398  count--;
399  }
400  break;
401  }
402  case sizeof(u16): {
403  const __le16 *buf = buffer;
404 
405  SSB_WARN_ON(count & 1);
406  while (count) {
407  __raw_writew((__force u16)(*buf), addr);
408  buf++;
409  count -= 2;
410  }
411  break;
412  }
413  case sizeof(u32): {
414  const __le16 *buf = buffer;
415 
416  SSB_WARN_ON(count & 3);
417  while (count) {
418  __raw_writew((__force u16)(*buf), addr);
419  buf++;
420  __raw_writew((__force u16)(*buf), addr + 2);
421  buf++;
422  count -= 4;
423  }
424  break;
425  }
426  default:
427  SSB_WARN_ON(1);
428  }
429 unlock:
430  mmiowb();
431  spin_unlock_irqrestore(&bus->bar_lock, flags);
432 }
433 #endif /* CONFIG_SSB_BLOCKIO */
434 
435 /* Not "static", as it's used in main.c */
436 const struct ssb_bus_ops ssb_pcmcia_ops = {
437  .read8 = ssb_pcmcia_read8,
438  .read16 = ssb_pcmcia_read16,
439  .read32 = ssb_pcmcia_read32,
440  .write8 = ssb_pcmcia_write8,
441  .write16 = ssb_pcmcia_write16,
442  .write32 = ssb_pcmcia_write32,
443 #ifdef CONFIG_SSB_BLOCKIO
444  .block_read = ssb_pcmcia_block_read,
445  .block_write = ssb_pcmcia_block_write,
446 #endif
447 };
448 
449 static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
450 {
451  unsigned int i;
452  int err;
453  u8 value;
454 
455  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
456  if (err)
457  return err;
458  for (i = 0; i < 1000; i++) {
459  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
460  if (err)
461  return err;
462  if (value & SSB_PCMCIA_SPROMCTL_DONE)
463  return 0;
464  udelay(10);
465  }
466 
467  return -ETIMEDOUT;
468 }
469 
470 /* offset is the 16bit word offset */
471 static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
472 {
473  int err;
474  u8 lo, hi;
475 
476  offset *= 2; /* Make byte offset */
477 
478  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
479  (offset & 0x00FF));
480  if (err)
481  return err;
482  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
483  (offset & 0xFF00) >> 8);
484  if (err)
485  return err;
486  err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
487  if (err)
488  return err;
489  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
490  if (err)
491  return err;
492  err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
493  if (err)
494  return err;
495  *value = (lo | (((u16)hi) << 8));
496 
497  return 0;
498 }
499 
500 /* offset is the 16bit word offset */
501 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
502 {
503  int err;
504 
505  offset *= 2; /* Make byte offset */
506 
507  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
508  (offset & 0x00FF));
509  if (err)
510  return err;
511  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
512  (offset & 0xFF00) >> 8);
513  if (err)
514  return err;
515  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
516  (value & 0x00FF));
517  if (err)
518  return err;
519  err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
520  (value & 0xFF00) >> 8);
521  if (err)
522  return err;
523  err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
524  if (err)
525  return err;
526  msleep(20);
527 
528  return 0;
529 }
530 
531 /* Read the SPROM image. bufsize is in 16bit words. */
532 static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
533 {
534  int err, i;
535 
536  for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
537  err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
538  if (err)
539  return err;
540  }
541 
542  return 0;
543 }
544 
545 /* Write the SPROM image. size is in 16bit words. */
546 static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
547 {
548  int i, err;
549  bool failed = 0;
550  size_t size = SSB_PCMCIA_SPROM_SIZE;
551 
553  "Writing SPROM. Do NOT turn off the power! "
554  "Please stand by...\n");
555  err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
556  if (err) {
558  "Could not enable SPROM write access.\n");
559  return -EBUSY;
560  }
561  ssb_printk(KERN_NOTICE PFX "[ 0%%");
562  msleep(500);
563  for (i = 0; i < size; i++) {
564  if (i == size / 4)
565  ssb_printk("25%%");
566  else if (i == size / 2)
567  ssb_printk("50%%");
568  else if (i == (size * 3) / 4)
569  ssb_printk("75%%");
570  else if (i % 2)
571  ssb_printk(".");
572  err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
573  if (err) {
575  "Failed to write to SPROM.\n");
576  failed = 1;
577  break;
578  }
579  }
580  err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
581  if (err) {
583  "Could not disable SPROM write access.\n");
584  failed = 1;
585  }
586  msleep(500);
587  if (!failed) {
588  ssb_printk("100%% ]\n");
589  ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
590  }
591 
592  return failed ? -EBUSY : 0;
593 }
594 
595 static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
596 {
597  //TODO
598  return 0;
599 }
600 
601 #define GOTO_ERROR_ON(condition, description) do { \
602  if (unlikely(condition)) { \
603  error_description = description; \
604  goto error; \
605  } \
606  } while (0)
607 
608 static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
609  tuple_t *tuple,
610  void *priv)
611 {
612  struct ssb_sprom *sprom = priv;
613 
614  if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
615  return -EINVAL;
616  if (tuple->TupleDataLen != ETH_ALEN + 2)
617  return -EINVAL;
618  if (tuple->TupleData[1] != ETH_ALEN)
619  return -EINVAL;
620  memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
621  return 0;
622 };
623 
624 static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
625  tuple_t *tuple,
626  void *priv)
627 {
628  struct ssb_init_invariants *iv = priv;
629  struct ssb_sprom *sprom = &iv->sprom;
630  struct ssb_boardinfo *bi = &iv->boardinfo;
631  const char *error_description;
632 
633  GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
634  switch (tuple->TupleData[0]) {
635  case SSB_PCMCIA_CIS_ID:
636  GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
637  (tuple->TupleDataLen != 7),
638  "id tpl size");
639  bi->vendor = tuple->TupleData[1] |
640  ((u16)tuple->TupleData[2] << 8);
641  break;
643  GOTO_ERROR_ON(tuple->TupleDataLen != 2,
644  "boardrev tpl size");
645  sprom->board_rev = tuple->TupleData[1];
646  break;
647  case SSB_PCMCIA_CIS_PA:
648  GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
649  (tuple->TupleDataLen != 10),
650  "pa tpl size");
651  sprom->pa0b0 = tuple->TupleData[1] |
652  ((u16)tuple->TupleData[2] << 8);
653  sprom->pa0b1 = tuple->TupleData[3] |
654  ((u16)tuple->TupleData[4] << 8);
655  sprom->pa0b2 = tuple->TupleData[5] |
656  ((u16)tuple->TupleData[6] << 8);
657  sprom->itssi_a = tuple->TupleData[7];
658  sprom->itssi_bg = tuple->TupleData[7];
659  sprom->maxpwr_a = tuple->TupleData[8];
660  sprom->maxpwr_bg = tuple->TupleData[8];
661  break;
663  /* We ignore this. */
664  break;
666  GOTO_ERROR_ON(tuple->TupleDataLen != 2,
667  "ccode tpl size");
668  sprom->country_code = tuple->TupleData[1];
669  break;
671  GOTO_ERROR_ON(tuple->TupleDataLen != 2,
672  "ant tpl size");
673  sprom->ant_available_a = tuple->TupleData[1];
674  sprom->ant_available_bg = tuple->TupleData[1];
675  break;
677  GOTO_ERROR_ON(tuple->TupleDataLen != 2,
678  "antg tpl size");
679  sprom->antenna_gain.a0 = tuple->TupleData[1];
680  sprom->antenna_gain.a1 = tuple->TupleData[1];
681  sprom->antenna_gain.a2 = tuple->TupleData[1];
682  sprom->antenna_gain.a3 = tuple->TupleData[1];
683  break;
685  GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
686  (tuple->TupleDataLen != 5),
687  "bfl tpl size");
688  sprom->boardflags_lo = tuple->TupleData[1] |
689  ((u16)tuple->TupleData[2] << 8);
690  break;
691  case SSB_PCMCIA_CIS_LEDS:
692  GOTO_ERROR_ON(tuple->TupleDataLen != 5,
693  "leds tpl size");
694  sprom->gpio0 = tuple->TupleData[1];
695  sprom->gpio1 = tuple->TupleData[2];
696  sprom->gpio2 = tuple->TupleData[3];
697  sprom->gpio3 = tuple->TupleData[4];
698  break;
699  }
700  return -ENOSPC; /* continue with next entry */
701 
702 error:
704  "PCMCIA: Failed to fetch device invariants: %s\n",
705  error_description);
706  return -ENODEV;
707 }
708 
709 
711  struct ssb_init_invariants *iv)
712 {
713  struct ssb_sprom *sprom = &iv->sprom;
714  int res;
715 
716  memset(sprom, 0xFF, sizeof(*sprom));
717  sprom->revision = 1;
718  sprom->boardflags_lo = 0;
719  sprom->boardflags_hi = 0;
720 
721  /* First fetch the MAC address. */
722  res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
723  ssb_pcmcia_get_mac, sprom);
724  if (res != 0) {
726  "PCMCIA: Failed to fetch MAC address\n");
727  return -ENODEV;
728  }
729 
730  /* Fetch the vendor specific tuples. */
731  res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
732  ssb_pcmcia_do_get_invariants, iv);
733  if ((res == 0) || (res == -ENOSPC))
734  return 0;
735 
737  "PCMCIA: Failed to fetch device invariants\n");
738  return -ENODEV;
739 }
740 
741 static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
742  struct device_attribute *attr,
743  char *buf)
744 {
745  struct pcmcia_device *pdev =
746  container_of(pcmciadev, struct pcmcia_device, dev);
747  struct ssb_bus *bus;
748 
749  bus = ssb_pcmcia_dev_to_bus(pdev);
750  if (!bus)
751  return -ENODEV;
752 
753  return ssb_attr_sprom_show(bus, buf,
754  ssb_pcmcia_sprom_read_all);
755 }
756 
757 static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
758  struct device_attribute *attr,
759  const char *buf, size_t count)
760 {
761  struct pcmcia_device *pdev =
762  container_of(pcmciadev, struct pcmcia_device, dev);
763  struct ssb_bus *bus;
764 
765  bus = ssb_pcmcia_dev_to_bus(pdev);
766  if (!bus)
767  return -ENODEV;
768 
769  return ssb_attr_sprom_store(bus, buf, count,
770  ssb_pcmcia_sprom_check_crc,
771  ssb_pcmcia_sprom_write_all);
772 }
773 
774 static DEVICE_ATTR(ssb_sprom, 0600,
775  ssb_pcmcia_attr_sprom_show,
776  ssb_pcmcia_attr_sprom_store);
777 
778 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
779 {
780  u8 val;
781  int err;
782 
783  err = ssb_pcmcia_cfg_read(bus, cor, &val);
784  if (err)
785  return err;
786  val &= ~COR_SOFT_RESET;
788  err = ssb_pcmcia_cfg_write(bus, cor, val);
789  if (err)
790  return err;
791  msleep(40);
792 
793  return 0;
794 }
795 
796 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */
798 {
799  int err;
800 
801  if (bus->bustype != SSB_BUSTYPE_PCMCIA)
802  return 0;
803 
804  /* Switch segment to a known state and sync
805  * bus->mapped_pcmcia_seg with hardware state. */
807  /* Init the COR register. */
808  err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
809  if (err)
810  return err;
811  /* Some cards also need this register to get poked. */
812  err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
813  if (err)
814  return err;
815 
816  return 0;
817 }
818 
819 void ssb_pcmcia_exit(struct ssb_bus *bus)
820 {
821  if (bus->bustype != SSB_BUSTYPE_PCMCIA)
822  return;
823 
824  device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
825 }
826 
827 int ssb_pcmcia_init(struct ssb_bus *bus)
828 {
829  int err;
830 
831  if (bus->bustype != SSB_BUSTYPE_PCMCIA)
832  return 0;
833 
834  err = ssb_pcmcia_hardware_setup(bus);
835  if (err)
836  goto error;
837 
839  mutex_init(&bus->sprom_mutex);
840  err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
841  if (err)
842  goto error;
843 
844  return 0;
845 error:
846  ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
847  return err;
848 }