[PATCH] Clean up DXE's IRQ handling

Eugene Krasnikov k.eugene.e at gmail.com
Thu Apr 18 17:28:18 EDT 2013


Nice, please send pull request.

2013/4/18 Pontus Fuchs <pontus.fuchs at gmail.com>:
> From: Pontus Fuchs <pontus2.fuchs at sonymobile.com>
>
> Free irq's on shutdown
> Check for errors
> Refactor and move irq allocation to dxe_init
> ---
>  dxe.c  |  256 +++++++++++++++++++++++++++++++++++-----------------------------
>  dxe.h  |    2 +-
>  main.c |    2 +-
>  3 files changed, 142 insertions(+), 118 deletions(-)
>
> diff --git a/dxe.c b/dxe.c
> index 4033eb8..daf25b2 100644
> --- a/dxe.c
> +++ b/dxe.c
> @@ -209,115 +209,6 @@ static int wcn36xx_dxe_ch_alloc_skb(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *
>         }
>         return 0;
>  }
> -int wcn36xx_dxe_init(struct wcn36xx *wcn)
> -{
> -       int reg_data = 0;
> -
> -       reg_data = WCN36XX_DXE_REG_RESET;
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data);
> -
> -       // Setting interrupt path
> -       reg_data = WCN36XX_DXE_CCU_INT;
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data);
> -
> -       /***************************************/
> -       /* Init descriptors for TX LOW channel */
> -       /***************************************/
> -       wcn36xx_dxe_init_descs(&wcn->dxe_tx_l_ch);
> -
> -       // Write chanel head to a NEXT register
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L,
> -               wcn->dxe_tx_l_ch.head_blk_ctl->desc_phy_addr);
> -
> -       // Program DMA destination addr for TX LOW
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_DEST_ADDR_TX_L,
> -               WCN36XX_DXE_WQ_TX_L);
> -
> -       wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
> -       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L);
> -
> -       /***************************************/
> -       /* Init descriptors for TX HIGH channel */
> -       /***************************************/
> -       wcn36xx_dxe_init_descs(&wcn->dxe_tx_h_ch);
> -
> -       // Write chanel head to a NEXT register
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H,
> -               wcn->dxe_tx_h_ch.head_blk_ctl->desc_phy_addr);
> -
> -       // Program DMA destination addr for TX HIGH
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_DEST_ADDR_TX_H,
> -               WCN36XX_DXE_WQ_TX_H);
> -
> -       wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
> -       // Enable channel interrupts
> -       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H);
> -
> -       /***************************************/
> -       /* Init descriptors for RX LOW channel */
> -       /***************************************/
> -       wcn36xx_dxe_init_descs(&wcn->dxe_rx_l_ch);
> -
> -       // For RX we need to prealocat buffers
> -       wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch);
> -
> -       // Write chanel head to a NEXT register
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L,
> -               wcn->dxe_rx_l_ch.head_blk_ctl->desc_phy_addr);
> -
> -       // Write DMA source address
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_SRC_ADDR_RX_L,
> -               WCN36XX_DXE_WQ_RX_L);
> -
> -       // Program preallocated destionatio Address
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_DEST_ADDR_RX_L,
> -               wcn->dxe_rx_l_ch.head_blk_ctl->desc->desc.phy_next_l);
> -
> -
> -       // Enable default control registers
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_REG_CTL_RX_L,
> -               WCN36XX_DXE_CH_DEFAULT_CTL_RX_L);
> -
> -       // Enable channel interrupts
> -       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L);
> -
> -       /***************************************/
> -       /* Init descriptors for RX HIGH channel */
> -       /***************************************/
> -       wcn36xx_dxe_init_descs(&wcn->dxe_rx_h_ch);
> -
> -       // For RX we need to prealocat buffers
> -       wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_h_ch);
> -
> -       // Write chanel head to a NEXT register
> -       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H,
> -               wcn->dxe_rx_h_ch.head_blk_ctl->desc_phy_addr);
> -
> -       // Write DMA source address
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_SRC_ADDR_RX_H,
> -               WCN36XX_DXE_WQ_RX_H);
> -
> -       // Program preallocated destionatio Address
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_CH_DEST_ADDR_RX_H,
> -                wcn->dxe_rx_h_ch.head_blk_ctl->desc->desc.phy_next_l);
> -
> -       // Enable default control registers
> -       wcn36xx_dxe_write_register(wcn,
> -               WCN36XX_DXE_REG_CTL_RX_H,
> -               WCN36XX_DXE_CH_DEFAULT_CTL_RX_H);
> -
> -       // Enable channel interrupts
> -       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H);
> -
> -       return 0;
> -}
>
>  static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
>  {
> @@ -333,19 +224,25 @@ static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev)
>         queue_work(wcn->ctl_wq, &wcn->rx_ready_work);
>         return IRQ_HANDLED;
>  }
> -int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn) {
> +static int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn)
> +{
> +       int ret;
>
>         ENTER();
>         // Register TX complete irq
> -       if (request_irq(wcn->tx_irq, wcn36xx_irq_tx_complete, IRQF_TRIGGER_HIGH,
> -                           "wcnss_wlan", wcn)) {
> -               return -EIO;
> +       ret =request_irq(wcn->tx_irq, wcn36xx_irq_tx_complete, IRQF_TRIGGER_HIGH,
> +                           "wcn36xx_tx", wcn);
> +       if (ret) {
> +               wcn36xx_error("failed to alloc tx irq");
> +               goto out_err;
>         }
>
>         // Register RX irq
> -       if (request_irq(wcn->rx_irq, wcn36xx_irq_rx_ready, IRQF_TRIGGER_HIGH,
> -                           "wcnss_wlan", wcn)){
> -               return -EIO;
> +       ret = request_irq(wcn->rx_irq, wcn36xx_irq_rx_ready, IRQF_TRIGGER_HIGH,
> +                           "wcn36xx_rx", wcn);
> +       if (ret) {
> +               wcn36xx_error("failed to alloc rx irq");
> +               goto out_txirq;
>         }
>         // disable tx irq, not supported
>         disable_irq_nosync(wcn->tx_irq);
> @@ -353,6 +250,12 @@ int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn) {
>         // enable rx irq
>         enable_irq_wake(wcn->rx_irq);
>         return 0;
> +
> +out_txirq:
> +       free_irq(wcn->tx_irq, wcn);
> +out_err:
> +       return -ret;
> +
>  }
>  void wcn36xx_rx_ready_work(struct work_struct *work)
>  {
> @@ -464,3 +367,124 @@ int wcn36xx_dxe_tx(struct wcn36xx *wcn, struct sk_buff *skb, u8 broadcast)
>                 WCN36XX_DXE_CH_DEFAULT_CTL_TX_H);
>         return 0;
>  }
> +int wcn36xx_dxe_init(struct wcn36xx *wcn)
> +{
> +       int reg_data = 0, ret;
> +
> +       reg_data = WCN36XX_DXE_REG_RESET;
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data);
> +
> +       // Setting interrupt path
> +       reg_data = WCN36XX_DXE_CCU_INT;
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data);
> +
> +       /***************************************/
> +       /* Init descriptors for TX LOW channel */
> +       /***************************************/
> +       wcn36xx_dxe_init_descs(&wcn->dxe_tx_l_ch);
> +
> +       // Write chanel head to a NEXT register
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L,
> +               wcn->dxe_tx_l_ch.head_blk_ctl->desc_phy_addr);
> +
> +       // Program DMA destination addr for TX LOW
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_DEST_ADDR_TX_L,
> +               WCN36XX_DXE_WQ_TX_L);
> +
> +       wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
> +       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L);
> +
> +       /***************************************/
> +       /* Init descriptors for TX HIGH channel */
> +       /***************************************/
> +       wcn36xx_dxe_init_descs(&wcn->dxe_tx_h_ch);
> +
> +       // Write chanel head to a NEXT register
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H,
> +               wcn->dxe_tx_h_ch.head_blk_ctl->desc_phy_addr);
> +
> +       // Program DMA destination addr for TX HIGH
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_DEST_ADDR_TX_H,
> +               WCN36XX_DXE_WQ_TX_H);
> +
> +       wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, &reg_data);
> +       // Enable channel interrupts
> +       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H);
> +
> +       /***************************************/
> +       /* Init descriptors for RX LOW channel */
> +       /***************************************/
> +       wcn36xx_dxe_init_descs(&wcn->dxe_rx_l_ch);
> +
> +       // For RX we need to prealocat buffers
> +       wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch);
> +
> +       // Write chanel head to a NEXT register
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L,
> +               wcn->dxe_rx_l_ch.head_blk_ctl->desc_phy_addr);
> +
> +       // Write DMA source address
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_SRC_ADDR_RX_L,
> +               WCN36XX_DXE_WQ_RX_L);
> +
> +       // Program preallocated destionatio Address
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_DEST_ADDR_RX_L,
> +               wcn->dxe_rx_l_ch.head_blk_ctl->desc->desc.phy_next_l);
> +
> +
> +       // Enable default control registers
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_REG_CTL_RX_L,
> +               WCN36XX_DXE_CH_DEFAULT_CTL_RX_L);
> +
> +       // Enable channel interrupts
> +       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L);
> +
> +       /***************************************/
> +       /* Init descriptors for RX HIGH channel */
> +       /***************************************/
> +       wcn36xx_dxe_init_descs(&wcn->dxe_rx_h_ch);
> +
> +       // For RX we need to prealocat buffers
> +       wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_h_ch);
> +
> +       // Write chanel head to a NEXT register
> +       wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H,
> +               wcn->dxe_rx_h_ch.head_blk_ctl->desc_phy_addr);
> +
> +       // Write DMA source address
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_SRC_ADDR_RX_H,
> +               WCN36XX_DXE_WQ_RX_H);
> +
> +       // Program preallocated destionatio Address
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_CH_DEST_ADDR_RX_H,
> +                wcn->dxe_rx_h_ch.head_blk_ctl->desc->desc.phy_next_l);
> +
> +       // Enable default control registers
> +       wcn36xx_dxe_write_register(wcn,
> +               WCN36XX_DXE_REG_CTL_RX_H,
> +               WCN36XX_DXE_CH_DEFAULT_CTL_RX_H);
> +
> +       // Enable channel interrupts
> +       wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H);
> +
> +       ret = wcn36xx_dxe_request_irqs(wcn);
> +       if (ret < 0)
> +               goto out_err;
> +       return 0;
> +
> +out_err:
> +       return ret;
> +}
> +
> +void wcn36xx_dxe_deinit(struct wcn36xx *wcn)
> +{
> +       free_irq(wcn->tx_irq, wcn);
> +       free_irq(wcn->rx_irq, wcn);
> +}
> diff --git a/dxe.h b/dxe.h
> index b16d48c..a8c0638 100644
> --- a/dxe.h
> +++ b/dxe.h
> @@ -209,7 +209,7 @@ int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
>  void wcn36xx_rx_ready_work(struct work_struct *work);
>  int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn);
>  int wcn36xx_dxe_init(struct wcn36xx *wcn);
> +void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
>  int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
> -int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn);
>  int wcn36xx_dxe_tx(struct wcn36xx *wcn, struct sk_buff *skb, u8 broadcast);
>  #endif /* _DXE_H_ */
> diff --git a/main.c b/main.c
> index 156e97e..0eb675a 100644
> --- a/main.c
> +++ b/main.c
> @@ -67,7 +67,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
>
>         // DMA chanel initialization
>         wcn36xx_dxe_init(wcn);
> -       wcn36xx_dxe_request_irqs(wcn);
>
>         return 0;
>  }
> @@ -77,6 +76,7 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
>
>         ENTER();
>
> +       wcn36xx_dxe_deinit(wcn);
>         wcn36xx_smd_close(wcn);
>
>         kfree(wcn->smd_buf);
> --
> 1.7.10.4
>
>
> _______________________________________________
> wcn36xx mailing list
> wcn36xx at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx



-- 
Best regards,
Eugene



More information about the wcn36xx mailing list