TTY/Serial patches for 5.5-rc1

Here is the "big" tty and serial driver patches for 5.5-rc1.  It's a bit
 later in the merge window than normal as I wanted to make sure some
 last-minute patches applied to it were all sane.  They seem to be :)
 
 There's a lot of little stuff in here, for the tty core, and for lots of
 serial drivers:
 	- reverts of uartlite serial driver patches that were wrong
 	- msm-serial driver fixes
 	- serial core updates and fixes
 	- tty core fixes
 	- serial driver dma mapping api changes
 	- lots of other tiny fixes and updates for serial drivers
 
 All of these have been in linux-next for a while with no reported
 issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXebFIQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylnmACgjfMcfQWa7uC9Q6m2DaQaRMaW6QoAnjg+TgBB
 eW9EhvyXL2VbrsuUl+iH
 =Am9O
 -----END PGP SIGNATURE-----

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

Pull tty/serial updates from Greg KH:
 "Here is the "big" tty and serial driver patches for 5.5-rc1.

  It's a bit later in the merge window than normal as I wanted to make
  sure some last-minute patches applied to it were all sane. They seem
  to be :)

  There's a lot of little stuff in here, for the tty core, and for lots
  of serial drivers:

   - reverts of uartlite serial driver patches that were wrong

   - msm-serial driver fixes

   - serial core updates and fixes

   - tty core fixes

   - serial driver dma mapping api changes

   - lots of other tiny fixes and updates for serial drivers

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (58 commits)
  Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices"
  vcs: prevent write access to vcsu devices
  tty: vt: keyboard: reject invalid keycodes
  tty: don't crash in tty_init_dev when missing tty_port
  serial: stm32: fix clearing interrupt error flags
  tty: Fix Kconfig indentation, continued
  serial: serial_core: Perform NULL checks for break_ctl ops
  tty: remove unused argument from tty_open_by_driver()
  tty: Fix Kconfig indentation
  {tty: serial, nand: onenand}: samsung: rename to fix build warning
  serial: ifx6x60: add missed pm_runtime_disable
  serial: pl011: Fix DMA ->flush_buffer()
  Revert "serial-uartlite: Move the uart register"
  Revert "serial-uartlite: Add get serial id if not provided"
  Revert "serial-uartlite: Do not use static struct uart_driver out of probe()"
  Revert "serial-uartlite: Add runtime support"
  Revert "serial-uartlite: Change logic how console_port is setup"
  Revert "serial-uartlite: Use allocated structure instead of static ones"
  tty: serial: msm_serial: Use dma_request_chan() directly for channel request
  tty: serial: tegra: Use dma_request_chan() directly for channel request
  ...
This commit is contained in:
Linus Torvalds 2019-12-03 14:09:14 -08:00
Родитель c3bed3b20e 27ed14d0ec
Коммит 537bd0a159
49 изменённых файлов: 665 добавлений и 715 удалений

Просмотреть файл

@ -6,10 +6,19 @@ Description: Configures which IO port the host side of the UART
Users: OpenBMC. Proposed changes should be mailed to Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org openbmc@lists.ozlabs.org
What: /sys/bus/platform/drivers/aspeed-vuart*/sirq What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq
Date: April 2017 Date: April 2017
Contact: Jeremy Kerr <jk@ozlabs.org> Contact: Jeremy Kerr <jk@ozlabs.org>
Description: Configures which interrupt number the host side of Description: Configures which interrupt number the host side of
the UART will appear on the host <-> BMC LPC bus. the UART will appear on the host <-> BMC LPC bus.
Users: OpenBMC. Proposed changes should be mailed to Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org openbmc@lists.ozlabs.org
What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq_polarity
Date: July 2019
Contact: Oskar Senft <osk@google.com>
Description: Configures the polarity of the serial interrupt to the
host via the BMC LPC bus.
Set to 0 for active-low or 1 for active-high.
Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org

Просмотреть файл

@ -1097,7 +1097,7 @@
mapped with the correct attributes. mapped with the correct attributes.
linflex,<addr> linflex,<addr>
Use early console provided by Freescale LinFlex UART Use early console provided by Freescale LINFlexD UART
serial driver for NXP S32V234 SoCs. A valid base serial driver for NXP S32V234 SoCs. A valid base
address must be provided, and the serial port must address must be provided, and the serial port must
already be setup and configured. already be setup and configured.

Просмотреть файл

@ -56,6 +56,11 @@ Optional properties:
- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
line respectively. It will use specified GPIO instead of the peripheral line respectively. It will use specified GPIO instead of the peripheral
function pin for the UART feature. If unsure, don't specify this property. function pin for the UART feature. If unsure, don't specify this property.
- aspeed,sirq-polarity-sense: Only applicable to aspeed,ast2500-vuart.
phandle to aspeed,ast2500-scu compatible syscon alongside register offset
and bit number to identify how the SIRQ polarity should be configured.
One possible data source is the LPC/eSPI mode bit.
Example: aspeed,sirq-polarity-sense = <&syscon 0x70 25>
Note: Note:
* fsl,ns16550: * fsl,ns16550:

Просмотреть файл

@ -21,8 +21,7 @@ Required properties:
Optional properties: Optional properties:
- dmas: A list of two dma specifiers, one for each entry in dma-names. - dmas: A list of two dma specifiers, one for each entry in dma-names.
- dma-names: should contain "tx" and "rx". - dma-names: should contain "tx" and "rx".
- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx, - rs485-rts-active-low, linux,rs485-enabled-at-boot-time: see rs485.txt
linux,rs485-enabled-at-boot-time: see rs485.txt
Note: Optional properties for DMA support. Write them both or both not. Note: Optional properties for DMA support. Write them both or both not.

Просмотреть файл

@ -54,8 +54,10 @@ Required properties:
- "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART.
- "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART. - "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART.
- "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART.
- "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. - "renesas,scif-r8a7796" for R8A77960 (R-Car M3-W) SCIF compatible UART.
- "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. - "renesas,hscif-r8a7796" for R8A77960 (R-Car M3-W) HSCIF compatible UART.
- "renesas,scif-r8a77961" for R8A77961 (R-Car M3-W+) SCIF compatible UART.
- "renesas,hscif-r8a77961" for R8A77961 (R-Car M3-W+) HSCIF compatible UART.
- "renesas,scif-r8a77965" for R8A77965 (R-Car M3-N) SCIF compatible UART. - "renesas,scif-r8a77965" for R8A77965 (R-Car M3-N) SCIF compatible UART.
- "renesas,hscif-r8a77965" for R8A77965 (R-Car M3-N) HSCIF compatible UART. - "renesas,hscif-r8a77965" for R8A77965 (R-Car M3-N) HSCIF compatible UART.
- "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART.

Просмотреть файл

@ -81,7 +81,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h`` ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c`` PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h`` PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h`` SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h`` SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c`` STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

Просмотреть файл

@ -87,7 +87,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h`` ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c`` PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h`` PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h`` SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h`` SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c`` STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

Просмотреть файл

@ -70,7 +70,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h`` ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c`` PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h`` PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h`` SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h`` SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c`` STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

Просмотреть файл

@ -379,6 +379,7 @@
interrupts = <8>; interrupts = <8>;
clocks = <&syscon ASPEED_CLK_APB>; clocks = <&syscon ASPEED_CLK_APB>;
no-loopback-test; no-loopback-test;
aspeed,sirq-polarity-sense = <&syscon 0x70 25>;
status = "disabled"; status = "disabled";
}; };

Просмотреть файл

@ -9,6 +9,6 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
# Board specific. # Board specific.
obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o
obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung.o obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung_mtd.o
onenand-objs = onenand_base.o onenand_bbt.o onenand-objs = onenand_base.o onenand_bbt.o

Просмотреть файл

@ -421,8 +421,6 @@ extern struct z8530_irqhandler z8530_sync, z8530_async, z8530_nop;
* Asynchronous Interfacing * Asynchronous Interfacing
*/ */
#define SERIAL_MAGIC 0x5301
/* /*
* The size of the serial xmit buffer is 1 page, or 4096 bytes * The size of the serial xmit buffer is 1 page, or 4096 bytes
*/ */

Просмотреть файл

@ -82,20 +82,20 @@ config HW_CONSOLE
default y default y
config VT_HW_CONSOLE_BINDING config VT_HW_CONSOLE_BINDING
bool "Support for binding and unbinding console drivers" bool "Support for binding and unbinding console drivers"
depends on HW_CONSOLE depends on HW_CONSOLE
---help--- ---help---
The virtual terminal is the device that interacts with the physical The virtual terminal is the device that interacts with the physical
terminal through console drivers. On these systems, at least one terminal through console drivers. On these systems, at least one
console driver is loaded. In other configurations, additional console console driver is loaded. In other configurations, additional console
drivers may be enabled, such as the framebuffer console. If more than drivers may be enabled, such as the framebuffer console. If more than
1 console driver is enabled, setting this to 'y' will allow you to 1 console driver is enabled, setting this to 'y' will allow you to
select the console driver that will serve as the backend for the select the console driver that will serve as the backend for the
virtual terminals. virtual terminals.
See <file:Documentation/driver-api/console.rst> for more See <file:Documentation/driver-api/console.rst> for more
information. For framebuffer console users, please refer to information. For framebuffer console users, please refer to
<file:Documentation/fb/fbcon.rst>. <file:Documentation/fb/fbcon.rst>.
config UNIX98_PTYS config UNIX98_PTYS
bool "Unix98 PTY support" if EXPERT bool "Unix98 PTY support" if EXPERT
@ -173,15 +173,15 @@ config ROCKETPORT
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
help help
This driver supports Comtrol RocketPort and RocketModem PCI boards. This driver supports Comtrol RocketPort and RocketModem PCI boards.
These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
modems. For information about the RocketPort/RocketModem boards modems. For information about the RocketPort/RocketModem boards
and this driver read <file:Documentation/driver-api/serial/rocket.rst>. and this driver read <file:Documentation/driver-api/serial/rocket.rst>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called rocket. module will be called rocket.
If you want to compile this driver into the kernel, say Y here. If If you want to compile this driver into the kernel, say Y here. If
you don't have a Comtrol RocketPort/RocketModem card installed, say N. you don't have a Comtrol RocketPort/RocketModem card installed, say N.
config CYCLADES config CYCLADES
tristate "Cyclades async mux support" tristate "Cyclades async mux support"
@ -437,8 +437,8 @@ config MIPS_EJTAG_FDC_KGDB
depends on MIPS_EJTAG_FDC_TTY && KGDB depends on MIPS_EJTAG_FDC_TTY && KGDB
default y default y
help help
This enables the use of KGDB over an FDC channel, allowing KGDB to be This enables the use of KGDB over an FDC channel, allowing KGDB to be
used remotely or when a serial port isn't available. used remotely or when a serial port isn't available.
config MIPS_EJTAG_FDC_KGDB_CHAN config MIPS_EJTAG_FDC_KGDB_CHAN
int "KGDB FDC channel" int "KGDB FDC channel"

