2 * Sonics Silicon Backplane PCI-Hostbus related functions.
4 * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10 * Derived from the Broadcom 4400 device driver.
11 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
13 * Copyright (C) 2006 Broadcom Corporation.
15 * Licensed under the GNU/GPL. See COPYING for details.
18 #include <linux/ssb/ssb.h>
19 #include <linux/ssb/ssb_regs.h>
20 #include <linux/pci.h>
21 #include <linux/delay.h>
23 #include "ssb_private.h"
26 /* Define the following to 1 to enable a printk on each coreswitch. */
27 #define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
30 /* Lowlevel coreswitching */
31 int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
38 err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
39 (coreidx * SSB_CORE_SIZE)
43 err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
47 cur_core = (cur_core - SSB_ENUM_BASE)
49 if (cur_core == coreidx)
52 if (attempts++ > SSB_BAR0_MAX_RETRIES)
58 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
62 int ssb_pci_switch_core(struct ssb_bus *bus,
63 struct ssb_device *dev)
68 #if SSB_VERBOSE_PCICORESWITCH_DEBUG
69 ssb_printk(KERN_INFO PFX
70 "Switching to %s core, index %d\n",
71 ssb_core_name(dev->id.coreid),
75 spin_lock_irqsave(&bus->bar_lock, flags);
76 err = ssb_pci_switch_coreidx(bus, dev->core_index);
78 bus->mapped_device = dev;
79 spin_unlock_irqrestore(&bus->bar_lock, flags);
84 /* Enable/disable the on board crystal oscillator and/or PLL. */
85 int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
88 u32 in, out, outenable;
91 if (bus->bustype != SSB_BUSTYPE_PCI)
94 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
97 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
100 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
107 /* Avoid glitching the clock if GPRS is already using it.
108 * We can't actually read the state of the PLLPD so we infer it
109 * by the value of XTAL_PU which *is* readable via gpioin.
111 if (!(in & SSB_GPIO_XTAL)) {
112 if (what & SSB_GPIO_XTAL) {
113 /* Turn the crystal on */
114 out |= SSB_GPIO_XTAL;
115 if (what & SSB_GPIO_PLL)
117 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
120 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
126 if (what & SSB_GPIO_PLL) {
127 /* Turn the PLL on */
128 out &= ~SSB_GPIO_PLL;
129 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
136 err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
139 pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
140 err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
144 if (what & SSB_GPIO_XTAL) {
145 /* Turn the crystal off */
146 out &= ~SSB_GPIO_XTAL;
148 if (what & SSB_GPIO_PLL) {
149 /* Turn the PLL off */
152 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
155 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
164 printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
169 /* Get the word-offset for a SSB_SPROM_XXX define. */
170 #define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
171 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
172 #define SPEX(_outvar, _offset, _mask, _shift) \
173 out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
175 static inline u8 ssb_crc8(u8 crc, u8 data)
177 /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
178 static const u8 t[] = {
179 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
180 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
181 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
182 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
183 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
184 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
185 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
186 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
187 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
188 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
189 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
190 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
191 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
192 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
193 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
194 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
195 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
196 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
197 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
198 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
199 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
200 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
201 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
202 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
203 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
204 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
205 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
206 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
207 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
208 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
209 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
210 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
212 return t[crc ^ data];
215 static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
220 for (word = 0; word < size - 1; word++) {
221 crc = ssb_crc8(crc, sprom[word] & 0x00FF);
222 crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
224 crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
230 static int sprom_check_crc(const u16 *sprom, u16 size)
236 crc = ssb_sprom_crc(sprom, size);
237 tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
238 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
239 if (crc != expected_crc)
245 static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
249 for (i = 0; i < bus->sprom_size; i++)
250 sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2));
253 static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
255 struct pci_dev *pdev = bus->host_pci;
258 u16 size = bus->sprom_size;
260 ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
261 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
264 spromctl |= SSB_SPROMCTL_WE;
265 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
268 ssb_printk(KERN_NOTICE PFX "[ 0%%");
270 for (i = 0; i < size; i++) {
273 else if (i == size / 2)
275 else if (i == (size * 3) / 4)
279 writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
283 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
286 spromctl &= ~SSB_SPROMCTL_WE;
287 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
291 ssb_printk("100%% ]\n");
292 ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
296 ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
300 static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
305 SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
306 SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
307 SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
308 for (i = 0; i < 3; i++) {
309 v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
310 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
312 for (i = 0; i < 3; i++) {
313 v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
314 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
316 for (i = 0; i < 3; i++) {
317 v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
318 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
320 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
321 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
322 SSB_SPROM1_ETHPHY_ET1A_SHIFT);
323 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
324 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
325 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
326 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
327 SSB_SPROM1_BINF_CCODE_SHIFT);
328 SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
329 SSB_SPROM1_BINF_ANTA_SHIFT);
330 SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
331 SSB_SPROM1_BINF_ANTBG_SHIFT);
332 SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
333 SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
334 SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
335 SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
336 SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
337 SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
338 SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
339 SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
340 SSB_SPROM1_GPIOA_P1_SHIFT);
341 SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
342 SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
343 SSB_SPROM1_GPIOB_P3_SHIFT);
344 SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
345 SSB_SPROM1_MAXPWR_A_SHIFT);
346 SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
347 SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
348 SSB_SPROM1_ITSSI_A_SHIFT);
349 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
350 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
351 SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
352 SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
353 SSB_SPROM1_AGAIN_BG_SHIFT);
356 static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
362 if (out->revision == 3) { /* rev 3 moved MAC */
363 loc[0] = SSB_SPROM3_IL0MAC;
364 loc[1] = SSB_SPROM3_ET0MAC;
365 loc[2] = SSB_SPROM3_ET1MAC;
367 loc[0] = SSB_SPROM1_IL0MAC;
368 loc[1] = SSB_SPROM1_ET0MAC;
369 loc[2] = SSB_SPROM1_ET1MAC;
371 for (i = 0; i < 3; i++) {
372 v = in[SPOFF(loc[0]) + i];
373 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
375 for (i = 0; i < 3; i++) {
376 v = in[SPOFF(loc[1]) + i];
377 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
379 for (i = 0; i < 3; i++) {
380 v = in[SPOFF(loc[2]) + i];
381 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
383 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
384 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
385 SSB_SPROM1_ETHPHY_ET1A_SHIFT);
386 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
387 SSB_SPROM1_BINF_CCODE_SHIFT);
388 SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
389 SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
390 SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
391 SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
392 SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
393 SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
394 SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
395 SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
396 SSB_SPROM1_GPIOA_P1_SHIFT);
397 SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
398 SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
399 SSB_SPROM1_GPIOB_P3_SHIFT);
400 SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
401 SSB_SPROM1_MAXPWR_A_SHIFT);
402 SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
403 SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
404 SSB_SPROM1_ITSSI_A_SHIFT);
405 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
406 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
407 SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
408 SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
409 SSB_SPROM1_AGAIN_BG_SHIFT);
412 static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in)
417 /* extract the r1 variables */
418 for (i = 0; i < 3; i++) {
419 v = in[SPOFF(SSB_SPROM4_IL0MAC) + i];
420 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
422 for (i = 0; i < 3; i++) {
423 v = in[SPOFF(SSB_SPROM4_ET0MAC) + i];
424 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
426 for (i = 0; i < 3; i++) {
427 v = in[SPOFF(SSB_SPROM4_ET1MAC) + i];
428 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
430 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
431 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
432 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
433 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
434 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
435 SPEX(antenna_gain_a, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_0, 0);
436 SPEX(antenna_gain_bg, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_1,
437 SSB_SPROM4_AGAIN_1_SHIFT);
438 /* TODO - get remaining rev 4 stuff needed */
441 static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
442 const u16 *in, u16 size)
444 memset(out, 0, sizeof(*out));
446 out->revision = in[size - 1] & 0x00FF;
447 if ((bus->chip_id & 0xFF00) == 0x4400) {
448 /* Workaround: The BCM44XX chip has a stupid revision
449 * number stored in the SPROM.
450 * Always extract r1. */
452 sprom_extract_r123(out, in);
453 sprom_extract_r1(&out->r1, in);
454 } else if (bus->chip_id == 0x4321) {
455 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
457 sprom_extract_r4(out, in);
459 if (out->revision == 0)
461 if (out->revision >= 1 && out->revision <= 3) {
462 sprom_extract_r123(out, in);
463 sprom_extract_r1(&out->r1, in);
465 if (out->revision == 4)
466 sprom_extract_r4(out, in);
467 if (out->revision >= 5)
473 ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
474 "detected. Will extract v1\n", out->revision);
475 sprom_extract_r1(&out->r1, in);
479 static int ssb_pci_sprom_get(struct ssb_bus *bus,
480 struct ssb_sprom *sprom)
485 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
488 bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
489 sprom_do_read(bus, buf);
490 err = sprom_check_crc(buf, bus->sprom_size);
492 /* check for rev 4 sprom - has special signature */
493 if (buf [32] == 0x5372) {
494 ssb_printk(KERN_WARNING PFX "Extracting a rev 4"
497 buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
501 bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
502 sprom_do_read(bus, buf);
503 err = sprom_check_crc(buf, bus->sprom_size);
506 ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
507 " SPROM CRC (corrupt SPROM)\n");
509 err = sprom_extract(bus, sprom, buf, bus->sprom_size);
516 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
517 struct ssb_boardinfo *bi)
519 pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
521 pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
523 pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
527 int ssb_pci_get_invariants(struct ssb_bus *bus,
528 struct ssb_init_invariants *iv)
532 err = ssb_pci_sprom_get(bus, &iv->sprom);
535 ssb_pci_get_boardinfo(bus, &iv->boardinfo);
541 #ifdef CONFIG_SSB_DEBUG
542 static int ssb_pci_assert_buspower(struct ssb_bus *bus)
544 if (likely(bus->powered_up))
547 printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
548 "while accessing PCI MMIO space\n");
549 if (bus->power_warn_count <= 10) {
550 bus->power_warn_count++;
557 static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
563 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
565 struct ssb_bus *bus = dev->bus;
567 if (unlikely(ssb_pci_assert_buspower(bus)))
569 if (unlikely(bus->mapped_device != dev)) {
570 if (unlikely(ssb_pci_switch_core(bus, dev)))
573 return ioread16(bus->mmio + offset);
576 static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
578 struct ssb_bus *bus = dev->bus;
580 if (unlikely(ssb_pci_assert_buspower(bus)))
582 if (unlikely(bus->mapped_device != dev)) {
583 if (unlikely(ssb_pci_switch_core(bus, dev)))
586 return ioread32(bus->mmio + offset);
589 static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
591 struct ssb_bus *bus = dev->bus;
593 if (unlikely(ssb_pci_assert_buspower(bus)))
595 if (unlikely(bus->mapped_device != dev)) {
596 if (unlikely(ssb_pci_switch_core(bus, dev)))
599 iowrite16(value, bus->mmio + offset);
602 static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
604 struct ssb_bus *bus = dev->bus;
606 if (unlikely(ssb_pci_assert_buspower(bus)))
608 if (unlikely(bus->mapped_device != dev)) {
609 if (unlikely(ssb_pci_switch_core(bus, dev)))
612 iowrite32(value, bus->mmio + offset);
615 /* Not "static", as it's used in main.c */
616 const struct ssb_bus_ops ssb_pci_ops = {
617 .read16 = ssb_pci_read16,
618 .read32 = ssb_pci_read32,
619 .write16 = ssb_pci_write16,
620 .write32 = ssb_pci_write32,
623 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, u16 size)
627 for (i = 0; i < size; i++)
628 pos += snprintf(buf + pos, buf_len - pos - 1,
629 "%04X", swab16(sprom[i]) & 0xFFFF);
630 pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
635 static int hex2sprom(u16 *sprom, const char *dump, size_t len, u16 size)
639 unsigned long parsed;
645 memcpy(tmp, dump, 4);
647 parsed = simple_strtoul(tmp, NULL, 16);
648 sprom[cnt++] = swab16((u16)parsed);
654 static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
655 struct device_attribute *attr,
658 struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
664 bus = ssb_pci_dev_to_bus(pdev);
668 sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
672 /* Use interruptible locking, as the SPROM write might
673 * be holding the lock for several seconds. So allow userspace
674 * to cancel operation. */
676 if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
678 sprom_do_read(bus, sprom);
679 mutex_unlock(&bus->pci_sprom_mutex);
681 count = sprom2hex(sprom, buf, PAGE_SIZE, bus->sprom_size);
687 return err ? err : count;
690 static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
691 struct device_attribute *attr,
692 const char *buf, size_t count)
694 struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
697 int res = 0, err = -ENODEV;
699 bus = ssb_pci_dev_to_bus(pdev);
703 sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
706 err = hex2sprom(sprom, buf, count, bus->sprom_size);
711 err = sprom_check_crc(sprom, bus->sprom_size);
717 /* Use interruptible locking, as the SPROM write might
718 * be holding the lock for several seconds. So allow userspace
719 * to cancel operation. */
721 if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
723 err = ssb_devices_freeze(bus);
724 if (err == -EOPNOTSUPP) {
725 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
726 "No suspend support. Is CONFIG_PM enabled?\n");
730 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
733 res = sprom_do_write(bus, sprom);
734 err = ssb_devices_thaw(bus);
736 ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
738 mutex_unlock(&bus->pci_sprom_mutex);
744 return err ? err : count;
747 static DEVICE_ATTR(ssb_sprom, 0600,
748 ssb_pci_attr_sprom_show,
749 ssb_pci_attr_sprom_store);
751 void ssb_pci_exit(struct ssb_bus *bus)
753 struct pci_dev *pdev;
755 if (bus->bustype != SSB_BUSTYPE_PCI)
758 pdev = bus->host_pci;
759 device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
762 int ssb_pci_init(struct ssb_bus *bus)
764 struct pci_dev *pdev;
767 if (bus->bustype != SSB_BUSTYPE_PCI)
770 pdev = bus->host_pci;
771 mutex_init(&bus->pci_sprom_mutex);
772 err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);