Merge "serial: msm_geni_serial: Prevent geni register access while suspend is in progress"
This commit is contained in:
commit
c0db2be621
@ -6,19 +6,22 @@
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/msm_gpi.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/qcom-geni-se-common.h>
|
||||
@ -28,9 +31,6 @@
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <uapi/linux/msm_geni_serial.h>
|
||||
|
||||
static bool con_enabled = IS_ENABLED(CONFIG_SERIAL_MSM_GENI_CONSOLE_DEFAULT_ENABLED);
|
||||
@ -457,6 +457,12 @@ struct msm_geni_serial_port {
|
||||
int hs_uart_operation;
|
||||
struct msm_geni_serial_ssr uart_ssr;
|
||||
struct geni_se_rsc rsc;
|
||||
/**
|
||||
* mutex to prevent race condition between runtime
|
||||
* suspend and get_mctrl which tries to access IOS registers
|
||||
* when runtime suspend was in progress
|
||||
*/
|
||||
struct mutex suspend_resume_lock;
|
||||
};
|
||||
|
||||
static const struct uart_ops msm_geni_serial_pops;
|
||||
@ -1403,17 +1409,26 @@ static unsigned int msm_geni_serial_get_mctrl(struct uart_port *uport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!uart_console(uport) && device_pending_suspend(uport)) {
|
||||
UART_LOG_DBG(port->ipc_log_misc, uport->dev,
|
||||
"%s.Device is suspended, %s\n",
|
||||
__func__, current->comm);
|
||||
return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS;
|
||||
if (!uart_console(uport)) {
|
||||
if (!mutex_trylock(&port->suspend_resume_lock)) {
|
||||
UART_LOG_DBG(port->ipc_log_misc, uport->dev,
|
||||
"%s.Device is being suspended, %s\n",
|
||||
__func__, current->comm);
|
||||
return mctrl;
|
||||
}
|
||||
if (device_pending_suspend(uport)) {
|
||||
UART_LOG_DBG(port->ipc_log_misc, uport->dev,
|
||||
"%s.Device is suspended, %s\n",
|
||||
__func__, current->comm);
|
||||
mutex_unlock(&port->suspend_resume_lock);
|
||||
return mctrl | TIOCM_CTS;
|
||||
}
|
||||
}
|
||||
|
||||
geni_ios = geni_read_reg(uport->membase, SE_GENI_IOS);
|
||||
if (!(geni_ios & IO2_DATA_IN))
|
||||
mctrl |= TIOCM_CTS;
|
||||
else
|
||||
else if (!uart_console(uport))
|
||||
msm_geni_update_uart_error_code(port, SOC_ERROR_START_TX_IOS_SOC_RFR_HIGH);
|
||||
|
||||
if (!port->manual_flow)
|
||||
@ -1421,6 +1436,10 @@ static unsigned int msm_geni_serial_get_mctrl(struct uart_port *uport)
|
||||
|
||||
UART_LOG_DBG(port->ipc_log_misc, uport->dev, "%s: geni_ios:0x%x, mctrl:0x%x\n",
|
||||
__func__, geni_ios, mctrl);
|
||||
|
||||
if (!uart_console(uport))
|
||||
mutex_unlock(&port->suspend_resume_lock);
|
||||
|
||||
return mctrl;
|
||||
}
|
||||
|
||||
@ -5596,6 +5615,8 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
|
||||
if (!dev_port->is_console)
|
||||
spin_lock_init(&dev_port->rx_lock);
|
||||
|
||||
mutex_init(&dev_port->suspend_resume_lock);
|
||||
|
||||
ret = uart_add_one_port(drv, uport);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Failed to register uart_port: %d\n", ret);
|
||||
@ -5694,7 +5715,7 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
|
||||
unsigned long long start_time;
|
||||
u32 geni_status = geni_read_reg(port->uport.membase,
|
||||
SE_GENI_STATUS);
|
||||
|
||||
mutex_lock(&port->suspend_resume_lock);
|
||||
UART_LOG_DBG(port->ipc_log_pwr, dev,
|
||||
"%s: Start geni_status : 0x%x\n", __func__, geni_status);
|
||||
|
||||
@ -5720,7 +5741,8 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
|
||||
*/
|
||||
if (port->wakeup_byte && port->wakeup_irq)
|
||||
msm_geni_serial_allow_rx(port);
|
||||
return -EBUSY;
|
||||
ret = -EBUSY;
|
||||
goto exit_runtime_suspend;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -5737,7 +5759,8 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
|
||||
*/
|
||||
if (port->wakeup_byte && port->wakeup_irq)
|
||||
msm_geni_serial_allow_rx(port);
|
||||
return -EBUSY;
|
||||
ret = -EBUSY;
|
||||
goto exit_runtime_suspend;
|
||||
}
|
||||
|
||||
geni_status = geni_read_reg(port->uport.membase, SE_GENI_STATUS);
|
||||
@ -5768,7 +5791,8 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
|
||||
UART_LOG_DBG(port->ipc_log_pwr, dev,
|
||||
"%s: return, stop_rx_seq busy\n", __func__);
|
||||
enable_irq(port->uport.irq);
|
||||
return -EBUSY;
|
||||
ret = -EBUSY;
|
||||
goto exit_runtime_suspend;
|
||||
}
|
||||
}
|
||||
if (count)
|
||||
@ -5804,6 +5828,7 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
|
||||
UART_LOG_DBG(port->ipc_log_pwr, dev, "%s: End %d\n", __func__, ret);
|
||||
__pm_relax(port->geni_wake);
|
||||
exit_runtime_suspend:
|
||||
mutex_unlock(&port->suspend_resume_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user