Просмотреть файл

@ -22,18 +22,8 @@
* *
*/ */
/*
* Serial driver configuration section. Here are the various options:
*
* SERIAL_PARANOIA_CHECK
* Check the magic number for the async_structure where
* ever possible.
*/
#include <linux/delay.h> #include <linux/delay.h>
#undef SERIAL_PARANOIA_CHECK
/* Set of debugging defines */ /* Set of debugging defines */
#undef SERIAL_DEBUG_INTR #undef SERIAL_DEBUG_INTR
@ -132,28 +122,6 @@ static struct serial_state rs_table[1];
#define serial_isroot() (capable(CAP_SYS_ADMIN)) #define serial_isroot() (capable(CAP_SYS_ADMIN))
static inline int serial_paranoia_check(struct serial_state *info,
char *name, const char *routine)
{
#ifdef SERIAL_PARANOIA_CHECK
static const char *badmagic =
"Warning: bad magic number for serial struct (%s) in %s\n";
static const char *badinfo =
"Warning: null async_struct for (%s) in %s\n";
if (!info) {
printk(badinfo, name, routine);
return 1;
}
if (info->magic != SERIAL_MAGIC) {
printk(badmagic, name, routine);
return 1;
}
#endif
return 0;
}
/* some serial hardware definitions */ /* some serial hardware definitions */
#define SDR_OVRUN (1<<15) #define SDR_OVRUN (1<<15)
#define SDR_RBF (1<<14) #define SDR_RBF (1<<14)
@ -189,9 +157,6 @@ static void rs_stop(struct tty_struct *tty)
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_stop"))
return;
local_irq_save(flags); local_irq_save(flags);
if (info->IER & UART_IER_THRI) { if (info->IER & UART_IER_THRI) {
info->IER &= ~UART_IER_THRI; info->IER &= ~UART_IER_THRI;
@ -209,9 +174,6 @@ static void rs_start(struct tty_struct *tty)
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_start"))
return;
local_irq_save(flags); local_irq_save(flags);
if (info->xmit.head != info->xmit.tail if (info->xmit.head != info->xmit.tail
&& info->xmit.buf && info->xmit.buf
@ -783,9 +745,6 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch)
info = tty->driver_data; info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
return 0;
if (!info->xmit.buf) if (!info->xmit.buf)
return 0; return 0;
@ -808,9 +767,6 @@ static void rs_flush_chars(struct tty_struct *tty)
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
return;
if (info->xmit.head == info->xmit.tail if (info->xmit.head == info->xmit.tail
|| tty->stopped || tty->stopped
|| tty->hw_stopped || tty->hw_stopped
@ -833,9 +789,6 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_write"))
return 0;
if (!info->xmit.buf) if (!info->xmit.buf)
return 0; return 0;
@ -878,8 +831,6 @@ static int rs_write_room(struct tty_struct *tty)
{ {
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_write_room"))
return 0;
return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
} }
@ -887,8 +838,6 @@ static int rs_chars_in_buffer(struct tty_struct *tty)
{ {
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
return 0;
return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
} }
@ -897,8 +846,6 @@ static void rs_flush_buffer(struct tty_struct *tty)
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
return;
local_irq_save(flags); local_irq_save(flags);
info->xmit.head = info->xmit.tail = 0; info->xmit.head = info->xmit.tail = 0;
local_irq_restore(flags); local_irq_restore(flags);
@ -914,9 +861,6 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_send_xchar"))
return;
info->x_char = ch; info->x_char = ch;
if (ch) { if (ch) {
/* Make sure transmit interrupts are on */ /* Make sure transmit interrupts are on */
@ -952,9 +896,6 @@ static void rs_throttle(struct tty_struct * tty)
printk("throttle %s ....\n", tty_name(tty)); printk("throttle %s ....\n", tty_name(tty));
#endif #endif
if (serial_paranoia_check(info, tty->name, "rs_throttle"))
return;
if (I_IXOFF(tty)) if (I_IXOFF(tty))
rs_send_xchar(tty, STOP_CHAR(tty)); rs_send_xchar(tty, STOP_CHAR(tty));
@ -974,9 +915,6 @@ static void rs_unthrottle(struct tty_struct * tty)
printk("unthrottle %s ....\n", tty_name(tty)); printk("unthrottle %s ....\n", tty_name(tty));
#endif #endif
if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
return;
if (I_IXOFF(tty)) { if (I_IXOFF(tty)) {
if (info->x_char) if (info->x_char)
info->x_char = 0; info->x_char = 0;
@ -1109,8 +1047,6 @@ static int rs_tiocmget(struct tty_struct *tty)
unsigned char control, status; unsigned char control, status;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty_io_error(tty)) if (tty_io_error(tty))
return -EIO; return -EIO;
@ -1131,8 +1067,6 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty_io_error(tty)) if (tty_io_error(tty))
return -EIO; return -EIO;
@ -1155,12 +1089,8 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
*/ */
static int rs_break(struct tty_struct *tty, int break_state) static int rs_break(struct tty_struct *tty, int break_state)
{ {
struct serial_state *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_break"))
return -EINVAL;
local_irq_save(flags); local_irq_save(flags);
if (break_state == -1) if (break_state == -1)
custom.adkcon = AC_SETCLR | AC_UARTBRK; custom.adkcon = AC_SETCLR | AC_UARTBRK;
@ -1212,9 +1142,6 @@ static int rs_ioctl(struct tty_struct *tty,
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
int ret; int ret;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if ((cmd != TIOCSERCONFIG) && if ((cmd != TIOCSERCONFIG) &&
(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
if (tty_io_error(tty)) if (tty_io_error(tty))
@ -1333,9 +1260,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
struct serial_state *state = tty->driver_data; struct serial_state *state = tty->driver_data;
struct tty_port *port = &state->tport; struct tty_port *port = &state->tport;
if (serial_paranoia_check(state, tty->name, "rs_close"))
return;
if (tty_port_close_start(port, tty, filp) == 0) if (tty_port_close_start(port, tty, filp) == 0)
return; return;
@ -1379,9 +1303,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
unsigned long orig_jiffies, char_time; unsigned long orig_jiffies, char_time;
int lsr; int lsr;
if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
return;
if (info->xmit_fifo_size == 0) if (info->xmit_fifo_size == 0)
return; /* Just in case.... */ return; /* Just in case.... */
@ -1440,9 +1361,6 @@ static void rs_hangup(struct tty_struct *tty)
{ {
struct serial_state *info = tty->driver_data; struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_hangup"))
return;
rs_flush_buffer(tty); rs_flush_buffer(tty);
shutdown(tty, info); shutdown(tty, info);
info->tport.count = 0; info->tport.count = 0;
@ -1467,8 +1385,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
port->tty = tty; port->tty = tty;
tty->driver_data = info; tty->driver_data = info;
tty->port = port; tty->port = port;
if (serial_paranoia_check(info, tty->name, "rs_open"))
return -ENODEV;
port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;

Просмотреть файл

@ -70,22 +70,22 @@ config HVC_XEN_FRONTEND
Xen driver for secondary virtual consoles Xen driver for secondary virtual consoles
config HVC_UDBG config HVC_UDBG
bool "udbg based fake hypervisor console" bool "udbg based fake hypervisor console"
depends on PPC depends on PPC
select HVC_DRIVER select HVC_DRIVER
help help
This is meant to be used during HW bring up or debugging when This is meant to be used during HW bring up or debugging when
no other console mechanism exist but udbg, to get you a quick no other console mechanism exist but udbg, to get you a quick
console for userspace. Do NOT enable in production kernels. console for userspace. Do NOT enable in production kernels.
config HVC_DCC config HVC_DCC
bool "ARM JTAG DCC console" bool "ARM JTAG DCC console"
depends on ARM || ARM64 depends on ARM || ARM64
select HVC_DRIVER select HVC_DRIVER
help help
This console uses the JTAG DCC on ARM to create a console under the HVC This console uses the JTAG DCC on ARM to create a console under the HVC
driver. This console is used through a JTAG only on ARM. If you don't have driver. This console is used through a JTAG only on ARM. If you don't have
a JTAG then you probably don't want this option. a JTAG then you probably don't want this option.
config HVC_RISCV_SBI config HVC_RISCV_SBI
bool "RISC-V SBI console support" bool "RISC-V SBI console support"

Просмотреть файл

@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. */ /* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. */
#include <linux/console.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <asm/dcc.h> #include <asm/dcc.h>
#include <asm/processor.h> #include <asm/processor.h>
@ -12,6 +15,31 @@
#define DCC_STATUS_RX (1 << 30) #define DCC_STATUS_RX (1 << 30)
#define DCC_STATUS_TX (1 << 29) #define DCC_STATUS_TX (1 << 29)
static void dcc_uart_console_putchar(struct uart_port *port, int ch)
{
while (__dcc_getstatus() & DCC_STATUS_TX)
cpu_relax();
__dcc_putchar(ch);
}
static void dcc_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, n, dcc_uart_console_putchar);
}
static int __init dcc_early_console_setup(struct earlycon_device *device,
const char *opt)
{
device->con->write = dcc_early_write;
return 0;
}
EARLYCON_DECLARE(dcc, dcc_early_console_setup);
static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
{ {
int i; int i;

Просмотреть файл

@ -1222,22 +1222,28 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
*/ */
static int get_ports(struct r_port *info, struct rocket_ports __user *retports) static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
{ {
struct rocket_ports tmp; struct rocket_ports *tmp;
int board; int board, ret = 0;
memset(&tmp, 0, sizeof (tmp)); tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
tmp.tty_major = rocket_driver->major; if (!tmp)
return -ENOMEM;
tmp->tty_major = rocket_driver->major;
for (board = 0; board < 4; board++) { for (board = 0; board < 4; board++) {
tmp.rocketModel[board].model = rocketModel[board].model; tmp->rocketModel[board].model = rocketModel[board].model;
strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString); strcpy(tmp->rocketModel[board].modelString,
tmp.rocketModel[board].numPorts = rocketModel[board].numPorts; rocketModel[board].modelString);
tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2; tmp->rocketModel[board].numPorts = rocketModel[board].numPorts;
tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber; tmp->rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
tmp->rocketModel[board].startingPortNumber =
rocketModel[board].startingPortNumber;
} }
if (copy_to_user(retports, &tmp, sizeof (*retports))) if (copy_to_user(retports, tmp, sizeof(*retports)))
return -EFAULT; ret = -EFAULT;
return 0; kfree(tmp);
return ret;
} }
static int reset_rm2(struct r_port *info, void __user *arg) static int reset_rm2(struct r_port *info, void __user *arg)

Просмотреть файл

@ -552,15 +552,96 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
} }
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct serdev_device *serdev = NULL;
int err;
if (acpi_bus_get_status(adev) || !adev->status.present || #define SERDEV_ACPI_MAX_SCAN_DEPTH 32
acpi_device_enumerated(adev))
return AE_OK; struct acpi_serdev_lookup {
acpi_handle device_handle;
acpi_handle controller_handle;
int n;
int index;
};
static int acpi_serdev_parse_resource(struct acpi_resource *ares, void *data)
{
struct acpi_serdev_lookup *lookup = data;
struct acpi_resource_uart_serialbus *sb;
acpi_status status;
if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
return 1;
if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
return 1;
if (lookup->index != -1 && lookup->n++ != lookup->index)
return 1;
sb = &ares->data.uart_serial_bus;
status = acpi_get_handle(lookup->device_handle,
sb->resource_source.string_ptr,
&lookup->controller_handle);
if (ACPI_FAILURE(status))
return 1;
/*
* NOTE: Ideally, we would also want to retreive other properties here,
* once setting them before opening the device is supported by serdev.
*/
return 1;
}
static int acpi_serdev_do_lookup(struct acpi_device *adev,
struct acpi_serdev_lookup *lookup)
{
struct list_head resource_list;
int ret;
lookup->device_handle = acpi_device_handle(adev);
lookup->controller_handle = NULL;
lookup->n = 0;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
acpi_serdev_parse_resource, lookup);
acpi_dev_free_resource_list(&resource_list);
if (ret < 0)
return -EINVAL;
return 0;
}
static int acpi_serdev_check_resources(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct acpi_serdev_lookup lookup;
int ret;
if (acpi_bus_get_status(adev) || !adev->status.present)
return -EINVAL;
/* Look for UARTSerialBusV2 resource */
lookup.index = -1; // we only care for the last device
ret = acpi_serdev_do_lookup(adev, &lookup);
if (ret)
return ret;
/* Make sure controller and ResourceSource handle match */
if (ACPI_HANDLE(ctrl->dev.parent) != lookup.controller_handle)
return -ENODEV;
return 0;
}
static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct serdev_device *serdev;
int err;
serdev = serdev_device_alloc(ctrl); serdev = serdev_device_alloc(ctrl);
if (!serdev) { if (!serdev) {
@ -583,7 +664,7 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
} }
static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
void *data, void **return_value) void *data, void **return_value)
{ {
struct serdev_controller *ctrl = data; struct serdev_controller *ctrl = data;
struct acpi_device *adev; struct acpi_device *adev;
@ -591,22 +672,28 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
if (acpi_bus_get_device(handle, &adev)) if (acpi_bus_get_device(handle, &adev))
return AE_OK; return AE_OK;
if (acpi_device_enumerated(adev))
return AE_OK;
if (acpi_serdev_check_resources(ctrl, adev))
return AE_OK;
return acpi_serdev_register_device(ctrl, adev); return acpi_serdev_register_device(ctrl, adev);
} }
static int acpi_serdev_register_devices(struct serdev_controller *ctrl) static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
{ {
acpi_status status; acpi_status status;
acpi_handle handle;
handle = ACPI_HANDLE(ctrl->dev.parent); if (!has_acpi_companion(ctrl->dev.parent))
if (!handle)
return -ENODEV; return -ENODEV;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
SERDEV_ACPI_MAX_SCAN_DEPTH,
acpi_serdev_add_device, NULL, ctrl, NULL); acpi_serdev_add_device, NULL, ctrl, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
dev_dbg(&ctrl->dev, "failed to enumerate serdev slaves\n"); dev_warn(&ctrl->dev, "failed to enumerate serdev slaves\n");
if (!ctrl->serdev) if (!ctrl->serdev)
return -ENODEV; return -ENODEV;

Просмотреть файл

@ -14,6 +14,8 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#include <linux/clk.h> #include <linux/clk.h>
@ -22,6 +24,7 @@
#define ASPEED_VUART_GCRA 0x20 #define ASPEED_VUART_GCRA 0x20
#define ASPEED_VUART_GCRA_VUART_EN BIT(0) #define ASPEED_VUART_GCRA_VUART_EN BIT(0)
#define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY BIT(1)
#define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5) #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5)
#define ASPEED_VUART_GCRB 0x24 #define ASPEED_VUART_GCRB 0x24
#define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4) #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4)
@ -131,8 +134,53 @@ static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RW(sirq); static DEVICE_ATTR_RW(sirq);
static ssize_t sirq_polarity_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
u8 reg;
reg = readb(vuart->regs + ASPEED_VUART_GCRA);
reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0);
}
static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart,
bool polarity)
{
u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA);
if (polarity)
reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
else
reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
}
static ssize_t sirq_polarity_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
unsigned long val;
int err;
err = kstrtoul(buf, 0, &val);
if (err)
return err;
aspeed_vuart_set_sirq_polarity(vuart, val != 0);
return count;
}
static DEVICE_ATTR_RW(sirq_polarity);
static struct attribute *aspeed_vuart_attrs[] = { static struct attribute *aspeed_vuart_attrs[] = {
&dev_attr_sirq.attr, &dev_attr_sirq.attr,
&dev_attr_sirq_polarity.attr,
&dev_attr_lpc_address.attr, &dev_attr_lpc_address.attr,
NULL, NULL,
}; };
@ -302,8 +350,30 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
return 1; return 1;
} }
static void aspeed_vuart_auto_configure_sirq_polarity(
struct aspeed_vuart *vuart, struct device_node *syscon_np,
u32 reg_offset, u32 reg_mask)
{
struct regmap *regmap;
u32 value;
regmap = syscon_node_to_regmap(syscon_np);
if (IS_ERR(regmap)) {
dev_warn(vuart->dev,
"could not get regmap for aspeed,sirq-polarity-sense\n");
return;
}
if (regmap_read(regmap, reg_offset, &value)) {
dev_warn(vuart->dev, "could not read hw strap table\n");
return;
}
aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0);
}
static int aspeed_vuart_probe(struct platform_device *pdev) static int aspeed_vuart_probe(struct platform_device *pdev)
{ {
struct of_phandle_args sirq_polarity_sense_args;
struct uart_8250_port port; struct uart_8250_port port;
struct aspeed_vuart *vuart; struct aspeed_vuart *vuart;
struct device_node *np; struct device_node *np;
@ -402,6 +472,20 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
vuart->line = rc; vuart->line = rc;
rc = of_parse_phandle_with_fixed_args(
np, "aspeed,sirq-polarity-sense", 2, 0,
&sirq_polarity_sense_args);
if (rc < 0) {
dev_dbg(&pdev->dev,
"aspeed,sirq-polarity-sense property not found\n");
} else {
aspeed_vuart_auto_configure_sirq_polarity(
vuart, sirq_polarity_sense_args.np,
sirq_polarity_sense_args.args[0],
BIT(sirq_polarity_sense_args.args[1]));
of_node_put(sirq_polarity_sense_args.np);
}
aspeed_vuart_set_enabled(vuart, true); aspeed_vuart_set_enabled(vuart, true);
aspeed_vuart_set_host_tx_discard(vuart, true); aspeed_vuart_set_host_tx_discard(vuart, true);
platform_set_drvdata(pdev, vuart); platform_set_drvdata(pdev, vuart);

Просмотреть файл

@ -280,9 +280,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
long rate; long rate;
int ret; int ret;
if (IS_ERR(d->clk))
goto out;
clk_disable_unprepare(d->clk); clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16); rate = clk_round_rate(d->clk, baud * 16);
if (rate < 0) if (rate < 0)
@ -293,8 +290,10 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
ret = clk_set_rate(d->clk, rate); ret = clk_set_rate(d->clk, rate);
clk_prepare_enable(d->clk); clk_prepare_enable(d->clk);
if (!ret) if (ret)
p->uartclk = rate; goto out;
p->uartclk = rate;
out: out:
p->status &= ~UPSTAT_AUTOCTS; p->status &= ~UPSTAT_AUTOCTS;
@ -386,10 +385,10 @@ static int dw8250_probe(struct platform_device *pdev)
{ {
struct uart_8250_port uart = {}, *up = &uart; struct uart_8250_port uart = {}, *up = &uart;
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0);
struct uart_port *p = &up->port; struct uart_port *p = &up->port;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct dw8250_data *data; struct dw8250_data *data;
int irq;
int err; int err;
u32 val; u32 val;
@ -398,11 +397,9 @@ static int dw8250_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
if (irq < 0) { irq = platform_get_irq(pdev, 0);
if (irq != -EPROBE_DEFER) if (irq < 0)
dev_err(dev, "cannot get irq\n");
return irq; return irq;
}
spin_lock_init(&p->lock); spin_lock_init(&p->lock);
p->mapbase = regs->start; p->mapbase = regs->start;
@ -472,19 +469,18 @@ static int dw8250_probe(struct platform_device *pdev)
device_property_read_u32(dev, "clock-frequency", &p->uartclk); device_property_read_u32(dev, "clock-frequency", &p->uartclk);
/* If there is separate baudclk, get the rate from it. */ /* If there is separate baudclk, get the rate from it. */
data->clk = devm_clk_get(dev, "baudclk"); data->clk = devm_clk_get_optional(dev, "baudclk");
if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) if (data->clk == NULL)
data->clk = devm_clk_get(dev, NULL); data->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) if (IS_ERR(data->clk))
return -EPROBE_DEFER; return PTR_ERR(data->clk);
if (!IS_ERR_OR_NULL(data->clk)) {
err = clk_prepare_enable(data->clk); err = clk_prepare_enable(data->clk);
if (err) if (err)
dev_warn(dev, "could not enable optional baudclk: %d\n", dev_warn(dev, "could not enable optional baudclk: %d\n", err);
err);
else if (data->clk)
p->uartclk = clk_get_rate(data->clk); p->uartclk = clk_get_rate(data->clk);
}
/* If no clock rate is defined, fail. */ /* If no clock rate is defined, fail. */
if (!p->uartclk) { if (!p->uartclk) {
@ -493,17 +489,16 @@ static int dw8250_probe(struct platform_device *pdev)
goto err_clk; goto err_clk;
} }
data->pclk = devm_clk_get(dev, "apb_pclk"); data->pclk = devm_clk_get_optional(dev, "apb_pclk");
if (IS_ERR(data->pclk) && PTR_ERR(data->pclk) == -EPROBE_DEFER) { if (IS_ERR(data->pclk)) {
err = -EPROBE_DEFER; err = PTR_ERR(data->pclk);
goto err_clk; goto err_clk;
} }
if (!IS_ERR(data->pclk)) {
err = clk_prepare_enable(data->pclk); err = clk_prepare_enable(data->pclk);
if (err) { if (err) {
dev_err(dev, "could not enable apb_pclk\n"); dev_err(dev, "could not enable apb_pclk\n");
goto err_clk; goto err_clk;
}
} }
data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
@ -546,12 +541,10 @@ err_reset:
reset_control_assert(data->rst); reset_control_assert(data->rst);
err_pclk: err_pclk:
if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
err_clk: err_clk:
if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
return err; return err;
} }
@ -567,11 +560,9 @@ static int dw8250_remove(struct platform_device *pdev)
reset_control_assert(data->rst); reset_control_assert(data->rst);
if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
pm_runtime_disable(dev); pm_runtime_disable(dev);
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
@ -604,11 +595,9 @@ static int dw8250_runtime_suspend(struct device *dev)
{ {
struct dw8250_data *data = dev_get_drvdata(dev); struct dw8250_data *data = dev_get_drvdata(dev);
if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
return 0; return 0;
} }
@ -617,11 +606,9 @@ static int dw8250_runtime_resume(struct device *dev)
{ {
struct dw8250_data *data = dev_get_drvdata(dev); struct dw8250_data *data = dev_get_drvdata(dev);
if (!IS_ERR(data->pclk)) clk_prepare_enable(data->pclk);
clk_prepare_enable(data->pclk);
if (!IS_ERR(data->clk)) clk_prepare_enable(data->clk);
clk_prepare_enable(data->clk);
return 0; return 0;
} }

