forked from Minki/linux
TTY/Serial patches for 5.11-rc1
Here is the "large" set of tty and serial patches for 5.11-rc1. Nothing major at all, some cleanups and some driver removals, always a nice sign: - build warning cleanups - vt locking and logic unwinding and cleanups - tiny serial driver fixes and updates - removal of the synclink serial driver as it's no longer needed - removal of dead termiox code All of this has been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCX9iGrw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yk6ZwCgurjtlXOdtrjM6kcvYfKZcILS7jQAoK1B1rH9 O6fVeZl8qRDWL4p06y2s =0Uho -----END PGP SIGNATURE----- Merge tag 'tty-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty / serial updates from Greg KH: "Here is the "large" set of tty and serial patches for 5.11-rc1. Nothing major at all, some cleanups and some driver removals, always a nice sign: - build warning cleanups - vt locking and logic unwinding and cleanups - tiny serial driver fixes and updates - removal of the synclink serial driver as it's no longer needed - removal of dead termiox code All of this has been in linux-next for a while with no reported issues" * tag 'tty-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (89 commits) serial: 8250_pci: Drop bogus __refdata annotation tty: serial: meson: enable console as module serial: 8250_omap: Avoid FIFO corruption caused by MDR1 access serial: imx: Move imx_uart_probe_dt() content into probe() serial: imx: Remove unneeded of_device_get_match_data() NULL check tty: Fix whitespace inconsistencies in vt_io_ioctl serial_core: Check for port state when tty is in error state dt-bindings: serial: Update DT binding docs to support SiFive FU740 SoC tty: use const parameters in port-flag accessors tty: use assign_bit() in port-flag accessors earlycon: drop semicolon from earlycon macro tty: Remove dead termiox code tty/serial/imx: Enable TXEN bit in imx_poll_init(). tty : serial: jsm: Fixed file by adding spacing tty: serial: uartlite: Support probe deferral earlycon: simplify earlycon-table implementation tty: serial: bcm63xx: lower driver dependencies serial: mxs-auart: Remove unneeded platform_device_id serial: 8250-mtk: Fix reference leak in mtk8250_probe serial: imx: Remove unused .id_table support ...
This commit is contained in:
commit
157f809894
@ -1,6 +1,7 @@
|
||||
OMAP UART controller
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "ti,am64-uart", "ti,am654-uart" for AM64 controllers
|
||||
- compatible : should be "ti,j721e-uart", "ti,am654-uart" for J721E controllers
|
||||
- compatible : should be "ti,am654-uart" for AM654 controllers
|
||||
- compatible : should be "ti,omap2-uart" for OMAP2 controllers
|
||||
|
@ -60,6 +60,7 @@ properties:
|
||||
- renesas,scif-r8a77980 # R-Car V3H
|
||||
- renesas,scif-r8a77990 # R-Car E3
|
||||
- renesas,scif-r8a77995 # R-Car D3
|
||||
- renesas,scif-r8a779a0 # R-Car V3U
|
||||
- const: renesas,rcar-gen3-scif # R-Car Gen3 and RZ/G2
|
||||
- const: renesas,scif # generic SCIF compatible UART
|
||||
|
||||
|
@ -17,7 +17,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: sifive,fu540-c000-uart
|
||||
- enum:
|
||||
- sifive,fu540-c000-uart
|
||||
- sifive,fu740-c000-uart
|
||||
- const: sifive,uart0
|
||||
|
||||
description:
|
||||
|
@ -598,8 +598,6 @@ CONFIG_GAMEPORT_FM801=m
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
CONFIG_ROCKETPORT=m
|
||||
CONFIG_CYCLADES=m
|
||||
CONFIG_SYNCLINK=m
|
||||
CONFIG_SYNCLINKMP=m
|
||||
CONFIG_SYNCLINK_GT=m
|
||||
CONFIG_NOZOMI=m
|
||||
CONFIG_N_HDLC=m
|
||||
|
@ -906,7 +906,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
|
||||
int offset;
|
||||
const char *p, *q, *options = NULL;
|
||||
int l;
|
||||
const struct earlycon_id **p_match;
|
||||
const struct earlycon_id *match;
|
||||
const void *fdt = initial_boot_params;
|
||||
|
||||
offset = fdt_path_offset(fdt, "/chosen");
|
||||
@ -933,10 +933,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p_match = __earlycon_table; p_match < __earlycon_table_end;
|
||||
p_match++) {
|
||||
const struct earlycon_id *match = *p_match;
|
||||
|
||||
for (match = __earlycon_table; match < __earlycon_table_end; match++) {
|
||||
if (!match->compatible[0])
|
||||
continue;
|
||||
|
||||
|
@ -259,33 +259,6 @@ config MOXA_SMARTIO
|
||||
This driver can also be built as a module. The module will be called
|
||||
mxser. If you want to do that, say M here.
|
||||
|
||||
config SYNCLINK
|
||||
tristate "Microgate SyncLink card support"
|
||||
depends on SERIAL_NONSTANDARD && PCI && ISA_DMA_API
|
||||
help
|
||||
Provides support for the SyncLink ISA and PCI multiprotocol serial
|
||||
adapters. These adapters support asynchronous and HDLC bit
|
||||
synchronous communication up to 10Mbps (PCI adapter).
|
||||
|
||||
This driver can only be built as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want).
|
||||
The module will be called synclink. If you want to do that, say M
|
||||
here.
|
||||
|
||||
config SYNCLINKMP
|
||||
tristate "SyncLink Multiport support"
|
||||
depends on SERIAL_NONSTANDARD && PCI
|
||||
help
|
||||
Enable support for the SyncLink Multiport (2 or 4 ports)
|
||||
serial adapter, running asynchronous and HDLC communications up
|
||||
to 2.048Mbps. Each ports is independently selectable for
|
||||
RS-232, V.35, RS-449, RS-530, and X.21
|
||||
|
||||
This driver may be built as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want).
|
||||
The module will be called synclinkmp. If you want to do that, say M
|
||||
here.
|
||||
|
||||
config SYNCLINK_GT
|
||||
tristate "SyncLink GT/AC support"
|
||||
depends on SERIAL_NONSTANDARD && PCI
|
||||
|
@ -28,8 +28,6 @@ obj-$(CONFIG_NOZOMI) += nozomi.o
|
||||
obj-$(CONFIG_NULL_TTY) += ttynull.o
|
||||
obj-$(CONFIG_ROCKETPORT) += rocket.o
|
||||
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
|
||||
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
|
||||
obj-$(CONFIG_SYNCLINK) += synclink.o
|
||||
obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
|
||||
obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o
|
||||
obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o
|
||||
|
@ -61,13 +61,13 @@ static void do_rw_io(struct goldfish_tty *qtty,
|
||||
spin_lock_irqsave(&qtty->lock, irq_flags);
|
||||
gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR,
|
||||
base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
|
||||
writel(count, base + GOLDFISH_TTY_REG_DATA_LEN);
|
||||
__raw_writel(count, base + GOLDFISH_TTY_REG_DATA_LEN);
|
||||
|
||||
if (is_write)
|
||||
writel(GOLDFISH_TTY_CMD_WRITE_BUFFER,
|
||||
__raw_writel(GOLDFISH_TTY_CMD_WRITE_BUFFER,
|
||||
base + GOLDFISH_TTY_REG_CMD);
|
||||
else
|
||||
writel(GOLDFISH_TTY_CMD_READ_BUFFER,
|
||||
__raw_writel(GOLDFISH_TTY_CMD_READ_BUFFER,
|
||||
base + GOLDFISH_TTY_REG_CMD);
|
||||
|
||||
spin_unlock_irqrestore(&qtty->lock, irq_flags);
|
||||
@ -142,7 +142,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id)
|
||||
unsigned char *buf;
|
||||
u32 count;
|
||||
|
||||
count = readl(base + GOLDFISH_TTY_REG_BYTES_READY);
|
||||
count = __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY);
|
||||
if (count == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
@ -159,7 +159,7 @@ static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty)
|
||||
{
|
||||
struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
|
||||
port);
|
||||
writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
|
||||
__raw_writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ static void goldfish_tty_shutdown(struct tty_port *port)
|
||||
{
|
||||
struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
|
||||
port);
|
||||
writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
|
||||
__raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
|
||||
}
|
||||
|
||||
static int goldfish_tty_open(struct tty_struct *tty, struct file *filp)
|
||||
@ -202,7 +202,7 @@ static int goldfish_tty_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
|
||||
void __iomem *base = qtty->base;
|
||||
return readl(base + GOLDFISH_TTY_REG_BYTES_READY);
|
||||
return __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY);
|
||||
}
|
||||
|
||||
static void goldfish_tty_console_write(struct console *co, const char *b,
|
||||
@ -357,7 +357,7 @@ static int goldfish_tty_probe(struct platform_device *pdev)
|
||||
* on Ranchu emulator (qemu2) returns 1 here and
|
||||
* driver will use physical addresses.
|
||||
*/
|
||||
qtty->version = readl(base + GOLDFISH_TTY_REG_VERSION);
|
||||
qtty->version = __raw_readl(base + GOLDFISH_TTY_REG_VERSION);
|
||||
|
||||
/*
|
||||
* Goldfish TTY device on Ranchu emulator (qemu2)
|
||||
@ -376,7 +376,7 @@ static int goldfish_tty_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
|
||||
__raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
|
||||
|
||||
ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED,
|
||||
"goldfish_tty", qtty);
|
||||
|
@ -103,7 +103,7 @@ static void hvc_opal_hvsi_close(struct hvc_struct *hp, int data)
|
||||
notifier_del_irq(hp, data);
|
||||
}
|
||||
|
||||
void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data)
|
||||
static void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data)
|
||||
{
|
||||
struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
|
||||
|
||||
|
@ -178,7 +178,7 @@ static void hvterm_hvsi_close(struct hvc_struct *hp, int data)
|
||||
notifier_del_irq(hp, data);
|
||||
}
|
||||
|
||||
void hvterm_hvsi_hangup(struct hvc_struct *hp, int data)
|
||||
static void hvterm_hvsi_hangup(struct hvc_struct *hp, int data)
|
||||
{
|
||||
struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
|
||||
|
||||
|
@ -74,7 +74,7 @@ module_param(debug, int, 0600);
|
||||
#define MAX_MTU 1500
|
||||
#define GSM_NET_TX_TIMEOUT (HZ*10)
|
||||
|
||||
/**
|
||||
/*
|
||||
* struct gsm_mux_net - network interface
|
||||
*
|
||||
* Created when net interface is initialized.
|
||||
@ -651,6 +651,7 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
|
||||
/**
|
||||
* gsm_data_kick - poke the queue
|
||||
* @gsm: GSM Mux
|
||||
* @dlci: DLCI sending the data
|
||||
*
|
||||
* The tty device has called us to indicate that room has appeared in
|
||||
* the transmit queue. Ram more data into the pipe if we have any
|
||||
@ -1005,6 +1006,7 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data,
|
||||
* @tty: virtual tty bound to the DLCI
|
||||
* @dlci: DLCI to affect
|
||||
* @modem: modem bits (full EA)
|
||||
* @clen: command length
|
||||
*
|
||||
* Used when a modem control message or line state inline in adaption
|
||||
* layer 2 is processed. Sort out the local modem state and throttles
|
||||
|
@ -396,6 +396,7 @@ static inline int is_utf8_continuation(unsigned char c)
|
||||
/**
|
||||
* is_continuation - multibyte check
|
||||
* @c: byte to check
|
||||
* @tty: terminal device
|
||||
*
|
||||
* Returns true if the utf8 character 'c' is a multibyte continuation
|
||||
* character and the terminal is in unicode mode.
|
||||
@ -1668,6 +1669,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
* @cp: input chars
|
||||
* @fp: flags for each char (if NULL, all chars are TTY_NORMAL)
|
||||
* @count: number of input chars in @cp
|
||||
* @flow: enable flow control
|
||||
*
|
||||
* Called by the terminal driver when a block of characters has
|
||||
* been received. This function must be called from soft contexts
|
||||
|
@ -414,11 +414,9 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
|
||||
buf16 = (u16 *) buf;
|
||||
*buf16 = __le16_to_cpu(readw(ptr));
|
||||
goto out;
|
||||
break;
|
||||
case 4: /* 4 bytes */
|
||||
*(buf) = __le32_to_cpu(readl(ptr));
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
while (i < size_bytes) {
|
||||
@ -460,15 +458,14 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
|
||||
buf16 = (const u16 *)buf;
|
||||
writew(__cpu_to_le16(*buf16), ptr);
|
||||
return 2;
|
||||
break;
|
||||
case 1: /*
|
||||
* also needs to write 4 bytes in this case
|
||||
* so falling through..
|
||||
*/
|
||||
fallthrough;
|
||||
case 4: /* 4 bytes */
|
||||
writel(__cpu_to_le32(*buf), ptr);
|
||||
return 4;
|
||||
break;
|
||||
}
|
||||
|
||||
while (i < size_bytes) {
|
||||
|
@ -699,6 +699,7 @@ static long pty_unix98_compat_ioctl(struct tty_struct *tty,
|
||||
/**
|
||||
* ptm_unix98_lookup - find a pty master
|
||||
* @driver: ptm driver
|
||||
* @file: unused
|
||||
* @idx: tty index
|
||||
*
|
||||
* Look up a pty master device. Called under the tty_mutex for now.
|
||||
@ -715,6 +716,7 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
|
||||
/**
|
||||
* pts_unix98_lookup - find a pty slave
|
||||
* @driver: pts driver
|
||||
* @file: file pointer to tty
|
||||
* @idx: tty index
|
||||
*
|
||||
* Look up a pty master device. Called under the tty_mutex for now.
|
||||
|
@ -788,13 +788,10 @@ static int serdev_remove_device(struct device *dev, void *data)
|
||||
*/
|
||||
void serdev_controller_remove(struct serdev_controller *ctrl)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
if (!ctrl)
|
||||
return;
|
||||
|
||||
dummy = device_for_each_child(&ctrl->dev, NULL,
|
||||
serdev_remove_device);
|
||||
device_for_each_child(&ctrl->dev, NULL, serdev_remove_device);
|
||||
pm_runtime_disable(&ctrl->dev);
|
||||
device_del(&ctrl->dev);
|
||||
}
|
||||
@ -803,6 +800,7 @@ EXPORT_SYMBOL_GPL(serdev_controller_remove);
|
||||
/**
|
||||
* serdev_driver_register() - Register client driver with serdev core
|
||||
* @sdrv: client driver to be associated with client-device.
|
||||
* @owner: client driver owner to set.
|
||||
*
|
||||
* This API will register the client driver with the serdev framework.
|
||||
* It is typically called from the driver's module-init function.
|
||||
|
@ -204,9 +204,6 @@ OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup);
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RT288X
|
||||
|
||||
unsigned int au_serial_in(struct uart_port *p, int offset);
|
||||
void au_serial_out(struct uart_port *p, int offset, int value);
|
||||
|
||||
static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
|
||||
{
|
||||
dev->port.serial_in = au_serial_in;
|
||||
|
@ -572,15 +572,22 @@ static int mtk8250_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
err = mtk8250_runtime_resume(&pdev->dev);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_pm_disable;
|
||||
|
||||
data->line = serial8250_register_8250_port(&uart);
|
||||
if (data->line < 0)
|
||||
return data->line;
|
||||
if (data->line < 0) {
|
||||
err = data->line;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk8250_remove(struct platform_device *pdev)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
@ -41,6 +42,7 @@
|
||||
*/
|
||||
#define UART_ERRATA_CLOCK_DISABLE (1 << 3)
|
||||
#define UART_HAS_EFR2 BIT(4)
|
||||
#define UART_HAS_RHR_IT_DIS BIT(5)
|
||||
|
||||
#define OMAP_UART_FCR_RX_TRIG 6
|
||||
#define OMAP_UART_FCR_TX_TRIG 4
|
||||
@ -94,6 +96,10 @@
|
||||
#define OMAP_UART_REV_52 0x0502
|
||||
#define OMAP_UART_REV_63 0x0603
|
||||
|
||||
/* Interrupt Enable Register 2 */
|
||||
#define UART_OMAP_IER2 0x1B
|
||||
#define UART_OMAP_IER2_RHR_IT_DIS BIT(2)
|
||||
|
||||
/* Enhanced features register 2 */
|
||||
#define UART_OMAP_EFR2 0x23
|
||||
#define UART_OMAP_EFR2_TIMEOUT_BEHAVE BIT(6)
|
||||
@ -184,11 +190,6 @@ static void omap_8250_mdr1_errataset(struct uart_8250_port *up,
|
||||
struct omap8250_priv *priv)
|
||||
{
|
||||
u8 timeout = 255;
|
||||
u8 old_mdr1;
|
||||
|
||||
old_mdr1 = serial_in(up, UART_OMAP_MDR1);
|
||||
if (old_mdr1 == priv->mdr1)
|
||||
return;
|
||||
|
||||
serial_out(up, UART_OMAP_MDR1, priv->mdr1);
|
||||
udelay(2);
|
||||
@ -533,6 +534,11 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state,
|
||||
static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
|
||||
struct omap8250_priv *priv)
|
||||
{
|
||||
const struct soc_device_attribute k3_soc_devices[] = {
|
||||
{ .family = "AM65X", },
|
||||
{ .family = "J721E", .revision = "SR1.0" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
u32 mvr, scheme;
|
||||
u16 revision, major, minor;
|
||||
|
||||
@ -580,6 +586,14 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* AM65x SR1.0, AM65x SR2.0 and J721e SR1.0 don't
|
||||
* don't have RHR_IT_DIS bit in IER2 register. So drop to flag
|
||||
* to enable errata workaround.
|
||||
*/
|
||||
if (soc_device_match(k3_soc_devices))
|
||||
priv->habit &= ~UART_HAS_RHR_IT_DIS;
|
||||
}
|
||||
|
||||
static void omap8250_uart_qos_work(struct work_struct *work)
|
||||
@ -761,17 +775,27 @@ static void __dma_rx_do_complete(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
struct tty_port *tty_port = &p->port.state->port;
|
||||
struct omap8250_priv *priv = p->port.private_data;
|
||||
struct dma_chan *rxchan = dma->rxchan;
|
||||
dma_cookie_t cookie;
|
||||
struct dma_tx_state state;
|
||||
int count;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
if (!dma->rx_running)
|
||||
goto out;
|
||||
|
||||
cookie = dma->rx_cookie;
|
||||
dma->rx_running = 0;
|
||||
|
||||
/* Re-enable RX FIFO interrupt now that transfer is complete */
|
||||
if (priv->habit & UART_HAS_RHR_IT_DIS) {
|
||||
reg = serial_in(p, UART_OMAP_IER2);
|
||||
reg &= ~UART_OMAP_IER2_RHR_IT_DIS;
|
||||
serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS);
|
||||
}
|
||||
|
||||
dmaengine_tx_status(rxchan, cookie, &state);
|
||||
|
||||
count = dma->rx_size - state.residue + state.in_flight_bytes;
|
||||
@ -867,6 +891,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p)
|
||||
int err = 0;
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
if (priv->rx_dma_broken)
|
||||
return -EINVAL;
|
||||
@ -902,6 +927,17 @@ static int omap_8250_rx_dma(struct uart_8250_port *p)
|
||||
|
||||
dma->rx_cookie = dmaengine_submit(desc);
|
||||
|
||||
/*
|
||||
* Disable RX FIFO interrupt while RX DMA is enabled, else
|
||||
* spurious interrupt may be raised when data is in the RX FIFO
|
||||
* but is yet to be drained by DMA.
|
||||
*/
|
||||
if (priv->habit & UART_HAS_RHR_IT_DIS) {
|
||||
reg = serial_in(p, UART_OMAP_IER2);
|
||||
reg |= UART_OMAP_IER2_RHR_IT_DIS;
|
||||
serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS);
|
||||
}
|
||||
|
||||
dma_async_issue_pending(dma->rxchan);
|
||||
out:
|
||||
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
|
||||
@ -1182,7 +1218,7 @@ static struct omap8250_dma_params am33xx_dma = {
|
||||
|
||||
static struct omap8250_platdata am654_platdata = {
|
||||
.dma_params = &am654_dma,
|
||||
.habit = UART_HAS_EFR2,
|
||||
.habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS,
|
||||
};
|
||||
|
||||
static struct omap8250_platdata am33xx_platdata = {
|
||||
|
@ -1964,7 +1964,7 @@ pci_moxa_setup(struct serial_private *priv,
|
||||
* This list is ordered alphabetically by vendor then device.
|
||||
* Specific entries must come before more generic entries.
|
||||
*/
|
||||
static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||
static struct pci_serial_quirk pci_serial_quirks[] = {
|
||||
/*
|
||||
* ADDI-DATA GmbH communication cards <info@addi-data.com>
|
||||
*/
|
||||
|
@ -559,16 +559,13 @@ static int multi_config(struct pcmcia_device *link)
|
||||
*/
|
||||
if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
|
||||
info->prodid == PRODID_POSSIO_GCC)) {
|
||||
int err;
|
||||
|
||||
if (link->config_index == 1 ||
|
||||
link->config_index == 3) {
|
||||
err = setup_serial(link, info, base2,
|
||||
link->irq);
|
||||
setup_serial(link, info, base2, link->irq);
|
||||
base2 = link->resource[0]->start;
|
||||
} else {
|
||||
err = setup_serial(link, info, link->resource[0]->start,
|
||||
link->irq);
|
||||
setup_serial(link, info, link->resource[0]->start,
|
||||
link->irq);
|
||||
}
|
||||
info->c950ctrl = base2;
|
||||
|
||||
|
@ -206,7 +206,7 @@ config SERIAL_MESON
|
||||
|
||||
config SERIAL_MESON_CONSOLE
|
||||
bool "Support for console on meson"
|
||||
depends on SERIAL_MESON=y
|
||||
depends on SERIAL_MESON
|
||||
select SERIAL_CORE_CONSOLE
|
||||
select SERIAL_EARLYCON
|
||||
help
|
||||
@ -704,22 +704,6 @@ config SERIAL_SH_SCI_DMA
|
||||
depends on SERIAL_SH_SCI && DMA_ENGINE
|
||||
default ARCH_RENESAS
|
||||
|
||||
config SERIAL_PNX8XXX
|
||||
bool "Enable PNX8XXX SoCs' UART Support"
|
||||
depends on SOC_PNX833X
|
||||
select SERIAL_CORE
|
||||
help
|
||||
If you have a MIPS-based Philips SoC such as PNX8330 and you want
|
||||
to use serial ports, say Y. Otherwise, say N.
|
||||
|
||||
config SERIAL_PNX8XXX_CONSOLE
|
||||
bool "Enable PNX8XX0 serial console"
|
||||
depends on SERIAL_PNX8XXX
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
If you have a MIPS-based Philips SoC such as PNX8330 and you want
|
||||
to use serial console, say Y. Otherwise, say N.
|
||||
|
||||
config SERIAL_HS_LPC32XX
|
||||
tristate "LPC32XX high speed serial port support"
|
||||
depends on ARCH_LPC32XX || COMPILE_TEST
|
||||
@ -1133,7 +1117,7 @@ config SERIAL_TIMBERDALE
|
||||
config SERIAL_BCM63XX
|
||||
tristate "Broadcom BCM63xx/BCM33xx UART support"
|
||||
select SERIAL_CORE
|
||||
depends on MIPS || ARM || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
help
|
||||
This enables the driver for the onchip UART core found on
|
||||
the following chipsets:
|
||||
|
@ -27,7 +27,6 @@ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
|
||||
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
|
||||
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
|
||||
obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o
|
||||
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
|
||||
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
|
||||
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
|
||||
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o
|
||||
|
@ -2789,7 +2789,7 @@ static const struct of_device_id sbsa_uart_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sbsa_uart_of_match);
|
||||
|
||||
static const struct acpi_device_id sbsa_uart_acpi_match[] = {
|
||||
static const struct acpi_device_id __maybe_unused sbsa_uart_acpi_match[] = {
|
||||
{ "ARMH0011", 0 },
|
||||
{},
|
||||
};
|
||||
|
@ -175,7 +175,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
|
||||
*/
|
||||
int __init setup_earlycon(char *buf)
|
||||
{
|
||||
const struct earlycon_id **p_match;
|
||||
const struct earlycon_id *match;
|
||||
bool empty_compatible = true;
|
||||
|
||||
if (!buf || !buf[0])
|
||||
@ -185,9 +185,7 @@ int __init setup_earlycon(char *buf)
|
||||
return -EALREADY;
|
||||
|
||||
again:
|
||||
for (p_match = __earlycon_table; p_match < __earlycon_table_end;
|
||||
p_match++) {
|
||||
const struct earlycon_id *match = *p_match;
|
||||
for (match = __earlycon_table; match < __earlycon_table_end; match++) {
|
||||
size_t len = strlen(match->name);
|
||||
|
||||
if (strncmp(buf, match->name, len))
|
||||
|
@ -252,23 +252,22 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id)
|
||||
flg = TTY_NORMAL;
|
||||
sport->icount.rx++;
|
||||
|
||||
if (status & (LINFLEXD_UARTSR_BOF | LINFLEXD_UARTSR_SZF |
|
||||
LINFLEXD_UARTSR_FEF | LINFLEXD_UARTSR_PE)) {
|
||||
if (status & LINFLEXD_UARTSR_SZF)
|
||||
status |= LINFLEXD_UARTSR_SZF;
|
||||
if (status & (LINFLEXD_UARTSR_BOF | LINFLEXD_UARTSR_FEF |
|
||||
LINFLEXD_UARTSR_PE)) {
|
||||
if (status & LINFLEXD_UARTSR_BOF)
|
||||
status |= LINFLEXD_UARTSR_BOF;
|
||||
sport->icount.overrun++;
|
||||
if (status & LINFLEXD_UARTSR_FEF) {
|
||||
if (!rx)
|
||||
if (!rx) {
|
||||
brk = true;
|
||||
status |= LINFLEXD_UARTSR_FEF;
|
||||
sport->icount.brk++;
|
||||
} else
|
||||
sport->icount.frame++;
|
||||
}
|
||||
if (status & LINFLEXD_UARTSR_PE)
|
||||
status |= LINFLEXD_UARTSR_PE;
|
||||
sport->icount.parity++;
|
||||
}
|
||||
|
||||
writel(status | LINFLEXD_UARTSR_RMB | LINFLEXD_UARTSR_DRFRFE,
|
||||
sport->membase + UARTSR);
|
||||
writel(status, sport->membase + UARTSR);
|
||||
status = readl(sport->membase + UARTSR);
|
||||
|
||||
if (brk) {
|
||||
|
@ -545,6 +545,7 @@ static void ifx_spi_hangup(struct tty_struct *tty)
|
||||
/**
|
||||
* ifx_port_activate
|
||||
* @port: our tty port
|
||||
* @tty: our tty device
|
||||
*
|
||||
* tty port activate method - called for first open. Serialized
|
||||
* with hangup and shutdown by the tty layer.
|
||||
@ -719,7 +720,7 @@ complete_exit:
|
||||
|
||||
/**
|
||||
* ifx_spio_io - I/O tasklet
|
||||
* @data: our SPI device
|
||||
* @t: tasklet construct used to fetch the SPI device
|
||||
*
|
||||
* Queue data for transmission if possible and then kick off the
|
||||
* transfer.
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/platform_data/serial-imx.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
|
||||
#include "serial_mctrl_gpio.h"
|
||||
@ -263,25 +262,6 @@ static struct imx_uart_data imx_uart_devdata[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct platform_device_id imx_uart_devtype[] = {
|
||||
{
|
||||
.name = "imx1-uart",
|
||||
.driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART],
|
||||
}, {
|
||||
.name = "imx21-uart",
|
||||
.driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX21_UART],
|
||||
}, {
|
||||
.name = "imx53-uart",
|
||||
.driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX53_UART],
|
||||
}, {
|
||||
.name = "imx6q-uart",
|
||||
.driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX6Q_UART],
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, imx_uart_devtype);
|
||||
|
||||
static const struct of_device_id imx_uart_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx6q-uart", .data = &imx_uart_devdata[IMX6Q_UART], },
|
||||
{ .compatible = "fsl,imx53-uart", .data = &imx_uart_devdata[IMX53_UART], },
|
||||
@ -1881,7 +1861,7 @@ static int imx_uart_poll_init(struct uart_port *port)
|
||||
ucr1 |= UCR1_UARTEN;
|
||||
ucr1 &= ~(UCR1_TRDYEN | UCR1_RTSDEN | UCR1_RRDYEN);
|
||||
|
||||
ucr2 |= UCR2_RXEN;
|
||||
ucr2 |= UCR2_RXEN | UCR2_TXEN;
|
||||
ucr2 &= ~UCR2_ATEN;
|
||||
|
||||
imx_uart_writel(sport, ucr1, UCR1);
|
||||
@ -2183,70 +2163,6 @@ static struct uart_driver imx_uart_uart_driver = {
|
||||
.cons = IMX_CONSOLE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/*
|
||||
* This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it
|
||||
* could successfully get all information from dt or a negative errno.
|
||||
*/
|
||||
static int imx_uart_probe_dt(struct imx_port *sport,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
int ret;
|
||||
|
||||
sport->devdata = of_device_get_match_data(&pdev->dev);
|
||||
if (!sport->devdata)
|
||||
/* no device tree device */
|
||||
return 1;
|
||||
|
||||
ret = of_alias_get_id(np, "serial");
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
sport->port.line = ret;
|
||||
|
||||
if (of_get_property(np, "uart-has-rtscts", NULL) ||
|
||||
of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */)
|
||||
sport->have_rtscts = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,dte-mode", NULL))
|
||||
sport->dte_mode = 1;
|
||||
|
||||
if (of_get_property(np, "rts-gpios", NULL))
|
||||
sport->have_rtsgpio = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,inverted-tx", NULL))
|
||||
sport->inverted_tx = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,inverted-rx", NULL))
|
||||
sport->inverted_rx = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int imx_uart_probe_dt(struct imx_port *sport,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void imx_uart_probe_pdata(struct imx_port *sport,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct imxuart_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
sport->port.line = pdev->id;
|
||||
sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data;
|
||||
|
||||
if (!pdata)
|
||||
return;
|
||||
|
||||
if (pdata->flags & IMXUART_HAVE_RTSCTS)
|
||||
sport->have_rtscts = 1;
|
||||
}
|
||||
|
||||
static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t)
|
||||
{
|
||||
struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx);
|
||||
@ -2275,6 +2191,7 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t)
|
||||
|
||||
static int imx_uart_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct imx_port *sport;
|
||||
void __iomem *base;
|
||||
int ret = 0;
|
||||
@ -2286,11 +2203,30 @@ static int imx_uart_probe(struct platform_device *pdev)
|
||||
if (!sport)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = imx_uart_probe_dt(sport, pdev);
|
||||
if (ret > 0)
|
||||
imx_uart_probe_pdata(sport, pdev);
|
||||
else if (ret < 0)
|
||||
sport->devdata = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
ret = of_alias_get_id(np, "serial");
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
sport->port.line = ret;
|
||||
|
||||
if (of_get_property(np, "uart-has-rtscts", NULL) ||
|
||||
of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */)
|
||||
sport->have_rtscts = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,dte-mode", NULL))
|
||||
sport->dte_mode = 1;
|
||||
|
||||
if (of_get_property(np, "rts-gpios", NULL))
|
||||
sport->have_rtsgpio = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,inverted-tx", NULL))
|
||||
sport->inverted_tx = 1;
|
||||
|
||||
if (of_get_property(np, "fsl,inverted-rx", NULL))
|
||||
sport->inverted_rx = 1;
|
||||
|
||||
if (sport->port.line >= ARRAY_SIZE(imx_uart_ports)) {
|
||||
dev_err(&pdev->dev, "serial%d out of range\n",
|
||||
@ -2639,7 +2575,6 @@ static struct platform_driver imx_uart_platform_driver = {
|
||||
.probe = imx_uart_probe,
|
||||
.remove = imx_uart_remove,
|
||||
|
||||
.id_table = imx_uart_devtype,
|
||||
.driver = {
|
||||
.name = "imx-uart",
|
||||
.of_match_table = imx_uart_dt_ids,
|
||||
|
@ -397,10 +397,8 @@ static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch)
|
||||
* which in this case is the break signal.
|
||||
*/
|
||||
if (linestatus & error_mask) {
|
||||
u8 discard;
|
||||
|
||||
linestatus = 0;
|
||||
discard = readb(&ch->ch_cls_uart->txrx);
|
||||
readb(&ch->ch_cls_uart->txrx);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -607,7 +607,7 @@ void jsm_input(struct jsm_channel *ch)
|
||||
* Give the Linux ld the flags in the
|
||||
* format it likes.
|
||||
*/
|
||||
if (*(ch->ch_equeue +tail +i) & UART_LSR_BI)
|
||||
if (*(ch->ch_equeue + tail + i) & UART_LSR_BI)
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_BREAK);
|
||||
else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE)
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_PARITY);
|
||||
|
@ -241,12 +241,11 @@ static unsigned int __serial_get_clock_div(unsigned long uartclk,
|
||||
|
||||
static void __serial_uart_flush(struct uart_port *port)
|
||||
{
|
||||
u32 tmp;
|
||||
int cnt = 0;
|
||||
|
||||
while ((readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) &&
|
||||
(cnt++ < FIFO_READ_LIMIT))
|
||||
tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
|
||||
readl(LPC32XX_HSUART_FIFO(port->membase));
|
||||
}
|
||||
|
||||
static void __serial_lpc32xx_rx(struct uart_port *port)
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
@ -267,7 +267,7 @@ struct max310x_one {
|
||||
container_of(_port, struct max310x_one, port)
|
||||
|
||||
struct max310x_port {
|
||||
struct max310x_devtype *devtype;
|
||||
const struct max310x_devtype *devtype;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
@ -1269,11 +1269,10 @@ static int max310x_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
static int max310x_probe(struct device *dev, const struct max310x_devtype *devtype,
|
||||
struct regmap *regmap, int irq)
|
||||
{
|
||||
int i, ret, fmin, fmax, freq, uartclk;
|
||||
struct clk *clk_osc, *clk_xtal;
|
||||
struct max310x_port *s;
|
||||
bool xtal = false;
|
||||
|
||||
@ -1287,23 +1286,24 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_osc = devm_clk_get(dev, "osc");
|
||||
clk_xtal = devm_clk_get(dev, "xtal");
|
||||
if (!IS_ERR(clk_osc)) {
|
||||
s->clk = clk_osc;
|
||||
s->clk = devm_clk_get_optional(dev, "osc");
|
||||
if (IS_ERR(s->clk))
|
||||
return PTR_ERR(s->clk);
|
||||
if (s->clk) {
|
||||
fmin = 500000;
|
||||
fmax = 35000000;
|
||||
} else if (!IS_ERR(clk_xtal)) {
|
||||
s->clk = clk_xtal;
|
||||
fmin = 1000000;
|
||||
fmax = 4000000;
|
||||
xtal = true;
|
||||
} else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
|
||||
PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
} else {
|
||||
dev_err(dev, "Cannot get clock\n");
|
||||
return -EINVAL;
|
||||
s->clk = devm_clk_get_optional(dev, "xtal");
|
||||
if (IS_ERR(s->clk))
|
||||
return PTR_ERR(s->clk);
|
||||
if (s->clk) {
|
||||
fmin = 1000000;
|
||||
fmax = 4000000;
|
||||
xtal = true;
|
||||
} else {
|
||||
dev_err(dev, "Cannot get clock\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(s->clk);
|
||||
@ -1478,7 +1478,7 @@ static struct regmap_config regcfg = {
|
||||
#ifdef CONFIG_SPI_MASTER
|
||||
static int max310x_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct max310x_devtype *devtype;
|
||||
const struct max310x_devtype *devtype;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
@ -1490,18 +1490,9 @@ static int max310x_spi_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (spi->dev.of_node) {
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(max310x_dt_ids, &spi->dev);
|
||||
if (!of_id)
|
||||
return -ENODEV;
|
||||
|
||||
devtype = (struct max310x_devtype *)of_id->data;
|
||||
} else {
|
||||
const struct spi_device_id *id_entry = spi_get_device_id(spi);
|
||||
|
||||
devtype = (struct max310x_devtype *)id_entry->driver_data;
|
||||
}
|
||||
devtype = device_get_match_data(&spi->dev);
|
||||
if (!devtype)
|
||||
devtype = (struct max310x_devtype *)spi_get_device_id(spi)->driver_data;
|
||||
|
||||
regcfg.max_register = devtype->nr * 0x20 - 1;
|
||||
regmap = devm_regmap_init_spi(spi, ®cfg);
|
||||
@ -1526,7 +1517,7 @@ MODULE_DEVICE_TABLE(spi, max310x_id_table);
|
||||
static struct spi_driver max310x_spi_driver = {
|
||||
.driver = {
|
||||
.name = MAX310X_NAME,
|
||||
.of_match_table = of_match_ptr(max310x_dt_ids),
|
||||
.of_match_table = max310x_dt_ids,
|
||||
.pm = &max310x_pm_ops,
|
||||
},
|
||||
.probe = max310x_spi_probe,
|
||||
|
@ -604,7 +604,6 @@ static int __init meson_serial_console_init(void)
|
||||
register_console(&meson_serial_console);
|
||||
return 0;
|
||||
}
|
||||
console_initcall(meson_serial_console_init);
|
||||
|
||||
static void meson_serial_early_console_write(struct console *co,
|
||||
const char *s,
|
||||
@ -634,6 +633,9 @@ OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart",
|
||||
|
||||
#define MESON_SERIAL_CONSOLE (&meson_serial_console)
|
||||
#else
|
||||
static int __init meson_serial_console_init(void) {
|
||||
return 0;
|
||||
}
|
||||
#define MESON_SERIAL_CONSOLE NULL
|
||||
#endif
|
||||
|
||||
@ -824,6 +826,10 @@ static int __init meson_uart_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = meson_serial_console_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = uart_register_driver(&meson_uart_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -426,7 +426,6 @@ static void msm_complete_tx_dma(void *args)
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
struct msm_dma *dma = &msm_port->tx_dma;
|
||||
struct dma_tx_state state;
|
||||
enum dma_status status;
|
||||
unsigned long flags;
|
||||
unsigned int count;
|
||||
u32 val;
|
||||
@ -437,7 +436,7 @@ static void msm_complete_tx_dma(void *args)
|
||||
if (!dma->count)
|
||||
goto done;
|
||||
|
||||
status = dmaengine_tx_status(dma->chan, dma->cookie, &state);
|
||||
dmaengine_tx_status(dma->chan, dma->cookie, &state);
|
||||
|
||||
dma_unmap_single(port->dev, dma->phys, dma->count, dma->dir);
|
||||
|
||||
@ -1525,7 +1524,7 @@ static void msm_poll_put_char(struct uart_port *port, unsigned char c)
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct uart_ops msm_uart_pops = {
|
||||
static const struct uart_ops msm_uart_pops = {
|
||||
.tx_empty = msm_tx_empty,
|
||||
.set_mctrl = msm_set_mctrl,
|
||||
.get_mctrl = msm_get_mctrl,
|
||||
|
@ -443,24 +443,16 @@ struct mxs_auart_port {
|
||||
bool ms_irq_enabled;
|
||||
};
|
||||
|
||||
static const struct platform_device_id mxs_auart_devtype[] = {
|
||||
{ .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
|
||||
{ .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
|
||||
{ .name = "as-auart-asm9260", .driver_data = ASM9260_AUART },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
|
||||
|
||||
static const struct of_device_id mxs_auart_dt_ids[] = {
|
||||
{
|
||||
.compatible = "fsl,imx28-auart",
|
||||
.data = &mxs_auart_devtype[IMX28_AUART]
|
||||
.data = (const void *)IMX28_AUART
|
||||
}, {
|
||||
.compatible = "fsl,imx23-auart",
|
||||
.data = &mxs_auart_devtype[IMX23_AUART]
|
||||
.data = (const void *)IMX23_AUART
|
||||
}, {
|
||||
.compatible = "alphascale,asm9260-auart",
|
||||
.data = &mxs_auart_devtype[ASM9260_AUART]
|
||||
.data = (const void *)ASM9260_AUART
|
||||
}, { /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
|
||||
@ -1639,8 +1631,6 @@ static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s)
|
||||
|
||||
static int mxs_auart_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(mxs_auart_dt_ids, &pdev->dev);
|
||||
struct mxs_auart_port *s;
|
||||
u32 version;
|
||||
int ret, irq;
|
||||
@ -1663,10 +1653,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (of_id) {
|
||||
pdev->id_entry = of_id->data;
|
||||
s->devtype = pdev->id_entry->driver_data;
|
||||
}
|
||||
s->devtype = (enum mxs_auart_type)of_device_get_match_data(&pdev->dev);
|
||||
|
||||
ret = mxs_get_clks(s, pdev);
|
||||
if (ret)
|
||||
|
@ -362,10 +362,10 @@ static inline void zssync(struct uart_pmac_port *port)
|
||||
|
||||
/* Misc macros */
|
||||
#define ZS_CLEARERR(port) (write_zsreg(port, 0, ERR_RES))
|
||||
#define ZS_CLEARFIFO(port) do { volatile unsigned char garbage; \
|
||||
garbage = read_zsdata(port); \
|
||||
garbage = read_zsdata(port); \
|
||||
garbage = read_zsdata(port); \
|
||||
#define ZS_CLEARFIFO(port) do { \
|
||||
read_zsdata(port); \
|
||||
read_zsdata(port); \
|
||||
read_zsdata(port); \
|
||||
} while(0)
|
||||
|
||||
#define ZS_IS_CONS(UP) ((UP)->flags & PMACZILOG_FLAG_IS_CONS)
|
||||
|
@ -1,858 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* UART driver for PNX8XXX SoCs
|
||||
*
|
||||
* Author: Per Hallsmark per.hallsmark@mvista.com
|
||||
* Ported to 2.6 kernel by EmbeddedAlley
|
||||
* Reworked by Vitaly Wool <vitalywool@gmail.com>
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
* Copyright (C) 2000 Deep Blue Solutions Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_pnx8xxx.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* We'll be using StrongARM sa1100 serial port major/minor */
|
||||
#define SERIAL_PNX8XXX_MAJOR 204
|
||||
#define MINOR_START 5
|
||||
|
||||
#define NR_PORTS 2
|
||||
|
||||
#define PNX8XXX_ISR_PASS_LIMIT 256
|
||||
|
||||
/*
|
||||
* Convert from ignore_status_mask or read_status_mask to FIFO
|
||||
* and interrupt status bits
|
||||
*/
|
||||
#define SM_TO_FIFO(x) ((x) >> 10)
|
||||
#define SM_TO_ISTAT(x) ((x) & 0x000001ff)
|
||||
#define FIFO_TO_SM(x) ((x) << 10)
|
||||
#define ISTAT_TO_SM(x) ((x) & 0x000001ff)
|
||||
|
||||
/*
|
||||
* This is the size of our serial port register set.
|
||||
*/
|
||||
#define UART_PORT_SIZE 0x1000
|
||||
|
||||
/*
|
||||
* This determines how often we check the modem status signals
|
||||
* for any change. They generally aren't connected to an IRQ
|
||||
* so we have to poll them. We also check immediately before
|
||||
* filling the TX fifo incase CTS has been dropped.
|
||||
*/
|
||||
#define MCTRL_TIMEOUT (250*HZ/1000)
|
||||
|
||||
extern struct pnx8xxx_port pnx8xxx_ports[];
|
||||
|
||||
static inline int serial_in(struct pnx8xxx_port *sport, int offset)
|
||||
{
|
||||
return (__raw_readl(sport->port.membase + offset));
|
||||
}
|
||||
|
||||
static inline void serial_out(struct pnx8xxx_port *sport, int offset, int value)
|
||||
{
|
||||
__raw_writel(value, sport->port.membase + offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle any change of modem status signal since we were last called.
|
||||
*/
|
||||
static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport)
|
||||
{
|
||||
unsigned int status, changed;
|
||||
|
||||
status = sport->port.ops->get_mctrl(&sport->port);
|
||||
changed = status ^ sport->old_status;
|
||||
|
||||
if (changed == 0)
|
||||
return;
|
||||
|
||||
sport->old_status = status;
|
||||
|
||||
if (changed & TIOCM_RI)
|
||||
sport->port.icount.rng++;
|
||||
if (changed & TIOCM_DSR)
|
||||
sport->port.icount.dsr++;
|
||||
if (changed & TIOCM_CAR)
|
||||
uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
|
||||
if (changed & TIOCM_CTS)
|
||||
uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
|
||||
|
||||
wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is our per-port timeout handler, for checking the
|
||||
* modem status signals.
|
||||
*/
|
||||
static void pnx8xxx_timeout(struct timer_list *t)
|
||||
{
|
||||
struct pnx8xxx_port *sport = from_timer(sport, t, timer);
|
||||
unsigned long flags;
|
||||
|
||||
if (sport->port.state) {
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
pnx8xxx_mctrl_check(sport);
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* interrupts disabled on entry
|
||||
*/
|
||||
static void pnx8xxx_stop_tx(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
u32 ien;
|
||||
|
||||
/* Disable TX intr */
|
||||
ien = serial_in(sport, PNX8XXX_IEN);
|
||||
serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLTX);
|
||||
|
||||
/* Clear all pending TX intr */
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);
|
||||
}
|
||||
|
||||
/*
|
||||
* interrupts may not be disabled on entry
|
||||
*/
|
||||
static void pnx8xxx_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
u32 ien;
|
||||
|
||||
/* Clear all pending TX intr */
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);
|
||||
|
||||
/* Enable TX intr */
|
||||
ien = serial_in(sport, PNX8XXX_IEN);
|
||||
serial_out(sport, PNX8XXX_IEN, ien | PNX8XXX_UART_INT_ALLTX);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts enabled
|
||||
*/
|
||||
static void pnx8xxx_stop_rx(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
u32 ien;
|
||||
|
||||
/* Disable RX intr */
|
||||
ien = serial_in(sport, PNX8XXX_IEN);
|
||||
serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLRX);
|
||||
|
||||
/* Clear all pending RX intr */
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the modem control timer to fire immediately.
|
||||
*/
|
||||
static void pnx8xxx_enable_ms(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
|
||||
mod_timer(&sport->timer, jiffies);
|
||||
}
|
||||
|
||||
static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
|
||||
{
|
||||
unsigned int status, ch, flg;
|
||||
|
||||
status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
|
||||
ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
|
||||
while (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFIFO)) {
|
||||
ch = serial_in(sport, PNX8XXX_FIFO) & 0xff;
|
||||
|
||||
sport->port.icount.rx++;
|
||||
|
||||
flg = TTY_NORMAL;
|
||||
|
||||
/*
|
||||
* note that the error handling code is
|
||||
* out of the main execution path
|
||||
*/
|
||||
if (status & (FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE |
|
||||
PNX8XXX_UART_FIFO_RXPAR |
|
||||
PNX8XXX_UART_FIFO_RXBRK) |
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))) {
|
||||
if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXBRK)) {
|
||||
status &= ~(FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
|
||||
FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR));
|
||||
sport->port.icount.brk++;
|
||||
if (uart_handle_break(&sport->port))
|
||||
goto ignore_char;
|
||||
} else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
|
||||
sport->port.icount.parity++;
|
||||
else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
|
||||
sport->port.icount.frame++;
|
||||
if (status & ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))
|
||||
sport->port.icount.overrun++;
|
||||
|
||||
status &= sport->port.read_status_mask;
|
||||
|
||||
if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
|
||||
flg = TTY_PARITY;
|
||||
else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
|
||||
flg = TTY_FRAME;
|
||||
|
||||
sport->port.sysrq = 0;
|
||||
}
|
||||
|
||||
if (uart_handle_sysrq_char(&sport->port, ch))
|
||||
goto ignore_char;
|
||||
|
||||
uart_insert_char(&sport->port, status,
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN), ch, flg);
|
||||
|
||||
ignore_char:
|
||||
serial_out(sport, PNX8XXX_LCR, serial_in(sport, PNX8XXX_LCR) |
|
||||
PNX8XXX_UART_LCR_RX_NEXT);
|
||||
status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
|
||||
ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
|
||||
}
|
||||
|
||||
spin_unlock(&sport->port.lock);
|
||||
tty_flip_buffer_push(&sport->port.state->port);
|
||||
spin_lock(&sport->port.lock);
|
||||
}
|
||||
|
||||
static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
|
||||
{
|
||||
struct circ_buf *xmit = &sport->port.state->xmit;
|
||||
|
||||
if (sport->port.x_char) {
|
||||
serial_out(sport, PNX8XXX_FIFO, sport->port.x_char);
|
||||
sport->port.icount.tx++;
|
||||
sport->port.x_char = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the modem control lines before
|
||||
* transmitting anything.
|
||||
*/
|
||||
pnx8xxx_mctrl_check(sport);
|
||||
|
||||
if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
|
||||
pnx8xxx_stop_tx(&sport->port);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* TX while bytes available
|
||||
*/
|
||||
while (((serial_in(sport, PNX8XXX_FIFO) &
|
||||
PNX8XXX_UART_FIFO_TXFIFO) >> 16) < 16) {
|
||||
serial_out(sport, PNX8XXX_FIFO, xmit->buf[xmit->tail]);
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
sport->port.icount.tx++;
|
||||
if (uart_circ_empty(xmit))
|
||||
break;
|
||||
}
|
||||
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup(&sport->port);
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
pnx8xxx_stop_tx(&sport->port);
|
||||
}
|
||||
|
||||
static irqreturn_t pnx8xxx_int(int irq, void *dev_id)
|
||||
{
|
||||
struct pnx8xxx_port *sport = dev_id;
|
||||
unsigned int status;
|
||||
|
||||
spin_lock(&sport->port.lock);
|
||||
/* Get the interrupts */
|
||||
status = serial_in(sport, PNX8XXX_ISTAT) & serial_in(sport, PNX8XXX_IEN);
|
||||
|
||||
/* Byte or break signal received */
|
||||
if (status & (PNX8XXX_UART_INT_RX | PNX8XXX_UART_INT_BREAK))
|
||||
pnx8xxx_rx_chars(sport);
|
||||
|
||||
/* TX holding register empty - transmit a byte */
|
||||
if (status & PNX8XXX_UART_INT_TX)
|
||||
pnx8xxx_tx_chars(sport);
|
||||
|
||||
/* Clear the ISTAT register */
|
||||
serial_out(sport, PNX8XXX_ICLR, status);
|
||||
|
||||
spin_unlock(&sport->port.lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TIOCSER_TEMT when transmitter is not busy.
|
||||
*/
|
||||
static unsigned int pnx8xxx_tx_empty(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
|
||||
return serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA ? 0 : TIOCSER_TEMT;
|
||||
}
|
||||
|
||||
static unsigned int pnx8xxx_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
unsigned int mctrl = TIOCM_DSR;
|
||||
unsigned int msr;
|
||||
|
||||
/* REVISIT */
|
||||
|
||||
msr = serial_in(sport, PNX8XXX_MCR);
|
||||
|
||||
mctrl |= msr & PNX8XXX_UART_MCR_CTS ? TIOCM_CTS : 0;
|
||||
mctrl |= msr & PNX8XXX_UART_MCR_DCD ? TIOCM_CAR : 0;
|
||||
|
||||
return mctrl;
|
||||
}
|
||||
|
||||
static void pnx8xxx_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
#if 0 /* FIXME */
|
||||
struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port;
|
||||
unsigned int msr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts always disabled.
|
||||
*/
|
||||
static void pnx8xxx_break_ctl(struct uart_port *port, int break_state)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
unsigned long flags;
|
||||
unsigned int lcr;
|
||||
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
lcr = serial_in(sport, PNX8XXX_LCR);
|
||||
if (break_state == -1)
|
||||
lcr |= PNX8XXX_UART_LCR_TXBREAK;
|
||||
else
|
||||
lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
|
||||
serial_out(sport, PNX8XXX_LCR, lcr);
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
}
|
||||
|
||||
static int pnx8xxx_startup(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Allocate the IRQ
|
||||
*/
|
||||
retval = request_irq(sport->port.irq, pnx8xxx_int, 0,
|
||||
"pnx8xxx-uart", sport);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Finally, clear and enable interrupts
|
||||
*/
|
||||
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
|
||||
PNX8XXX_UART_INT_ALLTX);
|
||||
|
||||
serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) |
|
||||
PNX8XXX_UART_INT_ALLRX |
|
||||
PNX8XXX_UART_INT_ALLTX);
|
||||
|
||||
/*
|
||||
* Enable modem status interrupts
|
||||
*/
|
||||
spin_lock_irq(&sport->port.lock);
|
||||
pnx8xxx_enable_ms(&sport->port);
|
||||
spin_unlock_irq(&sport->port.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pnx8xxx_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
int lcr;
|
||||
|
||||
/*
|
||||
* Stop our timer.
|
||||
*/
|
||||
del_timer_sync(&sport->timer);
|
||||
|
||||
/*
|
||||
* Disable all interrupts
|
||||
*/
|
||||
serial_out(sport, PNX8XXX_IEN, 0);
|
||||
|
||||
/*
|
||||
* Reset the Tx and Rx FIFOS, disable the break condition
|
||||
*/
|
||||
lcr = serial_in(sport, PNX8XXX_LCR);
|
||||
lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
|
||||
lcr |= PNX8XXX_UART_LCR_TX_RST | PNX8XXX_UART_LCR_RX_RST;
|
||||
serial_out(sport, PNX8XXX_LCR, lcr);
|
||||
|
||||
/*
|
||||
* Clear all interrupts
|
||||
*/
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
|
||||
PNX8XXX_UART_INT_ALLTX);
|
||||
|
||||
/*
|
||||
* Free the interrupt
|
||||
*/
|
||||
free_irq(sport->port.irq, sport);
|
||||
}
|
||||
|
||||
static void
|
||||
pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
struct ktermios *old)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
unsigned long flags;
|
||||
unsigned int lcr_fcr, old_ien, baud, quot;
|
||||
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
|
||||
|
||||
/*
|
||||
* We only support CS7 and CS8.
|
||||
*/
|
||||
while ((termios->c_cflag & CSIZE) != CS7 &&
|
||||
(termios->c_cflag & CSIZE) != CS8) {
|
||||
termios->c_cflag &= ~CSIZE;
|
||||
termios->c_cflag |= old_csize;
|
||||
old_csize = CS8;
|
||||
}
|
||||
|
||||
if ((termios->c_cflag & CSIZE) == CS8)
|
||||
lcr_fcr = PNX8XXX_UART_LCR_8BIT;
|
||||
else
|
||||
lcr_fcr = 0;
|
||||
|
||||
if (termios->c_cflag & CSTOPB)
|
||||
lcr_fcr |= PNX8XXX_UART_LCR_2STOPB;
|
||||
if (termios->c_cflag & PARENB) {
|
||||
lcr_fcr |= PNX8XXX_UART_LCR_PAREN;
|
||||
if (!(termios->c_cflag & PARODD))
|
||||
lcr_fcr |= PNX8XXX_UART_LCR_PAREVN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the core to calculate the divisor for us.
|
||||
*/
|
||||
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
|
||||
quot = uart_get_divisor(port, baud);
|
||||
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) |
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) |
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_RX);
|
||||
if (termios->c_iflag & INPCK)
|
||||
sport->port.read_status_mask |=
|
||||
FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
|
||||
FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
|
||||
if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
|
||||
sport->port.read_status_mask |=
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
|
||||
|
||||
/*
|
||||
* Characters to ignore
|
||||
*/
|
||||
sport->port.ignore_status_mask = 0;
|
||||
if (termios->c_iflag & IGNPAR)
|
||||
sport->port.ignore_status_mask |=
|
||||
FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
|
||||
FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
|
||||
if (termios->c_iflag & IGNBRK) {
|
||||
sport->port.ignore_status_mask |=
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
|
||||
/*
|
||||
* If we're ignoring parity and break indicators,
|
||||
* ignore overruns too (for real raw support).
|
||||
*/
|
||||
if (termios->c_iflag & IGNPAR)
|
||||
sport->port.ignore_status_mask |=
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN);
|
||||
}
|
||||
|
||||
/*
|
||||
* ignore all characters if CREAD is not set
|
||||
*/
|
||||
if ((termios->c_cflag & CREAD) == 0)
|
||||
sport->port.ignore_status_mask |=
|
||||
ISTAT_TO_SM(PNX8XXX_UART_INT_RX);
|
||||
|
||||
del_timer_sync(&sport->timer);
|
||||
|
||||
/*
|
||||
* Update the per-port timeout.
|
||||
*/
|
||||
uart_update_timeout(port, termios->c_cflag, baud);
|
||||
|
||||
/*
|
||||
* disable interrupts and drain transmitter
|
||||
*/
|
||||
old_ien = serial_in(sport, PNX8XXX_IEN);
|
||||
serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
|
||||
PNX8XXX_UART_INT_ALLRX));
|
||||
|
||||
while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA)
|
||||
barrier();
|
||||
|
||||
/* then, disable everything */
|
||||
serial_out(sport, PNX8XXX_IEN, 0);
|
||||
|
||||
/* Reset the Rx and Tx FIFOs too */
|
||||
lcr_fcr |= PNX8XXX_UART_LCR_TX_RST;
|
||||
lcr_fcr |= PNX8XXX_UART_LCR_RX_RST;
|
||||
|
||||
/* set the parity, stop bits and data size */
|
||||
serial_out(sport, PNX8XXX_LCR, lcr_fcr);
|
||||
|
||||
/* set the baud rate */
|
||||
quot -= 1;
|
||||
serial_out(sport, PNX8XXX_BAUD, quot);
|
||||
|
||||
serial_out(sport, PNX8XXX_ICLR, -1);
|
||||
|
||||
serial_out(sport, PNX8XXX_IEN, old_ien);
|
||||
|
||||
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
|
||||
pnx8xxx_enable_ms(&sport->port);
|
||||
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
}
|
||||
|
||||
static const char *pnx8xxx_type(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
|
||||
return sport->port.type == PORT_PNX8XXX ? "PNX8XXX" : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the memory region(s) being used by 'port'.
|
||||
*/
|
||||
static void pnx8xxx_release_port(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
|
||||
release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Request the memory region(s) being used by 'port'.
|
||||
*/
|
||||
static int pnx8xxx_request_port(struct uart_port *port)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
|
||||
"pnx8xxx-uart") != NULL ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure/autoconfigure the port.
|
||||
*/
|
||||
static void pnx8xxx_config_port(struct uart_port *port, int flags)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
|
||||
if (flags & UART_CONFIG_TYPE &&
|
||||
pnx8xxx_request_port(&sport->port) == 0)
|
||||
sport->port.type = PORT_PNX8XXX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the new serial_struct (for TIOCSSERIAL).
|
||||
* The only change we allow are to the flags and type, and
|
||||
* even then only between PORT_PNX8XXX and PORT_UNKNOWN
|
||||
*/
|
||||
static int
|
||||
pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
int ret = 0;
|
||||
|
||||
if (ser->type != PORT_UNKNOWN && ser->type != PORT_PNX8XXX)
|
||||
ret = -EINVAL;
|
||||
if (sport->port.irq != ser->irq)
|
||||
ret = -EINVAL;
|
||||
if (ser->io_type != SERIAL_IO_MEM)
|
||||
ret = -EINVAL;
|
||||
if (sport->port.uartclk / 16 != ser->baud_base)
|
||||
ret = -EINVAL;
|
||||
if ((void *)sport->port.mapbase != ser->iomem_base)
|
||||
ret = -EINVAL;
|
||||
if (sport->port.iobase != ser->port)
|
||||
ret = -EINVAL;
|
||||
if (ser->hub6 != 0)
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct uart_ops pnx8xxx_pops = {
|
||||
.tx_empty = pnx8xxx_tx_empty,
|
||||
.set_mctrl = pnx8xxx_set_mctrl,
|
||||
.get_mctrl = pnx8xxx_get_mctrl,
|
||||
.stop_tx = pnx8xxx_stop_tx,
|
||||
.start_tx = pnx8xxx_start_tx,
|
||||
.stop_rx = pnx8xxx_stop_rx,
|
||||
.enable_ms = pnx8xxx_enable_ms,
|
||||
.break_ctl = pnx8xxx_break_ctl,
|
||||
.startup = pnx8xxx_startup,
|
||||
.shutdown = pnx8xxx_shutdown,
|
||||
.set_termios = pnx8xxx_set_termios,
|
||||
.type = pnx8xxx_type,
|
||||
.release_port = pnx8xxx_release_port,
|
||||
.request_port = pnx8xxx_request_port,
|
||||
.config_port = pnx8xxx_config_port,
|
||||
.verify_port = pnx8xxx_verify_port,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Setup the PNX8XXX serial ports.
|
||||
*
|
||||
* Note also that we support "console=ttySx" where "x" is either 0 or 1.
|
||||
*/
|
||||
static void __init pnx8xxx_init_ports(void)
|
||||
{
|
||||
static int first = 1;
|
||||
int i;
|
||||
|
||||
if (!first)
|
||||
return;
|
||||
first = 0;
|
||||
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
timer_setup(&pnx8xxx_ports[i].timer, pnx8xxx_timeout, 0);
|
||||
pnx8xxx_ports[i].port.ops = &pnx8xxx_pops;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_PNX8XXX_CONSOLE
|
||||
|
||||
static void pnx8xxx_console_putchar(struct uart_port *port, int ch)
|
||||
{
|
||||
struct pnx8xxx_port *sport =
|
||||
container_of(port, struct pnx8xxx_port, port);
|
||||
int status;
|
||||
|
||||
do {
|
||||
/* Wait for UART_TX register to empty */
|
||||
status = serial_in(sport, PNX8XXX_FIFO);
|
||||
} while (status & PNX8XXX_UART_FIFO_TXFIFO);
|
||||
serial_out(sport, PNX8XXX_FIFO, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts are disabled on entering
|
||||
*/static void
|
||||
pnx8xxx_console_write(struct console *co, const char *s, unsigned int count)
|
||||
{
|
||||
struct pnx8xxx_port *sport = &pnx8xxx_ports[co->index];
|
||||
unsigned int old_ien, status;
|
||||
|
||||
/*
|
||||
* First, save IEN and then disable interrupts
|
||||
*/
|
||||
old_ien = serial_in(sport, PNX8XXX_IEN);
|
||||
serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
|
||||
PNX8XXX_UART_INT_ALLRX));
|
||||
|
||||
uart_console_write(&sport->port, s, count, pnx8xxx_console_putchar);
|
||||
|
||||
/*
|
||||
* Finally, wait for transmitter to become empty
|
||||
* and restore IEN
|
||||
*/
|
||||
do {
|
||||
/* Wait for UART_TX register to empty */
|
||||
status = serial_in(sport, PNX8XXX_FIFO);
|
||||
} while (status & PNX8XXX_UART_FIFO_TXFIFO);
|
||||
|
||||
/* Clear TX and EMPTY interrupt */
|
||||
serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_TX |
|
||||
PNX8XXX_UART_INT_EMPTY);
|
||||
|
||||
serial_out(sport, PNX8XXX_IEN, old_ien);
|
||||
}
|
||||
|
||||
static int __init
|
||||
pnx8xxx_console_setup(struct console *co, char *options)
|
||||
{
|
||||
struct pnx8xxx_port *sport;
|
||||
int baud = 38400;
|
||||
int bits = 8;
|
||||
int parity = 'n';
|
||||
int flow = 'n';
|
||||
|
||||
/*
|
||||
* Check whether an invalid uart number has been specified, and
|
||||
* if so, search for the first available port that does have
|
||||
* console support.
|
||||
*/
|
||||
if (co->index == -1 || co->index >= NR_PORTS)
|
||||
co->index = 0;
|
||||
sport = &pnx8xxx_ports[co->index];
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
||||
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
|
||||
}
|
||||
|
||||
static struct uart_driver pnx8xxx_reg;
|
||||
static struct console pnx8xxx_console = {
|
||||
.name = "ttyS",
|
||||
.write = pnx8xxx_console_write,
|
||||
.device = uart_console_device,
|
||||
.setup = pnx8xxx_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
.data = &pnx8xxx_reg,
|
||||
};
|
||||
|
||||
static int __init pnx8xxx_rs_console_init(void)
|
||||
{
|
||||
pnx8xxx_init_ports();
|
||||
register_console(&pnx8xxx_console);
|
||||
return 0;
|
||||
}
|
||||
console_initcall(pnx8xxx_rs_console_init);
|
||||
|
||||
#define PNX8XXX_CONSOLE &pnx8xxx_console
|
||||
#else
|
||||
#define PNX8XXX_CONSOLE NULL
|
||||
#endif
|
||||
|
||||
static struct uart_driver pnx8xxx_reg = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_name = "ttyS",
|
||||
.dev_name = "ttyS",
|
||||
.major = SERIAL_PNX8XXX_MAJOR,
|
||||
.minor = MINOR_START,
|
||||
.nr = NR_PORTS,
|
||||
.cons = PNX8XXX_CONSOLE,
|
||||
};
|
||||
|
||||
static int pnx8xxx_serial_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
|
||||
|
||||
return uart_suspend_port(&pnx8xxx_reg, &sport->port);
|
||||
}
|
||||
|
||||
static int pnx8xxx_serial_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
|
||||
|
||||
return uart_resume_port(&pnx8xxx_reg, &sport->port);
|
||||
}
|
||||
|
||||
static int pnx8xxx_serial_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = pdev->resource;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pdev->num_resources; i++, res++) {
|
||||
if (!(res->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
if (pnx8xxx_ports[i].port.mapbase != res->start)
|
||||
continue;
|
||||
|
||||
pnx8xxx_ports[i].port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PNX8XXX_CONSOLE);
|
||||
pnx8xxx_ports[i].port.dev = &pdev->dev;
|
||||
uart_add_one_port(&pnx8xxx_reg, &pnx8xxx_ports[i].port);
|
||||
platform_set_drvdata(pdev, &pnx8xxx_ports[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pnx8xxx_serial_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
|
||||
|
||||
if (sport)
|
||||
uart_remove_one_port(&pnx8xxx_reg, &sport->port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pnx8xxx_serial_driver = {
|
||||
.driver = {
|
||||
.name = "pnx8xxx-uart",
|
||||
},
|
||||
.probe = pnx8xxx_serial_probe,
|
||||
.remove = pnx8xxx_serial_remove,
|
||||
.suspend = pnx8xxx_serial_suspend,
|
||||
.resume = pnx8xxx_serial_resume,
|
||||
};
|
||||
|
||||
static int __init pnx8xxx_serial_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Serial: PNX8XXX driver\n");
|
||||
|
||||
pnx8xxx_init_ports();
|
||||
|
||||
ret = uart_register_driver(&pnx8xxx_reg);
|
||||
if (ret == 0) {
|
||||
ret = platform_driver_register(&pnx8xxx_serial_driver);
|
||||
if (ret)
|
||||
uart_unregister_driver(&pnx8xxx_reg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit pnx8xxx_serial_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pnx8xxx_serial_driver);
|
||||
uart_unregister_driver(&pnx8xxx_reg);
|
||||
}
|
||||
|
||||
module_init(pnx8xxx_serial_init);
|
||||
module_exit(pnx8xxx_serial_exit);
|
||||
|
||||
MODULE_AUTHOR("Embedded Alley Solutions, Inc.");
|
||||
MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR);
|
||||
MODULE_ALIAS("platform:pnx8xxx-uart");
|
@ -75,12 +75,17 @@
|
||||
#define TEGRA_UART_FCR_IIR_FIFO_EN 0x40
|
||||
|
||||
/**
|
||||
* tegra_uart_chip_data: SOC specific data.
|
||||
* struct tegra_uart_chip_data: SOC specific data.
|
||||
*
|
||||
* @tx_fifo_full_status: Status flag available for checking tx fifo full.
|
||||
* @allow_txfifo_reset_fifo_mode: allow_tx fifo reset with fifo mode or not.
|
||||
* Tegra30 does not allow this.
|
||||
* @support_clk_src_div: Clock source support the clock divider.
|
||||
* @fifo_mode_enable_status: Is FIFO mode enabled?
|
||||
* @uart_max_port: Maximum number of UART ports
|
||||
* @max_dma_burst_bytes: Maximum size of DMA bursts
|
||||
* @error_tolerance_low_range: Lowest number in the error tolerance range
|
||||
* @error_tolerance_high_range: Highest number in the error tolerance range
|
||||
*/
|
||||
struct tegra_uart_chip_data {
|
||||
bool tx_fifo_full_status;
|
||||
|
@ -1467,6 +1467,10 @@ static void uart_set_ldisc(struct tty_struct *tty)
|
||||
{
|
||||
struct uart_state *state = tty->driver_data;
|
||||
struct uart_port *uport;
|
||||
struct tty_port *port = &state->port;
|
||||
|
||||
if (!tty_port_initialized(port))
|
||||
return;
|
||||
|
||||
mutex_lock(&state->port.mutex);
|
||||
uport = uart_port_check(state);
|
||||
|
@ -207,7 +207,7 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx)
|
||||
continue;
|
||||
|
||||
ret = gpiod_to_irq(gpios->gpio[i]);
|
||||
if (ret <= 0) {
|
||||
if (ret < 0) {
|
||||
dev_err(port->dev,
|
||||
"failed to find corresponding irq for %s (idx=%d, err=%d)\n",
|
||||
mctrl_gpios_desc[i].name, idx, ret);
|
||||
|
@ -144,12 +144,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* sifive_serial_port - driver-specific data extension to struct uart_port
|
||||
* struct sifive_serial_port - driver-specific data extension to struct uart_port
|
||||
* @port: struct uart_port embedded in this struct
|
||||
* @dev: struct device *
|
||||
* @ier: shadowed copy of the interrupt enable register
|
||||
* @clkin_rate: input clock to the UART IP block.
|
||||
* @baud_rate: UART serial line rate (e.g., 115200 baud)
|
||||
* @clk: reference to this device's clock
|
||||
* @clk_notifier: clock rate change notifier for upstream clock changes
|
||||
*
|
||||
* Configuration data specific to this SiFive UART.
|
||||
|
@ -350,7 +350,6 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
|
||||
struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
struct dma_async_tx_descriptor *desc = NULL;
|
||||
dma_cookie_t cookie;
|
||||
unsigned int count, i;
|
||||
|
||||
if (stm32port->tx_dma_busy)
|
||||
@ -394,7 +393,7 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
|
||||
desc->callback_param = port;
|
||||
|
||||
/* Push current DMA TX transaction in the pending queue */
|
||||
cookie = dmaengine_submit(desc);
|
||||
dmaengine_submit(desc);
|
||||
|
||||
/* Issue pending DMA TX requests */
|
||||
dma_async_issue_pending(stm32port->tx_ch);
|
||||
@ -1087,7 +1086,6 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
|
||||
struct device *dev = &pdev->dev;
|
||||
struct dma_slave_config config;
|
||||
struct dma_async_tx_descriptor *desc = NULL;
|
||||
dma_cookie_t cookie;
|
||||
int ret;
|
||||
|
||||
/* Request DMA RX channel */
|
||||
@ -1132,7 +1130,7 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
|
||||
desc->callback_param = NULL;
|
||||
|
||||
/* Push current DMA transaction in the pending queue */
|
||||
cookie = dmaengine_submit(desc);
|
||||
dmaengine_submit(desc);
|
||||
|
||||
/* Issue pending DMA requests */
|
||||
dma_async_issue_pending(stm32port->rx_ch);
|
||||
|
@ -773,8 +773,8 @@ static int ulite_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0)
|
||||
return -ENXIO;
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
pdata->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
|
||||
if (IS_ERR(pdata->clk)) {
|
||||
|
@ -192,6 +192,7 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
|
||||
* @baud: Current baud rate
|
||||
* @clk_rate_change_nb: Notifier block for clock changes
|
||||
* @quirks: Flags for RXBS support.
|
||||
* @cts_override: Modem control state override
|
||||
*/
|
||||
struct cdns_uart {
|
||||
struct uart_port *port;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -620,7 +620,7 @@ static inline int sanity_check(struct slgt_info *info, char *devname, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* line discipline callback wrappers
|
||||
*
|
||||
* The wrappers maintain line discipline references
|
||||
@ -1678,6 +1678,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
/**
|
||||
* hdlcdev_tx_timeout - called by network layer when transmit timeout is detected
|
||||
* @dev: pointer to network device structure
|
||||
* @txqueue: unused
|
||||
*/
|
||||
static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -81,7 +81,7 @@ static void tty_audit_log(const char *description, dev_t dev,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_buf_push - Push buffered data out
|
||||
*
|
||||
* Generate an audit message from the contents of @buf, which is owned by
|
||||
@ -120,7 +120,7 @@ void tty_audit_exit(void)
|
||||
tty_audit_buf_free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_fork - Copy TTY audit state for a new task
|
||||
*
|
||||
* Set up TTY audit state in @sig from current. @sig needs no locking.
|
||||
@ -130,7 +130,7 @@ void tty_audit_fork(struct signal_struct *sig)
|
||||
sig->audit_tty = current->signal->audit_tty;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_tiocsti - Log TIOCSTI
|
||||
*/
|
||||
void tty_audit_tiocsti(struct tty_struct *tty, char ch)
|
||||
@ -145,7 +145,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
|
||||
tty_audit_log("ioctl=TIOCSTI", dev, &ch, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_push - Flush current's pending audit data
|
||||
*
|
||||
* Returns 0 if success, -EPERM if tty audit is disabled
|
||||
@ -166,7 +166,7 @@ int tty_audit_push(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_buf_get - Get an audit buffer.
|
||||
*
|
||||
* Get an audit buffer, allocate it if necessary. Return %NULL
|
||||
@ -193,7 +193,7 @@ static struct tty_audit_buf *tty_audit_buf_get(void)
|
||||
return tty_audit_buf_ref();
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_audit_add_data - Add data for TTY auditing.
|
||||
*
|
||||
* Audit @data of @size from @tty, if necessary.
|
||||
|
@ -222,6 +222,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
|
||||
|
||||
/**
|
||||
* tty_encode_baud_rate - set baud rate of the tty
|
||||
* @tty: terminal device
|
||||
* @ibaud: input baud rate
|
||||
* @obaud: output baud rate
|
||||
*
|
||||
|
@ -583,6 +583,7 @@ void tty_buffer_init(struct tty_port *port)
|
||||
/**
|
||||
* tty_buffer_set_limit - change the tty buffer memory limit
|
||||
* @port: tty port to change
|
||||
* @limit: memory limit to set
|
||||
*
|
||||
* Change the tty buffer memory limit.
|
||||
* Must be called before the other tty buffer functions are used.
|
||||
|
@ -208,7 +208,7 @@ void tty_add_file(struct tty_struct *tty, struct file *file)
|
||||
spin_unlock(&tty->files_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_free_file - free file->private_data
|
||||
*
|
||||
* This shall be used only for fail path handling when tty_add_file was not
|
||||
@ -514,8 +514,6 @@ static const struct file_operations hung_up_tty_fops = {
|
||||
static DEFINE_SPINLOCK(redirect_lock);
|
||||
static struct file *redirect;
|
||||
|
||||
extern void tty_sysctl_init(void);
|
||||
|
||||
/**
|
||||
* tty_wakeup - request more data
|
||||
* @tty: terminal
|
||||
@ -545,6 +543,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
|
||||
/**
|
||||
* __tty_hangup - actual handler for hangup events
|
||||
* @tty: tty device
|
||||
* @exit_session: if non-zero, signal all foreground group processes
|
||||
*
|
||||
* This can be called by a "kworker" kernel thread. That is process
|
||||
* synchronous but doesn't hold any locks, so we need to make sure we
|
||||
@ -1067,7 +1066,7 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
|
||||
return tty_write(file, buf, count, ppos);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_send_xchar - send priority character
|
||||
*
|
||||
* Send a high priority character to the tty even if stopped
|
||||
@ -1145,6 +1144,7 @@ static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
|
||||
/**
|
||||
* tty_driver_lookup_tty() - find an existing tty, if any
|
||||
* @driver: the driver for the tty
|
||||
* @file: file object
|
||||
* @idx: the minor number
|
||||
*
|
||||
* Return the tty, if found. If not found, return NULL or ERR_PTR() if the
|
||||
@ -1496,6 +1496,8 @@ EXPORT_SYMBOL(tty_kref_put);
|
||||
|
||||
/**
|
||||
* release_tty - release tty structure memory
|
||||
* @tty: tty device release
|
||||
* @idx: index of the tty device release
|
||||
*
|
||||
* Release both @tty and a possible linked partner (think pty pair),
|
||||
* and decrement the refcount of the backing module.
|
||||
@ -2970,7 +2972,7 @@ static struct device *tty_get_device(struct tty_struct *tty)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* alloc_tty_struct
|
||||
*
|
||||
* This subroutine allocates and initializes a tty structure.
|
||||
|
@ -443,51 +443,6 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TCGETX
|
||||
|
||||
/**
|
||||
* set_termiox - set termiox fields if possible
|
||||
* @tty: terminal
|
||||
* @arg: termiox structure from user
|
||||
* @opt: option flags for ioctl type
|
||||
*
|
||||
* Implement the device calling points for the SYS5 termiox ioctl
|
||||
* interface in Linux
|
||||
*/
|
||||
|
||||
static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
|
||||
{
|
||||
struct termiox tnew;
|
||||
struct tty_ldisc *ld;
|
||||
|
||||
if (tty->termiox == NULL)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
|
||||
return -EFAULT;
|
||||
|
||||
ld = tty_ldisc_ref(tty);
|
||||
if (ld != NULL) {
|
||||
if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
|
||||
ld->ops->flush_buffer(tty);
|
||||
tty_ldisc_deref(ld);
|
||||
}
|
||||
if (opt & TERMIOS_WAIT) {
|
||||
tty_wait_until_sent(tty, 0);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
down_write(&tty->termios_rwsem);
|
||||
if (tty->ops->set_termiox)
|
||||
tty->ops->set_termiox(tty, &tnew);
|
||||
up_write(&tty->termios_rwsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TIOCGETP
|
||||
/*
|
||||
* These are deprecated, but there is limited support..
|
||||
@ -815,23 +770,11 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
|
||||
return ret;
|
||||
#endif
|
||||
#ifdef TCGETX
|
||||
case TCGETX: {
|
||||
struct termiox ktermx;
|
||||
if (real_tty->termiox == NULL)
|
||||
return -EINVAL;
|
||||
down_read(&real_tty->termios_rwsem);
|
||||
memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
|
||||
up_read(&real_tty->termios_rwsem);
|
||||
if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
|
||||
ret = -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
case TCGETX:
|
||||
case TCSETX:
|
||||
return set_termiox(real_tty, p, 0);
|
||||
case TCSETXW:
|
||||
return set_termiox(real_tty, p, TERMIOS_WAIT);
|
||||
case TCSETXF:
|
||||
return set_termiox(real_tty, p, TERMIOS_FLUSH);
|
||||
return -EINVAL;
|
||||
#endif
|
||||
case TIOCGSOFTCAR:
|
||||
copy_termios(real_tty, &kterm);
|
||||
|
@ -21,6 +21,7 @@ static int is_ignored(int sig)
|
||||
/**
|
||||
* tty_check_change - check for POSIX terminal changes
|
||||
* @tty: tty to check
|
||||
* @sig: signal to send
|
||||
*
|
||||
* If we try to write to, or set the state of, a terminal and we're
|
||||
* not in the foreground, send a SIGTTOU. If the signal is blocked or
|
||||
@ -83,6 +84,7 @@ void proc_clear_tty(struct task_struct *p)
|
||||
|
||||
/**
|
||||
* proc_set_tty - set the controlling terminal
|
||||
* @tty: tty structure
|
||||
*
|
||||
* Only callable by the session leader and only if it does not already have
|
||||
* a controlling terminal.
|
||||
@ -333,6 +335,7 @@ void no_tty(void)
|
||||
/**
|
||||
* tiocsctty - set controlling tty
|
||||
* @tty: tty structure
|
||||
* @file: file structure used to check permissions
|
||||
* @arg: user argument
|
||||
*
|
||||
* This ioctl is used to manage job control. It permits a session
|
||||
|
@ -135,8 +135,10 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
|
||||
raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
|
||||
}
|
||||
|
||||
static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
|
||||
/**
|
||||
* tty_ldisc_get - take a reference to an ldisc
|
||||
* @tty: tty device
|
||||
* @disc: ldisc number
|
||||
*
|
||||
* Takes a reference to a line discipline. Deals with refcounts and
|
||||
@ -155,8 +157,6 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
|
||||
* takes tty_ldiscs_lock to guard against ldisc races
|
||||
*/
|
||||
|
||||
static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
|
||||
|
||||
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
|
||||
{
|
||||
struct tty_ldisc *ld;
|
||||
@ -190,7 +190,7 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
|
||||
return ld;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_ldisc_put - release the ldisc
|
||||
*
|
||||
* Complement of tty_ldisc_get().
|
||||
@ -250,12 +250,12 @@ const struct seq_operations tty_ldiscs_seq_ops = {
|
||||
* Returns: NULL if the tty has been hungup and not re-opened with
|
||||
* a new file descriptor, otherwise valid ldisc reference
|
||||
*
|
||||
* Note: Must not be called from an IRQ/timer context. The caller
|
||||
* Note 1: Must not be called from an IRQ/timer context. The caller
|
||||
* must also be careful not to hold other locks that will deadlock
|
||||
* against a discipline change, such as an existing ldisc reference
|
||||
* (which we check for)
|
||||
*
|
||||
* Note: a file_operations routine (read/poll/write) should use this
|
||||
* Note 2: a file_operations routine (read/poll/write) should use this
|
||||
* function to wait for any ldisc lifetime events to finish.
|
||||
*/
|
||||
|
||||
@ -701,6 +701,7 @@ int tty_ldisc_reinit(struct tty_struct *tty, int disc)
|
||||
/**
|
||||
* tty_ldisc_hangup - hangup ldisc reset
|
||||
* @tty: tty being hung up
|
||||
* @reinit: whether to re-initialise the tty
|
||||
*
|
||||
* Some tty devices reset their termios when they receive a hangup
|
||||
* event. In that situation we must also switch back to N_TTY properly
|
||||
|
@ -623,7 +623,7 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
|
||||
}
|
||||
EXPORT_SYMBOL(tty_port_close_end);
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_port_close
|
||||
*
|
||||
* Caller holds tty lock
|
||||
@ -659,7 +659,7 @@ int tty_port_install(struct tty_port *port, struct tty_driver *driver,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tty_port_install);
|
||||
|
||||
/**
|
||||
/*
|
||||
* tty_port_open
|
||||
*
|
||||
* Caller holds tty lock.
|
||||
|
@ -728,9 +728,8 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
|
||||
}
|
||||
EXPORT_SYMBOL(con_copy_unimap);
|
||||
|
||||
/**
|
||||
/*
|
||||
* con_get_unimap - get the unicode map
|
||||
* @vc: the console to read from
|
||||
*
|
||||
* Read the console unicode data for this console. Called from the ioctl
|
||||
* handlers.
|
||||
|
@ -26,36 +26,34 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/consolemap.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <linux/kbd_kern.h>
|
||||
#include <linux/kbd_diacr.h>
|
||||
#include <linux/vt_kern.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kbd_diacr.h>
|
||||
#include <linux/kbd_kern.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/vt_kern.h>
|
||||
|
||||
#include <asm/irq_regs.h>
|
||||
|
||||
extern void ctrl_alt_del(void);
|
||||
|
||||
/*
|
||||
* Exported functions/variables
|
||||
*/
|
||||
|
||||
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
|
||||
#define KBD_DEFMODE (BIT(VC_REPEAT) | BIT(VC_META))
|
||||
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_PARISC)
|
||||
#include <asm/kbdleds.h>
|
||||
@ -113,10 +111,22 @@ static struct kbd_struct kbd_table[MAX_NR_CONSOLES];
|
||||
static struct kbd_struct *kbd = kbd_table;
|
||||
|
||||
/* maximum values each key_handler can handle */
|
||||
static const int max_vals[] = {
|
||||
255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
|
||||
NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
|
||||
255, NR_LOCK - 1, 255, NR_BRL - 1
|
||||
static const unsigned char max_vals[] = {
|
||||
[ KT_LATIN ] = 255,
|
||||
[ KT_FN ] = ARRAY_SIZE(func_table) - 1,
|
||||
[ KT_SPEC ] = ARRAY_SIZE(fn_handler) - 1,
|
||||
[ KT_PAD ] = NR_PAD - 1,
|
||||
[ KT_DEAD ] = NR_DEAD - 1,
|
||||
[ KT_CONS ] = 255,
|
||||
[ KT_CUR ] = 3,
|
||||
[ KT_SHIFT ] = NR_SHIFT - 1,
|
||||
[ KT_META ] = 255,
|
||||
[ KT_ASCII ] = NR_ASCII - 1,
|
||||
[ KT_LOCK ] = NR_LOCK - 1,
|
||||
[ KT_LETTER ] = 255,
|
||||
[ KT_SLOCK ] = NR_LOCK - 1,
|
||||
[ KT_DEAD2 ] = 255,
|
||||
[ KT_BRL ] = NR_BRL - 1,
|
||||
};
|
||||
|
||||
static const int NR_TYPES = ARRAY_SIZE(max_vals);
|
||||
@ -125,7 +135,7 @@ static struct input_handler kbd_handler;
|
||||
static DEFINE_SPINLOCK(kbd_event_lock);
|
||||
static DEFINE_SPINLOCK(led_lock);
|
||||
static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf' and friends */
|
||||
static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
|
||||
static DECLARE_BITMAP(key_down, KEY_CNT); /* keyboard key bitmap */
|
||||
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
|
||||
static bool dead_key_next;
|
||||
|
||||
@ -134,7 +144,7 @@ static bool npadch_active;
|
||||
static unsigned int npadch_value;
|
||||
|
||||
static unsigned int diacr;
|
||||
static char rep; /* flag telling character repeat */
|
||||
static bool rep; /* flag telling character repeat */
|
||||
|
||||
static int shift_state = 0;
|
||||
|
||||
@ -314,12 +324,9 @@ static void put_queue(struct vc_data *vc, int ch)
|
||||
tty_schedule_flip(&vc->port);
|
||||
}
|
||||
|
||||
static void puts_queue(struct vc_data *vc, char *cp)
|
||||
static void puts_queue(struct vc_data *vc, const char *cp)
|
||||
{
|
||||
while (*cp) {
|
||||
tty_insert_flip_char(&vc->port, *cp, 0);
|
||||
cp++;
|
||||
}
|
||||
tty_insert_flip_string(&vc->port, cp, strlen(cp));
|
||||
tty_schedule_flip(&vc->port);
|
||||
}
|
||||
|
||||
@ -455,9 +462,9 @@ static void fn_enter(struct vc_data *vc)
|
||||
diacr = 0;
|
||||
}
|
||||
|
||||
put_queue(vc, 13);
|
||||
put_queue(vc, '\r');
|
||||
if (vc_kbd_mode(kbd, VC_CRLF))
|
||||
put_queue(vc, 10);
|
||||
put_queue(vc, '\n');
|
||||
}
|
||||
|
||||
static void fn_caps_toggle(struct vc_data *vc)
|
||||
@ -820,7 +827,7 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
|
||||
put_queue(vc, pad_chars[value]);
|
||||
if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
|
||||
put_queue(vc, 10);
|
||||
put_queue(vc, '\n');
|
||||
}
|
||||
|
||||
static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
@ -850,9 +857,9 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
shift_down[value]++;
|
||||
|
||||
if (shift_down[value])
|
||||
shift_state |= (1 << value);
|
||||
shift_state |= BIT(value);
|
||||
else
|
||||
shift_state &= ~(1 << value);
|
||||
shift_state &= ~BIT(value);
|
||||
|
||||
/* kludge */
|
||||
if (up_flag && shift_state != old_state && npadch_active) {
|
||||
@ -873,7 +880,7 @@ static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
put_queue(vc, '\033');
|
||||
put_queue(vc, value);
|
||||
} else
|
||||
put_queue(vc, value | 0x80);
|
||||
put_queue(vc, value | BIT(7));
|
||||
}
|
||||
|
||||
static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
@ -969,7 +976,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
return;
|
||||
|
||||
if (!up_flag) {
|
||||
pressed |= 1 << (value - 1);
|
||||
pressed |= BIT(value - 1);
|
||||
if (!brl_timeout)
|
||||
committing = pressed;
|
||||
} else if (brl_timeout) {
|
||||
@ -979,7 +986,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
committing = pressed;
|
||||
releasestart = jiffies;
|
||||
}
|
||||
pressed &= ~(1 << (value - 1));
|
||||
pressed &= ~BIT(value - 1);
|
||||
if (!pressed && committing) {
|
||||
k_brlcommit(vc, committing, 0);
|
||||
committing = 0;
|
||||
@ -989,7 +996,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
k_brlcommit(vc, committing, 0);
|
||||
committing = 0;
|
||||
}
|
||||
pressed &= ~(1 << (value - 1));
|
||||
pressed &= ~BIT(value - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1089,9 +1096,9 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
|
||||
unsigned int leds = *(unsigned int *)data;
|
||||
|
||||
if (test_bit(EV_LED, handle->dev->evbit)) {
|
||||
input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
|
||||
input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
|
||||
input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
|
||||
input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & BIT(0)));
|
||||
input_inject_event(handle, EV_LED, LED_NUML, !!(leds & BIT(1)));
|
||||
input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & BIT(2)));
|
||||
input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
@ -1249,8 +1256,14 @@ DECLARE_TASKLET_DISABLED_OLD(keyboard_tasklet, kbd_bh);
|
||||
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
|
||||
(defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
|
||||
|
||||
#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
|
||||
((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
|
||||
static inline bool kbd_is_hw_raw(const struct input_dev *dev)
|
||||
{
|
||||
if (!test_bit(EV_MSC, dev->evbit) || !test_bit(MSC_RAW, dev->mscbit))
|
||||
return false;
|
||||
|
||||
return dev->id.bustype == BUS_I8042 &&
|
||||
dev->id.vendor == 0x0001 && dev->id.product == 0x0001;
|
||||
}
|
||||
|
||||
static const unsigned short x86_keycodes[256] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
@ -1335,7 +1348,10 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
|
||||
|
||||
#else
|
||||
|
||||
#define HW_RAW(dev) 0
|
||||
static inline bool kbd_is_hw_raw(const struct input_dev *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
|
||||
{
|
||||
@ -1356,7 +1372,7 @@ static void kbd_rawcode(unsigned char data)
|
||||
put_queue(vc, data);
|
||||
}
|
||||
|
||||
static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
|
||||
static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
|
||||
{
|
||||
struct vc_data *vc = vc_cons[fg_console].d;
|
||||
unsigned short keysym, *key_map;
|
||||
@ -1411,16 +1427,13 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
|
||||
put_queue(vc, keycode | (!down << 7));
|
||||
} else {
|
||||
put_queue(vc, !down << 7);
|
||||
put_queue(vc, (keycode >> 7) | 0x80);
|
||||
put_queue(vc, keycode | 0x80);
|
||||
put_queue(vc, (keycode >> 7) | BIT(7));
|
||||
put_queue(vc, keycode | BIT(7));
|
||||
}
|
||||
raw_mode = true;
|
||||
}
|
||||
|
||||
if (down)
|
||||
set_bit(keycode, key_down);
|
||||
else
|
||||
clear_bit(keycode, key_down);
|
||||
assign_bit(keycode, key_down, down);
|
||||
|
||||
if (rep &&
|
||||
(!vc_kbd_mode(kbd, VC_REPEAT) ||
|
||||
@ -1471,7 +1484,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
|
||||
if (type == KT_LETTER) {
|
||||
type = KT_LATIN;
|
||||
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
|
||||
key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
|
||||
key_map = key_maps[shift_final ^ BIT(KG_SHIFT)];
|
||||
if (key_map)
|
||||
keysym = key_map[keycode];
|
||||
}
|
||||
@ -1501,10 +1514,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
|
||||
/* We are called with interrupts disabled, just take the lock */
|
||||
spin_lock(&kbd_event_lock);
|
||||
|
||||
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
|
||||
if (event_type == EV_MSC && event_code == MSC_RAW &&
|
||||
kbd_is_hw_raw(handle->dev))
|
||||
kbd_rawcode(value);
|
||||
if (event_type == EV_KEY && event_code <= KEY_MAX)
|
||||
kbd_keycode(event_code, value, HW_RAW(handle->dev));
|
||||
kbd_keycode(event_code, value, kbd_is_hw_raw(handle->dev));
|
||||
|
||||
spin_unlock(&kbd_event_lock);
|
||||
|
||||
@ -1515,18 +1529,16 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
|
||||
|
||||
static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (test_bit(EV_SND, dev->evbit))
|
||||
return true;
|
||||
|
||||
if (test_bit(EV_KEY, dev->evbit)) {
|
||||
for (i = KEY_RESERVED; i < BTN_MISC; i++)
|
||||
if (test_bit(i, dev->keybit))
|
||||
return true;
|
||||
for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
|
||||
if (test_bit(i, dev->keybit))
|
||||
return true;
|
||||
if (find_next_bit(dev->keybit, BTN_MISC, KEY_RESERVED) <
|
||||
BTN_MISC)
|
||||
return true;
|
||||
if (find_next_bit(dev->keybit, KEY_BRL_DOT10 + 1,
|
||||
KEY_BRL_DOT1) <= KEY_BRL_DOT10)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1887,239 +1899,191 @@ int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
|
||||
return kc;
|
||||
}
|
||||
|
||||
#define i (tmp.kb_index)
|
||||
#define s (tmp.kb_table)
|
||||
#define v (tmp.kb_value)
|
||||
static unsigned short vt_kdgkbent(unsigned char kbdmode, unsigned char idx,
|
||||
unsigned char map)
|
||||
{
|
||||
unsigned short *key_map, val;
|
||||
unsigned long flags;
|
||||
|
||||
/* Ensure another thread doesn't free it under us */
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
key_map = key_maps[map];
|
||||
if (key_map) {
|
||||
val = U(key_map[idx]);
|
||||
if (kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
|
||||
val = K_HOLE;
|
||||
} else
|
||||
val = idx ? K_HOLE : K_NOSUCHMAP;
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int vt_kdskbent(unsigned char kbdmode, unsigned char idx,
|
||||
unsigned char map, unsigned short val)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short *key_map, *new_map, oldval;
|
||||
|
||||
if (!idx && val == K_NOSUCHMAP) {
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
/* deallocate map */
|
||||
key_map = key_maps[map];
|
||||
if (map && key_map) {
|
||||
key_maps[map] = NULL;
|
||||
if (key_map[0] == U(K_ALLOCATED)) {
|
||||
kfree(key_map);
|
||||
keymap_count--;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (KTYP(val) < NR_TYPES) {
|
||||
if (KVAL(val) > max_vals[KTYP(val)])
|
||||
return -EINVAL;
|
||||
} else if (kbdmode != VC_UNICODE)
|
||||
return -EINVAL;
|
||||
|
||||
/* ++Geert: non-PC keyboards may generate keycode zero */
|
||||
#if !defined(__mc68000__) && !defined(__powerpc__)
|
||||
/* assignment to entry 0 only tests validity of args */
|
||||
if (!idx)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
|
||||
if (!new_map)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
key_map = key_maps[map];
|
||||
if (key_map == NULL) {
|
||||
int j;
|
||||
|
||||
if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
|
||||
!capable(CAP_SYS_RESOURCE)) {
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
kfree(new_map);
|
||||
return -EPERM;
|
||||
}
|
||||
key_maps[map] = new_map;
|
||||
key_map = new_map;
|
||||
key_map[0] = U(K_ALLOCATED);
|
||||
for (j = 1; j < NR_KEYS; j++)
|
||||
key_map[j] = U(K_HOLE);
|
||||
keymap_count++;
|
||||
} else
|
||||
kfree(new_map);
|
||||
|
||||
oldval = U(key_map[idx]);
|
||||
if (val == oldval)
|
||||
goto out;
|
||||
|
||||
/* Attention Key */
|
||||
if ((oldval == K_SAK || val == K_SAK) && !capable(CAP_SYS_ADMIN)) {
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
key_map[idx] = U(val);
|
||||
if (!map && (KTYP(oldval) == KT_SHIFT || KTYP(val) == KT_SHIFT))
|
||||
do_compute_shiftstate();
|
||||
out:
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
|
||||
int console)
|
||||
{
|
||||
struct kbd_struct *kb = kbd_table + console;
|
||||
struct kbentry tmp;
|
||||
ushort *key_map, *new_map, val, ov;
|
||||
unsigned long flags;
|
||||
struct kbentry kbe;
|
||||
|
||||
if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
|
||||
if (copy_from_user(&kbe, user_kbe, sizeof(struct kbentry)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!capable(CAP_SYS_TTY_CONFIG))
|
||||
perm = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case KDGKBENT:
|
||||
/* Ensure another thread doesn't free it under us */
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
key_map = key_maps[s];
|
||||
if (key_map) {
|
||||
val = U(key_map[i]);
|
||||
if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
|
||||
val = K_HOLE;
|
||||
} else
|
||||
val = (i ? K_HOLE : K_NOSUCHMAP);
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
return put_user(val, &user_kbe->kb_value);
|
||||
return put_user(vt_kdgkbent(kb->kbdmode, kbe.kb_index,
|
||||
kbe.kb_table),
|
||||
&user_kbe->kb_value);
|
||||
case KDSKBENT:
|
||||
if (!perm)
|
||||
if (!perm || !capable(CAP_SYS_TTY_CONFIG))
|
||||
return -EPERM;
|
||||
if (!i && v == K_NOSUCHMAP) {
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
/* deallocate map */
|
||||
key_map = key_maps[s];
|
||||
if (s && key_map) {
|
||||
key_maps[s] = NULL;
|
||||
if (key_map[0] == U(K_ALLOCATED)) {
|
||||
kfree(key_map);
|
||||
keymap_count--;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
if (KTYP(v) < NR_TYPES) {
|
||||
if (KVAL(v) > max_vals[KTYP(v)])
|
||||
return -EINVAL;
|
||||
} else
|
||||
if (kb->kbdmode != VC_UNICODE)
|
||||
return -EINVAL;
|
||||
|
||||
/* ++Geert: non-PC keyboards may generate keycode zero */
|
||||
#if !defined(__mc68000__) && !defined(__powerpc__)
|
||||
/* assignment to entry 0 only tests validity of args */
|
||||
if (!i)
|
||||
break;
|
||||
#endif
|
||||
|
||||
new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
|
||||
if (!new_map)
|
||||
return -ENOMEM;
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
key_map = key_maps[s];
|
||||
if (key_map == NULL) {
|
||||
int j;
|
||||
|
||||
if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
|
||||
!capable(CAP_SYS_RESOURCE)) {
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
kfree(new_map);
|
||||
return -EPERM;
|
||||
}
|
||||
key_maps[s] = new_map;
|
||||
key_map = new_map;
|
||||
key_map[0] = U(K_ALLOCATED);
|
||||
for (j = 1; j < NR_KEYS; j++)
|
||||
key_map[j] = U(K_HOLE);
|
||||
keymap_count++;
|
||||
} else
|
||||
kfree(new_map);
|
||||
|
||||
ov = U(key_map[i]);
|
||||
if (v == ov)
|
||||
goto out;
|
||||
/*
|
||||
* Attention Key.
|
||||
*/
|
||||
if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
return -EPERM;
|
||||
}
|
||||
key_map[i] = U(v);
|
||||
if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
|
||||
do_compute_shiftstate();
|
||||
out:
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
break;
|
||||
return vt_kdskbent(kb->kbdmode, kbe.kb_index, kbe.kb_table,
|
||||
kbe.kb_value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#undef i
|
||||
#undef s
|
||||
#undef v
|
||||
|
||||
/* FIXME: This one needs untangling */
|
||||
static char *vt_kdskbsent(char *kbs, unsigned char cur)
|
||||
{
|
||||
static DECLARE_BITMAP(is_kmalloc, MAX_NR_FUNC);
|
||||
char *cur_f = func_table[cur];
|
||||
|
||||
if (cur_f && strlen(cur_f) >= strlen(kbs)) {
|
||||
strcpy(cur_f, kbs);
|
||||
return kbs;
|
||||
}
|
||||
|
||||
func_table[cur] = kbs;
|
||||
|
||||
return __test_and_set_bit(cur, is_kmalloc) ? cur_f : NULL;
|
||||
}
|
||||
|
||||
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
|
||||
{
|
||||
struct kbsentry *kbs;
|
||||
u_char *q;
|
||||
int sz, fnw_sz;
|
||||
int delta;
|
||||
char *first_free, *fj, *fnw;
|
||||
int i, j, k;
|
||||
int ret;
|
||||
unsigned char kb_func;
|
||||
unsigned long flags;
|
||||
char *kbs;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_TTY_CONFIG))
|
||||
perm = 0;
|
||||
if (get_user(kb_func, &user_kdgkb->kb_func))
|
||||
return -EFAULT;
|
||||
|
||||
kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
|
||||
if (!kbs) {
|
||||
ret = -ENOMEM;
|
||||
goto reterr;
|
||||
}
|
||||
|
||||
/* we mostly copy too much here (512bytes), but who cares ;) */
|
||||
if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
|
||||
ret = -EFAULT;
|
||||
goto reterr;
|
||||
}
|
||||
kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
|
||||
i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
|
||||
kb_func = array_index_nospec(kb_func, MAX_NR_FUNC);
|
||||
|
||||
switch (cmd) {
|
||||
case KDGKBSENT: {
|
||||
/* size should have been a struct member */
|
||||
ssize_t len = sizeof(user_kdgkb->kb_string);
|
||||
|
||||
kbs = kmalloc(len, GFP_KERNEL);
|
||||
if (!kbs)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_irqsave(&func_buf_lock, flags);
|
||||
len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
|
||||
len = strlcpy(kbs, func_table[kb_func] ? : "", len);
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
|
||||
ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
|
||||
len + 1) ? -EFAULT : 0;
|
||||
ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ?
|
||||
-EFAULT : 0;
|
||||
|
||||
goto reterr;
|
||||
}
|
||||
case KDSKBSENT:
|
||||
if (!perm) {
|
||||
ret = -EPERM;
|
||||
goto reterr;
|
||||
}
|
||||
|
||||
fnw = NULL;
|
||||
fnw_sz = 0;
|
||||
/* race aginst other writers */
|
||||
again:
|
||||
spin_lock_irqsave(&func_buf_lock, flags);
|
||||
q = func_table[i];
|
||||
|
||||
/* fj pointer to next entry after 'q' */
|
||||
first_free = funcbufptr + (funcbufsize - funcbufleft);
|
||||
for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
|
||||
;
|
||||
if (j < MAX_NR_FUNC)
|
||||
fj = func_table[j];
|
||||
else
|
||||
fj = first_free;
|
||||
/* buffer usage increase by new entry */
|
||||
delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
|
||||
|
||||
if (delta <= funcbufleft) { /* it fits in current buf */
|
||||
if (j < MAX_NR_FUNC) {
|
||||
/* make enough space for new entry at 'fj' */
|
||||
memmove(fj + delta, fj, first_free - fj);
|
||||
for (k = j; k < MAX_NR_FUNC; k++)
|
||||
if (func_table[k])
|
||||
func_table[k] += delta;
|
||||
}
|
||||
if (!q)
|
||||
func_table[i] = fj;
|
||||
funcbufleft -= delta;
|
||||
} else { /* allocate a larger buffer */
|
||||
sz = 256;
|
||||
while (sz < funcbufsize - funcbufleft + delta)
|
||||
sz <<= 1;
|
||||
if (fnw_sz != sz) {
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
kfree(fnw);
|
||||
fnw = kmalloc(sz, GFP_KERNEL);
|
||||
fnw_sz = sz;
|
||||
if (!fnw) {
|
||||
ret = -ENOMEM;
|
||||
goto reterr;
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (!q)
|
||||
func_table[i] = fj;
|
||||
/* copy data before insertion point to new location */
|
||||
if (fj > funcbufptr)
|
||||
memmove(fnw, funcbufptr, fj - funcbufptr);
|
||||
for (k = 0; k < j; k++)
|
||||
if (func_table[k])
|
||||
func_table[k] = fnw + (func_table[k] - funcbufptr);
|
||||
|
||||
/* copy data after insertion point to new location */
|
||||
if (first_free > fj) {
|
||||
memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
|
||||
for (k = j; k < MAX_NR_FUNC; k++)
|
||||
if (func_table[k])
|
||||
func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
|
||||
}
|
||||
if (funcbufptr != func_buf)
|
||||
kfree(funcbufptr);
|
||||
funcbufptr = fnw;
|
||||
funcbufleft = funcbufleft - delta + sz - funcbufsize;
|
||||
funcbufsize = sz;
|
||||
}
|
||||
/* finally insert item itself */
|
||||
strcpy(func_table[i], kbs->kb_string);
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
reterr:
|
||||
case KDSKBSENT:
|
||||
if (!perm || !capable(CAP_SYS_TTY_CONFIG))
|
||||
return -EPERM;
|
||||
|
||||
kbs = strndup_user(user_kdgkb->kb_string,
|
||||
sizeof(user_kdgkb->kb_string));
|
||||
if (IS_ERR(kbs))
|
||||
return PTR_ERR(kbs);
|
||||
|
||||
spin_lock_irqsave(&func_buf_lock, flags);
|
||||
kbs = vt_kdskbsent(kbs, kb_func);
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(kbs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -596,12 +596,12 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
|
||||
return con_font_op(vc, &op);
|
||||
|
||||
case PIO_CMAP:
|
||||
if (!perm)
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
return con_set_cmap(up);
|
||||
|
||||
case GIO_CMAP:
|
||||
return con_get_cmap(up);
|
||||
return con_get_cmap(up);
|
||||
|
||||
case PIO_FONTX:
|
||||
if (!perm)
|
||||
|
@ -13,9 +13,9 @@ static inline void gf_write_ptr(const void *ptr, void __iomem *portl,
|
||||
{
|
||||
const unsigned long addr = (unsigned long)ptr;
|
||||
|
||||
writel(lower_32_bits(addr), portl);
|
||||
__raw_writel(lower_32_bits(addr), portl);
|
||||
#ifdef CONFIG_64BIT
|
||||
writel(upper_32_bits(addr), porth);
|
||||
__raw_writel(upper_32_bits(addr), porth);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -23,9 +23,9 @@ static inline void gf_write_dma_addr(const dma_addr_t addr,
|
||||
void __iomem *portl,
|
||||
void __iomem *porth)
|
||||
{
|
||||
writel(lower_32_bits(addr), portl);
|
||||
__raw_writel(lower_32_bits(addr), portl);
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
writel(upper_32_bits(addr), porth);
|
||||
__raw_writel(upper_32_bits(addr), porth);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,6 @@
|
||||
extern struct tasklet_struct keyboard_tasklet;
|
||||
|
||||
extern char *func_table[MAX_NR_FUNC];
|
||||
extern char func_buf[];
|
||||
extern char *funcbufptr;
|
||||
extern int funcbufsize, funcbufleft;
|
||||
|
||||
/*
|
||||
* kbd->xxx contains the VC-local things (flag settings etc..)
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
|
||||
*/
|
||||
|
||||
#ifndef ASMARM_ARCH_UART_H
|
||||
#define ASMARM_ARCH_UART_H
|
||||
|
||||
#define IMXUART_HAVE_RTSCTS (1<<0)
|
||||
|
||||
struct imxuart_platform_data {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#endif
|
@ -187,4 +187,9 @@ extern void serial8250_set_isa_configurator(void (*v)
|
||||
(int port, struct uart_port *up,
|
||||
u32 *capabilities));
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RT288X
|
||||
unsigned int au_serial_in(struct uart_port *p, int offset);
|
||||
void au_serial_out(struct uart_port *p, int offset, int value);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -357,8 +357,8 @@ struct earlycon_id {
|
||||
int (*setup)(struct earlycon_device *, const char *options);
|
||||
};
|
||||
|
||||
extern const struct earlycon_id *__earlycon_table[];
|
||||
extern const struct earlycon_id *__earlycon_table_end[];
|
||||
extern const struct earlycon_id __earlycon_table[];
|
||||
extern const struct earlycon_id __earlycon_table_end[];
|
||||
|
||||
#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
|
||||
#define EARLYCON_USED_OR_UNUSED __used
|
||||
@ -366,19 +366,13 @@ extern const struct earlycon_id *__earlycon_table_end[];
|
||||
#define EARLYCON_USED_OR_UNUSED __maybe_unused
|
||||
#endif
|
||||
|
||||
#define _OF_EARLYCON_DECLARE(_name, compat, fn, unique_id) \
|
||||
static const struct earlycon_id unique_id \
|
||||
EARLYCON_USED_OR_UNUSED __initconst \
|
||||
#define OF_EARLYCON_DECLARE(_name, compat, fn) \
|
||||
static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
|
||||
EARLYCON_USED_OR_UNUSED __section("__earlycon_table") \
|
||||
__aligned(__alignof__(struct earlycon_id)) \
|
||||
= { .name = __stringify(_name), \
|
||||
.compatible = compat, \
|
||||
.setup = fn }; \
|
||||
static const struct earlycon_id EARLYCON_USED_OR_UNUSED \
|
||||
__section("__earlycon_table") \
|
||||
* const __PASTE(__p, unique_id) = &unique_id
|
||||
|
||||
#define OF_EARLYCON_DECLARE(_name, compat, fn) \
|
||||
_OF_EARLYCON_DECLARE(_name, compat, fn, \
|
||||
__UNIQUE_ID(__earlycon_##_name))
|
||||
.setup = fn }
|
||||
|
||||
#define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn)
|
||||
|
||||
|
@ -1,67 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Embedded Alley Solutions, source@embeddedalley.com.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SERIAL_PNX8XXX_H
|
||||
#define _LINUX_SERIAL_PNX8XXX_H
|
||||
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
#define PNX8XXX_NR_PORTS 2
|
||||
|
||||
struct pnx8xxx_port {
|
||||
struct uart_port port;
|
||||
struct timer_list timer;
|
||||
unsigned int old_status;
|
||||
};
|
||||
|
||||
/* register offsets */
|
||||
#define PNX8XXX_LCR 0
|
||||
#define PNX8XXX_MCR 0x004
|
||||
#define PNX8XXX_BAUD 0x008
|
||||
#define PNX8XXX_CFG 0x00c
|
||||
#define PNX8XXX_FIFO 0x028
|
||||
#define PNX8XXX_ISTAT 0xfe0
|
||||
#define PNX8XXX_IEN 0xfe4
|
||||
#define PNX8XXX_ICLR 0xfe8
|
||||
#define PNX8XXX_ISET 0xfec
|
||||
#define PNX8XXX_PD 0xff4
|
||||
#define PNX8XXX_MID 0xffc
|
||||
|
||||
#define PNX8XXX_UART_LCR_TXBREAK (1<<30)
|
||||
#define PNX8XXX_UART_LCR_PAREVN 0x10000000
|
||||
#define PNX8XXX_UART_LCR_PAREN 0x08000000
|
||||
#define PNX8XXX_UART_LCR_2STOPB 0x04000000
|
||||
#define PNX8XXX_UART_LCR_8BIT 0x01000000
|
||||
#define PNX8XXX_UART_LCR_TX_RST 0x00040000
|
||||
#define PNX8XXX_UART_LCR_RX_RST 0x00020000
|
||||
#define PNX8XXX_UART_LCR_RX_NEXT 0x00010000
|
||||
|
||||
#define PNX8XXX_UART_MCR_SCR 0xFF000000
|
||||
#define PNX8XXX_UART_MCR_DCD 0x00800000
|
||||
#define PNX8XXX_UART_MCR_CTS 0x00100000
|
||||
#define PNX8XXX_UART_MCR_LOOP 0x00000010
|
||||
#define PNX8XXX_UART_MCR_RTS 0x00000002
|
||||
#define PNX8XXX_UART_MCR_DTR 0x00000001
|
||||
|
||||
#define PNX8XXX_UART_INT_TX 0x00000080
|
||||
#define PNX8XXX_UART_INT_EMPTY 0x00000040
|
||||
#define PNX8XXX_UART_INT_RCVTO 0x00000020
|
||||
#define PNX8XXX_UART_INT_RX 0x00000010
|
||||
#define PNX8XXX_UART_INT_RXOVRN 0x00000008
|
||||
#define PNX8XXX_UART_INT_FRERR 0x00000004
|
||||
#define PNX8XXX_UART_INT_BREAK 0x00000002
|
||||
#define PNX8XXX_UART_INT_PARITY 0x00000001
|
||||
#define PNX8XXX_UART_INT_ALLRX 0x0000003F
|
||||
#define PNX8XXX_UART_INT_ALLTX 0x000000C0
|
||||
|
||||
#define PNX8XXX_UART_FIFO_TXFIFO 0x001F0000
|
||||
#define PNX8XXX_UART_FIFO_TXFIFO_STA (0x1f<<16)
|
||||
#define PNX8XXX_UART_FIFO_RXBRK 0x00008000
|
||||
#define PNX8XXX_UART_FIFO_RXFE 0x00004000
|
||||
#define PNX8XXX_UART_FIFO_RXPAR 0x00002000
|
||||
#define PNX8XXX_UART_FIFO_RXFIFO 0x00001F00
|
||||
#define PNX8XXX_UART_FIFO_RBRTHR 0x000000FF
|
||||
|
||||
#endif
|
@ -303,7 +303,6 @@ struct tty_struct {
|
||||
spinlock_t flow_lock;
|
||||
/* Termios values are protected by the termios rwsem */
|
||||
struct ktermios termios, termios_locked;
|
||||
struct termiox *termiox; /* May be NULL for unsupported */
|
||||
char name[64];
|
||||
struct pid *pgrp; /* Protected by ctrl lock */
|
||||
/*
|
||||
@ -609,82 +608,64 @@ static inline struct tty_port *tty_port_get(struct tty_port *port)
|
||||
}
|
||||
|
||||
/* If the cts flow control is enabled, return true. */
|
||||
static inline bool tty_port_cts_enabled(struct tty_port *port)
|
||||
static inline bool tty_port_cts_enabled(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_CTS_FLOW, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_cts_flow(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_CTS_FLOW, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_CTS_FLOW, &port->iflags);
|
||||
assign_bit(TTY_PORT_CTS_FLOW, &port->iflags, val);
|
||||
}
|
||||
|
||||
static inline bool tty_port_active(struct tty_port *port)
|
||||
static inline bool tty_port_active(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_ACTIVE, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_active(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_ACTIVE, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_ACTIVE, &port->iflags);
|
||||
assign_bit(TTY_PORT_ACTIVE, &port->iflags, val);
|
||||
}
|
||||
|
||||
static inline bool tty_port_check_carrier(struct tty_port *port)
|
||||
static inline bool tty_port_check_carrier(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_CHECK_CD, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_check_carrier(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_CHECK_CD, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_CHECK_CD, &port->iflags);
|
||||
assign_bit(TTY_PORT_CHECK_CD, &port->iflags, val);
|
||||
}
|
||||
|
||||
static inline bool tty_port_suspended(struct tty_port *port)
|
||||
static inline bool tty_port_suspended(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_SUSPENDED, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_suspended(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_SUSPENDED, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_SUSPENDED, &port->iflags);
|
||||
assign_bit(TTY_PORT_SUSPENDED, &port->iflags, val);
|
||||
}
|
||||
|
||||
static inline bool tty_port_initialized(struct tty_port *port)
|
||||
static inline bool tty_port_initialized(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_INITIALIZED, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_initialized(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_INITIALIZED, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_INITIALIZED, &port->iflags);
|
||||
assign_bit(TTY_PORT_INITIALIZED, &port->iflags, val);
|
||||
}
|
||||
|
||||
static inline bool tty_port_kopened(struct tty_port *port)
|
||||
static inline bool tty_port_kopened(const struct tty_port *port)
|
||||
{
|
||||
return test_bit(TTY_PORT_KOPENED, &port->iflags);
|
||||
}
|
||||
|
||||
static inline void tty_port_set_kopened(struct tty_port *port, bool val)
|
||||
{
|
||||
if (val)
|
||||
set_bit(TTY_PORT_KOPENED, &port->iflags);
|
||||
else
|
||||
clear_bit(TTY_PORT_KOPENED, &port->iflags);
|
||||
assign_bit(TTY_PORT_KOPENED, &port->iflags, val);
|
||||
}
|
||||
|
||||
extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
|
||||
@ -720,6 +701,7 @@ extern int __must_check tty_ldisc_init(struct tty_struct *tty);
|
||||
extern void tty_ldisc_deinit(struct tty_struct *tty);
|
||||
extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
|
||||
char *f, int count);
|
||||
extern void tty_sysctl_init(void);
|
||||
|
||||
/* n_tty.c */
|
||||
extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops);
|
||||
|
@ -224,14 +224,6 @@
|
||||
* line). See tty_do_resize() if you need to wrap the standard method
|
||||
* in your own logic - the usual case.
|
||||
*
|
||||
* void (*set_termiox)(struct tty_struct *tty, struct termiox *new);
|
||||
*
|
||||
* Called when the device receives a termiox based ioctl. Passes down
|
||||
* the requested data from user space. This method will not be invoked
|
||||
* unless the tty also has a valid tty->termiox pointer.
|
||||
*
|
||||
* Optional: Called under the termios lock
|
||||
*
|
||||
* int (*get_icount)(struct tty_struct *tty, struct serial_icounter *icount);
|
||||
*
|
||||
* Called when the device receives a TIOCGICOUNT ioctl. Passed a kernel
|
||||
@ -285,7 +277,6 @@ struct tty_operations {
|
||||
int (*tiocmset)(struct tty_struct *tty,
|
||||
unsigned int set, unsigned int clear);
|
||||
int (*resize)(struct tty_struct *tty, struct winsize *ws);
|
||||
int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
|
||||
int (*get_icount)(struct tty_struct *tty,
|
||||
struct serial_icounter_struct *icount);
|
||||
int (*get_serial)(struct tty_struct *tty, struct serial_struct *p);
|
||||
|
@ -27,7 +27,6 @@
|
||||
#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
|
||||
|
||||
#define KT_LATIN 0 /* we depend on this being zero */
|
||||
#define KT_LETTER 11 /* symbol that can be acted upon by CapsLock */
|
||||
#define KT_FN 1
|
||||
#define KT_SPEC 2
|
||||
#define KT_PAD 3
|
||||
@ -38,6 +37,7 @@
|
||||
#define KT_META 8
|
||||
#define KT_ASCII 9
|
||||
#define KT_LOCK 10
|
||||
#define KT_LETTER 11 /* symbol that can be acted upon by CapsLock */
|
||||
#define KT_SLOCK 12
|
||||
#define KT_DEAD2 13
|
||||
#define KT_BRL 14
|
||||
|
@ -134,8 +134,6 @@
|
||||
/*Digi jsm */
|
||||
#define PORT_JSM 69
|
||||
|
||||
#define PORT_PNX8XXX 70
|
||||
|
||||
/* SUN4V Hypervisor Console */
|
||||
#define PORT_SUNHV 72
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user