You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'tty-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here's the big tty/serial driver update for 4.1-rc1. It was delayed for a bit due to some questions surrounding some of the console command line parsing changes that are in here. There's still one tiny regression for people who were previously putting multiple console command lines and expecting them all to be ignored for some odd reason, but Peter is working on fixing that. If not, I'll send a revert for the offending patch, but I have faith that Peter can address it. Other than the console work here, there's the usual serial driver updates and changes, and a buch of 8250 reworks to try to make that driver easier to maintain over time, and have it support more devices in the future. All of these have been in linux-next for a while" * tag 'tty-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits) n_gsm: Drop unneeded cast on netdev_priv sc16is7xx: expose RTS inversion in RS-485 mode serial: 8250_pci: port failed after wakeup from S3 earlycon: 8250: Document kernel command line options earlycon: 8250: Fix command line regression earlycon: Fix __earlycon_table stride tty: clean up the tty time logic a bit serial: 8250_dw: only get the clock rate in one place serial: 8250_dw: remove useless ACPI ID check dmaengine: hsu: move memory allocation to GFP_NOWAIT dmaengine: hsu: remove redundant pieces of code serial: 8250_pci: add Intel Tangier support dmaengine: hsu: add Intel Tangier PCI ID serial: 8250_pci: replace switch-case by formula for Intel MID serial: 8250_pci: replace switch-case by formula tty: cpm_uart: replace CONFIG_8xx by CONFIG_CPM1 serial: jsm: some off by one bugs serial: xuartps: Fix check in console_setup(). serial: xuartps: Get rid of register access macros. serial: xuartps: Fix iobase use. ...
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
|
||||
static const char hvc_opal_name[] = "hvc_opal";
|
||||
|
||||
static struct of_device_id hvc_opal_match[] = {
|
||||
static const struct of_device_id hvc_opal_match[] = {
|
||||
{ .name = "serial", .compatible = "ibm,opal-console-raw" },
|
||||
{ .name = "serial", .compatible = "ibm,opal-console-hvsi" },
|
||||
{ },
|
||||
|
||||
+6
-6
@@ -2669,7 +2669,7 @@ static inline void muxnet_put(struct gsm_mux_net *mux_net)
|
||||
static int gsm_mux_net_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *net)
|
||||
{
|
||||
struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
|
||||
struct gsm_mux_net *mux_net = netdev_priv(net);
|
||||
struct gsm_dlci *dlci = mux_net->dlci;
|
||||
muxnet_get(mux_net);
|
||||
|
||||
@@ -2698,7 +2698,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
|
||||
{
|
||||
struct net_device *net = dlci->net;
|
||||
struct sk_buff *skb;
|
||||
struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
|
||||
struct gsm_mux_net *mux_net = netdev_priv(net);
|
||||
muxnet_get(mux_net);
|
||||
|
||||
/* Allocate an sk_buff */
|
||||
@@ -2727,7 +2727,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
|
||||
|
||||
static int gsm_change_mtu(struct net_device *net, int new_mtu)
|
||||
{
|
||||
struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
|
||||
struct gsm_mux_net *mux_net = netdev_priv(net);
|
||||
if ((new_mtu < 8) || (new_mtu > mux_net->dlci->gsm->mtu))
|
||||
return -EINVAL;
|
||||
net->mtu = new_mtu;
|
||||
@@ -2763,7 +2763,7 @@ static void gsm_destroy_network(struct gsm_dlci *dlci)
|
||||
pr_debug("destroy network interface");
|
||||
if (!dlci->net)
|
||||
return;
|
||||
mux_net = (struct gsm_mux_net *)netdev_priv(dlci->net);
|
||||
mux_net = netdev_priv(dlci->net);
|
||||
muxnet_put(mux_net);
|
||||
}
|
||||
|
||||
@@ -2801,7 +2801,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
net->mtu = dlci->gsm->mtu;
|
||||
mux_net = (struct gsm_mux_net *)netdev_priv(net);
|
||||
mux_net = netdev_priv(net);
|
||||
mux_net->dlci = dlci;
|
||||
kref_init(&mux_net->ref);
|
||||
strncpy(nc->if_name, net->name, IFNAMSIZ); /* return net name */
|
||||
@@ -2824,7 +2824,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
|
||||
}
|
||||
|
||||
/* Line discipline for real tty */
|
||||
struct tty_ldisc_ops tty_ldisc_packet = {
|
||||
static struct tty_ldisc_ops tty_ldisc_packet = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_gsm",
|
||||
|
||||
@@ -21,7 +21,6 @@ struct uart_8250_dma {
|
||||
|
||||
/* Filter function */
|
||||
dma_filter_fn fn;
|
||||
|
||||
/* Parameter to the filter function */
|
||||
void *rx_param;
|
||||
void *tx_param;
|
||||
@@ -53,7 +52,7 @@ struct old_serial_port {
|
||||
unsigned int baud_base;
|
||||
unsigned int port;
|
||||
unsigned int irq;
|
||||
unsigned int flags;
|
||||
upf_t flags;
|
||||
unsigned char hub6;
|
||||
unsigned char io_type;
|
||||
unsigned char __iomem *iomem_base;
|
||||
@@ -85,9 +84,6 @@ struct serial8250_config {
|
||||
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
|
||||
#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
|
||||
|
||||
#define PROBE_RSA (1 << 0)
|
||||
#define PROBE_ANY (~0)
|
||||
|
||||
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
|
||||
@@ -198,3 +194,20 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
|
||||
}
|
||||
static inline void serial8250_release_dma(struct uart_8250_port *p) { }
|
||||
#endif
|
||||
|
||||
static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
status = serial_in(up, 0x04); /* EXCR2 */
|
||||
#define PRESL(x) ((x) & 0x30)
|
||||
if (PRESL(status) == 0x10) {
|
||||
/* already in high speed mode */
|
||||
return 0;
|
||||
} else {
|
||||
status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
|
||||
status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
|
||||
serial_out(up, 0x04, status);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
+329
-166
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
@@ -364,9 +363,9 @@ static int dw8250_probe_of(struct uart_port *p,
|
||||
}
|
||||
|
||||
if (of_property_read_bool(np, "cts-override")) {
|
||||
/* Always report DSR as active */
|
||||
data->msr_mask_on |= UART_MSR_DSR;
|
||||
data->msr_mask_off |= UART_MSR_DDSR;
|
||||
/* Always report CTS as active */
|
||||
data->msr_mask_on |= UART_MSR_CTS;
|
||||
data->msr_mask_off |= UART_MSR_DCTS;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(np, "ri-override")) {
|
||||
@@ -375,37 +374,16 @@ static int dw8250_probe_of(struct uart_port *p,
|
||||
data->msr_mask_off |= UART_MSR_TERI;
|
||||
}
|
||||
|
||||
/* clock got configured through clk api, all done */
|
||||
if (p->uartclk)
|
||||
return 0;
|
||||
|
||||
/* try to find out clock frequency from DT as fallback */
|
||||
if (of_property_read_u32(np, "clock-frequency", &val)) {
|
||||
dev_err(p->dev, "clk or clock-frequency not defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
p->uartclk = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw8250_probe_acpi(struct uart_8250_port *up,
|
||||
struct dw8250_data *data)
|
||||
{
|
||||
const struct acpi_device_id *id;
|
||||
struct uart_port *p = &up->port;
|
||||
|
||||
dw8250_setup_port(up);
|
||||
|
||||
id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
if (!p->uartclk)
|
||||
if (device_property_read_u32(p->dev, "clock-frequency",
|
||||
&p->uartclk))
|
||||
return -EINVAL;
|
||||
|
||||
p->iotype = UPIO_MEM32;
|
||||
p->serial_in = dw8250_serial_in32;
|
||||
p->serial_out = dw8250_serial_out32;
|
||||
@@ -425,18 +403,24 @@ static int dw8250_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct uart_8250_port uart = {};
|
||||
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
struct dw8250_data *data;
|
||||
int err;
|
||||
|
||||
if (!regs || !irq) {
|
||||
dev_err(&pdev->dev, "no registers/irq defined\n");
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "no registers defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (irq < 0) {
|
||||
if (irq != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "cannot get irq\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
spin_lock_init(&uart.port.lock);
|
||||
uart.port.mapbase = regs->start;
|
||||
uart.port.irq = irq->start;
|
||||
uart.port.irq = irq;
|
||||
uart.port.handle_irq = dw8250_handle_irq;
|
||||
uart.port.pm = dw8250_do_pm;
|
||||
uart.port.type = PORT_8250;
|
||||
@@ -453,12 +437,18 @@ static int dw8250_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
data->usr_reg = DW_UART_USR;
|
||||
|
||||
/* Always ask for fixed clock rate from a property. */
|
||||
device_property_read_u32(&pdev->dev, "clock-frequency",
|
||||
&uart.port.uartclk);
|
||||
|
||||
/* If there is separate baudclk, get the rate from it. */
|
||||
data->clk = devm_clk_get(&pdev->dev, "baudclk");
|
||||
if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER)
|
||||
data->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
if (!IS_ERR(data->clk)) {
|
||||
if (!IS_ERR_OR_NULL(data->clk)) {
|
||||
err = clk_prepare_enable(data->clk);
|
||||
if (err)
|
||||
dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n",
|
||||
@@ -467,6 +457,12 @@ static int dw8250_probe(struct platform_device *pdev)
|
||||
uart.port.uartclk = clk_get_rate(data->clk);
|
||||
}
|
||||
|
||||
/* If no clock rate is defined, fail. */
|
||||
if (!uart.port.uartclk) {
|
||||
dev_err(&pdev->dev, "clock rate not defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
|
||||
if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) {
|
||||
err = -EPROBE_DEFER;
|
||||
@@ -629,6 +625,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
|
||||
{ "80860F0A", 0 },
|
||||
{ "8086228A", 0 },
|
||||
{ "APMC0D08", 0},
|
||||
{ "AMD0020", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
|
||||
@@ -649,3 +646,4 @@ module_platform_driver(dw8250_platform_driver);
|
||||
MODULE_AUTHOR("Jamie Iles");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
|
||||
MODULE_ALIAS("platform:dw-apb-uart");
|
||||
|
||||
@@ -29,15 +29,12 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/serial.h>
|
||||
|
||||
static struct earlycon_device *early_device;
|
||||
|
||||
unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
|
||||
{
|
||||
switch (port->iotype) {
|
||||
@@ -90,7 +87,8 @@ static void __init serial_putc(struct uart_port *port, int c)
|
||||
static void __init early_serial8250_write(struct console *console,
|
||||
const char *s, unsigned int count)
|
||||
{
|
||||
struct uart_port *port = &early_device->port;
|
||||
struct earlycon_device *device = console->data;
|
||||
struct uart_port *port = &device->port;
|
||||
unsigned int ier;
|
||||
|
||||
/* Save the IER and disable interrupts preserving the UUE bit */
|
||||
@@ -107,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
|
||||
serial8250_early_out(port, UART_IER, ier);
|
||||
}
|
||||
|
||||
static unsigned int __init probe_baud(struct uart_port *port)
|
||||
{
|
||||
unsigned char lcr, dll, dlm;
|
||||
unsigned int quot;
|
||||
|
||||
lcr = serial8250_early_in(port, UART_LCR);
|
||||
serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
|
||||
dll = serial8250_early_in(port, UART_DLL);
|
||||
dlm = serial8250_early_in(port, UART_DLM);
|
||||
serial8250_early_out(port, UART_LCR, lcr);
|
||||
|
||||
quot = (dlm << 8) | dll;
|
||||
return (port->uartclk / 16) / quot;
|
||||
}
|
||||
|
||||
static void __init init_port(struct earlycon_device *device)
|
||||
{
|
||||
struct uart_port *port = &device->port;
|
||||
@@ -147,52 +130,20 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
|
||||
const char *options)
|
||||
{
|
||||
if (!(device->port.membase || device->port.iobase))
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
|
||||
if (!device->baud) {
|
||||
device->baud = probe_baud(&device->port);
|
||||
snprintf(device->options, sizeof(device->options), "%u",
|
||||
device->baud);
|
||||
}
|
||||
struct uart_port *port = &device->port;
|
||||
unsigned int ier;
|
||||
|
||||
init_port(device);
|
||||
/* assume the device was initialized, only mask interrupts */
|
||||
ier = serial8250_early_in(port, UART_IER);
|
||||
serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
|
||||
} else
|
||||
init_port(device);
|
||||
|
||||
early_device = device;
|
||||
device->con->write = early_serial8250_write;
|
||||
return 0;
|
||||
}
|
||||
EARLYCON_DECLARE(uart8250, early_serial8250_setup);
|
||||
EARLYCON_DECLARE(uart, early_serial8250_setup);
|
||||
|
||||
int __init setup_early_serial8250_console(char *cmdline)
|
||||
{
|
||||
char match[] = "uart8250";
|
||||
|
||||
if (cmdline && cmdline[4] == ',')
|
||||
match[4] = '\0';
|
||||
|
||||
return setup_earlycon(cmdline, match, early_serial8250_setup);
|
||||
}
|
||||
|
||||
int serial8250_find_port_for_earlycon(void)
|
||||
{
|
||||
struct earlycon_device *device = early_device;
|
||||
struct uart_port *port = device ? &device->port : NULL;
|
||||
int line;
|
||||
int ret;
|
||||
|
||||
if (!port || (!port->membase && !port->iobase))
|
||||
return -ENODEV;
|
||||
|
||||
line = serial8250_find_port(port);
|
||||
if (line < 0)
|
||||
return -ENODEV;
|
||||
|
||||
ret = update_console_cmdline("uart", 8250,
|
||||
"ttyS", line, device->options);
|
||||
if (ret < 0)
|
||||
ret = update_console_cmdline("uart", 0,
|
||||
"ttyS", line, device->options);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dio.h>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
+305
-127
File diff suppressed because it is too large
Load Diff
@@ -108,6 +108,7 @@ config SERIAL_8250_PCI
|
||||
tristate "8250/16550 PCI device support" if EXPERT
|
||||
depends on SERIAL_8250 && PCI
|
||||
default SERIAL_8250
|
||||
select RATIONAL
|
||||
help
|
||||
This builds standard PCI serial support. You may be able to
|
||||
disable this feature if you only need legacy serial support.
|
||||
|
||||
@@ -20,7 +20,7 @@ comment "Non-8250 serial port support"
|
||||
|
||||
config SERIAL_AMBA_PL010
|
||||
tristate "ARM AMBA PL010 serial port support"
|
||||
depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
|
||||
depends on ARM_AMBA
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have
|
||||
@@ -483,16 +483,6 @@ config SERIAL_SA1100_CONSOLE
|
||||
your boot loader (lilo or loadlin) about how to pass options to the
|
||||
kernel at boot time.)
|
||||
|
||||
config SERIAL_MFD_HSU
|
||||
tristate "Medfield High Speed UART support"
|
||||
depends on PCI
|
||||
select SERIAL_CORE
|
||||
|
||||
config SERIAL_MFD_HSU_CONSOLE
|
||||
bool "Medfile HSU serial console support"
|
||||
depends on SERIAL_MFD_HSU=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
|
||||
config SERIAL_BFIN
|
||||
tristate "Blackfin serial port support"
|
||||
depends on BLACKFIN
|
||||
@@ -835,7 +825,7 @@ config SERIAL_MCF_CONSOLE
|
||||
|
||||
config SERIAL_PMACZILOG
|
||||
tristate "Mac or PowerMac z85c30 ESCC support"
|
||||
depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)
|
||||
depends on (M68K && MAC) || PPC_PMAC
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This driver supports the Zilog z85C30 serial ports found on
|
||||
@@ -878,7 +868,7 @@ config SERIAL_PMACZILOG_CONSOLE
|
||||
|
||||
config SERIAL_CPM
|
||||
tristate "CPM SCC/SMC serial port support"
|
||||
depends on CPM2 || 8xx
|
||||
depends on CPM2 || CPM1
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This driver supports the SCC and SMC serial ports on Motorola
|
||||
@@ -1054,7 +1044,7 @@ config SERIAL_SGI_IOC3
|
||||
|
||||
config SERIAL_MSM
|
||||
bool "MSM on-chip serial port support"
|
||||
depends on ARCH_MSM || ARCH_QCOM
|
||||
depends on ARCH_QCOM
|
||||
select SERIAL_CORE
|
||||
|
||||
config SERIAL_MSM_CONSOLE
|
||||
@@ -1063,18 +1053,6 @@ config SERIAL_MSM_CONSOLE
|
||||
select SERIAL_CORE_CONSOLE
|
||||
select SERIAL_EARLYCON
|
||||
|
||||
config SERIAL_MSM_HS
|
||||
tristate "MSM UART High Speed: Serial Driver"
|
||||
depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
|
||||
select SERIAL_CORE
|
||||
help
|
||||
If you have a machine based on MSM family of SoCs, you
|
||||
can enable its onboard high speed serial port by enabling
|
||||
this option.
|
||||
|
||||
Choose M here to compile it as a module. The module will be
|
||||
called msm_serial_hs.
|
||||
|
||||
config SERIAL_VT8500
|
||||
bool "VIA VT8500 on-chip serial port support"
|
||||
depends on ARCH_VT8500
|
||||
@@ -1153,7 +1131,7 @@ config SERIAL_OMAP_CONSOLE
|
||||
|
||||
config SERIAL_OF_PLATFORM_NWPSERIAL
|
||||
tristate "NWP serial port driver"
|
||||
depends on PPC_OF && PPC_DCR
|
||||
depends on PPC_DCR
|
||||
select SERIAL_OF_PLATFORM
|
||||
select SERIAL_CORE_CONSOLE
|
||||
select SERIAL_CORE
|
||||
|
||||
@@ -62,7 +62,6 @@ obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
|
||||
obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
|
||||
obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
|
||||
obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
|
||||
obj-$(CONFIG_SERIAL_MSM_HS) += msm_serial_hs.o
|
||||
obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
|
||||
obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
|
||||
obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
|
||||
@@ -78,7 +77,6 @@ obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
|
||||
obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
|
||||
obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
|
||||
obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o
|
||||
obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o
|
||||
obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o
|
||||
obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o
|
||||
obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o
|
||||
|
||||
+129
-105
@@ -58,6 +58,7 @@
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define UART_NR 14
|
||||
|
||||
@@ -156,7 +157,9 @@ struct uart_amba_port {
|
||||
unsigned int lcrh_tx; /* vendor-specific */
|
||||
unsigned int lcrh_rx; /* vendor-specific */
|
||||
unsigned int old_cr; /* state during shutdown */
|
||||
struct delayed_work tx_softirq_work;
|
||||
bool autorts;
|
||||
unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */
|
||||
char type[12];
|
||||
#ifdef CONFIG_DMA_ENGINE
|
||||
/* DMA stuff */
|
||||
@@ -164,6 +167,7 @@ struct uart_amba_port {
|
||||
bool using_rx_dma;
|
||||
struct pl011_dmarx_data dmarx;
|
||||
struct pl011_dmatx_data dmatx;
|
||||
bool dma_probed;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -261,10 +265,11 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg,
|
||||
}
|
||||
}
|
||||
|
||||
static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *uap)
|
||||
static void pl011_dma_probe(struct uart_amba_port *uap)
|
||||
{
|
||||
/* DMA is the sole user of the platform data right now */
|
||||
struct amba_pl011_data *plat = dev_get_platdata(uap->port.dev);
|
||||
struct device *dev = uap->port.dev;
|
||||
struct dma_slave_config tx_conf = {
|
||||
.dst_addr = uap->port.mapbase + UART01x_DR,
|
||||
.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
|
||||
@@ -275,9 +280,14 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
|
||||
struct dma_chan *chan;
|
||||
dma_cap_mask_t mask;
|
||||
|
||||
chan = dma_request_slave_channel(dev, "tx");
|
||||
uap->dma_probed = true;
|
||||
chan = dma_request_slave_channel_reason(dev, "tx");
|
||||
if (IS_ERR(chan)) {
|
||||
if (PTR_ERR(chan) == -EPROBE_DEFER) {
|
||||
uap->dma_probed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chan) {
|
||||
/* We need platform data */
|
||||
if (!plat || !plat->dma_filter) {
|
||||
dev_info(uap->port.dev, "no DMA platform data\n");
|
||||
@@ -385,63 +395,17 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
/*
|
||||
* Stack up the UARTs and let the above initcall be done at device
|
||||
* initcall time, because the serial driver is called as an arch
|
||||
* initcall, and at this time the DMA subsystem is not yet registered.
|
||||
* At this point the driver will switch over to using DMA where desired.
|
||||
*/
|
||||
struct dma_uap {
|
||||
struct list_head node;
|
||||
struct uart_amba_port *uap;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static LIST_HEAD(pl011_dma_uarts);
|
||||
|
||||
static int __init pl011_dma_initcall(void)
|
||||
{
|
||||
struct list_head *node, *tmp;
|
||||
|
||||
list_for_each_safe(node, tmp, &pl011_dma_uarts) {
|
||||
struct dma_uap *dmau = list_entry(node, struct dma_uap, node);
|
||||
pl011_dma_probe_initcall(dmau->dev, dmau->uap);
|
||||
list_del(node);
|
||||
kfree(dmau);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(pl011_dma_initcall);
|
||||
|
||||
static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
|
||||
{
|
||||
struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL);
|
||||
if (dmau) {
|
||||
dmau->uap = uap;
|
||||
dmau->dev = dev;
|
||||
list_add_tail(&dmau->node, &pl011_dma_uarts);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
|
||||
{
|
||||
pl011_dma_probe_initcall(dev, uap);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pl011_dma_remove(struct uart_amba_port *uap)
|
||||
{
|
||||
/* TODO: remove the initcall if it has not yet executed */
|
||||
if (uap->dmatx.chan)
|
||||
dma_release_channel(uap->dmatx.chan);
|
||||
if (uap->dmarx.chan)
|
||||
dma_release_channel(uap->dmarx.chan);
|
||||
}
|
||||
|
||||
/* Forward declare this for the refill routine */
|
||||
/* Forward declare these for the refill routine */
|
||||
static int pl011_dma_tx_refill(struct uart_amba_port *uap);
|
||||
static void pl011_start_tx_pio(struct uart_amba_port *uap);
|
||||
|
||||
/*
|
||||
* The current DMA TX buffer has been sent.
|
||||
@@ -479,14 +443,13 @@ static void pl011_dma_tx_callback(void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl011_dma_tx_refill(uap) <= 0) {
|
||||
if (pl011_dma_tx_refill(uap) <= 0)
|
||||
/*
|
||||
* We didn't queue a DMA buffer for some reason, but we
|
||||
* have data pending to be sent. Re-enable the TX IRQ.
|
||||
*/
|
||||
uap->im |= UART011_TXIM;
|
||||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
}
|
||||
pl011_start_tx_pio(uap);
|
||||
|
||||
spin_unlock_irqrestore(&uap->port.lock, flags);
|
||||
}
|
||||
|
||||
@@ -664,12 +627,10 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
|
||||
if (!uap->dmatx.queued) {
|
||||
if (pl011_dma_tx_refill(uap) > 0) {
|
||||
uap->im &= ~UART011_TXIM;
|
||||
ret = true;
|
||||
} else {
|
||||
uap->im |= UART011_TXIM;
|
||||
writew(uap->im, uap->port.membase +
|
||||
UART011_IMSC);
|
||||
} else
|
||||
ret = false;
|
||||
}
|
||||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
} else if (!(uap->dmacr & UART011_TXDMAE)) {
|
||||
uap->dmacr |= UART011_TXDMAE;
|
||||
writew(uap->dmacr,
|
||||
@@ -1021,6 +982,9 @@ static void pl011_dma_startup(struct uart_amba_port *uap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!uap->dma_probed)
|
||||
pl011_dma_probe(uap);
|
||||
|
||||
if (!uap->dmatx.chan)
|
||||
return;
|
||||
|
||||
@@ -1142,7 +1106,7 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
|
||||
|
||||
#else
|
||||
/* Blank functions if the DMA engine is not available */
|
||||
static inline void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
|
||||
static inline void pl011_dma_probe(struct uart_amba_port *uap)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1208,15 +1172,24 @@ static void pl011_stop_tx(struct uart_port *port)
|
||||
pl011_dma_tx_stop(uap);
|
||||
}
|
||||
|
||||
static bool pl011_tx_chars(struct uart_amba_port *uap);
|
||||
|
||||
/* Start TX with programmed I/O only (no DMA) */
|
||||
static void pl011_start_tx_pio(struct uart_amba_port *uap)
|
||||
{
|
||||
uap->im |= UART011_TXIM;
|
||||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
if (!uap->tx_irq_seen)
|
||||
pl011_tx_chars(uap);
|
||||
}
|
||||
|
||||
static void pl011_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct uart_amba_port *uap =
|
||||
container_of(port, struct uart_amba_port, port);
|
||||
|
||||
if (!pl011_dma_tx_start(uap)) {
|
||||
uap->im |= UART011_TXIM;
|
||||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
}
|
||||
if (!pl011_dma_tx_start(uap))
|
||||
pl011_start_tx_pio(uap);
|
||||
}
|
||||
|
||||
static void pl011_stop_rx(struct uart_port *port)
|
||||
@@ -1274,40 +1247,87 @@ __acquires(&uap->port.lock)
|
||||
spin_lock(&uap->port.lock);
|
||||
}
|
||||
|
||||
static void pl011_tx_chars(struct uart_amba_port *uap)
|
||||
/*
|
||||
* Transmit a character
|
||||
* There must be at least one free entry in the TX FIFO to accept the char.
|
||||
*
|
||||
* Returns true if the FIFO might have space in it afterwards;
|
||||
* returns false if the FIFO definitely became full.
|
||||
*/
|
||||
static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c)
|
||||
{
|
||||
writew(c, uap->port.membase + UART01x_DR);
|
||||
uap->port.icount.tx++;
|
||||
|
||||
if (likely(uap->tx_irq_seen > 1))
|
||||
return true;
|
||||
|
||||
return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF);
|
||||
}
|
||||
|
||||
static bool pl011_tx_chars(struct uart_amba_port *uap)
|
||||
{
|
||||
struct circ_buf *xmit = &uap->port.state->xmit;
|
||||
int count;
|
||||
|
||||
if (unlikely(uap->tx_irq_seen < 2))
|
||||
/*
|
||||
* Initial FIFO fill level unknown: we must check TXFF
|
||||
* after each write, so just try to fill up the FIFO.
|
||||
*/
|
||||
count = uap->fifosize;
|
||||
else /* tx_irq_seen >= 2 */
|
||||
/*
|
||||
* FIFO initially at least half-empty, so we can simply
|
||||
* write half the FIFO without polling TXFF.
|
||||
|
||||
* Note: the *first* TX IRQ can still race with
|
||||
* pl011_start_tx_pio(), which can result in the FIFO
|
||||
* being fuller than expected in that case.
|
||||
*/
|
||||
count = uap->fifosize >> 1;
|
||||
|
||||
/*
|
||||
* If the FIFO is full we're guaranteed a TX IRQ at some later point,
|
||||
* and can't transmit immediately in any case:
|
||||
*/
|
||||
if (unlikely(uap->tx_irq_seen < 2 &&
|
||||
readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF))
|
||||
return false;
|
||||
|
||||
if (uap->port.x_char) {
|
||||
writew(uap->port.x_char, uap->port.membase + UART01x_DR);
|
||||
uap->port.icount.tx++;
|
||||
pl011_tx_char(uap, uap->port.x_char);
|
||||
uap->port.x_char = 0;
|
||||
return;
|
||||
--count;
|
||||
}
|
||||
if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
|
||||
pl011_stop_tx(&uap->port);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If we are using DMA mode, try to send some characters. */
|
||||
if (pl011_dma_tx_irq(uap))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
count = uap->fifosize >> 1;
|
||||
do {
|
||||
writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
|
||||
while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) {
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
uap->port.icount.tx++;
|
||||
if (uart_circ_empty(xmit))
|
||||
break;
|
||||
} while (--count > 0);
|
||||
}
|
||||
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup(&uap->port);
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
if (uart_circ_empty(xmit)) {
|
||||
pl011_stop_tx(&uap->port);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (unlikely(!uap->tx_irq_seen))
|
||||
schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout);
|
||||
|
||||
done:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pl011_modem_status(struct uart_amba_port *uap)
|
||||
@@ -1334,6 +1354,28 @@ static void pl011_modem_status(struct uart_amba_port *uap)
|
||||
wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
|
||||
}
|
||||
|
||||
static void pl011_tx_softirq(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct uart_amba_port *uap =
|
||||
container_of(dwork, struct uart_amba_port, tx_softirq_work);
|
||||
|
||||
spin_lock(&uap->port.lock);
|
||||
while (pl011_tx_chars(uap)) ;
|
||||
spin_unlock(&uap->port.lock);
|
||||
}
|
||||
|
||||
static void pl011_tx_irq_seen(struct uart_amba_port *uap)
|
||||
{
|
||||
if (likely(uap->tx_irq_seen > 1))
|
||||
return;
|
||||
|
||||
uap->tx_irq_seen++;
|
||||
if (uap->tx_irq_seen < 2)
|
||||
/* first TX IRQ */
|
||||
cancel_delayed_work(&uap->tx_softirq_work);
|
||||
}
|
||||
|
||||
static irqreturn_t pl011_int(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_amba_port *uap = dev_id;
|
||||
@@ -1372,8 +1414,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
|
||||
if (status & (UART011_DSRMIS|UART011_DCDMIS|
|
||||
UART011_CTSMIS|UART011_RIMIS))
|
||||
pl011_modem_status(uap);
|
||||
if (status & UART011_TXIS)
|
||||
if (status & UART011_TXIS) {
|
||||
pl011_tx_irq_seen(uap);
|
||||
pl011_tx_chars(uap);
|
||||
}
|
||||
|
||||
if (pass_counter-- == 0)
|
||||
break;
|
||||
@@ -1577,7 +1621,7 @@ static int pl011_startup(struct uart_port *port)
|
||||
{
|
||||
struct uart_amba_port *uap =
|
||||
container_of(port, struct uart_amba_port, port);
|
||||
unsigned int cr, lcr_h, fbrd, ibrd;
|
||||
unsigned int cr;
|
||||
int retval;
|
||||
|
||||
retval = pl011_hwinit(port);
|
||||
@@ -1595,30 +1639,8 @@ static int pl011_startup(struct uart_port *port)
|
||||
|
||||
writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
|
||||
|
||||
/*
|
||||
* Provoke TX FIFO interrupt into asserting. Taking care to preserve
|
||||
* baud rate and data format specified by FBRD, IBRD and LCRH as the
|
||||
* UART may already be in use as a console.
|
||||
*/
|
||||
spin_lock_irq(&uap->port.lock);
|
||||
|
||||
fbrd = readw(uap->port.membase + UART011_FBRD);
|
||||
ibrd = readw(uap->port.membase + UART011_IBRD);
|
||||
lcr_h = readw(uap->port.membase + uap->lcrh_rx);
|
||||
|
||||
cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
|
||||
writew(cr, uap->port.membase + UART011_CR);
|
||||
writew(0, uap->port.membase + UART011_FBRD);
|
||||
writew(1, uap->port.membase + UART011_IBRD);
|
||||
pl011_write_lcr_h(uap, 0);
|
||||
writew(0, uap->port.membase + UART01x_DR);
|
||||
while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
|
||||
barrier();
|
||||
|
||||
writew(fbrd, uap->port.membase + UART011_FBRD);
|
||||
writew(ibrd, uap->port.membase + UART011_IBRD);
|
||||
pl011_write_lcr_h(uap, lcr_h);
|
||||
|
||||
/* restore RTS and DTR */
|
||||
cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
|
||||
cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
|
||||
@@ -1672,13 +1694,15 @@ static void pl011_shutdown(struct uart_port *port)
|
||||
container_of(port, struct uart_amba_port, port);
|
||||
unsigned int cr;
|
||||
|
||||
cancel_delayed_work_sync(&uap->tx_softirq_work);
|
||||
|
||||
/*
|
||||
* disable all interrupts
|
||||
*/
|
||||
spin_lock_irq(&uap->port.lock);
|
||||
uap->im = 0;
|
||||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
writew(0xffff, uap->port.membase + UART011_ICR);
|
||||
writew(0xffff & ~UART011_TXIS, uap->port.membase + UART011_ICR);
|
||||
spin_unlock_irq(&uap->port.lock);
|
||||
|
||||
pl011_dma_shutdown(uap);
|
||||
@@ -2218,7 +2242,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
uap->port.ops = &amba_pl011_pops;
|
||||
uap->port.flags = UPF_BOOT_AUTOCONF;
|
||||
uap->port.line = i;
|
||||
pl011_dma_probe(&dev->dev, uap);
|
||||
INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq);
|
||||
|
||||
/* Ensure interrupts from this UART are masked and cleared */
|
||||
writew(0, uap->port.membase + UART011_IMSC);
|
||||
@@ -2233,7 +2257,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
if (!amba_reg.state) {
|
||||
ret = uart_register_driver(&amba_reg);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to register AMBA-PL011 driver\n");
|
||||
dev_err(&dev->dev,
|
||||
"Failed to register AMBA-PL011 driver\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -2242,7 +2267,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
if (ret) {
|
||||
amba_ports[i] = NULL;
|
||||
uart_unregister_driver(&amba_reg);
|
||||
pl011_dma_remove(uap);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -572,7 +572,7 @@ static int apbuart_probe(struct platform_device *op)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id apbuart_match[] = {
|
||||
static const struct of_device_id apbuart_match[] = {
|
||||
{
|
||||
.name = "GAISLER_APBUART",
|
||||
},
|
||||
|
||||
@@ -649,7 +649,7 @@ static int ar933x_uart_probe(struct platform_device *pdev)
|
||||
id = 0;
|
||||
}
|
||||
|
||||
if (id > CONFIG_SERIAL_AR933X_NR_UARTS)
|
||||
if (id >= CONFIG_SERIAL_AR933X_NR_UARTS)
|
||||
return -EINVAL;
|
||||
|
||||
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
|
||||
@@ -855,7 +855,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
|
||||
spin_lock_init(&atmel_port->lock_tx);
|
||||
sg_init_table(&atmel_port->sg_tx, 1);
|
||||
/* UART circular tx buffer is an aligned page. */
|
||||
BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
|
||||
BUG_ON(!PAGE_ALIGNED(port->state->xmit.buf));
|
||||
sg_set_page(&atmel_port->sg_tx,
|
||||
virt_to_page(port->state->xmit.buf),
|
||||
UART_XMIT_SIZE,
|
||||
@@ -1034,10 +1034,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
|
||||
spin_lock_init(&atmel_port->lock_rx);
|
||||
sg_init_table(&atmel_port->sg_rx, 1);
|
||||
/* UART circular rx buffer is an aligned page. */
|
||||
BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
|
||||
BUG_ON(!PAGE_ALIGNED(ring->buf));
|
||||
sg_set_page(&atmel_port->sg_rx,
|
||||
virt_to_page(ring->buf),
|
||||
ATMEL_SERIAL_RINGSIZE,
|
||||
sizeof(struct atmel_uart_char) * ATMEL_SERIAL_RINGSIZE,
|
||||
(int)ring->buf & ~PAGE_MASK);
|
||||
nent = dma_map_sg(port->dev,
|
||||
&atmel_port->sg_rx,
|
||||
@@ -1554,7 +1554,7 @@ static void atmel_tasklet_func(unsigned long data)
|
||||
spin_unlock(&port->lock);
|
||||
}
|
||||
|
||||
static int atmel_init_property(struct atmel_uart_port *atmel_port,
|
||||
static void atmel_init_property(struct atmel_uart_port *atmel_port,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -1595,7 +1595,6 @@ static int atmel_init_property(struct atmel_uart_port *atmel_port,
|
||||
atmel_port->use_dma_tx = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atmel_init_rs485(struct uart_port *port,
|
||||
@@ -1777,10 +1776,13 @@ static int atmel_startup(struct uart_port *port)
|
||||
if (retval)
|
||||
goto free_irq;
|
||||
|
||||
tasklet_enable(&atmel_port->tasklet);
|
||||
|
||||
/*
|
||||
* Initialize DMA (if necessary)
|
||||
*/
|
||||
atmel_init_property(atmel_port, pdev);
|
||||
atmel_set_ops(port);
|
||||
|
||||
if (atmel_port->prepare_rx) {
|
||||
retval = atmel_port->prepare_rx(port);
|
||||
@@ -1879,6 +1881,7 @@ static void atmel_shutdown(struct uart_port *port)
|
||||
* Clear out any scheduled tasklets before
|
||||
* we destroy the buffers
|
||||
*/
|
||||
tasklet_disable(&atmel_port->tasklet);
|
||||
tasklet_kill(&atmel_port->tasklet);
|
||||
|
||||
/*
|
||||
@@ -2256,8 +2259,8 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||
struct uart_port *port = &atmel_port->uart;
|
||||
struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
if (!atmel_init_property(atmel_port, pdev))
|
||||
atmel_set_ops(port);
|
||||
atmel_init_property(atmel_port, pdev);
|
||||
atmel_set_ops(port);
|
||||
|
||||
atmel_init_rs485(port, pdev);
|
||||
|
||||
@@ -2272,6 +2275,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||
|
||||
tasklet_init(&atmel_port->tasklet, atmel_tasklet_func,
|
||||
(unsigned long)port);
|
||||
tasklet_disable(&atmel_port->tasklet);
|
||||
|
||||
memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
|
||||
|
||||
@@ -2581,8 +2585,8 @@ static int atmel_init_gpios(struct atmel_uart_port *p, struct device *dev)
|
||||
struct gpio_desc *gpiod;
|
||||
|
||||
p->gpios = mctrl_gpio_init(dev, 0);
|
||||
if (IS_ERR_OR_NULL(p->gpios))
|
||||
return -1;
|
||||
if (IS_ERR(p->gpios))
|
||||
return PTR_ERR(p->gpios);
|
||||
|
||||
for (i = 0; i < UART_GPIO_MAX; i++) {
|
||||
gpiod = mctrl_gpio_to_gpiod(p->gpios, i);
|
||||
@@ -2635,9 +2639,10 @@ static int atmel_serial_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&port->lock_suspended);
|
||||
|
||||
ret = atmel_init_gpios(port, &pdev->dev);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "%s",
|
||||
"Failed to initialize GPIOs. The serial port may not work as expected");
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to initialize GPIOs.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = atmel_init_port(port, pdev);
|
||||
if (ret)
|
||||
|
||||
@@ -854,7 +854,7 @@ static int bcm_uart_probe(struct platform_device *pdev)
|
||||
|
||||
ret = uart_add_one_port(&bcm_uart_driver, port);
|
||||
if (ret) {
|
||||
ports[pdev->id].membase = 0;
|
||||
ports[pdev->id].membase = NULL;
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(pdev, port);
|
||||
@@ -868,7 +868,7 @@ static int bcm_uart_remove(struct platform_device *pdev)
|
||||
port = platform_get_drvdata(pdev);
|
||||
uart_remove_one_port(&bcm_uart_driver, port);
|
||||
/* mark port as free */
|
||||
ports[pdev->id].membase = 0;
|
||||
ports[pdev->id].membase = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -464,6 +464,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
|
||||
int x_pos, pos;
|
||||
unsigned long flags;
|
||||
|
||||
dma_disable_irq_nosync(uart->rx_dma_channel);
|
||||
spin_lock_irqsave(&uart->rx_lock, flags);
|
||||
|
||||
/* 2D DMA RX buffer ring is used. Because curr_y_count and
|
||||
@@ -496,6 +497,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&uart->rx_lock, flags);
|
||||
dma_enable_irq(uart->rx_dma_channel);
|
||||
|
||||
mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
|
||||
}
|
||||
|
||||
@@ -501,6 +501,8 @@ static int uart_clps711x_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, s);
|
||||
|
||||
s->gpios = mctrl_gpio_init(&pdev->dev, 0);
|
||||
if (IS_ERR(s->gpios))
|
||||
return PTR_ERR(s->gpios);
|
||||
|
||||
ret = uart_add_one_port(&clps711x_uart, &s->port);
|
||||
if (ret)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user