Просмотреть файл

@ -166,6 +166,23 @@ static void xr17v35x_set_divisor(struct uart_port *p, unsigned int baud,
serial_port_out(p, 0x2, quot_frac); serial_port_out(p, 0x2, quot_frac);
} }
static int xr17v35x_startup(struct uart_port *port)
{
/*
* First enable access to IER [7:5], ISR [5:4], FCR [5:4],
* MCR [7:5] and MSR [7:0]
*/
serial_port_out(port, UART_XR_EFR, UART_EFR_ECB);
/*
* Make sure all interrups are masked until initialization is
* complete and the FIFOs are cleared
*/
serial_port_out(port, UART_IER, 0);
return serial8250_do_startup(port);
}
static void exar_shutdown(struct uart_port *port) static void exar_shutdown(struct uart_port *port)
{ {
unsigned char lsr; unsigned char lsr;
@ -212,6 +229,8 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
port->port.get_divisor = xr17v35x_get_divisor; port->port.get_divisor = xr17v35x_get_divisor;
port->port.set_divisor = xr17v35x_set_divisor; port->port.set_divisor = xr17v35x_set_divisor;
port->port.startup = xr17v35x_startup;
} else { } else {
port->port.type = PORT_XR17D15X; port->port.type = PORT_XR17D15X;
} }

