Loading drivers/tty/serial/msm_serial_hs.c +45 −18 Original line number Diff line number Diff line Loading @@ -336,6 +336,7 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) { int rc = 0; mutex_lock(&msm_uport->clk_mutex); if (1 == atomic_inc_return(&msm_uport->clk_count)) { msm_hs_bus_voting(msm_uport, BUS_SCALING); /* Turn on core clk and iface clk */ Loading @@ -345,6 +346,7 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) dev_err(msm_uport->uport.dev, "%s: Could not turn on pclk [%d]\n", __func__, rc); mutex_unlock(&msm_uport->clk_mutex); return rc; } } Loading @@ -355,11 +357,13 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) "%s: Could not turn on core clk [%d]\n", __func__, rc); clk_disable_unprepare(msm_uport->pclk); mutex_unlock(&msm_uport->clk_mutex); return rc; } msm_uport->clk_state = MSM_HS_CLK_ON; MSM_HS_DBG("%s: Clock ON successful\n", __func__); } mutex_unlock(&msm_uport->clk_mutex); return rc; Loading @@ -376,6 +380,7 @@ static void msm_hs_clock_unvote(struct msm_hs_port *msm_uport) return; } mutex_lock(&msm_uport->clk_mutex); rc = atomic_dec_return(&msm_uport->clk_count); if (0 == rc) { /* Turn off the core clk and iface clk*/ Loading @@ -387,6 +392,7 @@ static void msm_hs_clock_unvote(struct msm_hs_port *msm_uport) msm_uport->clk_state = MSM_HS_CLK_OFF; MSM_HS_DBG("%s: Clock OFF successful\n", __func__); } mutex_unlock(&msm_uport->clk_mutex); } /* Check if the uport line number matches with user id stored in pdata. Loading Loading @@ -1821,8 +1827,6 @@ static int msm_hs_check_clock_off(struct uart_port *uport) if (msm_uport->clk_state != MSM_HS_CLK_REQUEST_OFF || !uart_circ_empty(tx_buf) || msm_uport->tx.dma_in_flight || msm_uport->imr_reg & UARTDM_ISR_TXLEV_BMSK) { spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) { msm_uport->clk_state = MSM_HS_CLK_ON; /* Pulling RFR line high */ Loading @@ -1833,6 +1837,8 @@ static int msm_hs_check_clock_off(struct uart_port *uport) msm_hs_write(uport, UART_DM_MR1, data); mb(); } spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); MSM_HS_DBG("%s(): clkstate %d", __func__, msm_uport->clk_state); return -1; } Loading Loading @@ -1870,7 +1876,9 @@ static int msm_hs_check_clock_off(struct uart_port *uport) mb(); /* we really want to clock off */ mutex_unlock(&msm_uport->clk_mutex); msm_hs_clock_unvote(msm_uport); mutex_lock(&msm_uport->clk_mutex); spin_lock_irqsave(&uport->lock, flags); if (use_low_power_wakeup(msm_uport)) { Loading Loading @@ -2091,7 +2099,9 @@ void msm_hs_request_clock_on(struct uart_port *uport) } spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); ret = msm_hs_clock_vote(msm_uport); mutex_lock(&msm_uport->clk_mutex); if (ret) { MSM_HS_INFO("Clock ON Failure" "For UART CLK Stalling HSUART\n"); Loading @@ -2106,8 +2116,10 @@ void msm_hs_request_clock_on(struct uart_port *uport) spin_unlock_irqrestore(&uport->lock, flags); MSM_HS_DBG("%s:Calling wait forxcompletion\n", __func__); mutex_unlock(&msm_uport->clk_mutex); ret = wait_event_timeout(msm_uport->bam_disconnect_wait, msm_uport->rx.flush == FLUSH_SHUTDOWN, 300); mutex_lock(&msm_uport->clk_mutex); if (!ret) MSM_HS_ERR("BAM Disconnect not happened\n"); spin_lock_irqsave(&uport->lock, flags); Loading Loading @@ -3180,8 +3192,25 @@ static void msm_hs_shutdown(struct uart_port *uport) struct msm_hs_tx *tx = &msm_uport->tx; struct sps_pipe *sps_pipe_handle = tx->cons.pipe_handle; MSM_HS_INFO("%s()\n", __func__); msm_hs_clock_vote(msm_uport); /* * cancel the hrtimer first so that * clk_state can not change in flight */ hrtimer_cancel(&msm_uport->clk_off_timer); flush_work(&msm_uport->clock_off_w); if (use_low_power_wakeup(msm_uport)) irq_set_irq_wake(msm_uport->wakeup.irq, 0); /* wake irq or uart irq is active depending on clk_state */ if (msm_uport->clk_state == MSM_HS_CLK_OFF) { if (use_low_power_wakeup(msm_uport)) disable_irq(msm_uport->wakeup.irq); } else { disable_irq(uport->irq); wake_unlock(&msm_uport->dma_wake_lock); } /* make sure tx tasklet finishes */ tasklet_kill(&msm_uport->tx.tlet); ret = wait_event_timeout(msm_uport->tx.wait, Loading @@ -3189,21 +3218,20 @@ static void msm_hs_shutdown(struct uart_port *uport) if (!ret) MSM_HS_WARN("Shutdown called when tx buff not empty"); /* BAM Disconnect for TX */ ret = sps_disconnect(sps_pipe_handle); if (ret) MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__); /* make sure rx tasklet finishes */ tasklet_kill(&msm_uport->rx.tlet); wait_event(msm_uport->rx.wait, msm_uport->rx.flush == FLUSH_SHUTDOWN); cancel_delayed_work_sync(&msm_uport->rx.flip_insert_work); flush_workqueue(msm_uport->hsuart_wq); WARN_ON(msm_uport->rx.flush < FLUSH_STOP); pm_runtime_disable(uport->dev); msm_uport->rx.buffer_pending = NONE_PENDING; MSM_HS_DBG("%s(): tx, rx events complete", __func__); msm_hs_clock_vote(msm_uport); mutex_lock(&msm_uport->clk_mutex); /* BAM Disconnect for TX */ ret = sps_disconnect(sps_pipe_handle); if (ret) MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__); WARN_ON(msm_uport->rx.flush < FLUSH_STOP); /* Disable the transmitter */ msm_hs_write(uport, UART_DM_CR, UARTDM_CR_TX_DISABLE_BMSK); /* Disable the receiver */ Loading @@ -3216,22 +3244,21 @@ static void msm_hs_shutdown(struct uart_port *uport) * Hence mb() requires here. */ mb(); mutex_unlock(&msm_uport->clk_mutex); hrtimer_cancel(&msm_uport->clk_off_timer); msm_uport->rx.buffer_pending = NONE_PENDING; MSM_HS_DBG("%s(): tx, rx events complete", __func__); msm_hs_clock_unvote(msm_uport); if (msm_uport->clk_state != MSM_HS_CLK_OFF) { /* to balance clk_state */ msm_hs_clock_unvote(msm_uport); wake_unlock(&msm_uport->dma_wake_lock); } pm_runtime_disable(uport->dev); msm_uport->clk_state = MSM_HS_CLK_PORT_OFF; dma_unmap_single(uport->dev, msm_uport->tx.dma_base, UART_XMIT_SIZE, DMA_TO_DEVICE); if (use_low_power_wakeup(msm_uport)) irq_set_irq_wake(msm_uport->wakeup.irq, 0); /* Free the interrupt */ free_irq(uport->irq, msm_uport); if (use_low_power_wakeup(msm_uport)) Loading Loading
drivers/tty/serial/msm_serial_hs.c +45 −18 Original line number Diff line number Diff line Loading @@ -336,6 +336,7 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) { int rc = 0; mutex_lock(&msm_uport->clk_mutex); if (1 == atomic_inc_return(&msm_uport->clk_count)) { msm_hs_bus_voting(msm_uport, BUS_SCALING); /* Turn on core clk and iface clk */ Loading @@ -345,6 +346,7 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) dev_err(msm_uport->uport.dev, "%s: Could not turn on pclk [%d]\n", __func__, rc); mutex_unlock(&msm_uport->clk_mutex); return rc; } } Loading @@ -355,11 +357,13 @@ static int msm_hs_clock_vote(struct msm_hs_port *msm_uport) "%s: Could not turn on core clk [%d]\n", __func__, rc); clk_disable_unprepare(msm_uport->pclk); mutex_unlock(&msm_uport->clk_mutex); return rc; } msm_uport->clk_state = MSM_HS_CLK_ON; MSM_HS_DBG("%s: Clock ON successful\n", __func__); } mutex_unlock(&msm_uport->clk_mutex); return rc; Loading @@ -376,6 +380,7 @@ static void msm_hs_clock_unvote(struct msm_hs_port *msm_uport) return; } mutex_lock(&msm_uport->clk_mutex); rc = atomic_dec_return(&msm_uport->clk_count); if (0 == rc) { /* Turn off the core clk and iface clk*/ Loading @@ -387,6 +392,7 @@ static void msm_hs_clock_unvote(struct msm_hs_port *msm_uport) msm_uport->clk_state = MSM_HS_CLK_OFF; MSM_HS_DBG("%s: Clock OFF successful\n", __func__); } mutex_unlock(&msm_uport->clk_mutex); } /* Check if the uport line number matches with user id stored in pdata. Loading Loading @@ -1821,8 +1827,6 @@ static int msm_hs_check_clock_off(struct uart_port *uport) if (msm_uport->clk_state != MSM_HS_CLK_REQUEST_OFF || !uart_circ_empty(tx_buf) || msm_uport->tx.dma_in_flight || msm_uport->imr_reg & UARTDM_ISR_TXLEV_BMSK) { spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) { msm_uport->clk_state = MSM_HS_CLK_ON; /* Pulling RFR line high */ Loading @@ -1833,6 +1837,8 @@ static int msm_hs_check_clock_off(struct uart_port *uport) msm_hs_write(uport, UART_DM_MR1, data); mb(); } spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); MSM_HS_DBG("%s(): clkstate %d", __func__, msm_uport->clk_state); return -1; } Loading Loading @@ -1870,7 +1876,9 @@ static int msm_hs_check_clock_off(struct uart_port *uport) mb(); /* we really want to clock off */ mutex_unlock(&msm_uport->clk_mutex); msm_hs_clock_unvote(msm_uport); mutex_lock(&msm_uport->clk_mutex); spin_lock_irqsave(&uport->lock, flags); if (use_low_power_wakeup(msm_uport)) { Loading Loading @@ -2091,7 +2099,9 @@ void msm_hs_request_clock_on(struct uart_port *uport) } spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); ret = msm_hs_clock_vote(msm_uport); mutex_lock(&msm_uport->clk_mutex); if (ret) { MSM_HS_INFO("Clock ON Failure" "For UART CLK Stalling HSUART\n"); Loading @@ -2106,8 +2116,10 @@ void msm_hs_request_clock_on(struct uart_port *uport) spin_unlock_irqrestore(&uport->lock, flags); MSM_HS_DBG("%s:Calling wait forxcompletion\n", __func__); mutex_unlock(&msm_uport->clk_mutex); ret = wait_event_timeout(msm_uport->bam_disconnect_wait, msm_uport->rx.flush == FLUSH_SHUTDOWN, 300); mutex_lock(&msm_uport->clk_mutex); if (!ret) MSM_HS_ERR("BAM Disconnect not happened\n"); spin_lock_irqsave(&uport->lock, flags); Loading Loading @@ -3180,8 +3192,25 @@ static void msm_hs_shutdown(struct uart_port *uport) struct msm_hs_tx *tx = &msm_uport->tx; struct sps_pipe *sps_pipe_handle = tx->cons.pipe_handle; MSM_HS_INFO("%s()\n", __func__); msm_hs_clock_vote(msm_uport); /* * cancel the hrtimer first so that * clk_state can not change in flight */ hrtimer_cancel(&msm_uport->clk_off_timer); flush_work(&msm_uport->clock_off_w); if (use_low_power_wakeup(msm_uport)) irq_set_irq_wake(msm_uport->wakeup.irq, 0); /* wake irq or uart irq is active depending on clk_state */ if (msm_uport->clk_state == MSM_HS_CLK_OFF) { if (use_low_power_wakeup(msm_uport)) disable_irq(msm_uport->wakeup.irq); } else { disable_irq(uport->irq); wake_unlock(&msm_uport->dma_wake_lock); } /* make sure tx tasklet finishes */ tasklet_kill(&msm_uport->tx.tlet); ret = wait_event_timeout(msm_uport->tx.wait, Loading @@ -3189,21 +3218,20 @@ static void msm_hs_shutdown(struct uart_port *uport) if (!ret) MSM_HS_WARN("Shutdown called when tx buff not empty"); /* BAM Disconnect for TX */ ret = sps_disconnect(sps_pipe_handle); if (ret) MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__); /* make sure rx tasklet finishes */ tasklet_kill(&msm_uport->rx.tlet); wait_event(msm_uport->rx.wait, msm_uport->rx.flush == FLUSH_SHUTDOWN); cancel_delayed_work_sync(&msm_uport->rx.flip_insert_work); flush_workqueue(msm_uport->hsuart_wq); WARN_ON(msm_uport->rx.flush < FLUSH_STOP); pm_runtime_disable(uport->dev); msm_uport->rx.buffer_pending = NONE_PENDING; MSM_HS_DBG("%s(): tx, rx events complete", __func__); msm_hs_clock_vote(msm_uport); mutex_lock(&msm_uport->clk_mutex); /* BAM Disconnect for TX */ ret = sps_disconnect(sps_pipe_handle); if (ret) MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__); WARN_ON(msm_uport->rx.flush < FLUSH_STOP); /* Disable the transmitter */ msm_hs_write(uport, UART_DM_CR, UARTDM_CR_TX_DISABLE_BMSK); /* Disable the receiver */ Loading @@ -3216,22 +3244,21 @@ static void msm_hs_shutdown(struct uart_port *uport) * Hence mb() requires here. */ mb(); mutex_unlock(&msm_uport->clk_mutex); hrtimer_cancel(&msm_uport->clk_off_timer); msm_uport->rx.buffer_pending = NONE_PENDING; MSM_HS_DBG("%s(): tx, rx events complete", __func__); msm_hs_clock_unvote(msm_uport); if (msm_uport->clk_state != MSM_HS_CLK_OFF) { /* to balance clk_state */ msm_hs_clock_unvote(msm_uport); wake_unlock(&msm_uport->dma_wake_lock); } pm_runtime_disable(uport->dev); msm_uport->clk_state = MSM_HS_CLK_PORT_OFF; dma_unmap_single(uport->dev, msm_uport->tx.dma_base, UART_XMIT_SIZE, DMA_TO_DEVICE); if (use_low_power_wakeup(msm_uport)) irq_set_irq_wake(msm_uport->wakeup.irq, 0); /* Free the interrupt */ free_irq(uport->irq, msm_uport); if (use_low_power_wakeup(msm_uport)) Loading