static void cpwm_event_callback(struct work_struct *work) { struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event); struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv); _adapter *adapter = dvobj->if1; struct reportpwrstate_parm report; /* DBG_871X("%s\n", __FUNCTION__); */ report.state = PS_STATE_S2; cpwm_int_hdl(adapter, &report); }
static void rpwmtimeout_workitem_callback(struct work_struct *work) { PADAPTER padapter; struct dvobj_priv *dvobj; struct pwrctrl_priv *pwrpriv; pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi); dvobj = pwrctl_to_dvobj(pwrpriv); padapter = dvobj->if1; /* DBG_871X("+%s: rpwm =0x%02X cpwm =0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); */ down(&pwrpriv->lock); if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) { DBG_871X("%s: rpwm =0x%02X cpwm =0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); goto exit; } up(&pwrpriv->lock); if (rtw_read8(padapter, 0x100) != 0xEA) { struct reportpwrstate_parm report; report.state = PS_STATE_S2; DBG_871X("\n%s: FW already leave 32K!\n\n", __func__); cpwm_int_hdl(padapter, &report); return; } down(&pwrpriv->lock); if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) { DBG_871X("%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm); goto exit; } pwrpriv->brpwmtimeout = true; rtw_set_rpwm(padapter, pwrpriv->rpwm); pwrpriv->brpwmtimeout = false; exit: up(&pwrpriv->lock); }
void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr) { PHAL_DATA_TYPE phal; static u32 last_c2h; phal = GET_HAL_DATA(padapter); if (sdio_hisr & SPI_HISR_CPWM1) { struct reportpwrstate_parm report; report.state = spi_read8(padapter, SPI_LOCAL_OFFSET | SDIO_REG_HCPWM1, NULL); #ifdef CONFIG_LPS_LCLK cpwm_int_hdl(padapter, &report); #endif } if (sdio_hisr & SPI_HISR_TXERR) { u32 status; status = rtw_read32(padapter, REG_TXDMA_STATUS); rtw_write32(padapter, REG_TXDMA_STATUS, status); //DBG_8192C("%s: SPI_HISR_TXERR (0x%08x)\n", __func__, status); } if (sdio_hisr & SPI_HISR_TXBCNOK) { DBG_8192C("%s: SPI_HISR_TXBCNOK\n", __func__); } if (sdio_hisr & SPI_HISR_TXBCNERR) { DBG_8192C("%s: SPI_HISR_TXBCNERR\n", __func__); } if (sdio_hisr & SPI_HISR_C2HCMD) { DBG_8192C("%s: C2H Command\n", __func__); last_c2h = rtw_c2h_wk_cmd(padapter); } else if (last_c2h != _SUCCESS) { /* check C2H stuck */ u8 have_c2h = 0; have_c2h = rtw_read8(padapter, REG_C2HEVT_CLEAR); if (have_c2h) { DBG_871X_LEVEL(_drv_err_, "%s: c2h stuck\n", __FUNCTION__); last_c2h = rtw_c2h_wk_cmd(padapter); } else { last_c2h = _SUCCESS; } } if (sdio_hisr & SPI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW) { struct dvobj_priv *dvobj = padapter->dvobj; PGSPI_DATA pgspi_data = &dvobj->intf_data; if (pgspi_data->priv_wq) queue_delayed_work(pgspi_data->priv_wq, &pgspi_data->recv_work, 0); } }
/* * * Parameters * padapter * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 * */ void rtw_set_rpwm(PADAPTER padapter, u8 pslv) { u8 rpwm; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; _func_enter_; pslv = PS_STATE(pslv); if (_TRUE ==padapter->pwrctrlpriv.btcoex_rfon) { if (pslv < PS_STATE_S4) pslv = PS_STATE_S3; if (pwrpriv->rpwm == pslv) { struct reportpwrstate_parm report; report.state = PS_STATE_S3; #ifdef CONFIG_LPS_LCLK cpwm_int_hdl(padapter, &report); #endif return; } } #ifdef CONFIG_LPS_RPWM_TIMER if (pwrpriv->brpwmtimeout == _TRUE) { DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __FUNCTION__, pslv); } else #endif // CONFIG_LPS_RPWM_TIMER { if ( (pwrpriv->rpwm == pslv) #ifdef CONFIG_LPS_LCLK || ((pwrpriv->rpwm >= PS_STATE_S2)&&(pslv >= PS_STATE_S2)) #endif ) { RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_, ("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __FUNCTION__, pwrpriv->rpwm, pslv)); return; } } if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->hw_init_completed == _FALSE)) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->hw_init_completed)); pwrpriv->cpwm = PS_STATE_S4; return; } if (padapter->bDriverStopped == _TRUE) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("%s: change power state(0x%02X) when DriverStopped\n", __FUNCTION__, pslv)); if (pslv < PS_STATE_S2) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __FUNCTION__, pslv)); return; } } rpwm = pslv | pwrpriv->tog; #ifdef CONFIG_LPS_LCLK // only when from PS_STATE S0/S1 to S2 and higher needs ACK if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2)) rpwm |= PS_ACK; #endif RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm)); pwrpriv->rpwm = pslv; #ifdef CONFIG_LPS_RPWM_TIMER if (rpwm & PS_ACK) _set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS); #endif // CONFIG_LPS_RPWM_TIMER rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); pwrpriv->tog += 0x80; if (_TRUE == padapter->pwrctrlpriv.btcoex_rfon) { struct reportpwrstate_parm report; report.state = pslv; #ifdef CONFIG_LPS_LCLK cpwm_int_hdl(padapter, &report); #endif } else { #ifdef CONFIG_LPS_LCLK // No LPS 32K, No Ack if (!(rpwm & PS_ACK)) #endif { pwrpriv->cpwm = pslv; } } _func_exit_; }