Просмотреть файл

@ -221,17 +221,6 @@ static void qrk_serial_exit_dma(struct lpss8250 *lpss) {}
static int qrk_serial_setup(struct lpss8250 *lpss, struct uart_port *port) static int qrk_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
{ {
struct pci_dev *pdev = to_pci_dev(port->dev);
int ret;
pci_set_master(pdev);
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
port->irq = pci_irq_vector(pdev, 0);
qrk_serial_setup_dma(lpss, port); qrk_serial_setup_dma(lpss, port);
return 0; return 0;
} }
@ -293,16 +282,22 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret) if (ret)
return ret; return ret;
pci_set_master(pdev);
lpss = devm_kzalloc(&pdev->dev, sizeof(*lpss), GFP_KERNEL); lpss = devm_kzalloc(&pdev->dev, sizeof(*lpss), GFP_KERNEL);
if (!lpss) if (!lpss)
return -ENOMEM; return -ENOMEM;
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
lpss->board = (struct lpss8250_board *)id->driver_data; lpss->board = (struct lpss8250_board *)id->driver_data;
memset(&uart, 0, sizeof(struct uart_8250_port)); memset(&uart, 0, sizeof(struct uart_8250_port));
uart.port.dev = &pdev->dev; uart.port.dev = &pdev->dev;
uart.port.irq = pdev->irq; uart.port.irq = pci_irq_vector(pdev, 0);
uart.port.private_data = &lpss->data; uart.port.private_data = &lpss->data;
uart.port.type = PORT_16550A; uart.port.type = PORT_16550A;
uart.port.iotype = UPIO_MEM; uart.port.iotype = UPIO_MEM;
@ -337,6 +332,7 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_exit: err_exit:
if (lpss->board->exit) if (lpss->board->exit)
lpss->board->exit(lpss); lpss->board->exit(lpss);
pci_free_irq_vectors(pdev);
return ret; return ret;
} }
@ -348,6 +344,7 @@ static void lpss8250_remove(struct pci_dev *pdev)
if (lpss->board->exit) if (lpss->board->exit)
lpss->board->exit(lpss); lpss->board->exit(lpss);
pci_free_irq_vectors(pdev);
} }
static const struct lpss8250_board byt_board = { static const struct lpss8250_board byt_board = {

Просмотреть файл

@ -544,7 +544,7 @@ static int mtk8250_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
data->rx_wakeup_irq = platform_get_irq(pdev, 1); data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
return 0; return 0;
} }

Просмотреть файл

