mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 23:29:46 +00:00
cpm_uart: Modem control lines support
This patch replaces the get_mctrl/set_mctrl stubs with modem control line read/write access through the GPIO lib. Available modem control lines are described in the device tree using GPIO bindings. The driver expect a GPIO pin for each of the CTS, RTS, DCD, DSR, DTR and RI signals. Unused control lines can be left out. Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
parent
dc2380ec85
commit
7485d26b7e
@ -7,6 +7,15 @@ Currently defined compatibles:
|
|||||||
- fsl,cpm2-scc-uart
|
- fsl,cpm2-scc-uart
|
||||||
- fsl,qe-uart
|
- fsl,qe-uart
|
||||||
|
|
||||||
|
Modem control lines connected to GPIO controllers are listed in the gpios
|
||||||
|
property as described in booting-without-of.txt, section IX.1 in the following
|
||||||
|
order:
|
||||||
|
|
||||||
|
CTS, RTS, DCD, DSR, DTR, and RI.
|
||||||
|
|
||||||
|
The gpios property is optional and can be left out when control lines are
|
||||||
|
not used.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
serial@11a00 {
|
serial@11a00 {
|
||||||
@ -18,4 +27,6 @@ Example:
|
|||||||
interrupt-parent = <&PIC>;
|
interrupt-parent = <&PIC>;
|
||||||
fsl,cpm-brg = <1>;
|
fsl,cpm-brg = <1>;
|
||||||
fsl,cpm-command = <00800000>;
|
fsl,cpm-command = <00800000>;
|
||||||
|
gpios = <&gpio_c 15 0
|
||||||
|
&gpio_d 29 0>;
|
||||||
};
|
};
|
||||||
|
@ -50,6 +50,15 @@
|
|||||||
|
|
||||||
#define SCC_WAIT_CLOSING 100
|
#define SCC_WAIT_CLOSING 100
|
||||||
|
|
||||||
|
#define GPIO_CTS 0
|
||||||
|
#define GPIO_RTS 1
|
||||||
|
#define GPIO_DCD 2
|
||||||
|
#define GPIO_DSR 3
|
||||||
|
#define GPIO_DTR 4
|
||||||
|
#define GPIO_RI 5
|
||||||
|
|
||||||
|
#define NUM_GPIOS (GPIO_RI+1)
|
||||||
|
|
||||||
struct uart_cpm_port {
|
struct uart_cpm_port {
|
||||||
struct uart_port port;
|
struct uart_port port;
|
||||||
u16 rx_nrfifos;
|
u16 rx_nrfifos;
|
||||||
@ -82,6 +91,7 @@ struct uart_cpm_port {
|
|||||||
int wait_closing;
|
int wait_closing;
|
||||||
/* value to combine with opcode to form cpm command */
|
/* value to combine with opcode to form cpm command */
|
||||||
u32 command;
|
u32 command;
|
||||||
|
int gpios[NUM_GPIOS];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int cpm_uart_nr;
|
extern int cpm_uart_nr;
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/fs_uart_pd.h>
|
#include <linux/fs_uart_pd.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/of_gpio.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
@ -96,13 +98,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
|
|||||||
|
|
||||||
static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||||
{
|
{
|
||||||
/* Whee. Do nothing. */
|
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_RTS] >= 0)
|
||||||
|
gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_DTR] >= 0)
|
||||||
|
gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
|
static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
|
||||||
{
|
{
|
||||||
/* Whee. Do nothing. */
|
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||||
return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
|
unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_CTS] >= 0) {
|
||||||
|
if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
|
||||||
|
mctrl &= ~TIOCM_CTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_DSR] >= 0) {
|
||||||
|
if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
|
||||||
|
mctrl &= ~TIOCM_DSR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_DCD] >= 0) {
|
||||||
|
if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
|
||||||
|
mctrl &= ~TIOCM_CAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinfo->gpios[GPIO_RI] >= 0) {
|
||||||
|
if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
|
||||||
|
mctrl |= TIOCM_RNG;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -991,6 +1021,7 @@ static int cpm_uart_init_port(struct device_node *np,
|
|||||||
void __iomem *mem, *pram;
|
void __iomem *mem, *pram;
|
||||||
int len;
|
int len;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
data = of_get_property(np, "fsl,cpm-brg", &len);
|
data = of_get_property(np, "fsl,cpm-brg", &len);
|
||||||
if (!data || len != 4) {
|
if (!data || len != 4) {
|
||||||
@ -1050,6 +1081,9 @@ static int cpm_uart_init_port(struct device_node *np,
|
|||||||
goto out_pram;
|
goto out_pram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_GPIOS; i++)
|
||||||
|
pinfo->gpios[i] = of_get_gpio(np, i);
|
||||||
|
|
||||||
return cpm_uart_request_port(&pinfo->port);
|
return cpm_uart_request_port(&pinfo->port);
|
||||||
|
|
||||||
out_pram:
|
out_pram:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user