diff options
| author | Rafał Miłecki <zajec5@gmail.com> | 2016-07-25 14:33:56 -0400 |
|---|---|---|
| committer | Kalle Valo <kvalo@codeaurora.org> | 2016-09-03 05:58:42 -0400 |
| commit | 3f37ec79dd21fbdbbab8143a48a87272b22fef22 (patch) | |
| tree | 252183a6ce36d8c314508f52e641c1439307f6bb | |
| parent | 441756b6a6e3818dc6f2e76b9526558d450ce778 (diff) | |
bcma: support BCM53573 series of wireless SoCs
BCM53573 seems to be the first series of Northstar family with wireless
on the chip. The base models are BCM53573-s (A0, A1) and there is also
BCM47189B0 which seems to be some small modification.
The only problem with these chipsets seems to be watchdog. It's totally
unavailable on 53573A0 / 53573A1 and preferable PMU watchdog is broken
on 53573B0 / 53573B1.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
| -rw-r--r-- | drivers/bcma/driver_chipcommon.c | 32 | ||||
| -rw-r--r-- | include/linux/bcma/bcma.h | 3 |
2 files changed, 32 insertions, 3 deletions
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index 921ce1834673..b4f6520e74f0 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c | |||
| @@ -36,12 +36,31 @@ u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc) | |||
| 36 | } | 36 | } |
| 37 | EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock); | 37 | EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock); |
| 38 | 38 | ||
| 39 | static bool bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc *cc) | ||
| 40 | { | ||
| 41 | struct bcma_bus *bus = cc->core->bus; | ||
| 42 | |||
| 43 | if (cc->capabilities & BCMA_CC_CAP_PMU) { | ||
| 44 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573) { | ||
| 45 | WARN(bus->chipinfo.rev <= 1, "No watchdog available\n"); | ||
| 46 | /* 53573B0 and 53573B1 have bugged PMU watchdog. It can | ||
| 47 | * be enabled but timer can't be bumped. Use CC one | ||
| 48 | * instead. | ||
| 49 | */ | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | return true; | ||
| 53 | } else { | ||
| 54 | return false; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 39 | static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc) | 58 | static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc) |
| 40 | { | 59 | { |
| 41 | struct bcma_bus *bus = cc->core->bus; | 60 | struct bcma_bus *bus = cc->core->bus; |
| 42 | u32 nb; | 61 | u32 nb; |
| 43 | 62 | ||
| 44 | if (cc->capabilities & BCMA_CC_CAP_PMU) { | 63 | if (bcma_core_cc_has_pmu_watchdog(cc)) { |
| 45 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) | 64 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) |
| 46 | nb = 32; | 65 | nb = 32; |
| 47 | else if (cc->core->id.rev < 26) | 66 | else if (cc->core->id.rev < 26) |
| @@ -95,9 +114,16 @@ static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc) | |||
| 95 | 114 | ||
| 96 | int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) | 115 | int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) |
| 97 | { | 116 | { |
| 117 | struct bcma_bus *bus = cc->core->bus; | ||
| 98 | struct bcm47xx_wdt wdt = {}; | 118 | struct bcm47xx_wdt wdt = {}; |
| 99 | struct platform_device *pdev; | 119 | struct platform_device *pdev; |
| 100 | 120 | ||
| 121 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573 && | ||
| 122 | bus->chipinfo.rev <= 1) { | ||
| 123 | pr_debug("No watchdog on 53573A0 / 53573A1\n"); | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 101 | wdt.driver_data = cc; | 127 | wdt.driver_data = cc; |
| 102 | wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; | 128 | wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; |
| 103 | wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; | 129 | wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; |
| @@ -105,7 +131,7 @@ int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) | |||
| 105 | bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; | 131 | bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; |
| 106 | 132 | ||
| 107 | pdev = platform_device_register_data(NULL, "bcm47xx-wdt", | 133 | pdev = platform_device_register_data(NULL, "bcm47xx-wdt", |
| 108 | cc->core->bus->num, &wdt, | 134 | bus->num, &wdt, |
| 109 | sizeof(wdt)); | 135 | sizeof(wdt)); |
| 110 | if (IS_ERR(pdev)) | 136 | if (IS_ERR(pdev)) |
| 111 | return PTR_ERR(pdev); | 137 | return PTR_ERR(pdev); |
| @@ -217,7 +243,7 @@ u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) | |||
| 217 | u32 maxt; | 243 | u32 maxt; |
| 218 | 244 | ||
| 219 | maxt = bcma_chipco_watchdog_get_max_timer(cc); | 245 | maxt = bcma_chipco_watchdog_get_max_timer(cc); |
| 220 | if (cc->capabilities & BCMA_CC_CAP_PMU) { | 246 | if (bcma_core_cc_has_pmu_watchdog(cc)) { |
| 221 | if (ticks == 1) | 247 | if (ticks == 1) |
| 222 | ticks = 2; | 248 | ticks = 2; |
| 223 | else if (ticks > maxt) | 249 | else if (ticks > maxt) |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 3db25df396cb..8eeedb2db924 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
| @@ -205,6 +205,9 @@ struct bcma_host_ops { | |||
| 205 | #define BCMA_PKG_ID_BCM4709 0 | 205 | #define BCMA_PKG_ID_BCM4709 0 |
| 206 | #define BCMA_CHIP_ID_BCM47094 53030 | 206 | #define BCMA_CHIP_ID_BCM47094 53030 |
| 207 | #define BCMA_CHIP_ID_BCM53018 53018 | 207 | #define BCMA_CHIP_ID_BCM53018 53018 |
| 208 | #define BCMA_CHIP_ID_BCM53573 53573 | ||
| 209 | #define BCMA_PKG_ID_BCM53573 0 | ||
| 210 | #define BCMA_PKG_ID_BCM47189 1 | ||
| 208 | 211 | ||
| 209 | /* Board types (on PCI usually equals to the subsystem dev id) */ | 212 | /* Board types (on PCI usually equals to the subsystem dev id) */ |
| 210 | /* BCM4313 */ | 213 | /* BCM4313 */ |