@ -48,6 +48,36 @@ static inline void tegra_serial_handle_break(struct uart_port *port)
} }
#endif #endif
static int of_8250_rs485_config(struct uart_port *port,
struct serial_rs485 *rs485)
{
struct uart_8250_port *up = up_to_u8250p(port);
/* Clamp the delays to [0, 100ms] */
rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
rs485->delay_rts_after_send = min(rs485->delay_rts_after_send, 100U);
port->rs485 = *rs485;
/*
* Both serial8250_em485_init and serial8250_em485_destroy
* are idempotent
*/
if (rs485->flags & SER_RS485_ENABLED) {
int ret = serial8250_em485_init(up);
if (ret) {
rs485->flags &= ~SER_RS485_ENABLED;
port->rs485.flags &= ~SER_RS485_ENABLED;
}
return ret;
}
serial8250_em485_destroy(up);
return 0;
}
/* /*
* Fill a struct uart_port for a given device node * Fill a struct uart_port for a given device node
*/ */
@ -178,6 +208,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->flags |= UPF_SKIP_TEST; port->flags |= UPF_SKIP_TEST;
port->dev = &ofdev->dev; port->dev = &ofdev->dev;
port->rs485_config = of_8250_rs485_config;
switch (type) { switch (type) {
case PORT_TEGRA: case PORT_TEGRA:

Просмотреть файл

@ -743,16 +743,8 @@ static int pci_ni8430_init(struct pci_dev *dev)
} }
/* UART Port Control Register */ /* UART Port Control Register */
#define NI16550_PCR_OFFSET 0x0f #define NI8430_PORTCON 0x0f
#define NI16550_PCR_RS422 0x00 #define NI8430_PORTCON_TXVR_ENABLE (1 << 3)
#define NI16550_PCR_ECHO_RS485 0x01
#define NI16550_PCR_DTR_RS485 0x02
#define NI16550_PCR_AUTO_RS485 0x03
#define NI16550_PCR_WIRE_MODE_MASK 0x03
#define NI16550_PCR_TXVR_ENABLE_BIT BIT(3)
#define NI16550_PCR_RS485_TERMINATION_BIT BIT(6)
#define NI16550_ACR_DTR_AUTO_DTR (0x2 << 3)
#define NI16550_ACR_DTR_MANUAL_DTR (0x0 << 3)
static int static int
pci_ni8430_setup(struct serial_private *priv, pci_ni8430_setup(struct serial_private *priv,
@ -774,117 +766,14 @@ pci_ni8430_setup(struct serial_private *priv,
return -ENOMEM; return -ENOMEM;
/* enable the transceiver */ /* enable the transceiver */
writeb(readb(p + offset + NI16550_PCR_OFFSET) | NI16550_PCR_TXVR_ENABLE_BIT, writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
p + offset + NI16550_PCR_OFFSET); p + offset + NI8430_PORTCON);
iounmap(p); iounmap(p);
return setup_port(priv, port, bar, offset, board->reg_shift); return setup_port(priv, port, bar, offset, board->reg_shift);
} }
static int pci_ni8431_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
u8 pcr, acr;
struct uart_8250_port *up;
up = container_of(port, struct uart_8250_port, port);
acr = up->acr;
pcr = port->serial_in(port, NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
if (rs485->flags & SER_RS485_ENABLED) {
/* RS-485 */
if ((rs485->flags & SER_RS485_RX_DURING_TX) &&
(rs485->flags & SER_RS485_RTS_ON_SEND)) {
dev_dbg(port->dev, "Invalid 2-wire mode\n");
return -EINVAL;
}
if (rs485->flags & SER_RS485_RX_DURING_TX) {
/* Echo */
dev_vdbg(port->dev, "2-wire DTR with echo\n");
pcr |= NI16550_PCR_ECHO_RS485;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
} else {
/* Auto or DTR */
if (rs485->flags & SER_RS485_RTS_ON_SEND) {
/* Auto */
dev_vdbg(port->dev, "2-wire Auto\n");
pcr |= NI16550_PCR_AUTO_RS485;
acr |= NI16550_ACR_DTR_AUTO_DTR;
} else {
/* DTR-controlled */
/* No Echo */
dev_vdbg(port->dev, "2-wire DTR no echo\n");
pcr |= NI16550_PCR_DTR_RS485;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
}
}
} else {
/* RS-422 */
dev_vdbg(port->dev, "4-wire\n");
pcr |= NI16550_PCR_RS422;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
}
dev_dbg(port->dev, "write pcr: 0x%08x\n", pcr);
port->serial_out(port, NI16550_PCR_OFFSET, pcr);
up->acr = acr;
port->serial_out(port, UART_SCR, UART_ACR);
port->serial_out(port, UART_ICR, up->acr);
/* Update the cache. */
port->rs485 = *rs485;
return 0;
}
static int pci_ni8431_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *uart, int idx)
{
u8 pcr, acr;
struct pci_dev *dev = priv->dev;
void __iomem *addr;
unsigned int bar, offset = board->first_offset;
if (idx >= board->num_ports)
return 1;
bar = FL_GET_BASE(board->flags);
offset += idx * board->uart_offset;
addr = pci_ioremap_bar(dev, bar);
if (!addr)
return -ENOMEM;
/* enable the transceiver */
writeb(readb(addr + NI16550_PCR_OFFSET) | NI16550_PCR_TXVR_ENABLE_BIT,
addr + NI16550_PCR_OFFSET);
pcr = readb(addr + NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
/* set wire mode to default RS-422 */
pcr |= NI16550_PCR_RS422;
acr = NI16550_ACR_DTR_MANUAL_DTR;
/* write port configuration to register */
writeb(pcr, addr + NI16550_PCR_OFFSET);
/* access and write to UART acr register */
writeb(UART_ACR, addr + UART_SCR);
writeb(acr, addr + UART_ICR);
uart->port.rs485_config = &pci_ni8431_config_rs485;
iounmap(addr);
return setup_port(priv, uart, bar, offset, board->reg_shift);
}
static int pci_netmos_9900_setup(struct serial_private *priv, static int pci_netmos_9900_setup(struct serial_private *priv,
const struct pciserial_board *board, const struct pciserial_board *board,
struct uart_8250_port *port, int idx) struct uart_8250_port *port, int idx)
@ -2021,15 +1910,6 @@ pci_moxa_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9 #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9
#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8 #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8
#define PCIE_DEVICE_ID_NI_PXIE8430_2328 0x74C2
#define PCIE_DEVICE_ID_NI_PXIE8430_23216 0x74C1
#define PCI_DEVICE_ID_NI_PXI8431_4852 0x7081
#define PCI_DEVICE_ID_NI_PXI8431_4854 0x70DE
#define PCI_DEVICE_ID_NI_PXI8431_4858 0x70E3
#define PCI_DEVICE_ID_NI_PXI8433_4852 0x70E9
#define PCI_DEVICE_ID_NI_PXI8433_4854 0x70ED
#define PCIE_DEVICE_ID_NI_PXIE8431_4858 0x74C4
#define PCIE_DEVICE_ID_NI_PXIE8431_48516 0x74C3
#define PCI_DEVICE_ID_MOXA_CP102E 0x1024 #define PCI_DEVICE_ID_MOXA_CP102E 0x1024
#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 #define PCI_DEVICE_ID_MOXA_CP102EL 0x1025
@ -2267,87 +2147,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.setup = pci_ni8430_setup, .setup = pci_ni8430_setup,
.exit = pci_ni8430_exit, .exit = pci_ni8430_exit,
}, },
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8430_2328,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8430_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8430_23216,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8430_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4852,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4854,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4858,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8433_4852,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8433_4854,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8431_4858,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8431_48516,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
/* Quatech */ /* Quatech */
{ {
.vendor = PCI_VENDOR_ID_QUATECH, .vendor = PCI_VENDOR_ID_QUATECH,
@ -3104,13 +2903,6 @@ enum pci_board_num_t {
pbn_ni8430_4, pbn_ni8430_4,
pbn_ni8430_8, pbn_ni8430_8,
pbn_ni8430_16, pbn_ni8430_16,
pbn_ni8430_pxie_8,
pbn_ni8430_pxie_16,
pbn_ni8431_2,
pbn_ni8431_4,
pbn_ni8431_8,
pbn_ni8431_pxie_8,
pbn_ni8431_pxie_16,
pbn_ADDIDATA_PCIe_1_3906250, pbn_ADDIDATA_PCIe_1_3906250,
pbn_ADDIDATA_PCIe_2_3906250, pbn_ADDIDATA_PCIe_2_3906250,
pbn_ADDIDATA_PCIe_4_3906250, pbn_ADDIDATA_PCIe_4_3906250,
@ -3763,55 +3555,6 @@ static struct pciserial_board pci_boards[] = {
.uart_offset = 0x10, .uart_offset = 0x10,
.first_offset = 0x800, .first_offset = 0x800,
}, },
[pbn_ni8430_pxie_16] = {
.flags = FL_BASE0,
.num_ports = 16,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8430_pxie_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_4] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_2] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_pxie_16] = {
.flags = FL_BASE0,
.num_ports = 16,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_pxie_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
/* /*
* ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com> * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
*/ */
@ -5565,33 +5308,6 @@ static const struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324, { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_4 }, pbn_ni8430_4 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_2328,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_pxie_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_23216,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_pxie_16 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4852,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_2 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4854,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_4 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4858,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_4858,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_pxie_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_48516,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_pxie_16 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4852,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_2 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4854,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_4 },
/* /*
* MOXA * MOXA

Просмотреть файл

@ -2114,20 +2114,6 @@ int serial8250_do_startup(struct uart_port *port)
enable_rsa(up); enable_rsa(up);
#endif #endif
if (port->type == PORT_XR17V35X) {
/*
* First enable access to IER [7:5], ISR [5:4], FCR [5:4],
* MCR [7:5] and MSR [7:0]
*/
serial_port_out(port, UART_XR_EFR, UART_EFR_ECB);
/*
* Make sure all interrups are masked until initialization is
* complete and the FIFOs are cleared
*/
serial_port_out(port, UART_IER, 0);
}
/* /*
* Clear the FIFO buffers and disable them. * Clear the FIFO buffers and disable them.
* (they will be reenabled in set_termios()) * (they will be reenabled in set_termios())

Просмотреть файл

@ -243,6 +243,7 @@ config SERIAL_8250_ASPEED_VUART
tristate "Aspeed Virtual UART" tristate "Aspeed Virtual UART"
depends on SERIAL_8250 depends on SERIAL_8250
depends on OF depends on OF
depends on REGMAP && MFD_SYSCON
help help
If you want to use the virtual UART (VUART) device on Aspeed If you want to use the virtual UART (VUART) device on Aspeed
BMC platforms, enable this option. This enables the 16550A- BMC platforms, enable this option. This enables the 16550A-
@ -334,7 +335,7 @@ config SERIAL_8250_BCM2835AUX
Features and limitations of the UART are Features and limitations of the UART are
Registers are similar to 16650 registers, Registers are similar to 16650 registers,
set bits in the control registers that are unsupported set bits in the control registers that are unsupported
are ignored and read back as 0 are ignored and read back as 0
7/8 bit operation with 1 start and 1 stop bit 7/8 bit operation with 1 start and 1 stop bit
8 symbols deep fifo for rx and tx 8 symbols deep fifo for rx and tx

Просмотреть файл

@ -287,26 +287,26 @@ config SERIAL_SAMSUNG_CONSOLE
boot time.) boot time.)
config SERIAL_SIRFSOC config SERIAL_SIRFSOC
tristate "SiRF SoC Platform Serial port support" tristate "SiRF SoC Platform Serial port support"
depends on ARCH_SIRF depends on ARCH_SIRF
select SERIAL_CORE select SERIAL_CORE
help help
Support for the on-chip UART on the CSR SiRFprimaII series, Support for the on-chip UART on the CSR SiRFprimaII series,
providing /dev/ttySiRF0, 1 and 2 (note, some machines may not providing /dev/ttySiRF0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port provide all of these ports, depending on how the serial port
pins are configured). pins are configured).
config SERIAL_SIRFSOC_CONSOLE config SERIAL_SIRFSOC_CONSOLE
bool "Support for console on SiRF SoC serial port" bool "Support for console on SiRF SoC serial port"
depends on SERIAL_SIRFSOC=y depends on SERIAL_SIRFSOC=y
select SERIAL_CORE_CONSOLE select SERIAL_CORE_CONSOLE
help help
Even if you say Y here, the currently visible virtual console Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but (/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as you can alter that using a kernel command line option such as
"console=ttySiRFx". (Try "man bootparam" or see the documentation of "console=ttySiRFx". (Try "man bootparam" or see the documentation of
your boot loader about how to pass options to the kernel at your boot loader about how to pass options to the kernel at
boot time.) boot time.)
config SERIAL_TEGRA config SERIAL_TEGRA
tristate "NVIDIA Tegra20/30 SoC serial controller" tristate "NVIDIA Tegra20/30 SoC serial controller"
@ -1078,41 +1078,41 @@ config SERIAL_SCCNXP_CONSOLE
Support for console on SCCNXP serial ports. Support for console on SCCNXP serial ports.
config SERIAL_SC16IS7XX_CORE config SERIAL_SC16IS7XX_CORE
tristate tristate
config SERIAL_SC16IS7XX config SERIAL_SC16IS7XX
tristate "SC16IS7xx serial support" tristate "SC16IS7xx serial support"
select SERIAL_CORE select SERIAL_CORE
depends on (SPI_MASTER && !I2C) || I2C depends on (SPI_MASTER && !I2C) || I2C
help help
This selects support for SC16IS7xx serial ports. This selects support for SC16IS7xx serial ports.
Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752,
SC16IS760 and SC16IS762. Select supported buses using options below. SC16IS760 and SC16IS762. Select supported buses using options below.
config SERIAL_SC16IS7XX_I2C config SERIAL_SC16IS7XX_I2C
bool "SC16IS7xx for I2C interface" bool "SC16IS7xx for I2C interface"
depends on SERIAL_SC16IS7XX depends on SERIAL_SC16IS7XX
depends on I2C depends on I2C
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_I2C if I2C select REGMAP_I2C if I2C
default y default y
help help
Enable SC16IS7xx driver on I2C bus, Enable SC16IS7xx driver on I2C bus,
If required say y, and say n to i2c if not required, If required say y, and say n to i2c if not required,
Enabled by default to support oldconfig. Enabled by default to support oldconfig.
You must select at least one bus for the driver to be built. You must select at least one bus for the driver to be built.
config SERIAL_SC16IS7XX_SPI config SERIAL_SC16IS7XX_SPI
bool "SC16IS7xx for spi interface" bool "SC16IS7xx for spi interface"
depends on SERIAL_SC16IS7XX depends on SERIAL_SC16IS7XX
depends on SPI_MASTER depends on SPI_MASTER
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_SPI if SPI_MASTER select REGMAP_SPI if SPI_MASTER
help help
Enable SC16IS7xx driver on SPI bus, Enable SC16IS7xx driver on SPI bus,
If required say y, and say n to spi if not required, If required say y, and say n to spi if not required,
This is additional support to exsisting driver. This is additional support to exsisting driver.
You must select at least one bus for the driver to be built. You must select at least one bus for the driver to be built.
config SERIAL_TIMBERDALE config SERIAL_TIMBERDALE
tristate "Support for timberdale UART" tristate "Support for timberdale UART"
@ -1212,7 +1212,7 @@ config SERIAL_ALTERA_UART_CONSOLE
Enable a Altera UART port to be the system console. Enable a Altera UART port to be the system console.
config SERIAL_IFX6X60 config SERIAL_IFX6X60
tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)"
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
depends on SPI && HAS_DMA depends on SPI && HAS_DMA
help help
@ -1392,19 +1392,19 @@ config SERIAL_FSL_LPUART_CONSOLE
you can make it the console by answering Y to this option. you can make it the console by answering Y to this option.
config SERIAL_FSL_LINFLEXUART config SERIAL_FSL_LINFLEXUART
tristate "Freescale linflexuart serial port support" tristate "Freescale LINFlexD UART serial port support"
depends on PRINTK depends on PRINTK
select SERIAL_CORE select SERIAL_CORE
help help
Support for the on-chip linflexuart on some Freescale SOCs. Support for the on-chip LINFlexD UART on some Freescale SOCs.
config SERIAL_FSL_LINFLEXUART_CONSOLE config SERIAL_FSL_LINFLEXUART_CONSOLE
bool "Console on Freescale linflexuart serial port" bool "Console on Freescale LINFlexD UART serial port"
depends on SERIAL_FSL_LINFLEXUART=y depends on SERIAL_FSL_LINFLEXUART=y
select SERIAL_CORE_CONSOLE select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON select SERIAL_EARLYCON
help help
If you have enabled the linflexuart serial port on the Freescale If you have enabled the LINFlexD UART serial port on the Freescale
SoCs, you can make it the console by answering Y to this option. SoCs, you can make it the console by answering Y to this option.
config SERIAL_CONEXANT_DIGICOLOR config SERIAL_CONEXANT_DIGICOLOR

Просмотреть файл

@ -30,7 +30,7 @@ obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX310X) += max310x.o obj-$(CONFIG_SERIAL_MAX310X) += max310x.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o

Просмотреть файл

@ -414,7 +414,7 @@ static void pl011_dma_probe(struct uart_amba_port *uap)
dma_cap_mask_t mask; dma_cap_mask_t mask;
uap->dma_probed = true; uap->dma_probed = true;
chan = dma_request_slave_channel_reason(dev, "tx"); chan = dma_request_chan(dev, "tx");
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
if (PTR_ERR(chan) == -EPROBE_DEFER) { if (PTR_ERR(chan) == -EPROBE_DEFER) {
uap->dma_probed = false; uap->dma_probed = false;
@ -813,10 +813,8 @@ __acquires(&uap->port.lock)
if (!uap->using_tx_dma) if (!uap->using_tx_dma)
return; return;
/* Avoid deadlock with the DMA engine callback */ dmaengine_terminate_async(uap->dmatx.chan);
spin_unlock(&uap->port.lock);
dmaengine_terminate_all(uap->dmatx.chan);
spin_lock(&uap->port.lock);
if (uap->dmatx.queued) { if (uap->dmatx.queued) {
dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
DMA_TO_DEVICE); DMA_TO_DEVICE);
@ -1236,10 +1234,6 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
#else #else
/* Blank functions if the DMA engine is not available */ /* Blank functions if the DMA engine is not available */
static inline void pl011_dma_probe(struct uart_amba_port *uap)
{
}
static inline void pl011_dma_remove(struct uart_amba_port *uap) static inline void pl011_dma_remove(struct uart_amba_port *uap)
{ {
} }

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* Freescale linflexuart serial port driver * Freescale LINFlexD UART serial port driver
* *
* Copyright 2012-2016 Freescale Semiconductor, Inc. * Copyright 2012-2016 Freescale Semiconductor, Inc.
* Copyright 2017-2019 NXP * Copyright 2017-2019 NXP
@ -940,5 +940,5 @@ static void __exit linflex_serial_exit(void)
module_init(linflex_serial_init); module_init(linflex_serial_init);
module_exit(linflex_serial_exit); module_exit(linflex_serial_exit);
MODULE_DESCRIPTION("Freescale linflex serial port driver"); MODULE_DESCRIPTION("Freescale LINFlexD serial port driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -437,8 +437,8 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
} }
sport->dma_tx_desc = dmaengine_prep_slave_sg(sport->dma_tx_chan, sgl, sport->dma_tx_desc = dmaengine_prep_slave_sg(sport->dma_tx_chan, sgl,
sport->dma_tx_nents, ret, DMA_MEM_TO_DEV,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); DMA_PREP_INTERRUPT);
if (!sport->dma_tx_desc) { if (!sport->dma_tx_desc) {
dma_unmap_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); dma_unmap_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
dev_err(dev, "Cannot prepare TX slave DMA!\n"); dev_err(dev, "Cannot prepare TX slave DMA!\n");
@ -1280,6 +1280,57 @@ static int lpuart_config_rs485(struct uart_port *port,
return 0; return 0;
} }
static int lpuart32_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
& ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE);
lpuart32_write(&sport->port, modem, UARTMODIR);
/* clear unsupported configurations */
rs485->delay_rts_before_send = 0;
rs485->delay_rts_after_send = 0;
rs485->flags &= ~SER_RS485_RX_DURING_TX;
if (rs485->flags & SER_RS485_ENABLED) {
/* Enable auto RS-485 RTS mode */
modem |= UARTMODEM_TXRTSE;
/*
* RTS needs to be logic HIGH either during transer _or_ after
* transfer, other variants are not supported by the hardware.
*/
if (!(rs485->flags & (SER_RS485_RTS_ON_SEND |
SER_RS485_RTS_AFTER_SEND)))
rs485->flags |= SER_RS485_RTS_ON_SEND;
if (rs485->flags & SER_RS485_RTS_ON_SEND &&
rs485->flags & SER_RS485_RTS_AFTER_SEND)
rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
/*
* The hardware defaults to RTS logic HIGH while transfer.
* Switch polarity in case RTS shall be logic HIGH
* after transfer.
* Note: UART is assumed to be active high.
*/
if (rs485->flags & SER_RS485_RTS_ON_SEND)
modem &= ~UARTMODEM_TXRTSPOL;
else if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
modem |= UARTMODEM_TXRTSPOL;
}
/* Store the new configuration */
sport->port.rs485 = *rs485;
lpuart32_write(&sport->port, modem, UARTMODIR);
return 0;
}
static unsigned int lpuart_get_mctrl(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port)
{ {
unsigned int temp = 0; unsigned int temp = 0;
@ -1333,18 +1384,7 @@ static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{ {
unsigned long temp;
temp = lpuart32_read(port, UARTMODIR) &
~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
if (mctrl & TIOCM_RTS)
temp |= UARTMODIR_RXRTSE;
if (mctrl & TIOCM_CTS)
temp |= UARTMODIR_TXCTSE;
lpuart32_write(port, temp, UARTMODIR);
} }
static void lpuart_break_ctl(struct uart_port *port, int break_state) static void lpuart_break_ctl(struct uart_port *port, int break_state)
@ -1889,11 +1929,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
ctrl |= UARTCTRL_M; ctrl |= UARTCTRL_M;
} }
/*
* When auto RS-485 RTS mode is enabled,
* hardware flow control need to be disabled.
*/
if (sport->port.rs485.flags & SER_RS485_ENABLED)
termios->c_cflag &= ~CRTSCTS;
if (termios->c_cflag & CRTSCTS) { if (termios->c_cflag & CRTSCTS) {
modem |= UARTMODEM_RXRTSE | UARTMODEM_TXCTSE; modem |= (UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
} else { } else {
termios->c_cflag &= ~CRTSCTS; termios->c_cflag &= ~CRTSCTS;
modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); modem &= ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
} }
if (termios->c_cflag & CSTOPB) if (termios->c_cflag & CSTOPB)
@ -2416,7 +2463,10 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.ops = &lpuart_pops; sport->port.ops = &lpuart_pops;
sport->port.flags = UPF_BOOT_AUTOCONF; sport->port.flags = UPF_BOOT_AUTOCONF;
sport->port.rs485_config = lpuart_config_rs485; if (lpuart_is_32(sport))
sport->port.rs485_config = lpuart32_config_rs485;
else
sport->port.rs485_config = lpuart_config_rs485;
sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(sport->ipg_clk)) { if (IS_ERR(sport->ipg_clk)) {
@ -2470,7 +2520,7 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.rs485.delay_rts_after_send) sport->port.rs485.delay_rts_after_send)
dev_err(&pdev->dev, "driver doesn't support RTS delays\n"); dev_err(&pdev->dev, "driver doesn't support RTS delays\n");
lpuart_config_rs485(&sport->port, &sport->port.rs485); sport->port.rs485_config(&sport->port, &sport->port.rs485);
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan) if (!sport->dma_tx_chan)

