diff options
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 2 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 5 | ||||
-rw-r--r-- | drivers/ssb/sprom.c | 14 | ||||
-rw-r--r-- | include/linux/ssb/ssb.h | 3 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_chipcommon.h | 15 |
5 files changed, 39 insertions, 0 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 59c3c0fdbec..59ae76bace1 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -233,6 +233,8 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) | |||
233 | { | 233 | { |
234 | if (!cc->dev) | 234 | if (!cc->dev) |
235 | return; /* We don't have a ChipCommon */ | 235 | return; /* We don't have a ChipCommon */ |
236 | if (cc->dev->id.revision >= 11) | ||
237 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); | ||
236 | ssb_pmu_init(cc); | 238 | ssb_pmu_init(cc); |
237 | chipco_powercontrol_init(cc); | 239 | chipco_powercontrol_init(cc); |
238 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); | 240 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 9e50896233a..a4b2b99f2c8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -620,6 +620,11 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
620 | int err = -ENOMEM; | 620 | int err = -ENOMEM; |
621 | u16 *buf; | 621 | u16 *buf; |
622 | 622 | ||
623 | if (!ssb_is_sprom_available(bus)) { | ||
624 | ssb_printk(KERN_ERR PFX "No SPROM available!\n"); | ||
625 | return -ENODEV; | ||
626 | } | ||
627 | |||
623 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); | 628 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); |
624 | if (!buf) | 629 | if (!buf) |
625 | goto out; | 630 | goto out; |
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index d0e6762fec5..83bc088b941 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c | |||
@@ -175,3 +175,17 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void) | |||
175 | { | 175 | { |
176 | return fallback_sprom; | 176 | return fallback_sprom; |
177 | } | 177 | } |
178 | |||
179 | /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ | ||
180 | bool ssb_is_sprom_available(struct ssb_bus *bus) | ||
181 | { | ||
182 | /* status register only exists on chipcomon rev >= 11 and we need check | ||
183 | for >= 31 only */ | ||
184 | /* this routine differs from specs as we do not access SPROM directly | ||
185 | on PCMCIA */ | ||
186 | if (bus->bustype == SSB_BUSTYPE_PCI && | ||
187 | bus->chipco.dev->id.revision >= 31) | ||
188 | return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; | ||
189 | |||
190 | return true; | ||
191 | } | ||
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 24f98854736..3b4da233e31 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -394,6 +394,9 @@ extern int ssb_bus_sdiobus_register(struct ssb_bus *bus, | |||
394 | 394 | ||
395 | extern void ssb_bus_unregister(struct ssb_bus *bus); | 395 | extern void ssb_bus_unregister(struct ssb_bus *bus); |
396 | 396 | ||
397 | /* Does the device have an SPROM? */ | ||
398 | extern bool ssb_is_sprom_available(struct ssb_bus *bus); | ||
399 | |||
397 | /* Set a fallback SPROM. | 400 | /* Set a fallback SPROM. |
398 | * See kdoc at the function definition for complete documentation. */ | 401 | * See kdoc at the function definition for complete documentation. */ |
399 | extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); | 402 | extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); |
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 4e27acf0a92..2cdf249b4e5 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */ | 53 | #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */ |
54 | #define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ | 54 | #define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ |
55 | #define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ | 55 | #define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ |
56 | #define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */ | ||
56 | #define SSB_CHIPCO_CORECTL 0x0008 | 57 | #define SSB_CHIPCO_CORECTL 0x0008 |
57 | #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ | 58 | #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ |
58 | #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ | 59 | #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ |
@@ -385,6 +386,7 @@ | |||
385 | 386 | ||
386 | 387 | ||
387 | /** Chip specific Chip-Status register contents. */ | 388 | /** Chip specific Chip-Status register contents. */ |
389 | #define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */ | ||
388 | #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003 | 390 | #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003 |
389 | #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ | 391 | #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ |
390 | #define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ | 392 | #define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ |
@@ -398,6 +400,18 @@ | |||
398 | #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4 | 400 | #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4 |
399 | #define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */ | 401 | #define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */ |
400 | 402 | ||
403 | /** Macros to determine SPROM presence based on Chip-Status register. */ | ||
404 | #define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \ | ||
405 | ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ | ||
406 | SSB_CHIPCO_CHST_4325_OTP_SEL) | ||
407 | #define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \ | ||
408 | (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS) | ||
409 | #define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \ | ||
410 | (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ | ||
411 | SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \ | ||
412 | ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ | ||
413 | SSB_CHIPCO_CHST_4325_OTP_SEL)) | ||
414 | |||
401 | 415 | ||
402 | 416 | ||
403 | /** Clockcontrol masks and values **/ | 417 | /** Clockcontrol masks and values **/ |
@@ -564,6 +578,7 @@ struct ssb_chipcommon_pmu { | |||
564 | struct ssb_chipcommon { | 578 | struct ssb_chipcommon { |
565 | struct ssb_device *dev; | 579 | struct ssb_device *dev; |
566 | u32 capabilities; | 580 | u32 capabilities; |
581 | u32 status; | ||
567 | /* Fast Powerup Delay constant */ | 582 | /* Fast Powerup Delay constant */ |
568 | u16 fast_pwrup_delay; | 583 | u16 fast_pwrup_delay; |
569 | struct ssb_chipcommon_pmu pmu; | 584 | struct ssb_chipcommon_pmu pmu; |