Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ace219b0 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "serial: msm_serial_hs: Allow system suspend when no client is active"

parents c8cbce19 861b7df6
Loading
Loading
Loading
Loading
+41 −30
Original line number Diff line number Diff line
@@ -258,6 +258,7 @@ struct msm_hs_port {
	atomic_t client_count;
	bool obs; /* out of band sleep flag */
	atomic_t client_req_state;
	int sys_suspend_noirq_cnt;
	void *ipc_msm_hs_log_ctxt;
	void *ipc_msm_hs_pwr_ctxt;
	int ipc_debug_mask;
@@ -395,8 +396,6 @@ static void msm_hs_resource_unvote(struct msm_hs_port *msm_uport)
{
	struct uart_port *uport = &(msm_uport->uport);
	int rc = atomic_read(&msm_uport->resource_count);
	struct msm_hs_tx *tx = &msm_uport->tx;
	struct msm_hs_rx *rx = &msm_uport->rx;

	MSM_HS_DBG("%s(): power usage count %d", __func__, rc);
	if (rc <= 0) {
@@ -405,15 +404,8 @@ static void msm_hs_resource_unvote(struct msm_hs_port *msm_uport)
		return;
	}
	atomic_dec(&msm_uport->resource_count);

	if (pm_runtime_enabled(uport->dev)) {
	pm_runtime_mark_last_busy(uport->dev);
	pm_runtime_put_autosuspend(uport->dev);
	} else {
		MSM_HS_DBG("%s():tx.flush:%d,in_flight:%d,rx.flush:%d\n",
		__func__, tx->flush, tx->dma_in_flight, rx->flush);
		msm_hs_pm_suspend(uport->dev);
	}
}

 /* Vote for resources before accessing them */
@@ -1390,8 +1382,9 @@ static void msm_hs_disconnect_rx(struct uart_port *uport)
	if (msm_uport->rx.flush == FLUSH_NONE)
		msm_uport->rx.flush = FLUSH_STOP;

	if (sps_is_pipe_empty(sps_pipe_handle, &prod_empty)) {
		MSM_HS_WARN("%s():Pipe Not Empty, ret=%d, flush=%d\n",
	if (!sps_is_pipe_empty(sps_pipe_handle, &prod_empty)) {
		if (prod_empty == false)
		MSM_HS_WARN("%s():Pipe Not Empty, prod=%d, flush=%d\n",
			__func__, prod_empty, msm_uport->rx.flush);
	}
	disconnect_rx_endpoint(msm_uport);
@@ -3295,6 +3288,7 @@ static int msm_hs_pm_resume(struct device *dev)
	LOG_USR_MSG(msm_uport->ipc_msm_hs_pwr_ctxt,
		"%s:PM State:Active client_count %d\n", __func__, client_count);
exit_pm_resume:
	msm_uport->sys_suspend_noirq_cnt = 0;
	mutex_unlock(&msm_uport->mtx);
	return ret;
}
@@ -3304,14 +3298,11 @@ static int msm_hs_pm_sys_suspend_noirq(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct msm_hs_port *msm_uport = get_matching_hs_port(pdev);
	enum msm_hs_pm_state prev_pwr_state;
	int clk_cnt, client_count, ret = 0;

	if (IS_ERR_OR_NULL(msm_uport))
		return -ENODEV;

	mutex_lock(&msm_uport->mtx);

	/*
	 * If there is an active clk request or an impending userspace request
	 * fail the suspend callback.
@@ -3319,19 +3310,40 @@ static int msm_hs_pm_sys_suspend_noirq(struct device *dev)
	clk_cnt = atomic_read(&msm_uport->resource_count);
	client_count = atomic_read(&msm_uport->client_count);
	if (msm_uport->pm_state == MSM_HS_PM_ACTIVE) {
		MSM_HS_WARN("%s:Fail Suspend.clk_cnt:%d,clnt_count:%d\n",
				 __func__, clk_cnt, client_count);
		if (clk_cnt == 0 && client_count == 0)
			msm_uport->sys_suspend_noirq_cnt++;
		/*Serve force suspend post autosuspend timer expires
		 */
		if (msm_uport->sys_suspend_noirq_cnt >= 2) {
			msm_uport->pm_state = MSM_HS_PM_SYS_SUSPENDED;
			msm_uport->sys_suspend_noirq_cnt = 0;
			mutex_unlock(&msm_uport->mtx);

			msm_hs_pm_suspend(dev);
			/*
			 * Synchronize RT-pm and system-pm, RT-PM thinks that
			 * we are active. The three calls below let the RT-PM
			 * know that we are suspended already without calling
			 * suspend callback
			 */
			pm_runtime_disable(dev);
			pm_runtime_set_suspended(dev);
			pm_runtime_enable(dev);

			/*To Balance out exit time Mutex unlock */
			mutex_lock(&msm_uport->mtx);
		} else {
			ret = -EBUSY;
		goto exit_suspend_noirq;
		}

	prev_pwr_state = msm_uport->pm_state;
	msm_uport->pm_state = MSM_HS_PM_SYS_SUSPENDED;
	LOG_USR_MSG(msm_uport->ipc_msm_hs_pwr_ctxt,
		"%s:PM State:Sys-Suspended client_count %d\n", __func__,
								client_count);
exit_suspend_noirq:
	}
	mutex_unlock(&msm_uport->mtx);
	if (ret)
		MSM_HS_WARN("%s:Fail Suspend.clk_cnt:%d,clnt_count:%d\n",
			__func__, clk_cnt, client_count);
	else
		LOG_USR_MSG(msm_uport->ipc_msm_hs_pwr_ctxt,
			"%s:PM State:Sys-Suspended client_count %d\n",
			__func__, client_count);
	return ret;
};

@@ -3817,11 +3829,10 @@ static void msm_hs_shutdown(struct uart_port *uport)
	if (atomic_read(&msm_uport->client_count)) {
		MSM_HS_WARN("%s: Client vote on, forcing to 0\n", __func__);
		atomic_set(&msm_uport->client_count, 0);
		LOG_USR_MSG(msm_uport->ipc_msm_hs_pwr_ctxt,
			"%s: Client_Count 0\n", __func__);
	}
	msm_hs_unconfig_uart_gpios(uport);
	MSM_HS_INFO("%s:UART port closed successfully\n", __func__);
	LOG_USR_MSG(msm_uport->ipc_msm_hs_pwr_ctxt,
		"%s:UART port closed, Client_Count 0\n", __func__);
}

static void __exit msm_serial_hs_exit(void)