Просмотреть файл

@ -1230,6 +1230,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi)
struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
/* stop activity */ /* stop activity */
tasklet_kill(&ifx_dev->io_work_tasklet); tasklet_kill(&ifx_dev->io_work_tasklet);
pm_runtime_disable(&spi->dev);
/* free irq */ /* free irq */
free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), ifx_dev); free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), ifx_dev);
free_irq(gpio_to_irq(ifx_dev->gpio.srdy), ifx_dev); free_irq(gpio_to_irq(ifx_dev->gpio.srdy), ifx_dev);

Просмотреть файл

@ -619,7 +619,7 @@ static void imx_uart_dma_tx(struct imx_port *sport)
dev_err(dev, "DMA mapping error for TX.\n"); dev_err(dev, "DMA mapping error for TX.\n");
return; return;
} }
desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents, desc = dmaengine_prep_slave_sg(chan, sgl, ret,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
if (!desc) { if (!desc) {
dma_unmap_sg(dev, sgl, sport->dma_tx_nents, dma_unmap_sg(dev, sgl, sport->dma_tx_nents,
@ -1034,8 +1034,6 @@ static void imx_uart_timeout(struct timer_list *t)
} }
} }
#define RX_BUF_SIZE (PAGE_SIZE)
/* /*
* There are two kinds of RX DMA interrupts(such as in the MX6Q): * There are two kinds of RX DMA interrupts(such as in the MX6Q):
* [1] the RX DMA buffer is full. * [1] the RX DMA buffer is full.
@ -1118,7 +1116,8 @@ static void imx_uart_dma_rx_callback(void *data)
} }
/* RX DMA buffer periods */ /* RX DMA buffer periods */
#define RX_DMA_PERIODS 4 #define RX_DMA_PERIODS 16
#define RX_BUF_SIZE (RX_DMA_PERIODS * PAGE_SIZE / 4)
static int imx_uart_start_rx_dma(struct imx_port *sport) static int imx_uart_start_rx_dma(struct imx_port *sport)
{ {

Просмотреть файл

@ -301,7 +301,7 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base)
dma = &msm_port->tx_dma; dma = &msm_port->tx_dma;
/* allocate DMA resources, if available */ /* allocate DMA resources, if available */
dma->chan = dma_request_slave_channel_reason(dev, "tx"); dma->chan = dma_request_chan(dev, "tx");
if (IS_ERR(dma->chan)) if (IS_ERR(dma->chan))
goto no_tx; goto no_tx;
@ -344,7 +344,7 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
dma = &msm_port->rx_dma; dma = &msm_port->rx_dma;
/* allocate DMA resources, if available */ /* allocate DMA resources, if available */
dma->chan = dma_request_slave_channel_reason(dev, "rx"); dma->chan = dma_request_chan(dev, "rx");
if (IS_ERR(dma->chan)) if (IS_ERR(dma->chan))
goto no_rx; goto no_rx;
@ -980,6 +980,7 @@ static unsigned int msm_get_mctrl(struct uart_port *port)
static void msm_reset(struct uart_port *port) static void msm_reset(struct uart_port *port)
{ {
struct msm_port *msm_port = UART_TO_MSM(port); struct msm_port *msm_port = UART_TO_MSM(port);
unsigned int mr;
/* reset everything */ /* reset everything */
msm_write(port, UART_CR_CMD_RESET_RX, UART_CR); msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
@ -987,7 +988,10 @@ static void msm_reset(struct uart_port *port)
msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR); msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR); msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
msm_write(port, UART_CR_CMD_SET_RFR, UART_CR); msm_write(port, UART_CR_CMD_RESET_RFR, UART_CR);
mr = msm_read(port, UART_MR1);
mr &= ~UART_MR1_RX_RDY_CTL;
msm_write(port, mr, UART_MR1);
/* Disable DM modes */ /* Disable DM modes */
if (msm_port->is_uartdm) if (msm_port->is_uartdm)

Просмотреть файл

@ -233,6 +233,7 @@ struct eg20t_port {
struct dma_chan *chan_rx; struct dma_chan *chan_rx;
struct scatterlist *sg_tx_p; struct scatterlist *sg_tx_p;
int nent; int nent;
int orig_nent;
struct scatterlist sg_rx; struct scatterlist sg_rx;
int tx_dma_use; int tx_dma_use;
void *rx_buf_virt; void *rx_buf_virt;
@ -787,9 +788,10 @@ static void pch_dma_tx_complete(void *arg)
} }
xmit->tail &= UART_XMIT_SIZE - 1; xmit->tail &= UART_XMIT_SIZE - 1;
async_tx_ack(priv->desc_tx); async_tx_ack(priv->desc_tx);
dma_unmap_sg(port->dev, sg, priv->nent, DMA_TO_DEVICE); dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE);
priv->tx_dma_use = 0; priv->tx_dma_use = 0;
priv->nent = 0; priv->nent = 0;
priv->orig_nent = 0;
kfree(priv->sg_tx_p); kfree(priv->sg_tx_p);
pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT);
} }
@ -1010,6 +1012,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__); dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__);
return 0; return 0;
} }
priv->orig_nent = num;
priv->nent = nent; priv->nent = nent;
for (i = 0; i < nent; i++, sg++) { for (i = 0; i < nent; i++, sg++) {

Просмотреть файл

@ -9,10 +9,12 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/qcom-geni-se.h> #include <linux/qcom-geni-se.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
@ -115,6 +117,7 @@ struct qcom_geni_serial_port {
bool brk; bool brk;
unsigned int tx_remaining; unsigned int tx_remaining;
int wakeup_irq;
}; };
static const struct uart_ops qcom_geni_console_pops; static const struct uart_ops qcom_geni_console_pops;
@ -754,6 +757,15 @@ out_write_wakeup:
uart_write_wakeup(uport); uart_write_wakeup(uport);
} }
static irqreturn_t qcom_geni_serial_wakeup_isr(int isr, void *dev)
{
struct uart_port *uport = dev;
pm_wakeup_event(uport->dev, 2000);
return IRQ_HANDLED;
}
static irqreturn_t qcom_geni_serial_isr(int isr, void *dev) static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
{ {
u32 m_irq_en; u32 m_irq_en;
@ -830,7 +842,7 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
if (uart_console(uport)) if (uart_console(uport))
console_stop(uport->cons); console_stop(uport->cons);
free_irq(uport->irq, uport); disable_irq(uport->irq);
spin_lock_irqsave(&uport->lock, flags); spin_lock_irqsave(&uport->lock, flags);
qcom_geni_serial_stop_tx(uport); qcom_geni_serial_stop_tx(uport);
qcom_geni_serial_stop_rx(uport); qcom_geni_serial_stop_rx(uport);
@ -890,21 +902,14 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
int ret; int ret;
struct qcom_geni_serial_port *port = to_dev_port(uport, uport); struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
scnprintf(port->name, sizeof(port->name),
"qcom_serial_%s%d",
(uart_console(uport) ? "console" : "uart"), uport->line);
if (!port->setup) { if (!port->setup) {
ret = qcom_geni_serial_port_setup(uport); ret = qcom_geni_serial_port_setup(uport);
if (ret) if (ret)
return ret; return ret;
} }
enable_irq(uport->irq);
ret = request_irq(uport->irq, qcom_geni_serial_isr, IRQF_TRIGGER_HIGH, return 0;
port->name, uport);
if (ret)
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
return ret;
} }
static unsigned long get_clk_cfg(unsigned long clk_freq) static unsigned long get_clk_cfg(unsigned long clk_freq)
@ -1297,11 +1302,44 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; port->tx_fifo_width = DEF_FIFO_WIDTH_BITS;
scnprintf(port->name, sizeof(port->name), "qcom_geni_serial_%s%d",
(uart_console(uport) ? "console" : "uart"), uport->line);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
uport->irq = irq; uport->irq = irq;
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
return ret;
}
if (!console) {
port->wakeup_irq = platform_get_irq(pdev, 1);
if (port->wakeup_irq < 0) {
dev_err(&pdev->dev, "Failed to get wakeup IRQ %d\n",
port->wakeup_irq);
} else {
irq_set_status_flags(port->wakeup_irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, port->wakeup_irq,
qcom_geni_serial_wakeup_isr,
IRQF_TRIGGER_FALLING, "uart_wakeup", uport);
if (ret) {
dev_err(uport->dev, "Failed to register wakeup IRQ ret %d\n",
ret);
return ret;
}
device_init_wakeup(&pdev->dev, true);
ret = dev_pm_set_wake_irq(&pdev->dev, port->wakeup_irq);
if (unlikely(ret))
dev_err(uport->dev, "%s:Failed to set IRQ wake:%d\n",
__func__, ret);
}
}
uport->private_data = drv; uport->private_data = drv;
platform_set_drvdata(pdev, port); platform_set_drvdata(pdev, port);
port->handle_rx = console ? handle_rx_console : handle_rx_uart; port->handle_rx = console ? handle_rx_console : handle_rx_uart;
@ -1324,7 +1362,12 @@ static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev); struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport; struct uart_port *uport = &port->uport;
return uart_suspend_port(uport->private_data, uport); uart_suspend_port(uport->private_data, uport);
if (port->wakeup_irq > 0)
enable_irq(port->wakeup_irq);
return 0;
} }
static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev) static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
@ -1332,6 +1375,9 @@ static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev); struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport; struct uart_port *uport = &port->uport;
if (port->wakeup_irq > 0)
disable_irq(port->wakeup_irq);
return uart_resume_port(uport->private_data, uport); return uart_resume_port(uport->private_data, uport);
} }

