Commit 356a0319 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tty-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty / serial driver updates from Greg KH:
 "Here is the "big" set of tty/serial driver updates for 6.12-rc1.

  Nothing major in here, just nice forward progress in the slow cleanup
  of the serial apis, and lots of other driver updates and fixes.

  Included in here are:

   - serial api updates from Jiri to make things more uniform and sane

   - 8250_platform driver cleanups

   - samsung serial driver fixes and updates

   - qcom-geni serial driver fixes from Johan for the bizarre UART
     engine that that chip seems to have. Hopefully it's in a better
     state now, but hardware designers still seem to come up with more
     ways to make broken UARTS 40+ years after this all should have
     finished.

   - sc16is7xx driver updates

   - omap 8250 driver updates

   - 8250_bcm2835aux driver updates

   - a few new serial driver bindings added

   - other serial minor driver updates

  All of these have been in linux-next for a long time with no reported
  problems"

* tag 'tty-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (65 commits)
  tty: serial: samsung: Fix serial rx on Apple A7-A9
  tty: serial: samsung: Fix A7-A11 serial earlycon SError
  tty: serial: samsung: Use bit manipulation macros for APPLE_S5L_*
  tty: rp2: Fix reset with non forgiving PCIe host bridges
  serial: 8250_aspeed_vuart: Enable module autoloading
  serial: qcom-geni: fix polled console corruption
  serial: qcom-geni: disable interrupts during console writes
  serial: qcom-geni: fix console corruption
  serial: qcom-geni: introduce qcom_geni_serial_poll_bitfield()
  serial: qcom-geni: fix arg types for qcom_geni_serial_poll_bit()
  soc: qcom: geni-se: add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers
  serial: qcom-geni: fix false console tx restart
  serial: qcom-geni: fix fifo polling timeout
  tty: hvc: convert comma to semicolon
  mxser: convert comma to semicolon
  serial: 8250_bcm2835aux: Fix clock imbalance in PM resume
  serial: sc16is7xx: convert bitmask definitions to use BIT() macro
  serial: sc16is7xx: fix copy-paste errors in EFR_SWFLOWx_BIT constants
  serial: sc16is7xx: remove SC16IS7XX_MSR_DELTA_MASK
  serial: xilinx_uartps: Make cdns_rs485_supported static
  ...
