msm_serial_hs: Add ioctl support for UART Clock on/off request
This change adds support for ioctl implementation in HSUART
driver. UART Client application (e.g. Bluetooth) can make
request for UART Clock on/off using the ioctl mechanism.
UART Clock status also can be queried using this mechanism.
CRs-Fixed: 496245
Change-Id: I9531cf2f9eda487082b9719341c5ad84c15ad5f7
Signed-off-by: Saket Saurabh <ssaurabh@codeaurora.org>
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 4d464c1..7f669d8 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -245,6 +245,48 @@
#define UARTDM_TO_MSM(uart_port) \
container_of((uart_port), struct msm_hs_port, uport)
+
+static int msm_hs_ioctl(struct uart_port *uport, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = 0, state = 1;
+ enum msm_hs_clk_states_e clk_state;
+ unsigned long flags;
+ struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+
+ switch (cmd) {
+ case MSM_ENABLE_UART_CLOCK: {
+ pr_debug("%s():ENABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+ msm_hs_request_clock_on(&msm_uport->uport);
+ break;
+ }
+ case MSM_DISABLE_UART_CLOCK: {
+ pr_debug("%s():DISABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+ msm_hs_request_clock_off(&msm_uport->uport);
+ break;
+ }
+ case MSM_GET_UART_CLOCK_STATUS: {
+ /* Return value 0 - UART CLOCK is OFF
+ * Return value 1 - UART CLOCK is ON */
+ pr_debug("%s():GET UART CLOCK STATUS: cmd=%d\n", __func__, cmd);
+ spin_lock_irqsave(&msm_uport->uport.lock, flags);
+ clk_state = msm_uport->clk_state;
+ spin_unlock_irqrestore(&msm_uport->uport.lock, flags);
+ if (clk_state <= MSM_HS_CLK_OFF)
+ state = 0;
+ ret = state;
+ break;
+ }
+ default: {
+ pr_debug("%s():Unknown cmd specified: cmd=%d\n", __func__, cmd);
+ ret = -ENOIOCTLCMD;
+ break;
+ }
+ }
+
+ return ret;
+}
+
static ssize_t show_clock(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -3307,6 +3349,7 @@
.release_port = msm_hs_release_port,
.request_port = msm_hs_request_port,
.flush_buffer = msm_hs_flush_buffer,
+ .ioctl = msm_hs_ioctl,
};
module_init(msm_serial_hs_init);
diff --git a/drivers/tty/serial/msm_serial_hs_hwreg.h b/drivers/tty/serial/msm_serial_hs_hwreg.h
index cdd0450..cd24f23 100644
--- a/drivers/tty/serial/msm_serial_hs_hwreg.h
+++ b/drivers/tty/serial/msm_serial_hs_hwreg.h
@@ -32,6 +32,10 @@
#define ADM1_CRCI_GSBI6_RX_SEL 0x800
#define ADM1_CRCI_GSBI6_TX_SEL 0x400
+#define MSM_ENABLE_UART_CLOCK 13
+#define MSM_DISABLE_UART_CLOCK 14
+#define MSM_GET_UART_CLOCK_STATUS 15
+
enum msm_hsl_regs {
UARTDM_MR1,
UARTDM_MR2,