Commit a1ce7a0d authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo

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: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ffdcad05
...@@ -197,6 +197,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) ...@@ -197,6 +197,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
return 0; return 0;
} }
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
enum brcmf_sdiod_state state)
{
if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
state == sdiodev->state)
return;
brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
switch (sdiodev->state) {
case BRCMF_SDIOD_DATA:
/* any other state means bus interface is down */
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
break;
case BRCMF_SDIOD_DOWN:
/* transition from DOWN to DATA means bus interface is up */
if (state == BRCMF_SDIOD_DATA)
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
break;
default:
break;
}
sdiodev->state = state;
}
static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
uint regaddr, u8 byte) uint regaddr, u8 byte)
{ {
...@@ -269,12 +293,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, ...@@ -269,12 +293,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
return ret; return ret;
} }
static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev)
{
sdiodev->state = BRCMF_STATE_NOMEDIUM;
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
}
static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
u8 regsz, void *data, bool write) u8 regsz, void *data, bool write)
{ {
...@@ -282,7 +300,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, ...@@ -282,7 +300,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
s32 retry = 0; s32 retry = 0;
int ret; int ret;
if (sdiodev->state == BRCMF_STATE_NOMEDIUM) if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
return -ENOMEDIUM; return -ENOMEDIUM;
/* /*
...@@ -308,7 +326,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, ...@@ -308,7 +326,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
if (ret == -ENOMEDIUM) if (ret == -ENOMEDIUM)
brcmf_sdiod_nomedium_state(sdiodev); brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
else if (ret != 0) { else if (ret != 0) {
/* /*
* SleepCSR register access can fail when * SleepCSR register access can fail when
...@@ -331,7 +349,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) ...@@ -331,7 +349,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
int err = 0, i; int err = 0, i;
u8 addr[3]; u8 addr[3];
if (sdiodev->state == BRCMF_STATE_NOMEDIUM) if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
return -ENOMEDIUM; return -ENOMEDIUM;
addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
...@@ -460,7 +478,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, ...@@ -460,7 +478,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
req_sz); req_sz);
if (err == -ENOMEDIUM) if (err == -ENOMEDIUM)
brcmf_sdiod_nomedium_state(sdiodev); brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
return err; return err;
} }
...@@ -595,7 +613,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, ...@@ -595,7 +613,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
if (ret == -ENOMEDIUM) { if (ret == -ENOMEDIUM) {
brcmf_sdiod_nomedium_state(sdiodev); brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
break; break;
} else if (ret != 0) { } else if (ret != 0) {
brcmf_err("CMD53 sg block %s failed %d\n", brcmf_err("CMD53 sg block %s failed %d\n",
...@@ -1050,6 +1068,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, ...@@ -1050,6 +1068,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
bus_if->wowl_supported = true; bus_if->wowl_supported = true;
#endif #endif
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
sdiodev->sleeping = false; sdiodev->sleeping = false;
atomic_set(&sdiodev->suspend, false); atomic_set(&sdiodev->suspend, false);
init_waitqueue_head(&sdiodev->idle_wait); init_waitqueue_head(&sdiodev->idle_wait);
......
...@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->rxpending = true; bus->rxpending = true;
for (rd->seq_num = bus->rx_seq, rxleft = maxframes; for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
!bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA;
rd->seq_num++, rxleft--) { rd->seq_num++, rxleft--) {
/* Handle glomming separately */ /* Handle glomming separately */
...@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) ...@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
} }
/* Deflow-control stack if needed */ /* Deflow-control stack if needed */
if ((bus->sdiodev->state == BRCMF_STATE_DATA) && if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
bus->txoff = false; bus->txoff = false;
brcmf_txflowblock(bus->sdiodev->dev, false); brcmf_txflowblock(bus->sdiodev->dev, false);
...@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev) ...@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
bus->watchdog_tsk = NULL; bus->watchdog_tsk = NULL;
} }
if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
sdio_claim_host(sdiodev->func[1]); sdio_claim_host(sdiodev->func[1]);
/* Enable clock for device interrupts */ /* Enable clock for device interrupts */
...@@ -2755,7 +2755,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) ...@@ -2755,7 +2755,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_sendfromq(bus, framecnt); brcmf_sdio_sendfromq(bus, framecnt);
} }
if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
brcmf_err("failed backplane access over SDIO, halting operation\n"); brcmf_err("failed backplane access over SDIO, halting operation\n");
atomic_set(&bus->intstatus, 0); atomic_set(&bus->intstatus, 0);
} else if (atomic_read(&bus->intstatus) || } else if (atomic_read(&bus->intstatus) ||
...@@ -3411,7 +3411,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, ...@@ -3411,7 +3411,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
} }
/* Allow full data communication using DPC from now on. */ /* Allow full data communication using DPC from now on. */
bus->sdiodev->state = BRCMF_STATE_DATA; brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
bcmerror = 0; bcmerror = 0;
err: err:
...@@ -3557,7 +3557,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) ...@@ -3557,7 +3557,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
return; return;
} }
if (bus->sdiodev->state != BRCMF_STATE_DATA) { if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
brcmf_err("bus is down. we have nothing to do\n"); brcmf_err("bus is down. we have nothing to do\n");
return; return;
} }
...@@ -3623,7 +3623,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) ...@@ -3623,7 +3623,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
} }
#ifdef DEBUG #ifdef DEBUG
/* Poll for console output periodically */ /* Poll for console output periodically */
if (bus->sdiodev->state == BRCMF_STATE_DATA && if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
bus->console_interval != 0) { bus->console_interval != 0) {
bus->console.count += BRCMF_WD_POLL_MS; bus->console.count += BRCMF_WD_POLL_MS;
if (bus->console.count >= bus->console_interval) { if (bus->console.count >= bus->console_interval) {
...@@ -4242,7 +4242,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) ...@@ -4242,7 +4242,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
destroy_workqueue(bus->brcmf_wq); destroy_workqueue(bus->brcmf_wq);
if (bus->ci) { if (bus->ci) {
if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
sdio_claim_host(bus->sdiodev->func[1]); sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdio_clkctl(bus, CLK_AVAIL, false); brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
/* Leave the device in state where it is /* Leave the device in state where it is
...@@ -4277,7 +4277,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) ...@@ -4277,7 +4277,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
} }
/* don't start the wd until fw is loaded */ /* don't start the wd until fw is loaded */
if (bus->sdiodev->state != BRCMF_STATE_DATA) if (bus->sdiodev->state != BRCMF_SDIOD_DATA)
return; return;
if (wdtick) { if (wdtick) {
......
...@@ -155,11 +155,17 @@ ...@@ -155,11 +155,17 @@
/* watchdog polling interval in ms */ /* watchdog polling interval in ms */
#define BRCMF_WD_POLL_MS 10 #define BRCMF_WD_POLL_MS 10
/* The state of the bus */ /**
enum brcmf_sdio_state { * enum brcmf_sdiod_state - the state of the bus.
BRCMF_STATE_DOWN, /* Device available, still initialising */ *
BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC.
BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled.
* @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible.
*/
enum brcmf_sdiod_state {
BRCMF_SDIOD_DOWN,
BRCMF_SDIOD_DATA,
BRCMF_SDIOD_NOMEDIUM
}; };
struct brcmf_sdreg { struct brcmf_sdreg {
...@@ -194,7 +200,7 @@ struct brcmf_sdio_dev { ...@@ -194,7 +200,7 @@ struct brcmf_sdio_dev {
char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
bool wowl_enabled; bool wowl_enabled;
enum brcmf_sdio_state state; enum brcmf_sdiod_state state;
}; };
/* sdio core registers */ /* sdio core registers */
...@@ -345,4 +351,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus); ...@@ -345,4 +351,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus);
void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
void brcmf_sdio_wowl_config(struct device *dev, bool enabled); void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
enum brcmf_sdiod_state state);
#endif /* BRCMFMAC_SDIO_H */ #endif /* BRCMFMAC_SDIO_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment