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:
Linus Torvalds 2020-12-15 13:57:14 -08:00
commit 157f809894
67 changed files with 476 additions and 15098 deletions

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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];

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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 = {

View File

@ -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>
*/

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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 },
{},
};

View File

@ -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))

View File

@ -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) {

View File

@ -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.

View File

@ -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,

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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, &regcfg);
@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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");

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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)) {

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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
*

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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)

View File

@ -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
}

View File

@ -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..)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -134,8 +134,6 @@
/*Digi jsm */
#define PORT_JSM 69
#define PORT_PNX8XXX 70
/* SUN4V Hypervisor Console */
#define PORT_SUNHV 72