Просмотреть файл

Просмотреть файл

@ -1122,8 +1122,7 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
int ret; int ret;
struct dma_slave_config dma_sconfig; struct dma_slave_config dma_sconfig;
dma_chan = dma_request_slave_channel_reason(tup->uport.dev, dma_chan = dma_request_chan(tup->uport.dev, dma_to_memory ? "rx" : "tx");
dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) { if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan); ret = PTR_ERR(dma_chan);
dev_err(tup->uport.dev, dev_err(tup->uport.dev,

Просмотреть файл

@ -1111,7 +1111,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
if (!uport) if (!uport)
goto out; goto out;
if (uport->type != PORT_UNKNOWN) if (uport->type != PORT_UNKNOWN && uport->ops->break_ctl)
uport->ops->break_ctl(uport, break_state); uport->ops->break_ctl(uport, break_state);
ret = 0; ret = 0;
out: out:

Просмотреть файл

@ -120,7 +120,8 @@ static u32 uart_usp_ff_empty_mask(struct uart_port *port)
empty_bit = ilog2(port->fifosize) + 1; empty_bit = ilog2(port->fifosize) + 1;
return (1 << empty_bit); return (1 << empty_bit);
} }
struct sirfsoc_uart_register sirfsoc_usp = {
static struct sirfsoc_uart_register sirfsoc_usp = {
.uart_reg = { .uart_reg = {
.sirfsoc_mode1 = 0x0000, .sirfsoc_mode1 = 0x0000,
.sirfsoc_mode2 = 0x0004, .sirfsoc_mode2 = 0x0004,
@ -186,7 +187,7 @@ struct sirfsoc_uart_register sirfsoc_usp = {
}, },
}; };
struct sirfsoc_uart_register sirfsoc_uart = { static struct sirfsoc_uart_register sirfsoc_uart = {
.uart_reg = { .uart_reg = {
.sirfsoc_line_ctrl = 0x0040, .sirfsoc_line_ctrl = 0x0040,
.sirfsoc_tx_rx_en = 0x004c, .sirfsoc_tx_rx_en = 0x004c,

Просмотреть файл

@ -919,6 +919,34 @@ static void sprd_pm(struct uart_port *port, unsigned int state,
} }
} }
#ifdef CONFIG_CONSOLE_POLL
static int sprd_poll_init(struct uart_port *port)
{
if (port->state->pm_state != UART_PM_STATE_ON) {
sprd_pm(port, UART_PM_STATE_ON, 0);
port->state->pm_state = UART_PM_STATE_ON;
}
return 0;
}
static int sprd_poll_get_char(struct uart_port *port)
{
while (!(serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK))
cpu_relax();
return serial_in(port, SPRD_RXD);
}
static void sprd_poll_put_char(struct uart_port *port, unsigned char ch)
{
while (serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK)
cpu_relax();
serial_out(port, SPRD_TXD, ch);
}
#endif
static const struct uart_ops serial_sprd_ops = { static const struct uart_ops serial_sprd_ops = {
.tx_empty = sprd_tx_empty, .tx_empty = sprd_tx_empty,
.get_mctrl = sprd_get_mctrl, .get_mctrl = sprd_get_mctrl,
@ -936,6 +964,11 @@ static const struct uart_ops serial_sprd_ops = {
.config_port = sprd_config_port, .config_port = sprd_config_port,
.verify_port = sprd_verify_port, .verify_port = sprd_verify_port,
.pm = sprd_pm, .pm = sprd_pm,
#ifdef CONFIG_CONSOLE_POLL
.poll_init = sprd_poll_init,
.poll_get_char = sprd_poll_get_char,
.poll_put_char = sprd_poll_put_char,
#endif
}; };
#ifdef CONFIG_SERIAL_SPRD_CONSOLE #ifdef CONFIG_SERIAL_SPRD_CONSOLE

Просмотреть файл

@ -240,8 +240,8 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)
* cleared by the sequence [read SR - read DR]. * cleared by the sequence [read SR - read DR].
*/ */
if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG) if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG)
stm32_clr_bits(port, ofs->icr, USART_ICR_ORECF | writel_relaxed(sr & USART_SR_ERR_MASK,
USART_ICR_PECF | USART_ICR_FECF); port->membase + ofs->icr);
c = stm32_get_char(port, &sr, &stm32_port->last_res); c = stm32_get_char(port, &sr, &stm32_port->last_res);
port->icount.rx++; port->icount.rx++;
@ -435,7 +435,7 @@ static void stm32_transmit_chars(struct uart_port *port)
if (ofs->icr == UNDEF_REG) if (ofs->icr == UNDEF_REG)
stm32_clr_bits(port, ofs->isr, USART_SR_TC); stm32_clr_bits(port, ofs->isr, USART_SR_TC);
else else
stm32_set_bits(port, ofs->icr, USART_ICR_TCCF); writel_relaxed(USART_ICR_TCCF, port->membase + ofs->icr);
if (stm32_port->tx_ch) if (stm32_port->tx_ch)
stm32_transmit_chars_dma(port); stm32_transmit_chars_dma(port);

