diff options
author | Arend van Spriel <arend@broadcom.com> | 2015-02-06 12:36:42 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-02-26 08:14:14 -0500 |
commit | a1ce7a0d6a4f1ed178c075c9dc02a06f0c68ab70 (patch) | |
tree | 8eab1cd47968a44baf23a8f38c24bb2ff63e070c /drivers/net/wireless/brcm80211/brcmfmac | |
parent | ffdcad05968ccb9ca2bb66f0e72467aa87baf2c2 (diff) |
brcmfmac: use helper function for changing SDIO state
Changing the SDIO state of the driver involves changing the bus
interface state. Adding a helper function makes sure that knowledge
is in one place.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio.h | 21 |
3 files changed, 54 insertions, 26 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 7944224e3fc9..1f7e2f245e9e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -197,6 +197,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, | ||
201 | enum brcmf_sdiod_state state) | ||
202 | { | ||
203 | if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM || | ||
204 | state == sdiodev->state) | ||
205 | return; | ||
206 | |||
207 | brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state); | ||
208 | switch (sdiodev->state) { | ||
209 | case BRCMF_SDIOD_DATA: | ||
210 | /* any other state means bus interface is down */ | ||
211 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN); | ||
212 | break; | ||
213 | case BRCMF_SDIOD_DOWN: | ||
214 | /* transition from DOWN to DATA means bus interface is up */ | ||
215 | if (state == BRCMF_SDIOD_DATA) | ||
216 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP); | ||
217 | break; | ||
218 | default: | ||
219 | break; | ||
220 | } | ||
221 | sdiodev->state = state; | ||
222 | } | ||
223 | |||
200 | static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, | 224 | static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, |
201 | uint regaddr, u8 byte) | 225 | uint regaddr, u8 byte) |
202 | { | 226 | { |
@@ -269,12 +293,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, | |||
269 | return ret; | 293 | return ret; |
270 | } | 294 | } |
271 | 295 | ||
272 | static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev) | ||
273 | { | ||
274 | sdiodev->state = BRCMF_STATE_NOMEDIUM; | ||
275 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN); | ||
276 | } | ||
277 | |||
278 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | 296 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, |
279 | u8 regsz, void *data, bool write) | 297 | u8 regsz, void *data, bool write) |
280 | { | 298 | { |
@@ -282,7 +300,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
282 | s32 retry = 0; | 300 | s32 retry = 0; |
283 | int ret; | 301 | int ret; |
284 | 302 | ||
285 | if (sdiodev->state == BRCMF_STATE_NOMEDIUM) | 303 | if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |
286 | return -ENOMEDIUM; | 304 | return -ENOMEDIUM; |
287 | 305 | ||
288 | /* | 306 | /* |
@@ -308,7 +326,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
308 | retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | 326 | retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |
309 | 327 | ||
310 | if (ret == -ENOMEDIUM) | 328 | if (ret == -ENOMEDIUM) |
311 | brcmf_sdiod_nomedium_state(sdiodev); | 329 | brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |
312 | else if (ret != 0) { | 330 | else if (ret != 0) { |
313 | /* | 331 | /* |
314 | * SleepCSR register access can fail when | 332 | * SleepCSR register access can fail when |
@@ -331,7 +349,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | |||
331 | int err = 0, i; | 349 | int err = 0, i; |
332 | u8 addr[3]; | 350 | u8 addr[3]; |
333 | 351 | ||
334 | if (sdiodev->state == BRCMF_STATE_NOMEDIUM) | 352 | if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |
335 | return -ENOMEDIUM; | 353 | return -ENOMEDIUM; |
336 | 354 | ||
337 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; | 355 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; |
@@ -460,7 +478,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
460 | err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, | 478 | err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, |
461 | req_sz); | 479 | req_sz); |
462 | if (err == -ENOMEDIUM) | 480 | if (err == -ENOMEDIUM) |
463 | brcmf_sdiod_nomedium_state(sdiodev); | 481 | brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |
464 | return err; | 482 | return err; |
465 | } | 483 | } |
466 | 484 | ||
@@ -595,7 +613,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
595 | 613 | ||
596 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; | 614 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; |
597 | if (ret == -ENOMEDIUM) { | 615 | if (ret == -ENOMEDIUM) { |
598 | brcmf_sdiod_nomedium_state(sdiodev); | 616 | brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |
599 | break; | 617 | break; |
600 | } else if (ret != 0) { | 618 | } else if (ret != 0) { |
601 | brcmf_err("CMD53 sg block %s failed %d\n", | 619 | brcmf_err("CMD53 sg block %s failed %d\n", |
@@ -1050,6 +1068,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
1050 | bus_if->wowl_supported = true; | 1068 | bus_if->wowl_supported = true; |
1051 | #endif | 1069 | #endif |
1052 | 1070 | ||
1071 | brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); | ||
1053 | sdiodev->sleeping = false; | 1072 | sdiodev->sleeping = false; |
1054 | atomic_set(&sdiodev->suspend, false); | 1073 | atomic_set(&sdiodev->suspend, false); |
1055 | init_waitqueue_head(&sdiodev->idle_wait); | 1074 | init_waitqueue_head(&sdiodev->idle_wait); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c index 314ab0391867..f3c49c4201e9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c | |||
@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1909 | bus->rxpending = true; | 1909 | bus->rxpending = true; |
1910 | 1910 | ||
1911 | for (rd->seq_num = bus->rx_seq, rxleft = maxframes; | 1911 | for (rd->seq_num = bus->rx_seq, rxleft = maxframes; |
1912 | !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; | 1912 | !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA; |
1913 | rd->seq_num++, rxleft--) { | 1913 | rd->seq_num++, rxleft--) { |
1914 | 1914 | ||
1915 | /* Handle glomming separately */ | 1915 | /* Handle glomming separately */ |
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | /* Deflow-control stack if needed */ | 2417 | /* Deflow-control stack if needed */ |
2418 | if ((bus->sdiodev->state == BRCMF_STATE_DATA) && | 2418 | if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) && |
2419 | bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { | 2419 | bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { |
2420 | bus->txoff = false; | 2420 | bus->txoff = false; |
2421 | brcmf_txflowblock(bus->sdiodev->dev, false); | 2421 | brcmf_txflowblock(bus->sdiodev->dev, false); |
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev) | |||
2503 | bus->watchdog_tsk = NULL; | 2503 | bus->watchdog_tsk = NULL; |
2504 | } | 2504 | } |
2505 | 2505 | ||
2506 | if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { | 2506 | if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { |
2507 | sdio_claim_host(sdiodev->func[1]); | 2507 | sdio_claim_host(sdiodev->func[1]); |
2508 | 2508 | ||
2509 | /* Enable clock for device interrupts */ | 2509 | /* Enable clock for device interrupts */ |
@@ -2755,7 +2755,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) | |||
2755 | brcmf_sdio_sendfromq(bus, framecnt); | 2755 | brcmf_sdio_sendfromq(bus, framecnt); |
2756 | } | 2756 | } |
2757 | 2757 | ||
2758 | if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { | 2758 | if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) { |
2759 | brcmf_err("failed backplane access over SDIO, halting operation\n"); | 2759 | brcmf_err("failed backplane access over SDIO, halting operation\n"); |
2760 | atomic_set(&bus->intstatus, 0); | 2760 | atomic_set(&bus->intstatus, 0); |
2761 | } else if (atomic_read(&bus->intstatus) || | 2761 | } else if (atomic_read(&bus->intstatus) || |
@@ -3411,7 +3411,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, | |||
3411 | } | 3411 | } |
3412 | 3412 | ||
3413 | /* Allow full data communication using DPC from now on. */ | 3413 | /* Allow full data communication using DPC from now on. */ |
3414 | bus->sdiodev->state = BRCMF_STATE_DATA; | 3414 | brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); |
3415 | bcmerror = 0; | 3415 | bcmerror = 0; |
3416 | 3416 | ||
3417 | err: | 3417 | err: |
@@ -3557,7 +3557,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) | |||
3557 | return; | 3557 | return; |
3558 | } | 3558 | } |
3559 | 3559 | ||
3560 | if (bus->sdiodev->state != BRCMF_STATE_DATA) { | 3560 | if (bus->sdiodev->state != BRCMF_SDIOD_DATA) { |
3561 | brcmf_err("bus is down. we have nothing to do\n"); | 3561 | brcmf_err("bus is down. we have nothing to do\n"); |
3562 | return; | 3562 | return; |
3563 | } | 3563 | } |
@@ -3623,7 +3623,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) | |||
3623 | } | 3623 | } |
3624 | #ifdef DEBUG | 3624 | #ifdef DEBUG |
3625 | /* Poll for console output periodically */ | 3625 | /* Poll for console output periodically */ |
3626 | if (bus->sdiodev->state == BRCMF_STATE_DATA && | 3626 | if (bus->sdiodev->state == BRCMF_SDIOD_DATA && |
3627 | bus->console_interval != 0) { | 3627 | bus->console_interval != 0) { |
3628 | bus->console.count += BRCMF_WD_POLL_MS; | 3628 | bus->console.count += BRCMF_WD_POLL_MS; |
3629 | if (bus->console.count >= bus->console_interval) { | 3629 | if (bus->console.count >= bus->console_interval) { |
@@ -4242,7 +4242,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
4242 | destroy_workqueue(bus->brcmf_wq); | 4242 | destroy_workqueue(bus->brcmf_wq); |
4243 | 4243 | ||
4244 | if (bus->ci) { | 4244 | if (bus->ci) { |
4245 | if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { | 4245 | if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { |
4246 | sdio_claim_host(bus->sdiodev->func[1]); | 4246 | sdio_claim_host(bus->sdiodev->func[1]); |
4247 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); | 4247 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); |
4248 | /* Leave the device in state where it is | 4248 | /* Leave the device in state where it is |
@@ -4277,7 +4277,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) | |||
4277 | } | 4277 | } |
4278 | 4278 | ||
4279 | /* don't start the wd until fw is loaded */ | 4279 | /* don't start the wd until fw is loaded */ |
4280 | if (bus->sdiodev->state != BRCMF_STATE_DATA) | 4280 | if (bus->sdiodev->state != BRCMF_SDIOD_DATA) |
4281 | return; | 4281 | return; |
4282 | 4282 | ||
4283 | if (wdtick) { | 4283 | if (wdtick) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h index ec2586a8425c..a6cdc6061c3a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h | |||
@@ -155,11 +155,17 @@ | |||
155 | /* watchdog polling interval in ms */ | 155 | /* watchdog polling interval in ms */ |
156 | #define BRCMF_WD_POLL_MS 10 | 156 | #define BRCMF_WD_POLL_MS 10 |
157 | 157 | ||
158 | /* The state of the bus */ | 158 | /** |
159 | enum brcmf_sdio_state { | 159 | * enum brcmf_sdiod_state - the state of the bus. |
160 | BRCMF_STATE_DOWN, /* Device available, still initialising */ | 160 | * |
161 | BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ | 161 | * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC. |
162 | BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ | 162 | * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled. |
163 | * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible. | ||
164 | */ | ||
165 | enum brcmf_sdiod_state { | ||
166 | BRCMF_SDIOD_DOWN, | ||
167 | BRCMF_SDIOD_DATA, | ||
168 | BRCMF_SDIOD_NOMEDIUM | ||
163 | }; | 169 | }; |
164 | 170 | ||
165 | struct brcmf_sdreg { | 171 | struct brcmf_sdreg { |
@@ -194,7 +200,7 @@ struct brcmf_sdio_dev { | |||
194 | char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; | 200 | char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; |
195 | char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; | 201 | char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; |
196 | bool wowl_enabled; | 202 | bool wowl_enabled; |
197 | enum brcmf_sdio_state state; | 203 | enum brcmf_sdiod_state state; |
198 | }; | 204 | }; |
199 | 205 | ||
200 | /* sdio core registers */ | 206 | /* sdio core registers */ |
@@ -345,4 +351,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus); | |||
345 | void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); | 351 | void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); |
346 | void brcmf_sdio_wowl_config(struct device *dev, bool enabled); | 352 | void brcmf_sdio_wowl_config(struct device *dev, bool enabled); |
347 | 353 | ||
354 | void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, | ||
355 | enum brcmf_sdiod_state state); | ||
356 | |||
348 | #endif /* BRCMFMAC_SDIO_H */ | 357 | #endif /* BRCMFMAC_SDIO_H */ |