parents 4965ddb1 5ed771f1
......@@ -76,6 +76,7 @@ properties:
clock-frequency: true
current-speed: true
overrun-throttle-ms: true
wakeup-source: true
required:
- compatible
......
......@@ -23,13 +23,20 @@ properties:
- const: atmel,at91sam9260-dbgu
- const: atmel,at91sam9260-usart
- items:
- const: microchip,sam9x60-usart
- enum:
- microchip,sam9x60-usart
- microchip,sam9x7-usart
- const: atmel,at91sam9260-usart
- items:
- const: microchip,sam9x60-dbgu
- const: microchip,sam9x60-usart
- const: atmel,at91sam9260-dbgu
- const: atmel,at91sam9260-usart
- items:
- const: microchip,sam9x7-dbgu
- const: atmel,at91sam9260-dbgu
- const: microchip,sam9x7-usart
- const: atmel,at91sam9260-usart
reg:
maxItems: 1
......
......@@ -36,6 +36,7 @@ properties:
- mediatek,mt7622-uart
- mediatek,mt7623-uart
- mediatek,mt7629-uart
- mediatek,mt7981-uart
- mediatek,mt7986-uart
- mediatek,mt7988-uart
- mediatek,mt8127-uart
......
......@@ -46,6 +46,7 @@ properties:
- items:
- enum:
- renesas,scif-r8a774a1 # RZ/G2M
- renesas,scif-r8a774a3 # RZ/G2M v3.0
- renesas,scif-r8a774b1 # RZ/G2N
- renesas,scif-r8a774c0 # RZ/G2E
- renesas,scif-r8a774e1 # RZ/G2H
......
......@@ -56,14 +56,8 @@ properties:
maxItems: 5
clock-names:
description: N = 0 is allowed for SoCs without internal baud clock mux.
minItems: 2
items:
- const: uart
- pattern: '^clk_uart_baud[0-3]$'
- pattern: '^clk_uart_baud[0-3]$'
- pattern: '^clk_uart_baud[0-3]$'
- pattern: '^clk_uart_baud[0-3]$'
maxItems: 5
dmas:
items:
......@@ -103,18 +97,45 @@ allOf:
compatible:
contains:
enum:
- samsung,s5pv210-uart
- samsung,s3c6400-uart
then:
properties:
clocks:
minItems: 2
minItems: 3
maxItems: 3
clock-names:
items:
- const: uart
- const: clk_uart_baud2
- const: clk_uart_baud3
else:
properties:
clock-names:
minItems: 2
items:
- const: uart
- pattern: '^clk_uart_baud[0-1]$'
- pattern: '^clk_uart_baud[0-1]$'
- const: clk_uart_baud0
- const: clk_uart_baud1
- const: clk_uart_baud2
- const: clk_uart_baud3
- if:
properties:
compatible:
contains:
enum:
- samsung,s5pv210-uart
then:
properties:
clocks:
minItems: 3
maxItems: 3
clock-names:
minItems: 3
maxItems: 3
- if:
properties:
......@@ -129,10 +150,9 @@ allOf:
properties:
clocks:
maxItems: 2
clock-names:
items:
- const: uart
- const: clk_uart_baud0
maxItems: 2
- if:
properties:
......@@ -146,6 +166,12 @@ allOf:
properties:
reg-io-width: false
clocks:
maxItems: 2
clock-names:
maxItems: 2
unevaluatedProperties: false
examples:
......@@ -163,3 +189,19 @@ examples:
<&clocks SCLK_UART>;
samsung,uart-fifosize = <16>;
};
- |
#include <dt-bindings/clock/google,gs101.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
serial_0: serial@10a00000 {
compatible = "google,gs101-uart";
reg = <0x10a00000 0xc0>;
clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_0>,
<&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_0>;
clock-names = "uart", "clk_uart_baud0";
interrupts = <GIC_SPI 634 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-0 = <&uart0_bus>;
pinctrl-names = "default";
samsung,uart-fifosize = <256>;
};
......@@ -94,6 +94,39 @@ pwm@10048000 {
#pwm-cells = <2>;
};
serial@11002000 {
compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
reg = <0 0x11002000 0 0x100>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uart", "wakeup";
clocks = <&infracfg CLK_INFRA_UART0_SEL>,
<&infracfg CLK_INFRA_UART0_CK>;
clock-names = "baud", "bus";
status = "disabled";
};
serial@11003000 {
compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
reg = <0 0x11003000 0 0x100>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uart", "wakeup";
clocks = <&infracfg CLK_INFRA_UART1_SEL>,
<&infracfg CLK_INFRA_UART1_CK>;
clock-names = "baud", "bus";
status = "disabled";
};
serial@11004000 {
compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
reg = <0 0x11004000 0 0x100>;
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uart", "wakeup";
clocks = <&infracfg CLK_INFRA_UART2_SEL>,
<&infracfg CLK_INFRA_UART2_CK>;
clock-names = "baud", "bus";
status = "disabled";
};
i2c@11007000 {
compatible = "mediatek,mt7981-i2c";
reg = <0 0x11007000 0 0x1000>,
......
......@@ -37,8 +37,6 @@
#include <linux/semaphore.h>
#include <linux/refcount.h>
#define SIXPACK_VERSION "Revision: 0.3.0"
/* sixpack priority commands */
#define SIXP_SEOF 0x40 /* start and end of a 6pack frame */
#define SIXP_TX_URUN 0x48 /* transmit overrun */
......@@ -88,22 +86,18 @@ struct sixpack {
struct net_device *dev; /* easy for intr handling */
/* These are pointers to the malloc()ed frame buffers. */
unsigned char *rbuff; /* receiver buffer */
int rcount; /* received chars counter */
unsigned char *xbuff; /* transmitter buffer */
unsigned char *xhead; /* next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
unsigned char raw_buf[4];
unsigned char cooked_buf[400];
u8 raw_buf[4];
u8 cooked_buf[400];
unsigned int rx_count;
unsigned int rx_count_cooked;
spinlock_t rxlock;
int mtu; /* Our mtu (to spot changes!) */
int buffsize; /* Max buffers sizes */
unsigned long flags; /* Flag values/ mode etc */
unsigned char mode; /* 6pack mode */
......@@ -113,8 +107,8 @@ struct sixpack {
unsigned char slottime;
unsigned char duplex;
unsigned char led_state;
unsigned char status;
unsigned char status1;
u8 status;
u8 status1;
unsigned char status2;
unsigned char tx_enable;
unsigned char tnc_state;
......@@ -128,7 +122,7 @@ struct sixpack {
#define AX25_6PACK_HEADER_LEN 0
static void sixpack_decode(struct sixpack *, const unsigned char[], int);
static void sixpack_decode(struct sixpack *, const u8 *, size_t);
static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
/*
......@@ -167,7 +161,7 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
unsigned char *msg, *p = icp;
int actual, count;
if (len > sp->mtu) { /* sp->mtu = AX25_MTU = max. PACLEN = 256 */
if (len > AX25_MTU + 73) {
msg = "oversized transmit packet!";
goto out_drop;
}
......@@ -333,7 +327,7 @@ static void sp_bump(struct sixpack *sp, char cmd)
{
struct sk_buff *skb;
int count;
unsigned char *ptr;
u8 *ptr;
count = sp->rcount + 1;
......@@ -431,7 +425,7 @@ static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp,
const u8 *fp, size_t count)
{
struct sixpack *sp;
int count1;
size_t count1;
if (!count)
return;
......@@ -544,7 +538,7 @@ static inline int tnc_init(struct sixpack *sp)
*/
static int sixpack_open(struct tty_struct *tty)
{
char *rbuff = NULL, *xbuff = NULL;
char *xbuff = NULL;
struct net_device *dev;
struct sixpack *sp;
unsigned long len;
......@@ -574,10 +568,8 @@ static int sixpack_open(struct tty_struct *tty)
len = dev->mtu * 2;
rbuff = kmalloc(len + 4, GFP_KERNEL);
xbuff = kmalloc(len + 4, GFP_KERNEL);
if (rbuff == NULL || xbuff == NULL) {
if (xbuff == NULL) {
err = -ENOBUFS;
goto out_free;
}
......@@ -586,11 +578,8 @@ static int sixpack_open(struct tty_struct *tty)
sp->tty = tty;
sp->rbuff = rbuff;
sp->xbuff = xbuff;
sp->mtu = AX25_MTU + 73;
sp->buffsize = len;
sp->rcount = 0;
sp->rx_count = 0;
sp->rx_count_cooked = 0;
......@@ -631,7 +620,6 @@ static int sixpack_open(struct tty_struct *tty)
out_free:
kfree(xbuff);
kfree(rbuff);
free_netdev(dev);
......@@ -676,7 +664,6 @@ static void sixpack_close(struct tty_struct *tty)
del_timer_sync(&sp->resync_t);
/* Free all 6pack frame buffers after unreg. */
kfree(sp->rbuff);
kfree(sp->xbuff);
free_netdev(sp->dev);
......@@ -756,21 +743,14 @@ static struct tty_ldisc_ops sp_ldisc = {
/* Initialize 6pack control device -- register 6pack line discipline */
static const char msg_banner[] __initconst = KERN_INFO \
"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
static const char msg_regfail[] __initconst = KERN_ERR \
"6pack: can't register line discipline (err = %d)\n";
static int __init sixpack_init_driver(void)
{
int status;
printk(msg_banner);
/* Register the provided line protocol discipline */
status = tty_register_ldisc(&sp_ldisc);
if (status)
printk(msg_regfail, status);
pr_err("6pack: can't register line discipline (err = %d)\n", status);
return status;
}
......@@ -820,9 +800,9 @@ static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
/* decode 4 sixpack-encoded bytes into 3 data bytes */
static void decode_data(struct sixpack *sp, unsigned char inbyte)
static void decode_data(struct sixpack *sp, u8 inbyte)
{
unsigned char *buf;
u8 *buf;
if (sp->rx_count != 3) {
sp->raw_buf[sp->rx_count++] = inbyte;
......@@ -848,9 +828,9 @@ static void decode_data(struct sixpack *sp, unsigned char inbyte)
/* identify and execute a 6pack priority command byte */
static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
static void decode_prio_command(struct sixpack *sp, u8 cmd)
{
int actual;
ssize_t actual;
if ((cmd & SIXP_PRIO_DATA_MASK) != 0) { /* idle ? */
......@@ -898,9 +878,9 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
/* identify and execute a standard 6pack command byte */
static void decode_std_command(struct sixpack *sp, unsigned char cmd)
static void decode_std_command(struct sixpack *sp, u8 cmd)
{
unsigned char checksum = 0, rest = 0;
u8 checksum = 0, rest = 0;
short i;
switch (cmd & SIXP_CMD_MASK) { /* normal command */
......@@ -948,10 +928,10 @@ static void decode_std_command(struct sixpack *sp, unsigned char cmd)
/* decode a 6pack packet */
static void
sixpack_decode(struct sixpack *sp, const unsigned char *pre_rbuff, int count)
sixpack_decode(struct sixpack *sp, const u8 *pre_rbuff, size_t count)
{
unsigned char inbyte;
int count1;
size_t count1;
u8 inbyte;
for (count1 = 0; count1 < count; count1++) {
inbyte = pre_rbuff[count1];
......
......@@ -64,18 +64,18 @@ struct mctp_serial {
u16 txfcs, rxfcs, rxfcs_rcvd;
unsigned int txlen, rxlen;
unsigned int txpos, rxpos;
unsigned char txbuf[BUFSIZE],
u8 txbuf[BUFSIZE],
rxbuf[BUFSIZE];
};
static bool needs_escape(unsigned char c)
static bool needs_escape(u8 c)
{
return c == BYTE_ESC || c == BYTE_FRAME;
}
static int next_chunk_len(struct mctp_serial *dev)
static unsigned int next_chunk_len(struct mctp_serial *dev)
{
int i;
unsigned int i;
/* either we have no bytes to send ... */
if (dev->txpos == dev->txlen)
......@@ -99,7 +99,7 @@ static int next_chunk_len(struct mctp_serial *dev)
return i;
}
static int write_chunk(struct mctp_serial *dev, unsigned char *buf, int len)
static ssize_t write_chunk(struct mctp_serial *dev, u8 *buf, size_t len)
{
return dev->tty->ops->write(dev->tty, buf, len);
}
......@@ -108,9 +108,10 @@ static void mctp_serial_tx_work(struct work_struct *work)
{
struct mctp_serial *dev = container_of(work, struct mctp_serial,
tx_work);
unsigned char c, buf[3];
unsigned long flags;
int len, txlen;
ssize_t txlen;
unsigned int len;
u8 c, buf[3];
spin_lock_irqsave(&dev->lock, flags);
......@@ -293,7 +294,7 @@ static void mctp_serial_rx(struct mctp_serial *dev)
dev->netdev->stats.rx_bytes += dev->rxlen;
}
static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
static void mctp_serial_push_header(struct mctp_serial *dev, u8 c)
{
switch (dev->rxpos) {
case 0:
......@@ -323,7 +324,7 @@ static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
}
}
static void mctp_serial_push_trailer(struct mctp_serial *dev, unsigned char c)
static void mctp_serial_push_trailer(struct mctp_serial *dev, u8 c)
{
switch (dev->rxpos) {
case 0:
......@@ -347,7 +348,7 @@ static void mctp_serial_push_trailer(struct mctp_serial *dev, unsigned char c)
}
}
static void mctp_serial_push(struct mctp_serial *dev, unsigned char c)
static void mctp_serial_push(struct mctp_serial *dev, u8 c)
{
switch (dev->rxstate) {
case STATE_IDLE:
......@@ -394,7 +395,7 @@ static void mctp_serial_tty_receive_buf(struct tty_struct *tty, const u8 *c,
const u8 *f, size_t len)
{
struct mctp_serial *dev = tty->disc_data;
int i;
size_t i;
if (!netif_running(dev->netdev))
return;
......
......@@ -303,7 +303,7 @@ int hvsilib_write_mctrl(struct hvsi_priv *pv, int dtr)
pr_devel("HVSI@%x: %s DTR...\n", pv->termno,
dtr ? "Setting" : "Clearing");
ctrl.hdr.type = VS_CONTROL_PACKET_HEADER,
ctrl.hdr.type = VS_CONTROL_PACKET_HEADER;
ctrl.hdr.len = sizeof(struct hvsi_control);
ctrl.verb = cpu_to_be16(VSV_SET_MODEM_CTL);
ctrl.mask = cpu_to_be32(HVSI_TSDTR);
......
......@@ -208,9 +208,6 @@ static const struct {
};
#define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info)
/* driver_data correspond to the lines in the structure above
see also ISA probe function before you change something */
static const struct pci_device_id mxser_pcibrds[] = {
{ PCI_DEVICE_DATA(MOXA, C168, 8) },
{ PCI_DEVICE_DATA(MOXA, C104, 4) },
......@@ -986,7 +983,7 @@ static int mxser_get_serial_info(struct tty_struct *tty,
ss->baud_base = MXSER_BAUD_BASE;
ss->close_delay = close_delay;
ss->closing_wait = closing_wait;
ss->custom_divisor = MXSER_CUSTOM_DIVISOR,
ss->custom_divisor = MXSER_CUSTOM_DIVISOR;
mutex_unlock(&port->mutex);
return 0;
}
......@@ -1773,8 +1770,6 @@ static void mxser_initbrd(struct mxser_board *brd, bool high_baud)
mxser_process_txrx_fifo(info);
info->port.close_delay = 5 * HZ / 10;
info->port.closing_wait = 30 * HZ;
spin_lock_init(&info->slock);
/* before set INT ISR, disable all int */
......
......@@ -529,7 +529,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
bool found = false;
for_each_available_child_of_node(ctrl->dev.of_node, node) {
if (!of_get_property(node, "compatible", NULL))
if (!of_property_present(node, "compatible"))
continue;
dev_dbg(&ctrl->dev, "adding child %pOF\n", node);
......
......@@ -561,6 +561,7 @@ static const struct of_device_id aspeed_vuart_table[] = {
{ .compatible = "aspeed,ast2500-vuart" },
{ },
};
MODULE_DEVICE_TABLE(of, aspeed_vuart_table);
static struct platform_driver aspeed_vuart_driver = {
.driver = {
......
......@@ -13,6 +13,7 @@
*/
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
......@@ -213,11 +214,57 @@ static const struct acpi_device_id bcm2835aux_serial_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, bcm2835aux_serial_acpi_match);
static bool bcm2835aux_can_disable_clock(struct device *dev)
{
struct bcm2835aux_data *data = dev_get_drvdata(dev);
struct uart_8250_port *up = serial8250_get_port(data->line);
if (device_may_wakeup(dev))
return false;
if (uart_console(&up->port) && !console_suspend_enabled)
return false;
return true;
}
static int bcm2835aux_suspend(struct device *dev)
{
struct bcm2835aux_data *data = dev_get_drvdata(dev);
serial8250_suspend_port(data->line);
if (!bcm2835aux_can_disable_clock(dev))
return 0;
clk_disable_unprepare(data->clk);
return 0;
}
static int bcm2835aux_resume(struct device *dev)
{
struct bcm2835aux_data *data = dev_get_drvdata(dev);
int ret;
if (bcm2835aux_can_disable_clock(dev)) {
ret = clk_prepare_enable(data->clk);
if (ret)
return ret;
}
serial8250_resume_port(data->line);
return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835aux_dev_pm_ops, bcm2835aux_suspend, bcm2835aux_resume);
static struct platform_driver bcm2835aux_serial_driver = {
.driver = {
.name = "bcm2835-aux-uart",
.of_match_table = bcm2835aux_serial_match,
.acpi_match_table = bcm2835aux_serial_acpi_match,
.pm = pm_ptr(&bcm2835aux_dev_pm_ops),
},
.probe = bcm2835aux_serial_probe,
.remove_new = bcm2835aux_serial_remove,
......
......@@ -89,7 +89,9 @@ int serial8250_tx_dma(struct uart_8250_port *p)
struct tty_port *tport = &p->port.state->port;
struct dma_async_tx_descriptor *desc;
struct uart_port *up = &p->port;
struct scatterlist sg;
struct scatterlist *sg;
struct scatterlist sgl[2];
int i;
int ret;
if (dma->tx_running) {
......@@ -110,18 +112,17 @@ int serial8250_tx_dma(struct uart_8250_port *p)
serial8250_do_prepare_tx_dma(p);
sg_init_table(&sg, 1);
/* kfifo can do more than one sg, we don't (quite yet) */
ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
sg_init_table(sgl, ARRAY_SIZE(sgl));
ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, sgl, ARRAY_SIZE(sgl),
UART_XMIT_SIZE, dma->tx_addr);
/* we already checked empty fifo above, so there should be something */
if (WARN_ON_ONCE(ret != 1))
return 0;
dma->tx_size = 0;
dma->tx_size = sg_dma_len(&sg);
for_each_sg(sgl, sg, ret, i)
dma->tx_size += sg_dma_len(sg);
desc = dmaengine_prep_slave_sg(dma->txchan, &sg, 1,
desc = dmaengine_prep_slave_sg(dma->txchan, sgl, ret,
DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
......
......@@ -89,7 +89,7 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud,
unsigned int quot, unsigned int quot_frac)
{
dw8250_writel_ext(p, DW_UART_DLF, quot_frac);
serial8250_do_set_divisor(p, baud, quot, quot_frac);
serial8250_do_set_divisor(p, baud, quot);
}
void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios,
......
......@@ -171,6 +171,17 @@ OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup);
OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup);
OF_EARLYCON_DECLARE(uart, "snps,dw-apb-uart", early_serial8250_setup);
static int __init early_serial8250_rs2_setup(struct earlycon_device *device,
const char *options)
{
device->port.regshift = 2;
return early_serial8250_setup(device, options);
}
OF_EARLYCON_DECLARE(uart, "intel,xscale-uart", early_serial8250_rs2_setup);
OF_EARLYCON_DECLARE(uart, "mrvl,mmp-uart", early_serial8250_rs2_setup);
OF_EARLYCON_DECLARE(uart, "mrvl,pxa-uart", early_serial8250_rs2_setup);
#ifdef CONFIG_SERIAL_8250_OMAP
static int __init early_omap8250_setup(struct earlycon_device *device,
......
......@@ -500,7 +500,7 @@ static unsigned int xr17v35x_get_divisor(struct uart_port *p, unsigned int baud,
static void xr17v35x_set_divisor(struct uart_port *p, unsigned int baud,
unsigned int quot, unsigned int quot_frac)
{
serial8250_do_set_divisor(p, baud, quot, quot_frac);
serial8250_do_set_divisor(p, baud, quot);
/* Preserve bits not related to baudrate; DLD[7:4]. */
quot_frac |= serial_port_in(p, 0x2) & 0xf0;
......
......@@ -137,7 +137,6 @@ struct omap8250_priv {
atomic_t active;
bool is_suspending;
int wakeirq;
int wakeups_enabled;
u32 latency;
u32 calc_latency;
struct pm_qos_request pm_qos_request;
......@@ -1523,7 +1522,10 @@ static int omap8250_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
device_init_wakeup(&pdev->dev, true);
device_set_wakeup_capable(&pdev->dev, true);
if (of_property_read_bool(np, "wakeup-source"))
device_set_wakeup_enable(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
......@@ -1581,7 +1583,7 @@ static int omap8250_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, up.port.irq, omap8250_irq, 0,
dev_name(&pdev->dev), priv);
if (ret < 0)
return ret;
goto err;
priv->wakeirq = irq_of_parse_and_map(np, 1);
......@@ -1622,7 +1624,7 @@ static void omap8250_remove(struct platform_device *pdev)
flush_work(&priv->qos_work);
pm_runtime_disable(&pdev->dev);
cpu_latency_qos_remove_request(&priv->pm_qos_request);
device_init_wakeup(&pdev->dev, false);
device_set_wakeup_capable(&pdev->dev, false);
}
static int omap8250_prepare(struct device *dev)
......
......@@ -1277,7 +1277,7 @@ static void pci_oxsemi_tornado_set_divisor(struct uart_port *port,
serial_icr_write(up, UART_TCR, tcr);
serial_icr_write(up, UART_CPR, cpr);
serial_icr_write(up, UART_CKS, cpr2);
serial8250_do_set_divisor(port, baud, quot, 0);
serial8250_do_set_divisor(port, baud, quot);
}
/*
......
......@@ -2,11 +2,15 @@
/*
* Universal/legacy platform driver for 8250/16550-type serial ports
*
* Supports: ISA-compatible 8250/16550 ports
* Supports:
* ISA-compatible 8250/16550 ports
* ACPI 8250/16550 ports
* PNP 8250/16550 ports
* "serial8250" platform devices
*/
#include <linux/acpi.h>
#include <linux/array_size.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/once.h>
......@@ -22,9 +26,9 @@
/*
* Configuration:
* share_irqs Whether we pass IRQF_SHARED to request_irq().
* share_irqs: Whether we pass IRQF_SHARED to request_irq().
* This option is unsafe when used on edge-triggered interrupts.
* skip_txen_test Force skip of txen test at init time.
* skip_txen_test: Force skip of txen test at init time.
*/
unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
unsigned int skip_txen_test;
......@@ -61,9 +65,9 @@ static void __init __serial8250_isa_init_ports(void)
nr_uarts = UART_NR;
/*
* Set up initial isa ports based on nr_uart module param, or else
* Set up initial ISA ports based on nr_uart module param, or else
* default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not
* need to increase nr_uarts when setting up the initial isa ports.
* need to increase nr_uarts when setting up the initial ISA ports.
*/
for (i = 0; i < nr_uarts; i++)
serial8250_setup_port(i);
......@@ -101,13 +105,63 @@ void __init serial8250_isa_init_ports(void)
}
/*
* Register a set of serial devices attached to a platform device. The
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
* Generic 16550A platform devices
*/
static int serial8250_probe(struct platform_device *dev)
static int serial8250_probe_acpi(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct uart_8250_port uart = { };
struct resource *regs;
unsigned char iotype;
int ret, line;
regs = platform_get_mem_or_io(pdev, 0);
if (!regs)
return dev_err_probe(dev, -EINVAL, "no registers defined\n");
switch (resource_type(regs)) {
case IORESOURCE_IO:
uart.port.iobase = regs->start;
iotype = UPIO_PORT;
break;
case IORESOURCE_MEM:
uart.port.mapbase = regs->start;
uart.port.mapsize = resource_size(regs);
uart.port.flags = UPF_IOREMAP;
iotype = UPIO_MEM;
break;
default:
return -EINVAL;
}
/* default clock frequency */
uart.port.uartclk = 1843200;
uart.port.type = PORT_16550A;
uart.port.dev = &pdev->dev;
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
ret = uart_read_and_validate_port_properties(&uart.port);
/* no interrupt -> fall back to polling */
if (ret == -ENXIO)
ret = 0;
if (ret)
return ret;
/*
* The previous call may not set iotype correctly when reg-io-width
* property is absent and it doesn't support IO port resource.
*/
uart.port.iotype = iotype;
line = serial8250_register_8250_port(&uart);
if (line < 0)
return line;
return 0;
}
static int serial8250_probe_platform(struct platform_device *dev, struct plat_serial8250_port *p)
{
struct plat_serial8250_port *p = dev_get_platdata(&dev->dev);
struct uart_8250_port uart;
int ret, i, irqflag = 0;
......@@ -155,6 +209,31 @@ static int serial8250_probe(struct platform_device *dev)
return 0;
}
/*
* Register a set of serial devices attached to a platform device.
* The list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
static int serial8250_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct plat_serial8250_port *p;
p = dev_get_platdata(dev);
if (p)
return serial8250_probe_platform(pdev, p);
/*
* Probe platform UART devices defined using standard hardware
* discovery mechanism like ACPI or DT. Support only ACPI based
* serial device for now.
*/
if (has_acpi_companion(dev))
return serial8250_probe_acpi(pdev);
return 0;
}
/*
* Remove serial ports registered against a platform device.
*/
......@@ -198,6 +277,12 @@ static int serial8250_resume(struct platform_device *dev)
return 0;
}
static const struct acpi_device_id acpi_platform_serial_table[] = {
{ "RSCV0003" }, /* RISC-V Generic 16550A UART */
{ }
};
MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table);
static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe,
.remove_new = serial8250_remove,
......@@ -205,12 +290,13 @@ static struct platform_driver serial8250_isa_driver = {
.resume = serial8250_resume,
.driver = {
.name = "serial8250",
.acpi_match_table = acpi_platform_serial_table,
},
};
/*
* This "device" covers _all_ ISA 8250-compatible serial devices listed
* in the table in include/asm/serial.h
* in the table in include/asm/serial.h.
*/
struct platform_device *serial8250_isa_devs;
......@@ -239,8 +325,7 @@ static int __init serial8250_init(void)
if (ret)
goto unreg_uart_drv;
serial8250_isa_devs = platform_device_alloc("serial8250",
PLAT8250_DEV_LEGACY);
serial8250_isa_devs = platform_device_alloc("serial8250", PLAT8250_DEV_LEGACY);
if (!serial8250_isa_devs) {
ret = -ENOMEM;
goto unreg_pnp;
......@@ -279,7 +364,7 @@ static void __exit serial8250_exit(void)
/*
* This tells serial8250_unregister_port() not to re-register
* the ports (thereby making serial8250_isa_driver permanently
* in use.)
* in use).
*/
serial8250_isa_devs = NULL;
......@@ -312,12 +397,13 @@ MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
#ifndef MODULE
/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name
* working as well for the module options so we don't break people. We
/*
* This module was renamed to 8250_core in 3.7. Keep the old "8250" name
* working as well for the module options so we don't break people. We
* need to keep the names identical and the convenient macros will happily
* refuse to let us do that by failing the build with redefinition errors
* of global variables. So we stick them inside a dummy function to avoid
* those conflicts. The options still get parsed, and the redefined
* of global variables. So we stick them inside a dummy function to avoid
* those conflicts. The options still get parsed, and the redefined
* MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
*
* This is hacky. I'm sorry.
......
......@@ -2609,7 +2609,7 @@ static unsigned char serial8250_compute_lcr(struct uart_8250_port *up,
}
void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
unsigned int quot, unsigned int quot_frac)
unsigned int quot)
{
struct uart_8250_port *up = up_to_u8250p(port);
......@@ -2641,7 +2641,7 @@ static void serial8250_set_divisor(struct uart_port *port, unsigned int baud,
if (port->set_divisor)
port->set_divisor(port, baud, quot, quot_frac);
else
serial8250_do_set_divisor(port, baud, quot, quot_frac);
serial8250_do_set_divisor(port, baud, quot);
}
static unsigned int serial8250_get_baud_rate(struct uart_port *port,
......
......@@ -165,22 +165,6 @@ static struct platform_driver serial_pxa_driver = {
module_platform_driver(serial_pxa_driver);
#ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init early_serial_pxa_setup(struct earlycon_device *device,
const char *options)
{
struct uart_port *port = &device->port;
if (!(device->port.membase || device->port.iobase))
return -ENODEV;
port->regshift = 2;
return early_serial8250_setup(device, NULL);
}
OF_EARLYCON_DECLARE(early_pxa, "mrvl,pxa-uart", early_serial_pxa_setup);
OF_EARLYCON_DECLARE(mmp, "mrvl,mmp-uart", early_serial_pxa_setup);
#endif
MODULE_AUTHOR("Sergei Ianovich");
MODULE_DESCRIPTION("driver for PXA on-board UARTS");
MODULE_LICENSE("GPL");
......
......@@ -124,13 +124,14 @@ struct qcom_geni_serial_port {
dma_addr_t tx_dma_addr;
dma_addr_t rx_dma_addr;
bool setup;
unsigned int baud;
unsigned long poll_timeout_us;
unsigned long clk_rate;
void *rx_buf;
u32 loopback;
bool brk;
unsigned int tx_remaining;
unsigned int tx_queued;
int wakeup_irq;
bool rx_tx_swap;
bool cts_rts_swap;
......@@ -144,6 +145,9 @@ static const struct uart_ops qcom_geni_uart_pops;
static struct uart_driver qcom_geni_console_driver;
static struct uart_driver qcom_geni_uart_driver;
static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport)
{
return container_of(uport, struct qcom_geni_serial_port, uport);
......@@ -265,27 +269,18 @@ static bool qcom_geni_serial_secondary_active(struct uart_port *uport)
return readl(uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE;
}
static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
int offset, int field, bool set)
static bool qcom_geni_serial_poll_bitfield(struct uart_port *uport,
unsigned int offset, u32 field, u32 val)
{
u32 reg;
struct qcom_geni_serial_port *port;
unsigned int baud;
unsigned int fifo_bits;
unsigned long timeout_us = 20000;
struct qcom_geni_private_data *private_data = uport->private_data;
if (private_data->drv) {
port = to_dev_port(uport);
baud = port->baud;
if (!baud)
baud = 115200;
fifo_bits = port->tx_fifo_depth * port->tx_fifo_width;
/*
* Total polling iterations based on FIFO worth of bytes to be
* sent at current baud. Add a little fluff to the wait.
*/
timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500;
if (port->poll_timeout_us)
timeout_us = port->poll_timeout_us;
}
/*
......@@ -295,7 +290,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
while (timeout_us) {
reg = readl(uport->membase + offset);
if ((bool)(reg & field) == set)
if ((reg & field) == val)
return true;
udelay(10);
timeout_us -= 10;
......@@ -303,6 +298,12 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
return false;
}
static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
unsigned int offset, u32 field, bool set)
{
return qcom_geni_serial_poll_bitfield(uport, offset, field, set ? field : 0);
}
static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
{
u32 m_cmd;
......@@ -315,18 +316,16 @@ static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
static void qcom_geni_serial_poll_tx_done(struct uart_port *uport)
{
int done;
u32 irq_clear = M_CMD_DONE_EN;
done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_CMD_DONE_EN, true);
if (!done) {
writel(M_GENI_CMD_ABORT, uport->membase +
SE_GENI_M_CMD_CTRL_REG);
irq_clear |= M_CMD_ABORT_EN;
qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_CMD_ABORT_EN, true);
writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
static void qcom_geni_serial_abort_rx(struct uart_port *uport)
......@@ -386,17 +385,27 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
unsigned char c)
{
writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
if (qcom_geni_serial_main_active(uport)) {
qcom_geni_serial_poll_tx_done(uport);
__qcom_geni_serial_cancel_tx_cmd(uport);
}
writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_setup_tx(uport, 1);
WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_TX_FIFO_WATERMARK_EN, true));
writel(c, uport->membase + SE_GENI_TX_FIFOn);
writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_poll_tx_done(uport);
}
#endif
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
static void qcom_geni_serial_drain_fifo(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
qcom_geni_serial_poll_bitfield(uport, SE_GENI_M_GP_LENGTH, GP_LENGTH,
port->tx_queued);
}
static void qcom_geni_serial_wr_char(struct uart_port *uport, unsigned char ch)
{
struct qcom_geni_private_data *private_data = uport->private_data;
......@@ -431,6 +440,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
}
writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_setup_tx(uport, bytes_to_send);
for (i = 0; i < count; ) {
size_t chars_to_write = 0;
......@@ -469,10 +479,9 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
{
struct uart_port *uport;
struct qcom_geni_serial_port *port;
u32 m_irq_en, s_irq_en;
bool locked = true;
unsigned long flags;
u32 geni_status;
u32 irq_en;
WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
......@@ -486,40 +495,28 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
else
uart_port_lock_irqsave(uport, &flags);
geni_status = readl(uport->membase + SE_GENI_STATUS);
if (!locked) {
/*
* We can only get here if an oops is in progress then we were
* unable to get the lock. This means we can't safely access
* our state variables like tx_remaining. About the best we
* can do is wait for the FIFO to be empty before we start our
* transfer, so we'll do that.
*/
qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_TX_FIFO_NOT_EMPTY_EN, false);
} else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) {
/*
* It seems we can't interrupt existing transfers if all data
* has been sent, in which case we need to look for done first.
*/
qcom_geni_serial_poll_tx_done(uport);
if (!kfifo_is_empty(&uport->state->port.xmit_fifo)) {
irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
writel(irq_en | M_TX_FIFO_WATERMARK_EN,
uport->membase + SE_GENI_M_IRQ_EN);
}
m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
s_irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
writel(0, uport->membase + SE_GENI_M_IRQ_EN);
writel(0, uport->membase + SE_GENI_S_IRQ_EN);
if (qcom_geni_serial_main_active(uport)) {
/* Wait for completion or drain FIFO */
if (!locked || port->tx_remaining == 0)
qcom_geni_serial_poll_tx_done(uport);
else
qcom_geni_serial_drain_fifo(uport);
qcom_geni_serial_cancel_tx_cmd(uport);
}
__qcom_geni_serial_console_write(uport, s, count);
writel(m_irq_en, uport->membase + SE_GENI_M_IRQ_EN);
writel(s_irq_en, uport->membase + SE_GENI_S_IRQ_EN);
if (locked) {
if (port->tx_remaining)
qcom_geni_serial_setup_tx(uport, port->tx_remaining);
if (locked)
uart_port_unlock_irqrestore(uport, flags);
}
}
static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
......@@ -682,13 +679,10 @@ static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport)
writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
}
static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
if (!qcom_geni_serial_main_active(uport))
return;
geni_se_cancel_m_cmd(&port->se);
if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_CMD_CANCEL_EN, true)) {
......@@ -698,8 +692,19 @@ static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
if (!qcom_geni_serial_main_active(uport))
return;
__qcom_geni_serial_cancel_tx_cmd(uport);
port->tx_remaining = 0;
port->tx_queued = 0;
}
static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool drop)
......@@ -923,9 +928,10 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
if (!chunk)
goto out_write_wakeup;
if (!port->tx_remaining) {
if (!active) {
qcom_geni_serial_setup_tx(uport, pending);
port->tx_remaining = pending;
port->tx_queued = 0;
irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
......@@ -934,6 +940,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
}
qcom_geni_serial_send_chunk_fifo(uport, chunk);
port->tx_queued += chunk;
/*
* The tx fifo watermark is level triggered and latched. Though we had
......@@ -1244,11 +1251,11 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
unsigned long clk_rate;
u32 ver, sampling_rate;
unsigned int avg_bw_core;
unsigned long timeout;
qcom_geni_serial_stop_rx(uport);
/* baud rate */
baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
port->baud = baud;
sampling_rate = UART_OVERSAMPLING;
/* Sampling rate is halved for IP versions >= 2.5 */
......@@ -1326,9 +1333,21 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
else
tx_trans_cfg |= UART_CTS_MASK;
if (baud)
if (baud) {
uart_update_timeout(uport, termios->c_cflag, baud);
/*
* Make sure that qcom_geni_serial_poll_bitfield() waits for
* the FIFO, two-word intermediate transfer register and shift
* register to clear.
*
* Note that uart_fifo_timeout() also adds a 20 ms margin.
*/
timeout = jiffies_to_usecs(uart_fifo_timeout(uport));
timeout += 3 * timeout / port->tx_fifo_depth;
WRITE_ONCE(port->poll_timeout_us, timeout);
}
if (!uart_console(uport))
writel(port->loopback,
uport->membase + SE_UART_LOOPBACK_CFG);
......
......@@ -577,8 +577,8 @@ static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id)
u32 clk_cfg;
writew(1, base + RP2_GLOBAL_CMD);
readw(base + RP2_GLOBAL_CMD);
msleep(100);
readw(base + RP2_GLOBAL_CMD);
writel(0, base + RP2_CLK_PRESCALER);
/* TDM clock configuration */
......
......@@ -550,6 +550,7 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
case TYPE_APPLE_S5L:
s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTO_LEGACY_ENA, S3C2410_UCON);
break;
default:
disable_irq_nosync(ourport->rx_irq);
......@@ -707,9 +708,8 @@ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport);
static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
static irqreturn_t s3c24xx_serial_rx_chars_dma(struct s3c24xx_uart_port *ourport)
{
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
struct s3c24xx_uart_dma *dma = ourport->dma;
struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
......@@ -843,9 +843,8 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
tty_flip_buffer_push(&port->state->port);
}
static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
static irqreturn_t s3c24xx_serial_rx_chars_pio(struct s3c24xx_uart_port *ourport)
{
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
uart_port_lock(port);
......@@ -855,13 +854,11 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
return IRQ_HANDLED;
}
static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
static irqreturn_t s3c24xx_serial_rx_irq(struct s3c24xx_uart_port *ourport)
{
struct s3c24xx_uart_port *ourport = dev_id;
if (ourport->dma && ourport->dma->rx_chan)
return s3c24xx_serial_rx_chars_dma(dev_id);
return s3c24xx_serial_rx_chars_pio(dev_id);
return s3c24xx_serial_rx_chars_dma(ourport);
return s3c24xx_serial_rx_chars_pio(ourport);
}
static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
......@@ -928,9 +925,8 @@ static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
s3c24xx_serial_stop_tx(port);
}
static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
static irqreturn_t s3c24xx_serial_tx_irq(struct s3c24xx_uart_port *ourport)
{
struct s3c24xx_uart_port *ourport = id;
struct uart_port *port = &ourport->port;
uart_port_lock(port);
......@@ -944,17 +940,17 @@ static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
/* interrupt handler for s3c64xx and later SoC's.*/
static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
{
const struct s3c24xx_uart_port *ourport = id;
struct s3c24xx_uart_port *ourport = id;
const struct uart_port *port = &ourport->port;
u32 pend = rd_regl(port, S3C64XX_UINTP);
irqreturn_t ret = IRQ_HANDLED;
if (pend & S3C64XX_UINTM_RXD_MSK) {
ret = s3c24xx_serial_rx_irq(irq, id);
ret = s3c24xx_serial_rx_irq(ourport);
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
}
if (pend & S3C64XX_UINTM_TXD_MSK) {
ret = s3c24xx_serial_tx_irq(irq, id);
ret = s3c24xx_serial_tx_irq(ourport);
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
}
return ret;
......@@ -963,19 +959,21 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
/* interrupt handler for Apple SoC's.*/
static irqreturn_t apple_serial_handle_irq(int irq, void *id)
{
const struct s3c24xx_uart_port *ourport = id;
struct s3c24xx_uart_port *ourport = id;
const struct uart_port *port = &ourport->port;
u32 pend = rd_regl(port, S3C2410_UTRSTAT);
irqreturn_t ret = IRQ_NONE;
if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO |
APPLE_S5L_UTRSTAT_RXTO_LEGACY)) {
wr_regl(port, S3C2410_UTRSTAT,
APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO);
ret = s3c24xx_serial_rx_irq(irq, id);
APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO |
APPLE_S5L_UTRSTAT_RXTO_LEGACY);
ret = s3c24xx_serial_rx_irq(ourport);
}
if (pend & APPLE_S5L_UTRSTAT_TXTHRESH) {
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_TXTHRESH);
ret = s3c24xx_serial_tx_irq(irq, id);
ret = s3c24xx_serial_tx_irq(ourport);
}
return ret;
......@@ -1195,7 +1193,8 @@ static void apple_s5l_serial_shutdown(struct uart_port *port)
ucon = rd_regl(port, S3C2410_UCON);
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
APPLE_S5L_UCON_RXTO_ENA_MSK);
APPLE_S5L_UCON_RXTO_ENA_MSK |
APPLE_S5L_UCON_RXTO_LEGACY_ENA_MSK);
wr_regl(port, S3C2410_UCON, ucon);
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
......@@ -1292,6 +1291,7 @@ static int apple_s5l_serial_startup(struct uart_port *port)
/* Enable Rx Interrupt */
s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTO_LEGACY_ENA, S3C2410_UCON);
return ret;
}
......@@ -2148,13 +2148,15 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
APPLE_S5L_UCON_RXTO_ENA_MSK);
APPLE_S5L_UCON_RXTO_ENA_MSK |
APPLE_S5L_UCON_RXTO_LEGACY_ENA_MSK);
if (ourport->tx_enabled)
ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
if (ourport->rx_enabled)
ucon |= APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
APPLE_S5L_UCON_RXTO_ENA_MSK;
APPLE_S5L_UCON_RXTO_ENA_MSK |
APPLE_S5L_UCON_RXTO_LEGACY_ENA_MSK;
wr_regl(port, S3C2410_UCON, ucon);
......@@ -2541,7 +2543,7 @@ static const struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
.name = "Apple S5L UART",
.type = TYPE_APPLE_S5L,
.port_type = PORT_8250,
.iotype = UPIO_MEM,
.iotype = UPIO_MEM32,
.fifosize = 16,
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
......@@ -2827,6 +2829,9 @@ OF_EARLYCON_DECLARE(gs101, "google,gs101-uart", gs101_early_console_setup);
static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
const char *opt)
{
/* Apple A7-A11 requires MMIO32 register accesses. */
device->port.iotype = UPIO_MEM32;
/* Close enough to S3C2410 for earlycon... */
device->port.private_data = &s3c2410_early_console_data;
......
This diff is collapsed.
......@@ -407,14 +407,16 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
/*
* Turn off DTR and RTS early.
*/
if (uport && uart_console(uport) && tty) {
uport->cons->cflag = tty->termios.c_cflag;
uport->cons->ispeed = tty->termios.c_ispeed;
uport->cons->ospeed = tty->termios.c_ospeed;
}
if (uport) {
if (uart_console(uport) && tty) {
uport->cons->cflag = tty->termios.c_cflag;
uport->cons->ispeed = tty->termios.c_ispeed;
uport->cons->ospeed = tty->termios.c_ospeed;
}
if (!tty || C_HUPCL(tty))
uart_port_dtr_rts(uport, false);
if (!tty || C_HUPCL(tty))
uart_port_dtr_rts(uport, false);
}
uart_port_shutdown(port);
}
......@@ -1102,21 +1104,19 @@ static int uart_tiocmget(struct tty_struct *tty)
struct uart_state *state = tty->driver_data;
struct tty_port *port = &state->port;
struct uart_port *uport;
int result = -EIO;
int result;
guard(mutex)(&port->mutex);
mutex_lock(&port->mutex);
uport = uart_port_check(state);
if (!uport)
goto out;
if (!uport || tty_io_error(tty))
return -EIO;
uart_port_lock_irq(uport);
result = uport->mctrl;
result |= uport->ops->get_mctrl(uport);
uart_port_unlock_irq(uport);
if (!tty_io_error(tty)) {
uart_port_lock_irq(uport);
result = uport->mctrl;
result |= uport->ops->get_mctrl(uport);
uart_port_unlock_irq(uport);
}
out:
mutex_unlock(&port->mutex);
return result;
}
......@@ -1126,20 +1126,16 @@ uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
struct uart_state *state = tty->driver_data;
struct tty_port *port = &state->port;
struct uart_port *uport;
int ret = -EIO;
mutex_lock(&port->mutex);
guard(mutex)(&port->mutex);
uport = uart_port_check(state);
if (!uport)
goto out;
if (!uport || tty_io_error(tty))
return -EIO;
if (!tty_io_error(tty)) {
uart_update_mctrl(uport, set, clear);
ret = 0;
}
out:
mutex_unlock(&port->mutex);
return ret;
uart_update_mctrl(uport, set, clear);
return 0;
}
static int uart_break_ctl(struct tty_struct *tty, int break_state)
......@@ -1147,19 +1143,17 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
struct uart_state *state = tty->driver_data;
struct tty_port *port = &state->port;
struct uart_port *uport;
int ret = -EIO;
mutex_lock(&port->mutex);
guard(mutex)(&port->mutex);
uport = uart_port_check(state);
if (!uport)
goto out;
return -EIO;
if (uport->type != PORT_UNKNOWN && uport->ops->break_ctl)
uport->ops->break_ctl(uport, break_state);
ret = 0;
out:
mutex_unlock(&port->mutex);
return ret;
return 0;
}
static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
......@@ -1176,17 +1170,14 @@ static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
* changing, and hence any extra opens of the port while
* we're auto-configuring.
*/
if (mutex_lock_interruptible(&port->mutex))
return -ERESTARTSYS;
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &port->mutex) {
uport = uart_port_check(state);
if (!uport)
return -EIO;
uport = uart_port_check(state);
if (!uport) {
ret = -EIO;
goto out;
}
if (tty_port_users(port) != 1)
return -EBUSY;
ret = -EBUSY;
if (tty_port_users(port) == 1) {
uart_shutdown(tty, state);
/*
......@@ -1207,14 +1198,15 @@ static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
uport->ops->config_port(uport, flags);
ret = uart_startup(tty, state, true);
if (ret == 0)
tty_port_set_initialized(port, true);
if (ret < 0)
return ret;
if (ret > 0)
ret = 0;
return 0;
tty_port_set_initialized(port, true);
}
out:
mutex_unlock(&port->mutex);
return ret;
return 0;
}
static void uart_enable_ms(struct uart_port *uport)
......@@ -1709,10 +1701,11 @@ static void uart_set_termios(struct tty_struct *tty,
unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK;
bool sw_changed = false;
mutex_lock(&state->port.mutex);
guard(mutex)(&state->port.mutex);
uport = uart_port_check(state);
if (!uport)
goto out;
return;
/*
* Drivers doing software flow control also need to know
......@@ -1735,9 +1728,8 @@ static void uart_set_termios(struct tty_struct *tty,
tty->termios.c_ospeed == old_termios->c_ospeed &&
tty->termios.c_ispeed == old_termios->c_ispeed &&
((tty->termios.c_iflag ^ old_termios->c_iflag) & iflag_mask) == 0 &&
!sw_changed) {
goto out;
}
!sw_changed)
return;
uart_change_line_settings(tty, state, old_termios);
/* reload cflag from termios; port driver may have overridden flags */
......@@ -1754,8 +1746,6 @@ static void uart_set_termios(struct tty_struct *tty,
mask |= TIOCM_RTS;
uart_set_mctrl(uport, mask);
}
out:
mutex_unlock(&state->port.mutex);
}
/*
......@@ -2049,10 +2039,11 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
unsigned int status;
int mmio;
mutex_lock(&port->mutex);
guard(mutex)(&port->mutex);
uport = uart_port_check(state);
if (!uport)
goto out;
return;
mmio = uport->iotype >= UPIO_MEM;
seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
......@@ -2064,7 +2055,7 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
if (uport->type == PORT_UNKNOWN) {
seq_putc(m, '\n');
goto out;
return;
}
if (capable(CAP_SYS_ADMIN)) {
......@@ -2115,8 +2106,6 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
seq_putc(m, '\n');
#undef STATBIT
#undef INFOBIT
out:
mutex_unlock(&port->mutex);
}
static int uart_proc_show(struct seq_file *m, void *v)
......@@ -2393,13 +2382,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
struct device *tty_dev;
struct uart_match match = {uport, drv};
mutex_lock(&port->mutex);
guard(mutex)(&port->mutex);
tty_dev = device_find_child(&uport->port_dev->dev, &match, serial_match_port);
if (tty_dev && device_may_wakeup(tty_dev)) {
enable_irq_wake(uport->irq);
put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
}
put_device(tty_dev);
......@@ -2417,7 +2405,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
uart_port_unlock_irq(uport);
}
device_set_awake_path(uport->dev);
goto unlock;
return 0;
}
uport->suspended = 1;
......@@ -2460,8 +2448,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
console_stop(uport->cons);
uart_change_pm(state, UART_PM_STATE_OFF);
unlock:
mutex_unlock(&port->mutex);
return 0;
}
......@@ -2475,14 +2461,13 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
struct uart_match match = {uport, drv};
struct ktermios termios;
mutex_lock(&port->mutex);
guard(mutex)(&port->mutex);
tty_dev = device_find_child(&uport->port_dev->dev, &match, serial_match_port);
if (!uport->suspended && device_may_wakeup(tty_dev)) {
if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq))))
disable_irq_wake(uport->irq);
put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
}
put_device(tty_dev);
......@@ -2555,8 +2540,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
tty_port_set_suspended(port, false);
}
mutex_unlock(&port->mutex);
return 0;
}
EXPORT_SYMBOL(uart_resume_port);
......@@ -2696,14 +2679,13 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
int ret = 0;
tport = &state->port;
mutex_lock(&tport->mutex);
guard(mutex)(&tport->mutex);
port = uart_port_check(state);
if (!port || port->type == PORT_UNKNOWN ||
!(port->ops->poll_get_char && port->ops->poll_put_char)) {
ret = -1;
goto out;
}
!(port->ops->poll_get_char && port->ops->poll_put_char))
return -1;
pm_state = state->pm_state;
uart_change_pm(state, UART_PM_STATE_ON);
......@@ -2723,10 +2705,10 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
ret = uart_set_options(port, NULL, baud, parity, bits, flow);
console_list_unlock();
}
out:
if (ret)
uart_change_pm(state, pm_state);
mutex_unlock(&tport->mutex);
return ret;
}
......
......@@ -808,7 +808,6 @@ static void asc_serial_remove(struct platform_device *pdev)
uart_remove_one_port(&asc_uart_driver, port);
}
#ifdef CONFIG_PM_SLEEP
static int asc_serial_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
......@@ -823,8 +822,6 @@ static int asc_serial_resume(struct device *dev)
return uart_resume_port(&asc_uart_driver, port);
}
#endif /* CONFIG_PM_SLEEP */
/*----------------------------------------------------------------------*/
#ifdef CONFIG_SERIAL_ST_ASC_CONSOLE
......@@ -932,16 +929,15 @@ static struct uart_driver asc_uart_driver = {
.cons = ASC_SERIAL_CONSOLE,
};
static const struct dev_pm_ops asc_serial_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(asc_serial_suspend, asc_serial_resume)
};
static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend,
asc_serial_resume);
static struct platform_driver asc_serial_driver = {
.probe = asc_serial_probe,
.remove_new = asc_serial_remove,
.driver = {
.name = DRIVER_NAME,
.pm = &asc_serial_pm_ops,
.pm = pm_sleep_ptr(&asc_serial_pm_ops),
.of_match_table = of_match_ptr(asc_match),
},
};
......
......@@ -219,7 +219,7 @@ struct cdns_platform_data {
u32 quirks;
};
struct serial_rs485 cdns_rs485_supported = {
static struct serial_rs485 cdns_rs485_supported = {
.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
SER_RS485_RTS_AFTER_SEND,
.delay_rts_before_send = 1,
......
......@@ -350,22 +350,19 @@ int tty_dev_name_to_number(const char *name, dev_t *number)
return ret;
prefix_length = str - name;
mutex_lock(&tty_mutex);
guard(mutex)(&tty_mutex);
list_for_each_entry(p, &tty_drivers, tty_drivers)
if (prefix_length == strlen(p->name) && strncmp(name,
p->name, prefix_length) == 0) {
if (index < p->num) {
*number = MKDEV(p->major, p->minor_start + index);
goto out;
return 0;
}
}
/* if here then driver wasn't found */
ret = -ENODEV;
out:
mutex_unlock(&tty_mutex);
return ret;
return -ENODEV;
}
EXPORT_SYMBOL_GPL(tty_dev_name_to_number);
......
......@@ -110,7 +110,6 @@ struct dbc_port {
struct tasklet_struct push;
struct list_head write_pool;
struct kfifo write_fifo;
bool registered;
};
......
......@@ -24,19 +24,6 @@ static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc)
return dbc->priv;
}
static unsigned int
dbc_send_packet(struct dbc_port *port, char *packet, unsigned int size)
{
unsigned int len;
len = kfifo_len(&port->write_fifo);
if (len < size)
size = len;
if (size != 0)
size = kfifo_out(&port->write_fifo, packet, size);
return size;
}
static int dbc_start_tx(struct dbc_port *port)
__releases(&port->port_lock)
__acquires(&port->port_lock)
......@@ -49,7 +36,7 @@ static int dbc_start_tx(struct dbc_port *port)
while (!list_empty(pool)) {
req = list_entry(pool->next, struct dbc_request, list_pool);
len = dbc_send_packet(port, req->buf, DBC_MAX_PACKET);
len = kfifo_out(&port->port.xmit_fifo, req->buf, DBC_MAX_PACKET);
if (len == 0)
break;
do_tty_wake = true;
......@@ -216,7 +203,7 @@ static ssize_t dbc_tty_write(struct tty_struct *tty, const u8 *buf,
spin_lock_irqsave(&port->port_lock, flags);
if (count)
count = kfifo_in(&port->write_fifo, buf, count);
count = kfifo_in(&port->port.xmit_fifo, buf, count);
dbc_start_tx(port);
spin_unlock_irqrestore(&port->port_lock, flags);
......@@ -230,7 +217,7 @@ static int dbc_tty_put_char(struct tty_struct *tty, u8 ch)
int status;
spin_lock_irqsave(&port->port_lock, flags);
status = kfifo_put(&port->write_fifo, ch);
status = kfifo_put(&port->port.xmit_fifo, ch);
spin_unlock_irqrestore(&port->port_lock, flags);
return status;
......@@ -253,7 +240,7 @@ static unsigned int dbc_tty_write_room(struct tty_struct *tty)
unsigned int room;
spin_lock_irqsave(&port->port_lock, flags);
room = kfifo_avail(&port->write_fifo);
room = kfifo_avail(&port->port.xmit_fifo);
spin_unlock_irqrestore(&port->port_lock, flags);
return room;
......@@ -266,7 +253,7 @@ static unsigned int dbc_tty_chars_in_buffer(struct tty_struct *tty)
unsigned int chars;
spin_lock_irqsave(&port->port_lock, flags);
chars = kfifo_len(&port->write_fifo);
chars = kfifo_len(&port->port.xmit_fifo);
spin_unlock_irqrestore(&port->port_lock, flags);
return chars;
......@@ -424,7 +411,8 @@ static int xhci_dbc_tty_register_device(struct xhci_dbc *dbc)
goto err_idr;
}
ret = kfifo_alloc(&port->write_fifo, DBC_WRITE_BUF_SIZE, GFP_KERNEL);
ret = kfifo_alloc(&port->port.xmit_fifo, DBC_WRITE_BUF_SIZE,
GFP_KERNEL);
if (ret)
goto err_exit_port;
......@@ -453,7 +441,7 @@ static int xhci_dbc_tty_register_device(struct xhci_dbc *dbc)
xhci_dbc_free_requests(&port->read_pool);
xhci_dbc_free_requests(&port->write_pool);
err_free_fifo:
kfifo_free(&port->write_fifo);
kfifo_free(&port->port.xmit_fifo);
err_exit_port:
idr_remove(&dbc_tty_minors, port->minor);
err_idr:
......@@ -478,7 +466,7 @@ static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc)
idr_remove(&dbc_tty_minors, port->minor);
mutex_unlock(&dbc_tty_minors_lock);
kfifo_free(&port->write_fifo);
kfifo_free(&port->port.xmit_fifo);
xhci_dbc_free_requests(&port->read_pool);
xhci_dbc_free_requests(&port->read_queue);
xhci_dbc_free_requests(&port->write_pool);
......
......@@ -193,7 +193,7 @@ void serial8250_do_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate);
void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
unsigned int quot, unsigned int quot_frac);
unsigned int quot);
int fsl8250_handle_irq(struct uart_port *port);
int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr);
......
......@@ -246,24 +246,28 @@
S5PV210_UFCON_TXTRIG4 | \
S5PV210_UFCON_RXTRIG4)
#define APPLE_S5L_UCON_RXTO_ENA 9
#define APPLE_S5L_UCON_RXTHRESH_ENA 12
#define APPLE_S5L_UCON_TXTHRESH_ENA 13
#define APPLE_S5L_UCON_RXTO_ENA_MSK (1 << APPLE_S5L_UCON_RXTO_ENA)
#define APPLE_S5L_UCON_RXTHRESH_ENA_MSK (1 << APPLE_S5L_UCON_RXTHRESH_ENA)
#define APPLE_S5L_UCON_TXTHRESH_ENA_MSK (1 << APPLE_S5L_UCON_TXTHRESH_ENA)
#define APPLE_S5L_UCON_RXTO_ENA 9
#define APPLE_S5L_UCON_RXTO_LEGACY_ENA 11
#define APPLE_S5L_UCON_RXTHRESH_ENA 12
#define APPLE_S5L_UCON_TXTHRESH_ENA 13
#define APPLE_S5L_UCON_RXTO_ENA_MSK BIT(APPLE_S5L_UCON_RXTO_ENA)
#define APPLE_S5L_UCON_RXTO_LEGACY_ENA_MSK BIT(APPLE_S5L_UCON_RXTO_LEGACY_ENA)
#define APPLE_S5L_UCON_RXTHRESH_ENA_MSK BIT(APPLE_S5L_UCON_RXTHRESH_ENA)
#define APPLE_S5L_UCON_TXTHRESH_ENA_MSK BIT(APPLE_S5L_UCON_TXTHRESH_ENA)
#define APPLE_S5L_UCON_DEFAULT (S3C2410_UCON_TXIRQMODE | \
S3C2410_UCON_RXIRQMODE | \
S3C2410_UCON_RXFIFO_TOI)
#define APPLE_S5L_UCON_MASK (APPLE_S5L_UCON_RXTO_ENA_MSK | \
APPLE_S5L_UCON_RXTO_LEGACY_ENA_MSK | \
APPLE_S5L_UCON_RXTHRESH_ENA_MSK | \
APPLE_S5L_UCON_TXTHRESH_ENA_MSK)
#define APPLE_S5L_UTRSTAT_RXTHRESH (1<<4)
#define APPLE_S5L_UTRSTAT_TXTHRESH (1<<5)
#define APPLE_S5L_UTRSTAT_RXTO (1<<9)
#define APPLE_S5L_UTRSTAT_ALL_FLAGS (0x3f0)
#define APPLE_S5L_UTRSTAT_RXTO_LEGACY BIT(3)
#define APPLE_S5L_UTRSTAT_RXTHRESH BIT(4)
#define APPLE_S5L_UTRSTAT_TXTHRESH BIT(5)
#define APPLE_S5L_UTRSTAT_RXTO BIT(9)
#define APPLE_S5L_UTRSTAT_ALL_FLAGS GENMASK(9, 3)
#ifndef __ASSEMBLY__
......
......@@ -88,11 +88,15 @@ struct geni_se {
#define SE_GENI_M_IRQ_STATUS 0x610
#define SE_GENI_M_IRQ_EN 0x614
#define SE_GENI_M_IRQ_CLEAR 0x618
#define SE_GENI_M_IRQ_EN_SET 0x61c
#define SE_GENI_M_IRQ_EN_CLEAR 0x620
#define SE_GENI_S_CMD0 0x630
#define SE_GENI_S_CMD_CTRL_REG 0x634
#define SE_GENI_S_IRQ_STATUS 0x640
#define SE_GENI_S_IRQ_EN 0x644
#define SE_GENI_S_IRQ_CLEAR 0x648
#define SE_GENI_S_IRQ_EN_SET 0x64c
#define SE_GENI_S_IRQ_EN_CLEAR 0x650
#define SE_GENI_TX_FIFOn 0x700
#define SE_GENI_RX_FIFOn 0x780
#define SE_GENI_TX_FIFO_STATUS 0x800
......@@ -101,6 +105,8 @@ struct geni_se {
#define SE_GENI_RX_WATERMARK_REG 0x810
#define SE_GENI_RX_RFR_WATERMARK_REG 0x814
#define SE_GENI_IOS 0x908
#define SE_GENI_M_GP_LENGTH 0x910
#define SE_GENI_S_GP_LENGTH 0x914
#define SE_DMA_TX_IRQ_STAT 0xc40
#define SE_DMA_TX_IRQ_CLR 0xc44
#define SE_DMA_TX_FSM_RST 0xc58
......@@ -234,6 +240,9 @@ struct geni_se {
#define IO2_DATA_IN BIT(1)
#define RX_DATA_IN BIT(0)
/* SE_GENI_M_GP_LENGTH and SE_GENI_S_GP_LENGTH fields */
#define GP_LENGTH GENMASK(31, 0)
/* SE_DMA_TX_IRQ_STAT Register fields */
#define TX_DMA_DONE BIT(0)
#define TX_EOT BIT(1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment