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

Commit b382f222 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "serial: msm_geni_serial: Allow clock_on/off ioctl to be optional"

parents dcb61238 790ab2f4
Loading
Loading
Loading
Loading
+70 −16
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ struct msm_geni_serial_port {
	struct completion m_cmd_timeout;
	struct completion s_cmd_timeout;
	spinlock_t rx_lock;
	bool pm_auto_suspend_disable;
};

static const struct uart_ops msm_geni_serial_pops;
@@ -531,8 +532,12 @@ static int vote_clock_off(struct uart_port *uport)
static int msm_geni_serial_ioctl(struct uart_port *uport, unsigned int cmd,
						unsigned long arg)
{
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
	int ret = -ENOIOCTLCMD;

	if (port->pm_auto_suspend_disable)
		return ret;

	switch (cmd) {
	case TIOCPMGET:
	case MSM_GENI_SERIAL_TIOCPMGET: {
@@ -709,9 +714,12 @@ static void msm_geni_serial_power_off(struct uart_port *uport)
								__func__);
		return;
	}

	if (pm_runtime_enabled(uport->dev)) {
		pm_runtime_mark_last_busy(uport->dev);
		pm_runtime_put_autosuspend(uport->dev);
	}
}

static int msm_geni_serial_poll_bit(struct uart_port *uport,
				int offset, int bit_field, bool set)
@@ -1167,7 +1175,7 @@ static void msm_geni_serial_start_tx(struct uart_port *uport)
		goto exit_start_tx;
	}

	if (!uart_console(uport)) {
	if (!uart_console(uport) && pm_runtime_enabled(uport->dev)) {
		IPC_LOG_MSG(msm_port->ipc_log_misc,
				"%s.Power on.\n", __func__);
		pm_runtime_get(uport->dev);
@@ -2207,6 +2215,9 @@ static void msm_geni_serial_shutdown(struct uart_port *uport)
		msm_geni_serial_stop_tx(uport);
	}

	if (msm_port->pm_auto_suspend_disable)
		disable_irq(uport->irq);

	if (!uart_console(uport)) {
		if (msm_port->ioctl_count) {
			int i;
@@ -2220,11 +2231,13 @@ static void msm_geni_serial_shutdown(struct uart_port *uport)
			msm_port->ioctl_count = 0;
		}

		if (pm_runtime_enabled(uport->dev)) {
			ret = pm_runtime_put_sync_suspend(uport->dev);
			if (ret) {
				IPC_LOG_MSG(msm_port->ipc_log_pwr,
				"%s: Failed to suspend:%d\n", __func__, ret);
			}
		}

		if (msm_port->wakeup_irq > 0) {
			irq_set_irq_wake(msm_port->wakeup_irq, 0);
@@ -2371,7 +2384,7 @@ static int msm_geni_serial_startup(struct uart_port *uport)
	 * and disabled in runtime_suspend to avoid spurious interrupts
	 * after suspend.
	 */
	if (uart_console(uport))
	if (uart_console(uport) ||  msm_port->pm_auto_suspend_disable)
		enable_irq(uport->irq);

	if (msm_port->wakeup_irq > 0) {
@@ -2842,9 +2855,32 @@ static void msm_geni_serial_cons_pm(struct uart_port *uport,
{
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);

	if (unlikely(!uart_console(uport)))
	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
		se_geni_resources_on(&msm_port->serial_rsc);
	else if (new_state == UART_PM_STATE_OFF &&
			old_state == UART_PM_STATE_ON)
		se_geni_resources_off(&msm_port->serial_rsc);
}

static void msm_geni_serial_hs_pm(struct uart_port *uport,
		unsigned int new_state, unsigned int old_state)
{
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);

	/*
	 * This will get call for system suspend/resume and
	 * Applicable for hs-uart without runtime pm framework support.
	 */
	if (pm_runtime_enabled(uport->dev))
		return;

	/*
	 * Default PM State is UNDEFINED Setting it to OFF State.
	 * This will allow add one port to do resources on and off during probe
	 */
	if (old_state == UART_PM_STATE_UNDEFINED)
		old_state = UART_PM_STATE_OFF;

	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
		se_geni_resources_on(&msm_port->serial_rsc);
	else if (new_state == UART_PM_STATE_OFF &&
@@ -2886,6 +2922,8 @@ static const struct uart_ops msm_geni_serial_pops = {
	.break_ctl = msm_geni_serial_break_ctl,
	.flush_buffer = NULL,
	.ioctl = msm_geni_serial_ioctl,
	/* For HSUART nodes without IOCTL support */
	.pm = msm_geni_serial_hs_pm,
};

static const struct of_device_id msm_geni_device_tbl[] = {
@@ -3217,6 +3255,14 @@ static int msm_geni_serial_probe(struct platform_device *pdev)

	uport->private_data = (void *)drv;
	platform_set_drvdata(pdev, dev_port);
	/*
	 * To Disable PM runtime API that will make ioctl based
	 * vote_clock_on/off optional and rely on system PM
	 */
	dev_port->pm_auto_suspend_disable =
		of_property_read_bool(pdev->dev.of_node,
		"qcom,auto-suspend-disable");

	if (is_console) {
		dev_port->handle_rx = handle_rx_console;
		dev_port->rx_fifo = devm_kzalloc(uport->dev, sizeof(u32),
@@ -3226,11 +3272,16 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
		dev_port->rx_fifo = devm_kzalloc(uport->dev,
				sizeof(dev_port->rx_fifo_depth * sizeof(u32)),
								GFP_KERNEL);
		if (dev_port->pm_auto_suspend_disable) {
			pm_runtime_set_active(&pdev->dev);
			pm_runtime_forbid(&pdev->dev);
		} else {
			pm_runtime_set_suspended(&pdev->dev);
			pm_runtime_set_autosuspend_delay(&pdev->dev, 150);
			pm_runtime_use_autosuspend(&pdev->dev);
			pm_runtime_enable(&pdev->dev);
		}
	}

	if (IS_ENABLED(CONFIG_SERIAL_MSM_GENI_HALF_SAMPLING) &&
			dev_port->rumi_platform && dev_port->is_console) {
@@ -3290,6 +3341,8 @@ static int msm_geni_serial_remove(struct platform_device *pdev)

	if (!uart_console(&port->uport))
		wakeup_source_unregister(port->geni_wake);
	if (port->pm_auto_suspend_disable)
		pm_runtime_allow(&pdev->dev);
	uart_remove_one_port(drv, &port->uport);
	if (port->rx_dma) {
		geni_se_iommu_free_buf(port->wrapper_dev, &port->rx_dma,
@@ -3416,7 +3469,7 @@ static int msm_geni_serial_sys_suspend(struct device *dev)
	struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
	struct uart_port *uport = &port->uport;

	if (uart_console(uport)) {
	if (uart_console(uport) || port->pm_auto_suspend_disable) {
		uart_suspend_port((struct uart_driver *)uport->private_data,
					uport);
	} else {
@@ -3445,8 +3498,9 @@ static int msm_geni_serial_sys_resume(struct device *dev)
	struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
	struct uart_port *uport = &port->uport;

	if (uart_console(uport) &&
	    console_suspend_enabled && uport->suspended) {
	if ((uart_console(uport) &&
	    console_suspend_enabled && uport->suspended) ||
		port->pm_auto_suspend_disable) {
		uart_resume_port((struct uart_driver *)uport->private_data,
									uport);
	}