Просмотреть файл

@ -22,7 +22,6 @@
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pm_runtime.h>
#define ULITE_NAME "ttyUL" #define ULITE_NAME "ttyUL"
#define ULITE_MAJOR 204 #define ULITE_MAJOR 204
@ -55,7 +54,6 @@
#define ULITE_CONTROL_RST_TX 0x01 #define ULITE_CONTROL_RST_TX 0x01
#define ULITE_CONTROL_RST_RX 0x02 #define ULITE_CONTROL_RST_RX 0x02
#define ULITE_CONTROL_IE 0x10 #define ULITE_CONTROL_IE 0x10
#define UART_AUTOSUSPEND_TIMEOUT 3000
/* Static pointer to console port */ /* Static pointer to console port */
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
@ -65,7 +63,6 @@ static struct uart_port *console_port;
struct uartlite_data { struct uartlite_data {
const struct uartlite_reg_ops *reg_ops; const struct uartlite_reg_ops *reg_ops;
struct clk *clk; struct clk *clk;
struct uart_driver *ulite_uart_driver;
}; };
struct uartlite_reg_ops { struct uartlite_reg_ops {
@ -393,12 +390,12 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
static void ulite_pm(struct uart_port *port, unsigned int state, static void ulite_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate) unsigned int oldstate)
{ {
if (!state) { struct uartlite_data *pdata = port->private_data;
pm_runtime_get_sync(port->dev);
} else { if (!state)
pm_runtime_mark_last_busy(port->dev); clk_enable(pdata->clk);
pm_runtime_put_autosuspend(port->dev); else
} clk_disable(pdata->clk);
} }
#ifdef CONFIG_CONSOLE_POLL #ifdef CONFIG_CONSOLE_POLL
@ -697,9 +694,7 @@ static int ulite_release(struct device *dev)
int rc = 0; int rc = 0;
if (port) { if (port) {
struct uartlite_data *pdata = port->private_data; rc = uart_remove_one_port(&ulite_uart_driver, port);
rc = uart_remove_one_port(pdata->ulite_uart_driver, port);
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
port->mapbase = 0; port->mapbase = 0;
} }
@ -717,11 +712,8 @@ static int __maybe_unused ulite_suspend(struct device *dev)
{ {
struct uart_port *port = dev_get_drvdata(dev); struct uart_port *port = dev_get_drvdata(dev);
if (port) { if (port)
struct uartlite_data *pdata = port->private_data; uart_suspend_port(&ulite_uart_driver, port);
uart_suspend_port(pdata->ulite_uart_driver, port);
}
return 0; return 0;
} }
@ -736,41 +728,17 @@ static int __maybe_unused ulite_resume(struct device *dev)
{ {
struct uart_port *port = dev_get_drvdata(dev); struct uart_port *port = dev_get_drvdata(dev);
if (port) { if (port)
struct uartlite_data *pdata = port->private_data; uart_resume_port(&ulite_uart_driver, port);
uart_resume_port(pdata->ulite_uart_driver, port);
}
return 0; return 0;
} }
static int __maybe_unused ulite_runtime_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct uartlite_data *pdata = port->private_data;
clk_disable(pdata->clk);
return 0;
};
static int __maybe_unused ulite_runtime_resume(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct uartlite_data *pdata = port->private_data;
clk_enable(pdata->clk);
return 0;
}
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* Platform bus binding * Platform bus binding
*/ */
static const struct dev_pm_ops ulite_pm_ops = { static SIMPLE_DEV_PM_OPS(ulite_pm_ops, ulite_suspend, ulite_resume);
SET_SYSTEM_SLEEP_PM_OPS(ulite_suspend, ulite_resume)
SET_RUNTIME_PM_OPS(ulite_runtime_suspend,
ulite_runtime_resume, NULL)
};
#if defined(CONFIG_OF) #if defined(CONFIG_OF)
/* Match table for of_platform binding */ /* Match table for of_platform binding */
@ -795,22 +763,6 @@ static int ulite_probe(struct platform_device *pdev)
if (prop) if (prop)
id = be32_to_cpup(prop); id = be32_to_cpup(prop);
#endif #endif
if (id < 0) {
/* Look for a serialN alias */
id = of_alias_get_id(pdev->dev.of_node, "serial");
if (id < 0)
id = 0;
}
if (!ulite_uart_driver.state) {
dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
ret = uart_register_driver(&ulite_uart_driver);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
return ret;
}
}
pdata = devm_kzalloc(&pdev->dev, sizeof(struct uartlite_data), pdata = devm_kzalloc(&pdev->dev, sizeof(struct uartlite_data),
GFP_KERNEL); GFP_KERNEL);
if (!pdata) if (!pdata)
@ -836,22 +788,24 @@ static int ulite_probe(struct platform_device *pdev)
pdata->clk = NULL; pdata->clk = NULL;
} }
pdata->ulite_uart_driver = &ulite_uart_driver;
ret = clk_prepare_enable(pdata->clk); ret = clk_prepare_enable(pdata->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to prepare clock\n"); dev_err(&pdev->dev, "Failed to prepare clock\n");
return ret; return ret;
} }
pm_runtime_use_autosuspend(&pdev->dev); if (!ulite_uart_driver.state) {
pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT); dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
pm_runtime_set_active(&pdev->dev); ret = uart_register_driver(&ulite_uart_driver);
pm_runtime_enable(&pdev->dev); if (ret < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
return ret;
}
}
ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata); ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
pm_runtime_mark_last_busy(&pdev->dev); clk_disable(pdata->clk);
pm_runtime_put_autosuspend(&pdev->dev);
return ret; return ret;
} }
@ -860,14 +814,9 @@ static int ulite_remove(struct platform_device *pdev)
{ {
struct uart_port *port = dev_get_drvdata(&pdev->dev); struct uart_port *port = dev_get_drvdata(&pdev->dev);
struct uartlite_data *pdata = port->private_data; struct uartlite_data *pdata = port->private_data;
int rc;
clk_unprepare(pdata->clk); clk_disable_unprepare(pdata->clk);
rc = ulite_release(&pdev->dev); return ulite_release(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
return rc;
} }
/* work with hotplug and coldplug */ /* work with hotplug and coldplug */

Просмотреть файл

@ -1345,9 +1345,12 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
if (!tty->port) if (!tty->port)
tty->port = driver->ports[idx]; tty->port = driver->ports[idx];
WARN_RATELIMIT(!tty->port, if (WARN_RATELIMIT(!tty->port,
"%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", "%s: %s driver does not set tty->port. This would crash the kernel. Fix the driver!\n",
__func__, tty->driver->name); __func__, tty->driver->name)) {
retval = -EINVAL;
goto err_release_lock;
}
retval = tty_ldisc_lock(tty, 5 * HZ); retval = tty_ldisc_lock(tty, 5 * HZ);
if (retval) if (retval)
@ -1925,7 +1928,6 @@ EXPORT_SYMBOL_GPL(tty_kopen);
/** /**
* tty_open_by_driver - open a tty device * tty_open_by_driver - open a tty device
* @device: dev_t of device to open * @device: dev_t of device to open
* @inode: inode of device file
* @filp: file pointer to tty * @filp: file pointer to tty
* *
* Performs the driver lookup, checks for a reopen, or otherwise * Performs the driver lookup, checks for a reopen, or otherwise
@ -1938,7 +1940,7 @@ EXPORT_SYMBOL_GPL(tty_kopen);
* - concurrent tty driver removal w/ lookup * - concurrent tty driver removal w/ lookup
* - concurrent tty removal from driver table * - concurrent tty removal from driver table
*/ */
static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, static struct tty_struct *tty_open_by_driver(dev_t device,
struct file *filp) struct file *filp)
{ {
struct tty_struct *tty; struct tty_struct *tty;
@ -2030,7 +2032,7 @@ retry_open:
tty = tty_open_current_tty(device, filp); tty = tty_open_current_tty(device, filp);
if (!tty) if (!tty)
tty = tty_open_by_driver(device, inode, filp); tty = tty_open_by_driver(device, filp);
if (IS_ERR(tty)) { if (IS_ERR(tty)) {
tty_free_file(filp); tty_free_file(filp);

Просмотреть файл

@ -156,12 +156,7 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
* takes tty_ldiscs_lock to guard against ldisc races * takes tty_ldiscs_lock to guard against ldisc races
*/ */
#if defined(CONFIG_LDISC_AUTOLOAD) static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
#define INITIAL_AUTOLOAD_STATE 1
#else
#define INITIAL_AUTOLOAD_STATE 0
#endif
static int tty_ldisc_autoload = INITIAL_AUTOLOAD_STATE;
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
{ {

Просмотреть файл

@ -1491,7 +1491,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
kbd_rawcode(value); kbd_rawcode(value);
if (event_type == EV_KEY) if (event_type == EV_KEY && event_code <= KEY_MAX)
kbd_keycode(event_code, value, HW_RAW(handle->dev)); kbd_keycode(event_code, value, HW_RAW(handle->dev));
spin_unlock(&kbd_event_lock); spin_unlock(&kbd_event_lock);

Просмотреть файл

@ -456,6 +456,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
size_t ret; size_t ret;
char *con_buf; char *con_buf;
if (use_unicode(inode))
return -EOPNOTSUPP;
con_buf = (char *) __get_free_page(GFP_KERNEL); con_buf = (char *) __get_free_page(GFP_KERNEL);
if (!con_buf) if (!con_buf)
return -ENOMEM; return -ENOMEM;

Просмотреть файл

@ -290,7 +290,7 @@
/* Sunix UART */ /* Sunix UART */
#define PORT_SUNIX 121 #define PORT_SUNIX 121
/* Freescale Linflex UART */ /* Freescale LINFlexD UART */
#define PORT_LINFLEXUART 122 #define PORT_LINFLEXUART 122
#endif /* _UAPILINUX_SERIAL_CORE_H */ #endif /* _UAPILINUX_SERIAL_CORE_H */