Commit 1f944f97 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull tty/serial updates from Greg KH:
 "Here is the big set of TTY / Serial patches for 5.7-rc1

  Lots of console fixups and reworking in here, serial core tweaks
  (doesn't that ever get old, why are we still creating new serial
  devices?), serial driver updates, line-protocol driver updates, and
  some vt cleanups and fixes included in here as well.

  All have been in linux-next with no reported issues"

* tag 'tty-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (161 commits)
  serial: 8250: Optimize irq enable after console write
  serial: 8250: Fix rs485 delay after console write
  vt: vt_ioctl: fix use-after-free in vt_in_use()
  vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console
  tty: serial: make SERIAL_SPRD depend on COMMON_CLK
  tty: serial: fsl_lpuart: fix return value checking
  tty: serial: fsl_lpuart: move dma_request_chan()
  ARM: dts: tango4: Make /serial compatible with ns16550a
  ARM: dts: mmp*: Make the serial ports compatible with xscale-uart
  ARM: dts: mmp*: Fix serial port names
  ARM: dts: mmp2-brownstone: Don't redeclare phandle references
  ARM: dts: pxa*: Make the serial ports compatible with xscale-uart
  ARM: dts: pxa*: Fix serial port names
  ARM: dts: pxa*: Don't redeclare phandle references
  serial: omap: drop unused dt-bindings header
  serial: 8250: 8250_omap: Add DMA support for UARTs on K3 SoCs
  serial: 8250: 8250_omap: Work around errata causing spurious IRQs with DMA
  serial: 8250: 8250_omap: Extend driver data to pass FIFO trigger info
  serial: 8250: 8250_omap: Move locking out from __dma_rx_do_complete()
  serial: 8250: 8250_omap: Account for data in flight during DMA teardown
  ...
parents dfabb077 8d5b3054
...@@ -154,3 +154,10 @@ Description: ...@@ -154,3 +154,10 @@ Description:
device specification. For example, when user sets 7bytes on device specification. For example, when user sets 7bytes on
16550A, which has 1/4/8/14 bytes trigger, the RX trigger is 16550A, which has 1/4/8/14 bytes trigger, the RX trigger is
automatically changed to 4 bytes. automatically changed to 4 bytes.
What: /sys/class/tty/ttyS0/console
Date: February 2020
Contact: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Description:
Allows user to detach or attach back the given device as
kernel console. It shows and accepts a boolean variable.
...@@ -8,6 +8,10 @@ Required properties: ...@@ -8,6 +8,10 @@ Required properties:
Optional properties: Optional properties:
- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works - fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
in DCE mode by default. in DCE mode by default.
- fsl,inverted-tx , fsl,inverted-rx : Indicate that the hardware attached
to the peripheral inverts the signal transmitted or received,
respectively, and that the peripheral should invert its output/input
using the INVT/INVR registers.
- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx, - rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
linux,rs485-enabled-at-boot-time: see rs485.txt. Note that for RS485 linux,rs485-enabled-at-boot-time: see rs485.txt. Note that for RS485
you must enable either the "uart-has-rtscts" or the "rts-gpios" you must enable either the "uart-has-rtscts" or the "rts-gpios"
......
...@@ -6,6 +6,8 @@ Required properties: ...@@ -6,6 +6,8 @@ Required properties:
on Vybrid vf610 SoC with 8-bit register organization on Vybrid vf610 SoC with 8-bit register organization
- "fsl,ls1021a-lpuart" for lpuart compatible with the one integrated - "fsl,ls1021a-lpuart" for lpuart compatible with the one integrated
on LS1021A SoC with 32-bit big-endian register organization on LS1021A SoC with 32-bit big-endian register organization
- "fsl,ls1028a-lpuart" for lpuart compatible with the one integrated
on LS1028A SoC with 32-bit little-endian register organization
- "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated - "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated
on i.MX7ULP SoC with 32-bit little-endian register organization on i.MX7ULP SoC with 32-bit little-endian register organization
- "fsl,imx8qxp-lpuart" for lpuart compatible with the one integrated - "fsl,imx8qxp-lpuart" for lpuart compatible with the one integrated
...@@ -15,10 +17,10 @@ Required properties: ...@@ -15,10 +17,10 @@ Required properties:
- reg : Address and length of the register set for the device - reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt - interrupts : Should contain uart interrupt
- clocks : phandle + clock specifier pairs, one for each entry in clock-names - clocks : phandle + clock specifier pairs, one for each entry in clock-names
- clock-names : For vf610/ls1021a/imx7ulp, "ipg" clock is for uart bus/baud - clock-names : For vf610/ls1021a/ls1028a/imx7ulp, "ipg" clock is for uart
clock. For imx8qxp lpuart, "ipg" clock is bus clock that is used to access bus/baud clock. For imx8qxp lpuart, "ipg" clock is bus clock that is used
lpuart controller registers, it also requires "baud" clock for module to to access lpuart controller registers, it also requires "baud" clock for
receive/transmit data. module to receive/transmit data.
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.
......
...@@ -19,176 +19,174 @@ memory { ...@@ -19,176 +19,174 @@ memory {
device_type = "memory"; device_type = "memory";
reg = <0x00000000 0x08000000>; reg = <0x00000000 0x08000000>;
}; };
};
&uart3 {
status = "okay";
};
soc { &twsi1 {
apb@d4000000 { status = "okay";
uart3: uart@d4018000 { pmic: max8925@3c {
status = "okay"; compatible = "maxium,max8925";
}; reg = <0x3c>;
twsi1: i2c@d4011000 { interrupts = <1>;
status = "okay"; interrupt-parent = <&intcmux4>;
pmic: max8925@3c { interrupt-controller;
compatible = "maxium,max8925"; #interrupt-cells = <1>;
reg = <0x3c>; maxim,tsc-irq = <0>;
interrupts = <1>;
interrupt-parent = <&intcmux4>;
interrupt-controller;
#interrupt-cells = <1>;
maxim,tsc-irq = <0>;
regulators { regulators {
SDV1 { SDV1 {
regulator-min-microvolt = <637500>; regulator-min-microvolt = <637500>;
regulator-max-microvolt = <1425000>; regulator-max-microvolt = <1425000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
SDV2 { SDV2 {
regulator-min-microvolt = <650000>; regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2225000>; regulator-max-microvolt = <2225000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
SDV3 { SDV3 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO1 { LDO1 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO2 { LDO2 {
regulator-min-microvolt = <650000>; regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>; regulator-max-microvolt = <2250000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO3 { LDO3 {
regulator-min-microvolt = <650000>; regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>; regulator-max-microvolt = <2250000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO4 { LDO4 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO5 { LDO5 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO6 { LDO6 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO7 { LDO7 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO8 { LDO8 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO9 { LDO9 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO10 { LDO10 {
regulator-min-microvolt = <750000>; regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>; regulator-max-microvolt = <3900000>;
};
LDO11 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO12 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO13 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO14 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO15 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO16 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO17 {
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>;
regulator-boot-on;
regulator-always-on;
};
LDO18 {
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>;
regulator-boot-on;
regulator-always-on;
};
LDO19 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO20 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
};
backlight {
maxim,max8925-dual-string = <0>;
};
charger {
batt-detect = <0>;
topoff-threshold = <1>;
fast-charge = <7>;
no-temp-support = <0>;
no-insert-detect = <0>;
};
};
};
rtc: rtc@d4010000 {
status = "okay";
}; };
LDO11 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO12 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO13 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO14 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO15 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO16 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO17 {
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>;
regulator-boot-on;
regulator-always-on;
};
LDO18 {
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <2250000>;
regulator-boot-on;
regulator-always-on;
};
LDO19 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
LDO20 {
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <3900000>;
regulator-boot-on;
regulator-always-on;
};
};
backlight {
maxim,max8925-dual-string = <0>;
};
charger {
batt-detect = <0>;
topoff-threshold = <1>;
fast-charge = <7>;
no-temp-support = <0>;
no-insert-detect = <0>;
}; };
}; };
}; };
&rtc {
status = "okay";
};
...@@ -208,8 +208,8 @@ timer0: timer@d4014000 { ...@@ -208,8 +208,8 @@ timer0: timer@d4014000 {
clocks = <&soc_clocks MMP2_CLK_TIMER>; clocks = <&soc_clocks MMP2_CLK_TIMER>;
}; };
uart1: uart@d4030000 { uart1: serial@d4030000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4030000 0x1000>; reg = <0xd4030000 0x1000>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks MMP2_CLK_UART0>; clocks = <&soc_clocks MMP2_CLK_UART0>;
...@@ -218,8 +218,8 @@ uart1: uart@d4030000 { ...@@ -218,8 +218,8 @@ uart1: uart@d4030000 {
status = "disabled"; status = "disabled";
}; };
uart2: uart@d4017000 { uart2: serial@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks MMP2_CLK_UART1>; clocks = <&soc_clocks MMP2_CLK_UART1>;
...@@ -228,8 +228,8 @@ uart2: uart@d4017000 { ...@@ -228,8 +228,8 @@ uart2: uart@d4017000 {
status = "disabled"; status = "disabled";
}; };
uart3: uart@d4018000 { uart3: serial@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
interrupts = <24>; interrupts = <24>;
clocks = <&soc_clocks MMP2_CLK_UART2>; clocks = <&soc_clocks MMP2_CLK_UART2>;
...@@ -238,8 +238,8 @@ uart3: uart@d4018000 { ...@@ -238,8 +238,8 @@ uart3: uart@d4018000 {
status = "disabled"; status = "disabled";
}; };
uart4: uart@d4016000 { uart4: serial@d4016000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4016000 0x1000>; reg = <0xd4016000 0x1000>;
interrupts = <46>; interrupts = <46>;
clocks = <&soc_clocks MMP2_CLK_UART3>; clocks = <&soc_clocks MMP2_CLK_UART3>;
......
...@@ -318,8 +318,8 @@ timer: timer@d4014000 { ...@@ -318,8 +318,8 @@ timer: timer@d4014000 {
clocks = <&soc_clocks MMP2_CLK_TIMER>; clocks = <&soc_clocks MMP2_CLK_TIMER>;
}; };
uart1: uart@d4030000 { uart1: serial@d4030000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4030000 0x1000>; reg = <0xd4030000 0x1000>;
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_clocks MMP2_CLK_UART0>; clocks = <&soc_clocks MMP2_CLK_UART0>;
...@@ -328,8 +328,8 @@ uart1: uart@d4030000 { ...@@ -328,8 +328,8 @@ uart1: uart@d4030000 {
status = "disabled"; status = "disabled";
}; };
uart2: uart@d4017000 { uart2: serial@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_clocks MMP2_CLK_UART1>; clocks = <&soc_clocks MMP2_CLK_UART1>;
...@@ -338,8 +338,8 @@ uart2: uart@d4017000 { ...@@ -338,8 +338,8 @@ uart2: uart@d4017000 {
status = "disabled"; status = "disabled";
}; };
uart3: uart@d4018000 { uart3: serial@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_clocks MMP2_CLK_UART2>; clocks = <&soc_clocks MMP2_CLK_UART2>;
...@@ -348,8 +348,8 @@ uart3: uart@d4018000 { ...@@ -348,8 +348,8 @@ uart3: uart@d4018000 {
status = "disabled"; status = "disabled";
}; };
uart4: uart@d4016000 { uart4: serial@d4016000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4016000 0x1000>; reg = <0xd4016000 0x1000>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_clocks MMP2_CLK_UART3>; clocks = <&soc_clocks MMP2_CLK_UART3>;
......
...@@ -18,18 +18,16 @@ chosen { ...@@ -18,18 +18,16 @@ chosen {
memory { memory {
reg = <0x00000000 0x04000000>; reg = <0x00000000 0x04000000>;
}; };
};
soc { &uart1 {
apb@d4000000 { status = "okay";
uart1: uart@d4017000 { };
status = "okay";
}; &twsi1 {
twsi1: i2c@d4011000 { status = "okay";
status = "okay"; };
};
rtc: rtc@d4010000 { &rtc {
status = "okay"; status = "okay";
};
};
};
}; };
...@@ -55,27 +55,30 @@ timer0: timer@d4014000 { ...@@ -55,27 +55,30 @@ timer0: timer@d4014000 {
interrupts = <13>; interrupts = <13>;
}; };
uart1: uart@d4017000 { uart1: serial@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
reg-shift = <2>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks PXA168_CLK_UART0>; clocks = <&soc_clocks PXA168_CLK_UART0>;
resets = <&soc_clocks PXA168_CLK_UART0>; resets = <&soc_clocks PXA168_CLK_UART0>;
status = "disabled"; status = "disabled";
}; };
uart2: uart@d4018000 { uart2: serial@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
reg-shift = <2>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks PXA168_CLK_UART1>; clocks = <&soc_clocks PXA168_CLK_UART1>;
resets = <&soc_clocks PXA168_CLK_UART1>; resets = <&soc_clocks PXA168_CLK_UART1>;
status = "disabled"; status = "disabled";
}; };
uart3: uart@d4026000 { uart3: serial@d4026000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4026000 0x1000>; reg = <0xd4026000 0x1000>;
reg-shift = <2>;
interrupts = <29>; interrupts = <29>;
clocks = <&soc_clocks PXA168_CLK_UART2>; clocks = <&soc_clocks PXA168_CLK_UART2>;
resets = <&soc_clocks PXA168_CLK_UART2>; resets = <&soc_clocks PXA168_CLK_UART2>;
......
...@@ -18,155 +18,153 @@ chosen { ...@@ -18,155 +18,153 @@ chosen {
memory { memory {
reg = <0x00000000 0x10000000>; reg = <0x00000000 0x10000000>;
}; };
};
soc { &uart1 {
apb@d4000000 { status = "okay";
uart1: uart@d4017000 { };
status = "okay";
}; &twsi1 {
twsi1: i2c@d4011000 { status = "okay";
status = "okay";
pmic: 88pm860x@34 { pmic: 88pm860x@34 {
compatible = "marvell,88pm860x"; compatible = "marvell,88pm860x";
reg = <0x34>; reg = <0x34>;
interrupts = <4>; interrupts = <4>;
interrupt-parent = <&intc>; interrupt-parent = <&intc>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
marvell,88pm860x-irq-read-clr; marvell,88pm860x-irq-read-clr;
marvell,88pm860x-slave-addr = <0x11>; marvell,88pm860x-slave-addr = <0x11>;
regulators { regulators {
BUCK1 { BUCK1 {
regulator-min-microvolt = <1000000>; regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1500000>; regulator-max-microvolt = <1500000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
BUCK2 { BUCK2 {
regulator-min-microvolt = <1000000>; regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1500000>; regulator-max-microvolt = <1500000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
BUCK3 { BUCK3 {
regulator-min-microvolt = <1000000>; regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3000000>; regulator-max-microvolt = <3000000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO1 { LDO1 {
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <2800000>; regulator-max-microvolt = <2800000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO2 { LDO2 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO3 { LDO3 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO4 { LDO4 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-always-on; regulator-always-on;
}; };
LDO5 { LDO5 {
regulator-min-microvolt = <2900000>; regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO6 { LDO6 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO7 { LDO7 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2900000>; regulator-max-microvolt = <2900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO8 { LDO8 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2900000>; regulator-max-microvolt = <2900000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO9 { LDO9 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO10 { LDO10 {
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-boot-on;
regulator-always-on; regulator-always-on;
}; };
LDO12 { LDO12 {
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-always-on; regulator-always-on;
}; };
LDO13 { LDO13 {
regulator-min-microvolt = <1200000>; regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-always-on; regulator-always-on;
}; };
LDO14 { LDO14 {
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-always-on; regulator-always-on;
}; };
}; };
rtc { rtc {
marvell,88pm860x-vrtc = <1>; marvell,88pm860x-vrtc = <1>;
}; };
touch { touch {
marvell,88pm860x-gpadc-prebias = <1>; marvell,88pm860x-gpadc-prebias = <1>;
marvell,88pm860x-gpadc-slot-cycle = <1>; marvell,88pm860x-gpadc-slot-cycle = <1>;
marvell,88pm860x-tsi-prebias = <6>; marvell,88pm860x-tsi-prebias = <6>;
marvell,88pm860x-pen-prebias = <16>; marvell,88pm860x-pen-prebias = <16>;
marvell,88pm860x-pen-prechg = <2>; marvell,88pm860x-pen-prechg = <2>;
marvell,88pm860x-resistor-X = <300>; marvell,88pm860x-resistor-X = <300>;
}; };
backlights { backlights {
backlight-0 { backlight-0 {
marvell,88pm860x-iset = <4>; marvell,88pm860x-iset = <4>;
marvell,88pm860x-pwm = <3>; marvell,88pm860x-pwm = <3>;
}; };
backlight-2 { backlight-2 {
}; };
}; };
leds { leds {
led0-red { led0-red {
marvell,88pm860x-iset = <12>; marvell,88pm860x-iset = <12>;
}; };
led0-green { led0-green {
marvell,88pm860x-iset = <12>; marvell,88pm860x-iset = <12>;
}; };
led0-blue { led0-blue {
marvell,88pm860x-iset = <12>; marvell,88pm860x-iset = <12>;
};
};
};
};
rtc: rtc@d4010000 {
status = "okay";
}; };
}; };
}; };
}; };
&rtc {
status = "okay";
};
...@@ -67,27 +67,30 @@ timer1: timer@d4016000 { ...@@ -67,27 +67,30 @@ timer1: timer@d4016000 {
status = "disabled"; status = "disabled";
}; };
uart1: uart@d4017000 { uart1: serial@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
reg-shift = <2>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks PXA910_CLK_UART0>; clocks = <&soc_clocks PXA910_CLK_UART0>;
resets = <&soc_clocks PXA910_CLK_UART0>; resets = <&soc_clocks PXA910_CLK_UART0>;
status = "disabled"; status = "disabled";
}; };
uart2: uart@d4018000 { uart2: serial@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
reg-shift = <2>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks PXA910_CLK_UART1>; clocks = <&soc_clocks PXA910_CLK_UART1>;
resets = <&soc_clocks PXA910_CLK_UART1>; resets = <&soc_clocks PXA910_CLK_UART1>;
status = "disabled"; status = "disabled";
}; };
uart3: uart@d4036000 { uart3: serial@d4036000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart", "intel,xscale-uart";
reg = <0xd4036000 0x1000>; reg = <0xd4036000 0x1000>;
reg-shift = <2>;
interrupts = <59>; interrupts = <59>;
clocks = <&soc_clocks PXA910_CLK_UART2>; clocks = <&soc_clocks PXA910_CLK_UART2>;
resets = <&soc_clocks PXA910_CLK_UART2>; resets = <&soc_clocks PXA910_CLK_UART2>;
......
...@@ -85,7 +85,7 @@ tick-counter@10048 { ...@@ -85,7 +85,7 @@ tick-counter@10048 {
}; };
uart: serial@10700 { uart: serial@10700 {
compatible = "ralink,rt2880-uart"; compatible = "ralink,rt2880-uart", "ns16550a";
reg = <0x10700 0x30>; reg = <0x10700 0x30>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>; clock-frequency = <7372800>;
......
...@@ -249,7 +249,7 @@ config ARCH_TEGRA ...@@ -249,7 +249,7 @@ config ARCH_TEGRA
This enables support for the NVIDIA Tegra SoC family. This enables support for the NVIDIA Tegra SoC family.
config ARCH_SPRD config ARCH_SPRD
bool "Spreadtrum SoC platform" tristate "Spreadtrum SoC platform"
help help
Support for Spreadtrum ARM based SoCs Support for Spreadtrum ARM based SoCs
......
...@@ -333,6 +333,79 @@ duart1: serial@21c0600 { ...@@ -333,6 +333,79 @@ duart1: serial@21c0600 {
status = "disabled"; status = "disabled";
}; };
lpuart0: serial@2260000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x2260000 0x0 0x1000>;
interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 32>,
<&edma0 1 33>;
status = "disabled";
};
lpuart1: serial@2270000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x2270000 0x0 0x1000>;
interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 30>,
<&edma0 1 31>;
status = "disabled";
};
lpuart2: serial@2280000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x2280000 0x0 0x1000>;
interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 28>,
<&edma0 1 29>;
status = "disabled";
};
lpuart3: serial@2290000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x2290000 0x0 0x1000>;
interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 26>,
<&edma0 1 27>;
status = "disabled";
};
lpuart4: serial@22a0000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x22a0000 0x0 0x1000>;
interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 24>,
<&edma0 1 25>;
status = "disabled";
};
lpuart5: serial@22b0000 {
compatible = "fsl,ls1028a-lpuart";
reg = <0x0 0x22b0000 0x0 0x1000>;
interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 1>;
clock-names = "ipg";
dma-names = "rx","tx";
dmas = <&edma0 1 22>,
<&edma0 1 23>;
status = "disabled";
};
edma0: dma-controller@22c0000 { edma0: dma-controller@22c0000 {
#dma-cells = <2>; #dma-cells = <2>;
compatible = "fsl,ls1028a-edma"; compatible = "fsl,ls1028a-edma";
......
...@@ -347,8 +347,6 @@ int braille_register_console(struct console *console, int index, ...@@ -347,8 +347,6 @@ int braille_register_console(struct console *console, int index,
{ {
int ret; int ret;
if (!(console->flags & CON_BRL))
return 0;
if (!console_options) if (!console_options)
/* Only support VisioBraille for now */ /* Only support VisioBraille for now */
console_options = "57600o8"; console_options = "57600o8";
...@@ -371,8 +369,6 @@ int braille_unregister_console(struct console *console) ...@@ -371,8 +369,6 @@ int braille_unregister_console(struct console *console)
{ {
if (braille_co != console) if (braille_co != console)
return -EINVAL; return -EINVAL;
if (!(console->flags & CON_BRL))
return 0;
unregister_keyboard_notifier(&keyboard_notifier_block); unregister_keyboard_notifier(&keyboard_notifier_block);
unregister_vt_notifier(&vt_notifier_block); unregister_vt_notifier(&vt_notifier_block);
braille_co = NULL; braille_co = NULL;
......
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* hvc_console.h * hvc_console.h
* Copyright (C) 2005 IBM Corporation * Copyright (C) 2005 IBM Corporation
......
...@@ -243,6 +243,7 @@ static struct fdc_word mips_ejtag_fdc_encode(const char **ptrs, ...@@ -243,6 +243,7 @@ static struct fdc_word mips_ejtag_fdc_encode(const char **ptrs,
/* Fall back to a 3 byte encoding */ /* Fall back to a 3 byte encoding */
word.bytes = 3; word.bytes = 3;
word.word &= 0x00ffffff; word.word &= 0x00ffffff;
/* Fall through */
case 3: case 3:
/* 3 byte encoding */ /* 3 byte encoding */
word.word |= 0x82000000; word.word |= 0x82000000;
......
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0 /* SPDX-License-Identifier: GPL-2.0 */
/* /*
* n_tracesink.h - Kernel driver API to route trace data in kernel space. * n_tracesink.h - Kernel driver API to route trace data in kernel space.
* *
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
#ifdef N_TTY_TRACE #ifdef N_TTY_TRACE
# define n_tty_trace(f, args...) trace_printk(f, ##args) # define n_tty_trace(f, args...) trace_printk(f, ##args)
#else #else
# define n_tty_trace(f, args...) # define n_tty_trace(f, args...) no_printk(f, ##args)
#endif #endif
struct n_tty_data { struct n_tty_data {
...@@ -654,9 +654,9 @@ static size_t __process_echoes(struct tty_struct *tty) ...@@ -654,9 +654,9 @@ static size_t __process_echoes(struct tty_struct *tty)
op = echo_buf(ldata, tail + 1); op = echo_buf(ldata, tail + 1);
switch (op) { switch (op) {
case ECHO_OP_ERASE_TAB: {
unsigned int num_chars, num_bs; unsigned int num_chars, num_bs;
case ECHO_OP_ERASE_TAB:
if (MASK(ldata->echo_commit) == MASK(tail + 2)) if (MASK(ldata->echo_commit) == MASK(tail + 2))
goto not_yet_stored; goto not_yet_stored;
num_chars = echo_buf(ldata, tail + 2); num_chars = echo_buf(ldata, tail + 2);
...@@ -687,7 +687,7 @@ static size_t __process_echoes(struct tty_struct *tty) ...@@ -687,7 +687,7 @@ static size_t __process_echoes(struct tty_struct *tty)
} }
tail += 3; tail += 3;
break; break;
}
case ECHO_OP_SET_CANON_COL: case ECHO_OP_SET_CANON_COL:
ldata->canon_column = ldata->column; ldata->canon_column = ldata->column;
tail += 2; tail += 2;
......
...@@ -301,7 +301,7 @@ struct ctrl_dl { ...@@ -301,7 +301,7 @@ struct ctrl_dl {
unsigned int DCD:1; unsigned int DCD:1;
unsigned int RI:1; unsigned int RI:1;
unsigned int CTS:1; unsigned int CTS:1;
unsigned int reserverd:4; unsigned int reserved:4;
u8 port; u8 port;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -839,40 +839,39 @@ static char *interrupt2str(u16 interrupt) ...@@ -839,40 +839,39 @@ static char *interrupt2str(u16 interrupt)
static char buf[TMP_BUF_MAX]; static char buf[TMP_BUF_MAX];
char *p = buf; char *p = buf;
interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 ") : NULL; if (interrupt & MDM_DL1)
interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX, "MDM_DL1 ");
"MDM_DL2 ") : NULL; if (interrupt & MDM_DL2)
p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_DL2 ");
interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), if (interrupt & MDM_UL1)
"MDM_UL1 ") : NULL; p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_UL1 ");
interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), if (interrupt & MDM_UL2)
"MDM_UL2 ") : NULL; p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_UL2 ");
if (interrupt & DIAG_DL1)
interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_DL1 ");
"DIAG_DL1 ") : NULL; if (interrupt & DIAG_DL2)
interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_DL2 ");
"DIAG_DL2 ") : NULL;
if (interrupt & DIAG_UL)
interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_UL ");
"DIAG_UL ") : NULL;
if (interrupt & APP1_DL)
interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP1_DL ");
"APP1_DL ") : NULL; if (interrupt & APP2_DL)
interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP2_DL ");
"APP2_DL ") : NULL;
if (interrupt & APP1_UL)
interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP1_UL ");
"APP1_UL ") : NULL; if (interrupt & APP2_UL)
interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP2_UL ");
"APP2_UL ") : NULL;
if (interrupt & CTRL_DL)
interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "CTRL_DL ");
"CTRL_DL ") : NULL; if (interrupt & CTRL_UL)
interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "CTRL_UL ");
"CTRL_UL ") : NULL;
if (interrupt & RESET)
interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX - (p - buf), p += scnprintf(p, TMP_BUF_MAX - (p - buf), "RESET ");
"RESET ") : NULL;
return buf; return buf;
} }
......
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* Driver for 8250/16550-type serial ports * Driver for 8250/16550-type serial ports
* *
...@@ -156,7 +156,9 @@ void serial8250_rpm_put(struct uart_8250_port *p); ...@@ -156,7 +156,9 @@ void serial8250_rpm_put(struct uart_8250_port *p);
void serial8250_rpm_get_tx(struct uart_8250_port *p); void serial8250_rpm_get_tx(struct uart_8250_port *p);
void serial8250_rpm_put_tx(struct uart_8250_port *p); void serial8250_rpm_put_tx(struct uart_8250_port *p);
int serial8250_em485_init(struct uart_8250_port *p); int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485);
void serial8250_em485_start_tx(struct uart_8250_port *p);
void serial8250_em485_stop_tx(struct uart_8250_port *p);
void serial8250_em485_destroy(struct uart_8250_port *p); void serial8250_em485_destroy(struct uart_8250_port *p);
/* MCR <-> TIOCM conversion */ /* MCR <-> TIOCM conversion */
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
* *
* Based on 8250_lpc18xx.c: * Based on 8250_lpc18xx.c:
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* The bcm2835aux is capable of RTS auto flow-control, but this driver doesn't
* take advantage of it yet. When adding support, be sure not to enable it
* simultaneously to rs485.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
...@@ -16,16 +20,64 @@ ...@@ -16,16 +20,64 @@
#include "8250.h" #include "8250.h"
#define BCM2835_AUX_UART_CNTL 8
#define BCM2835_AUX_UART_CNTL_RXEN 0x01 /* Receiver enable */
#define BCM2835_AUX_UART_CNTL_TXEN 0x02 /* Transmitter enable */
#define BCM2835_AUX_UART_CNTL_AUTORTS 0x04 /* RTS set by RX fill level */
#define BCM2835_AUX_UART_CNTL_AUTOCTS 0x08 /* CTS stops transmitter */
#define BCM2835_AUX_UART_CNTL_RTS3 0x00 /* RTS set until 3 chars left */
#define BCM2835_AUX_UART_CNTL_RTS2 0x10 /* RTS set until 2 chars left */
#define BCM2835_AUX_UART_CNTL_RTS1 0x20 /* RTS set until 1 chars left */
#define BCM2835_AUX_UART_CNTL_RTS4 0x30 /* RTS set until 4 chars left */
#define BCM2835_AUX_UART_CNTL_RTSINV 0x40 /* Invert auto RTS polarity */
#define BCM2835_AUX_UART_CNTL_CTSINV 0x80 /* Invert auto CTS polarity */
/** /**
* struct bcm2835aux_data - driver private data of BCM2835 auxiliary UART * struct bcm2835aux_data - driver private data of BCM2835 auxiliary UART
* @clk: clock producer of the port's uartclk * @clk: clock producer of the port's uartclk
* @line: index of the port's serial8250_ports[] entry * @line: index of the port's serial8250_ports[] entry
* @cntl: cached copy of CNTL register
*/ */
struct bcm2835aux_data { struct bcm2835aux_data {
struct clk *clk; struct clk *clk;
int line; int line;
u32 cntl;
}; };
static void bcm2835aux_rs485_start_tx(struct uart_8250_port *up)
{
if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
struct bcm2835aux_data *data = dev_get_drvdata(up->port.dev);
data->cntl &= ~BCM2835_AUX_UART_CNTL_RXEN;
serial_out(up, BCM2835_AUX_UART_CNTL, data->cntl);
}
/*
* On the bcm2835aux, the MCR register contains no other
* flags besides RTS. So no need for a read-modify-write.
*/
if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND)
serial8250_out_MCR(up, 0);
else
serial8250_out_MCR(up, UART_MCR_RTS);
}
static void bcm2835aux_rs485_stop_tx(struct uart_8250_port *up)
{
if (up->port.rs485.flags & SER_RS485_RTS_AFTER_SEND)
serial8250_out_MCR(up, 0);
else
serial8250_out_MCR(up, UART_MCR_RTS);
if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
struct bcm2835aux_data *data = dev_get_drvdata(up->port.dev);
data->cntl |= BCM2835_AUX_UART_CNTL_RXEN;
serial_out(up, BCM2835_AUX_UART_CNTL, data->cntl);
}
}
static int bcm2835aux_serial_probe(struct platform_device *pdev) static int bcm2835aux_serial_probe(struct platform_device *pdev)
{ {
struct uart_8250_port up = { }; struct uart_8250_port up = { };
...@@ -47,6 +99,14 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) ...@@ -47,6 +99,14 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
up.port.fifosize = 8; up.port.fifosize = 8;
up.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE | up.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE |
UPF_SKIP_TEST | UPF_IOREMAP; UPF_SKIP_TEST | UPF_IOREMAP;
up.port.rs485_config = serial8250_em485_config;
up.rs485_start_tx = bcm2835aux_rs485_start_tx;
up.rs485_stop_tx = bcm2835aux_rs485_stop_tx;
/* initialize cached copy with power-on reset value */
data->cntl = BCM2835_AUX_UART_CNTL_RXEN | BCM2835_AUX_UART_CNTL_TXEN;
platform_set_drvdata(pdev, data);
/* get the clock - this also enables the HW */ /* get the clock - this also enables the HW */
data->clk = devm_clk_get(&pdev->dev, NULL); data->clk = devm_clk_get(&pdev->dev, NULL);
...@@ -102,8 +162,6 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) ...@@ -102,8 +162,6 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
} }
data->line = ret; data->line = ret;
platform_set_drvdata(pdev, data);
return 0; return 0;
dis_clk: dis_clk:
...@@ -137,6 +195,24 @@ static struct platform_driver bcm2835aux_serial_driver = { ...@@ -137,6 +195,24 @@ static struct platform_driver bcm2835aux_serial_driver = {
}; };
module_platform_driver(bcm2835aux_serial_driver); module_platform_driver(bcm2835aux_serial_driver);
#ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init early_bcm2835aux_setup(struct earlycon_device *device,
const char *options)
{
if (!device->port.membase)
return -ENODEV;
device->port.iotype = UPIO_MEM32;
device->port.regshift = 2;
return early_serial8250_setup(device, NULL);
}
OF_EARLYCON_DECLARE(bcm2835aux, "brcm,bcm2835-aux-uart",
early_bcm2835aux_setup);
#endif
MODULE_DESCRIPTION("BCM2835 auxiliar UART driver"); MODULE_DESCRIPTION("BCM2835 auxiliar UART driver");
MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>"); MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -608,6 +608,14 @@ static int univ8250_console_setup(struct console *co, char *options) ...@@ -608,6 +608,14 @@ static int univ8250_console_setup(struct console *co, char *options)
return retval; return retval;
} }
static int univ8250_console_exit(struct console *co)
{
struct uart_port *port;
port = &serial8250_ports[co->index].port;
return serial8250_console_exit(port);
}
/** /**
* univ8250_console_match - non-standard console matching * univ8250_console_match - non-standard console matching
* @co: registering console * @co: registering console
...@@ -666,6 +674,7 @@ static struct console univ8250_console = { ...@@ -666,6 +674,7 @@ static struct console univ8250_console = {
.write = univ8250_console_write, .write = univ8250_console_write,
.device = uart_console_device, .device = uart_console_device,
.setup = univ8250_console_setup, .setup = univ8250_console_setup,
.exit = univ8250_console_exit,
.match = univ8250_console_match, .match = univ8250_console_match,
.flags = CON_PRINTBUFFER | CON_ANYTIME, .flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1, .index = -1,
...@@ -1007,14 +1016,18 @@ int serial8250_register_8250_port(struct uart_8250_port *up) ...@@ -1007,14 +1016,18 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
uart->port.unthrottle = up->port.unthrottle; uart->port.unthrottle = up->port.unthrottle;
uart->port.rs485_config = up->port.rs485_config; uart->port.rs485_config = up->port.rs485_config;
uart->port.rs485 = up->port.rs485; uart->port.rs485 = up->port.rs485;
uart->rs485_start_tx = up->rs485_start_tx;
uart->rs485_stop_tx = up->rs485_stop_tx;
uart->dma = up->dma; uart->dma = up->dma;
/* Take tx_loadsz from fifosize if it wasn't set separately */ /* Take tx_loadsz from fifosize if it wasn't set separately */
if (uart->port.fifosize && !uart->tx_loadsz) if (uart->port.fifosize && !uart->tx_loadsz)
uart->tx_loadsz = uart->port.fifosize; uart->tx_loadsz = uart->port.fifosize;
if (up->port.dev) if (up->port.dev) {
uart->port.dev = up->port.dev; uart->port.dev = up->port.dev;
uart_get_rs485_mode(uart->port.dev, &uart->port.rs485);
}
if (up->port.flags & UPF_FIXED_TYPE) if (up->port.flags & UPF_FIXED_TYPE)
uart->port.type = up->port.type; uart->port.type = up->port.type;
......
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* Synopsys DesignWare 8250 library header file. */ /* Synopsys DesignWare 8250 library header file. */
#include <linux/types.h> #include <linux/types.h>
......
...@@ -135,7 +135,7 @@ struct exar8250 { ...@@ -135,7 +135,7 @@ struct exar8250 {
unsigned int nr; unsigned int nr;
struct exar8250_board *board; struct exar8250_board *board;
void __iomem *virt; void __iomem *virt;
int line[0]; int line[];
}; };
static void exar_pm(struct uart_port *port, unsigned int state, unsigned int old) static void exar_pm(struct uart_port *port, unsigned int state, unsigned int old)
......
...@@ -156,6 +156,11 @@ static int byt_serial_setup(struct lpss8250 *lpss, struct uart_port *port) ...@@ -156,6 +156,11 @@ static int byt_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
return 0; return 0;
} }
static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
{
return 0;
}
#ifdef CONFIG_SERIAL_8250_DMA #ifdef CONFIG_SERIAL_8250_DMA
static const struct dw_dma_platform_data qrk_serial_dma_pdata = { static const struct dw_dma_platform_data qrk_serial_dma_pdata = {
.nr_channels = 2, .nr_channels = 2,
...@@ -356,6 +361,7 @@ static const struct lpss8250_board byt_board = { ...@@ -356,6 +361,7 @@ static const struct lpss8250_board byt_board = {
static const struct lpss8250_board ehl_board = { static const struct lpss8250_board ehl_board = {
.freq = 200000000, .freq = 200000000,
.base_baud = 12500000, .base_baud = 12500000,
.setup = ehl_serial_setup,
}; };
static const struct lpss8250_board qrk_board = { static const struct lpss8250_board qrk_board = {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */
#define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */
#define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */
#define MTK_UART_DEBUG0 0x18
#define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */
#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
...@@ -388,9 +389,18 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -388,9 +389,18 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) static int __maybe_unused mtk8250_runtime_suspend(struct device *dev)
{ {
struct mtk8250_data *data = dev_get_drvdata(dev); struct mtk8250_data *data = dev_get_drvdata(dev);
struct uart_8250_port *up = serial8250_get_port(data->line);
clk_disable_unprepare(data->uart_clk); /* wait until UART in idle status */
clk_disable_unprepare(data->bus_clk); while
(serial_in(up, MTK_UART_DEBUG0));
if (data->clk_count == 0U) {
dev_dbg(dev, "%s clock count is 0\n", __func__);
} else {
clk_disable_unprepare(data->bus_clk);
data->clk_count--;
}
return 0; return 0;
} }
...@@ -400,16 +410,16 @@ static int __maybe_unused mtk8250_runtime_resume(struct device *dev) ...@@ -400,16 +410,16 @@ static int __maybe_unused mtk8250_runtime_resume(struct device *dev)
struct mtk8250_data *data = dev_get_drvdata(dev); struct mtk8250_data *data = dev_get_drvdata(dev);
int err; int err;
err = clk_prepare_enable(data->uart_clk); if (data->clk_count > 0U) {
if (err) { dev_dbg(dev, "%s clock count is %d\n", __func__,
dev_warn(dev, "Can't enable clock\n"); data->clk_count);
return err; } else {
} err = clk_prepare_enable(data->bus_clk);
if (err) {
err = clk_prepare_enable(data->bus_clk); dev_warn(dev, "Can't enable bus clock\n");
if (err) { return err;
dev_warn(dev, "Can't enable bus clock\n"); }
return err; data->clk_count++;
} }
return 0; return 0;
...@@ -419,12 +429,14 @@ static void ...@@ -419,12 +429,14 @@ static void
mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
{ {
if (!state) if (!state)
pm_runtime_get_sync(port->dev); if (!mtk8250_runtime_resume(port->dev))
pm_runtime_get_sync(port->dev);
serial8250_do_pm(port, state, old); serial8250_do_pm(port, state, old);
if (state) if (state)
pm_runtime_put_sync_suspend(port->dev); if (!pm_runtime_put_sync_suspend(port->dev))
mtk8250_runtime_suspend(port->dev);
} }
#ifdef CONFIG_SERIAL_8250_DMA #ifdef CONFIG_SERIAL_8250_DMA
...@@ -501,6 +513,8 @@ static int mtk8250_probe(struct platform_device *pdev) ...@@ -501,6 +513,8 @@ static int mtk8250_probe(struct platform_device *pdev)
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->clk_count = 0;
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
err = mtk8250_probe_of(pdev, &uart.port, data); err = mtk8250_probe_of(pdev, &uart.port, data);
if (err) if (err)
...@@ -533,6 +547,7 @@ static int mtk8250_probe(struct platform_device *pdev) ...@@ -533,6 +547,7 @@ static int mtk8250_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
pm_runtime_enable(&pdev->dev);
err = mtk8250_runtime_resume(&pdev->dev); err = mtk8250_runtime_resume(&pdev->dev);
if (err) if (err)
return err; return err;
...@@ -541,9 +556,6 @@ static int mtk8250_probe(struct platform_device *pdev) ...@@ -541,9 +556,6 @@ static int mtk8250_probe(struct platform_device *pdev)
if (data->line < 0) if (data->line < 0)
return data->line; return data->line;
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
return 0; return 0;
...@@ -556,11 +568,13 @@ static int mtk8250_remove(struct platform_device *pdev) ...@@ -556,11 +568,13 @@ static int mtk8250_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
serial8250_unregister_port(data->line); serial8250_unregister_port(data->line);
mtk8250_runtime_suspend(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mtk8250_runtime_suspend(&pdev->dev);
return 0; return 0;
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -26,67 +25,16 @@ struct of_serial_info { ...@@ -26,67 +25,16 @@ struct of_serial_info {
int line; int line;
}; };
#ifdef CONFIG_ARCH_TEGRA
static void tegra_serial_handle_break(struct uart_port *p)
{
unsigned int status, tmout = 10000;
do {
status = p->serial_in(p, UART_LSR);
if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
status = p->serial_in(p, UART_RX);
else
break;
if (--tmout == 0)
break;
udelay(1);
} while (1);
}
#else
static inline void tegra_serial_handle_break(struct uart_port *port)
{
}
#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
*/ */
static int of_platform_serial_setup(struct platform_device *ofdev, static int of_platform_serial_setup(struct platform_device *ofdev,
int type, struct uart_port *port, int type, struct uart_8250_port *up,
struct of_serial_info *info) struct of_serial_info *info)
{ {
struct resource resource; struct resource resource;
struct device_node *np = ofdev->dev.of_node; struct device_node *np = ofdev->dev.of_node;
struct uart_port *port = &up->port;
u32 clk, spd, prop; u32 clk, spd, prop;
int ret, irq; int ret, irq;
...@@ -207,13 +155,11 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ...@@ -207,13 +155,11 @@ 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; port->rs485_config = serial8250_em485_config;
up->rs485_start_tx = serial8250_em485_start_tx;
up->rs485_stop_tx = serial8250_em485_stop_tx;
switch (type) { switch (type) {
case PORT_TEGRA:
port->handle_break = tegra_serial_handle_break;
break;
case PORT_RT2880: case PORT_RT2880:
port->iotype = UPIO_AU; port->iotype = UPIO_AU;
break; break;
...@@ -258,7 +204,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) ...@@ -258,7 +204,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
return -ENOMEM; return -ENOMEM;
memset(&port8250, 0, sizeof(port8250)); memset(&port8250, 0, sizeof(port8250));
ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); ret = of_platform_serial_setup(ofdev, port_type, &port8250, info);
if (ret) if (ret)
goto err_free; goto err_free;
...@@ -358,7 +304,6 @@ static const struct of_device_id of_platform_serial_table[] = { ...@@ -358,7 +304,6 @@ static const struct of_device_id of_platform_serial_table[] = {
{ .compatible = "ns16550", .data = (void *)PORT_16550, }, { .compatible = "ns16550", .data = (void *)PORT_16550, },
{ .compatible = "ns16750", .data = (void *)PORT_16750, }, { .compatible = "ns16750", .data = (void *)PORT_16750, },
{ .compatible = "ns16850", .data = (void *)PORT_16850, }, { .compatible = "ns16850", .data = (void *)PORT_16850, },
{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
{ .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, },
{ .compatible = "intel,xscale-uart", .data = (void *)PORT_XSCALE, }, { .compatible = "intel,xscale-uart", .data = (void *)PORT_XSCALE, },
......
This diff is collapsed.
...@@ -53,7 +53,7 @@ struct serial_private { ...@@ -53,7 +53,7 @@ struct serial_private {
unsigned int nr; unsigned int nr;
struct pci_serial_quirk *quirk; struct pci_serial_quirk *quirk;
const struct pciserial_board *board; const struct pciserial_board *board;
int line[0]; int line[];
}; };
static const struct pci_device_id pci_use_msi[] = { static const struct pci_device_id pci_use_msi[] = {
......
This diff is collapsed.
...@@ -123,7 +123,7 @@ static int serial_pxa_probe(struct platform_device *pdev) ...@@ -123,7 +123,7 @@ static int serial_pxa_probe(struct platform_device *pdev)
uart.port.regshift = 2; uart.port.regshift = 2;
uart.port.irq = irqres->start; uart.port.irq = irqres->start;
uart.port.fifosize = 64; uart.port.fifosize = 64;
uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST; uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE;
uart.port.dev = &pdev->dev; uart.port.dev = &pdev->dev;
uart.port.uartclk = clk_get_rate(data->clk); uart.port.uartclk = clk_get_rate(data->clk);
uart.port.pm = serial_pxa_pm; uart.port.pm = serial_pxa_pm;
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Serial Port driver for Tegra devices
*
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include "8250.h"
struct tegra_uart {
struct clk *clk;
struct reset_control *rst;
int line;
};
static void tegra_uart_handle_break(struct uart_port *p)
{
unsigned int status, tmout = 10000;
do {
status = p->serial_in(p, UART_LSR);
if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
status = p->serial_in(p, UART_RX);
else
break;
if (--tmout == 0)
break;
udelay(1);
} while (1);
}
static int tegra_uart_probe(struct platform_device *pdev)
{
struct uart_8250_port port8250;
struct tegra_uart *uart;
struct uart_port *port;
struct resource *res;
int ret;
uart = devm_kzalloc(&pdev->dev, sizeof(*uart), GFP_KERNEL);
if (!uart)
return -ENOMEM;
memset(&port8250, 0, sizeof(port8250));
port = &port8250.port;
spin_lock_init(&port->lock);
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
UPF_FIXED_TYPE;
port->iotype = UPIO_MEM32;
port->regshift = 2;
port->type = PORT_TEGRA;
port->irqflags |= IRQF_SHARED;
port->dev = &pdev->dev;
port->handle_break = tegra_uart_handle_break;
ret = of_alias_get_id(pdev->dev.of_node, "serial");
if (ret >= 0)
port->line = ret;
ret = platform_get_irq(pdev, 0);
if (ret < 0)
return ret;
port->irq = ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
port->membase = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!port->membase)
return -ENOMEM;
port->mapbase = res->start;
port->mapsize = resource_size(res);
uart->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
if (IS_ERR(uart->rst))
return PTR_ERR(uart->rst);
if (device_property_read_u32(&pdev->dev, "clock-frequency",
&port->uartclk)) {
uart->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(uart->clk)) {
dev_err(&pdev->dev, "failed to get clock!\n");
return -ENODEV;
}
ret = clk_prepare_enable(uart->clk);
if (ret < 0)
return ret;
port->uartclk = clk_get_rate(uart->clk);
}
ret = reset_control_deassert(uart->rst);
if (ret)
goto err_clkdisable;
ret = serial8250_register_8250_port(&port8250);
if (ret < 0)
goto err_clkdisable;
platform_set_drvdata(pdev, uart);
uart->line = ret;
return 0;
err_clkdisable:
clk_disable_unprepare(uart->clk);
return ret;
}
static int tegra_uart_remove(struct platform_device *pdev)
{
struct tegra_uart *uart = platform_get_drvdata(pdev);
serial8250_unregister_port(uart->line);
reset_control_assert(uart->rst);
clk_disable_unprepare(uart->clk);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tegra_uart_suspend(struct device *dev)
{
struct tegra_uart *uart = dev_get_drvdata(dev);
struct uart_8250_port *port8250 = serial8250_get_port(uart->line);
struct uart_port *port = &port8250->port;
serial8250_suspend_port(uart->line);
if (!uart_console(port) || console_suspend_enabled)
clk_disable_unprepare(uart->clk);
return 0;
}
static int tegra_uart_resume(struct device *dev)
{
struct tegra_uart *uart = dev_get_drvdata(dev);
struct uart_8250_port *port8250 = serial8250_get_port(uart->line);
struct uart_port *port = &port8250->port;
if (!uart_console(port) || console_suspend_enabled)
clk_prepare_enable(uart->clk);
serial8250_resume_port(uart->line);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(tegra_uart_pm_ops, tegra_uart_suspend,
tegra_uart_resume);
static const struct of_device_id tegra_uart_of_match[] = {
{ .compatible = "nvidia,tegra20-uart", },
{ },
};
MODULE_DEVICE_TABLE(of, tegra_uart_of_match);
static const struct acpi_device_id tegra_uart_acpi_match[] = {
{ "NVDA0100", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, tegra_uart_acpi_match);
static struct platform_driver tegra_uart_driver = {
.driver = {
.name = "tegra-uart",
.pm = &tegra_uart_pm_ops,
.of_match_table = tegra_uart_of_match,
.acpi_match_table = ACPI_PTR(tegra_uart_acpi_match),
},
.probe = tegra_uart_probe,
.remove = tegra_uart_remove,
};
module_platform_driver(tegra_uart_driver);
MODULE_AUTHOR("Jeff Brasen <jbrasen@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra 8250 Driver");
MODULE_LICENSE("GPL v2");
...@@ -500,6 +500,15 @@ config SERIAL_8250_PXA ...@@ -500,6 +500,15 @@ config SERIAL_8250_PXA
applicable to both devicetree and legacy boards, and early console is applicable to both devicetree and legacy boards, and early console is
part of its support. part of its support.
config SERIAL_8250_TEGRA
tristate "8250 support for Tegra serial ports"
default SERIAL_8250
depends on SERIAL_8250
depends on ARCH_TEGRA || COMPILE_TEST
help
Select this option if you have machine with an NVIDIA Tegra SoC and
wish to enable 8250 serial driver for the Tegra serial interfaces.
config SERIAL_OF_PLATFORM config SERIAL_OF_PLATFORM
tristate "Devicetree based probing for 8250 ports" tristate "Devicetree based probing for 8250 ports"
depends on SERIAL_8250 && OF depends on SERIAL_8250 && OF
......
...@@ -37,6 +37,7 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o ...@@ -37,6 +37,7 @@ obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
obj-$(CONFIG_SERIAL_8250_TEGRA) += 8250_tegra.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
...@@ -260,15 +260,6 @@ config SERIAL_SAMSUNG_UARTS ...@@ -260,15 +260,6 @@ config SERIAL_SAMSUNG_UARTS
help help
Select the number of available UART ports for the Samsung S3C Select the number of available UART ports for the Samsung S3C
serial driver serial driver
config SERIAL_SAMSUNG_DEBUG
bool "Samsung SoC serial debug"
depends on SERIAL_SAMSUNG && DEBUG_LL
help
Add support for debugging the serial driver. Since this is
generally being used as a console, we use our own output
routines that go via the low-level debug printascii()
function.
config SERIAL_SAMSUNG_CONSOLE config SERIAL_SAMSUNG_CONSOLE
bool "Support for console on Samsung SoC serial port" bool "Support for console on Samsung SoC serial port"
...@@ -1111,7 +1102,7 @@ config SERIAL_SC16IS7XX_SPI ...@@ -1111,7 +1102,7 @@ config SERIAL_SC16IS7XX_SPI
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 existing 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
...@@ -1279,6 +1270,7 @@ config SERIAL_AR933X ...@@ -1279,6 +1270,7 @@ config SERIAL_AR933X
tristate "AR933X serial port support" tristate "AR933X serial port support"
depends on HAVE_CLK && ATH79 depends on HAVE_CLK && ATH79
select SERIAL_CORE select SERIAL_CORE
select SERIAL_MCTRL_GPIO if GPIOLIB
help help
If you have an Atheros AR933X SOC based board and want to use the If you have an Atheros AR933X SOC based board and want to use the
built-in UART of the SoC, say Y to this option. built-in UART of the SoC, say Y to this option.
...@@ -1452,8 +1444,8 @@ config SERIAL_MEN_Z135 ...@@ -1452,8 +1444,8 @@ config SERIAL_MEN_Z135
config SERIAL_SPRD config SERIAL_SPRD
tristate "Support for Spreadtrum serial" tristate "Support for Spreadtrum serial"
depends on ARCH_SPRD
select SERIAL_CORE select SERIAL_CORE
depends on COMMON_CLK
help help
This enables the driver for the Spreadtrum's serial. This enables the driver for the Spreadtrum's serial.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/sysrq.h> #include <linux/sysrq.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
...@@ -29,6 +30,8 @@ ...@@ -29,6 +30,8 @@
#include <asm/mach-ath79/ar933x_uart.h> #include <asm/mach-ath79/ar933x_uart.h>
#include "serial_mctrl_gpio.h"
#define DRIVER_NAME "ar933x-uart" #define DRIVER_NAME "ar933x-uart"
#define AR933X_UART_MAX_SCALE 0xff #define AR933X_UART_MAX_SCALE 0xff
...@@ -47,6 +50,8 @@ struct ar933x_uart_port { ...@@ -47,6 +50,8 @@ struct ar933x_uart_port {
unsigned int min_baud; unsigned int min_baud;
unsigned int max_baud; unsigned int max_baud;
struct clk *clk; struct clk *clk;
struct mctrl_gpios *gpios;
struct gpio_desc *rts_gpiod;
}; };
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
...@@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up) ...@@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
} }
static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up)
{
up->ier |= AR933X_UART_INT_RX_VALID;
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
}
static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up)
{
up->ier &= ~AR933X_UART_INT_RX_VALID;
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
}
static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
{ {
unsigned int rdata; unsigned int rdata;
...@@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port) ...@@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
static unsigned int ar933x_uart_get_mctrl(struct uart_port *port) static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
{ {
return TIOCM_CAR; struct ar933x_uart_port *up =
container_of(port, struct ar933x_uart_port, port);
int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
mctrl_gpio_get(up->gpios, &ret);
return ret;
} }
static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{ {
struct ar933x_uart_port *up =
container_of(port, struct ar933x_uart_port, port);
mctrl_gpio_set(up->gpios, mctrl);
} }
static void ar933x_uart_start_tx(struct uart_port *port) static void ar933x_uart_start_tx(struct uart_port *port)
...@@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct uart_port *port) ...@@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct uart_port *port)
ar933x_uart_start_tx_interrupt(up); ar933x_uart_start_tx_interrupt(up);
} }
static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up)
{
unsigned int status;
unsigned int timeout = 60000;
/* Wait up to 60ms for the character(s) to be sent. */
do {
status = ar933x_uart_read(up, AR933X_UART_CS_REG);
if (--timeout == 0)
break;
udelay(1);
} while (status & AR933X_UART_CS_TX_BUSY);
if (timeout == 0)
dev_err(up->port.dev, "waiting for TX timed out\n");
}
static void ar933x_uart_rx_flush(struct ar933x_uart_port *up)
{
unsigned int status;
/* clear RX_VALID interrupt */
ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID);
/* remove characters from the RX FIFO */
do {
ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
} while (status & AR933X_UART_DATA_RX_CSR);
}
static void ar933x_uart_stop_tx(struct uart_port *port) static void ar933x_uart_stop_tx(struct uart_port *port)
{ {
struct ar933x_uart_port *up = struct ar933x_uart_port *up =
...@@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct uart_port *port) ...@@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct uart_port *port)
struct ar933x_uart_port *up = struct ar933x_uart_port *up =
container_of(port, struct ar933x_uart_port, port); container_of(port, struct ar933x_uart_port, port);
up->ier &= ~AR933X_UART_INT_RX_VALID; ar933x_uart_stop_rx_interrupt(up);
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
} }
static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
...@@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) ...@@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
{ {
struct circ_buf *xmit = &up->port.state->xmit; struct circ_buf *xmit = &up->port.state->xmit;
struct serial_rs485 *rs485conf = &up->port.rs485;
int count; int count;
bool half_duplex_send = false;
if (uart_tx_stopped(&up->port)) if (uart_tx_stopped(&up->port))
return; return;
if ((rs485conf->flags & SER_RS485_ENABLED) &&
(up->port.x_char || !uart_circ_empty(xmit))) {
ar933x_uart_stop_rx_interrupt(up);
gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
half_duplex_send = true;
}
count = up->port.fifosize; count = up->port.fifosize;
do { do {
unsigned int rdata; unsigned int rdata;
...@@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) ...@@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&up->port); uart_write_wakeup(&up->port);
if (!uart_circ_empty(xmit)) if (!uart_circ_empty(xmit)) {
ar933x_uart_start_tx_interrupt(up); ar933x_uart_start_tx_interrupt(up);
} else if (half_duplex_send) {
ar933x_uart_wait_tx_complete(up);
ar933x_uart_rx_flush(up);
ar933x_uart_start_rx_interrupt(up);
gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
}
} }
static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
...@@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct uart_port *port) ...@@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct uart_port *port)
AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE); AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
/* Enable RX interrupts */ /* Enable RX interrupts */
up->ier = AR933X_UART_INT_RX_VALID; ar933x_uart_start_rx_interrupt(up);
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
spin_unlock_irqrestore(&up->port.lock, flags); spin_unlock_irqrestore(&up->port.lock, flags);
...@@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart_ops = { ...@@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart_ops = {
.verify_port = ar933x_uart_verify_port, .verify_port = ar933x_uart_verify_port,
}; };
static int ar933x_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485conf)
{
struct ar933x_uart_port *up =
container_of(port, struct ar933x_uart_port, port);
if ((rs485conf->flags & SER_RS485_ENABLED) &&
!up->rts_gpiod) {
dev_err(port->dev, "RS485 needs rts-gpio\n");
return 1;
}
port->rs485 = *rs485conf;
return 0;
}
#ifdef CONFIG_SERIAL_AR933X_CONSOLE #ifdef CONFIG_SERIAL_AR933X_CONSOLE
static struct ar933x_uart_port * static struct ar933x_uart_port *
ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
...@@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct platform_device *pdev)
goto err_disable_clk; goto err_disable_clk;
} }
uart_get_rs485_mode(&pdev->dev, &port->rs485);
port->mapbase = mem_res->start; port->mapbase = mem_res->start;
port->line = id; port->line = id;
port->irq = irq_res->start; port->irq = irq_res->start;
...@@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct platform_device *pdev)
port->regshift = 2; port->regshift = 2;
port->fifosize = AR933X_UART_FIFO_SIZE; port->fifosize = AR933X_UART_FIFO_SIZE;
port->ops = &ar933x_uart_ops; port->ops = &ar933x_uart_ops;
port->rs485_config = ar933x_config_rs485;
baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1); baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD); up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
...@@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct platform_device *pdev)
baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
up->gpios = mctrl_gpio_init(port, 0);
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
return PTR_ERR(up->gpios);
up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
if ((port->rs485.flags & SER_RS485_ENABLED) &&
!up->rts_gpiod) {
dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n");
port->rs485.flags &= ~SER_RS485_ENABLED;
}
#ifdef CONFIG_SERIAL_AR933X_CONSOLE #ifdef CONFIG_SERIAL_AR933X_CONSOLE
ar933x_console_ports[up->port.line] = up; ar933x_console_ports[up->port.line] = up;
#endif #endif
......
...@@ -20,15 +20,12 @@ ...@@ -20,15 +20,12 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/atmel_pdc.h> #include <linux/atmel_pdc.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/platform_data/atmel.h> #include <linux/platform_data/atmel.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/suspend.h> #include <linux/suspend.h>
...@@ -2679,18 +2676,8 @@ static struct console atmel_console = { ...@@ -2679,18 +2676,8 @@ static struct console atmel_console = {
#define ATMEL_CONSOLE_DEVICE (&atmel_console) #define ATMEL_CONSOLE_DEVICE (&atmel_console)
static inline bool atmel_is_console_port(struct uart_port *port)
{
return port->cons && port->cons->index == port->line;
}
#else #else
#define ATMEL_CONSOLE_DEVICE NULL #define ATMEL_CONSOLE_DEVICE NULL
static inline bool atmel_is_console_port(struct uart_port *port)
{
return false;
}
#endif #endif
static struct uart_driver atmel_uart = { static struct uart_driver atmel_uart = {
...@@ -2719,14 +2706,14 @@ static int atmel_serial_suspend(struct platform_device *pdev, ...@@ -2719,14 +2706,14 @@ static int atmel_serial_suspend(struct platform_device *pdev,
struct uart_port *port = platform_get_drvdata(pdev); struct uart_port *port = platform_get_drvdata(pdev);
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
if (atmel_is_console_port(port) && console_suspend_enabled) { if (uart_console(port) && console_suspend_enabled) {
/* Drain the TX shifter */ /* Drain the TX shifter */
while (!(atmel_uart_readl(port, ATMEL_US_CSR) & while (!(atmel_uart_readl(port, ATMEL_US_CSR) &
ATMEL_US_TXEMPTY)) ATMEL_US_TXEMPTY))
cpu_relax(); cpu_relax();
} }
if (atmel_is_console_port(port) && !console_suspend_enabled) { if (uart_console(port) && !console_suspend_enabled) {
/* Cache register values as we won't get a full shutdown/startup /* Cache register values as we won't get a full shutdown/startup
* cycle * cycle
*/ */
...@@ -2762,7 +2749,7 @@ static int atmel_serial_resume(struct platform_device *pdev) ...@@ -2762,7 +2749,7 @@ static int atmel_serial_resume(struct platform_device *pdev)
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned long flags; unsigned long flags;
if (atmel_is_console_port(port) && !console_suspend_enabled) { if (uart_console(port) && !console_suspend_enabled) {
atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr); atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr);
atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr); atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr);
atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr); atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr);
...@@ -2916,7 +2903,7 @@ static int atmel_serial_probe(struct platform_device *pdev) ...@@ -2916,7 +2903,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
goto err_add_port; goto err_add_port;
#ifdef CONFIG_SERIAL_ATMEL_CONSOLE #ifdef CONFIG_SERIAL_ATMEL_CONSOLE
if (atmel_is_console_port(&atmel_port->uart) if (uart_console(&atmel_port->uart)
&& ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) {
/* /*
* The serial core enabled the clock for us, so undo * The serial core enabled the clock for us, so undo
...@@ -2959,7 +2946,7 @@ static int atmel_serial_probe(struct platform_device *pdev) ...@@ -2959,7 +2946,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
kfree(atmel_port->rx_ring.buf); kfree(atmel_port->rx_ring.buf);
atmel_port->rx_ring.buf = NULL; atmel_port->rx_ring.buf = NULL;
err_alloc_ring: err_alloc_ring:
if (!atmel_is_console_port(&atmel_port->uart)) { if (!uart_console(&atmel_port->uart)) {
clk_put(atmel_port->clk); clk_put(atmel_port->clk);
atmel_port->clk = NULL; atmel_port->clk = NULL;
} }
......
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* include/linux/atmel_serial.h * include/linux/atmel_serial.h
* *
......
// SPDX-License-Identifier: GPL-2.0 /* SPDX-License-Identifier: GPL-2.0 */
/* /*
* Driver for CPM (SCC/SMC) serial ports * Driver for CPM (SCC/SMC) serial ports
* *
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fs_uart_pd.h> #include <linux/fs_uart_pd.h>
struct gpio_desc;
#if defined(CONFIG_CPM2) #if defined(CONFIG_CPM2)
#include "cpm_uart_cpm2.h" #include "cpm_uart_cpm2.h"
#elif defined(CONFIG_CPM1) #elif defined(CONFIG_CPM1)
...@@ -80,7 +82,7 @@ struct uart_cpm_port { ...@@ -80,7 +82,7 @@ struct uart_cpm_port {
int wait_closing; int wait_closing;
/* value to combine with opcode to form cpm command */ /* value to combine with opcode to form cpm command */
u32 command; u32 command;
int gpios[NUM_GPIOS]; struct gpio_desc *gpios[NUM_GPIOS];
}; };
extern int cpm_uart_nr; extern int cpm_uart_nr;
......
...@@ -30,8 +30,7 @@ ...@@ -30,8 +30,7 @@
#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/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of_gpio.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -88,11 +87,11 @@ static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) ...@@ -88,11 +87,11 @@ static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
struct uart_cpm_port *pinfo = struct uart_cpm_port *pinfo =
container_of(port, struct uart_cpm_port, port); container_of(port, struct uart_cpm_port, port);
if (pinfo->gpios[GPIO_RTS] >= 0) if (pinfo->gpios[GPIO_RTS])
gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); gpiod_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
if (pinfo->gpios[GPIO_DTR] >= 0) if (pinfo->gpios[GPIO_DTR])
gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); gpiod_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
} }
static unsigned int cpm_uart_get_mctrl(struct uart_port *port) static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
...@@ -101,23 +100,23 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port) ...@@ -101,23 +100,23 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
container_of(port, struct uart_cpm_port, port); container_of(port, struct uart_cpm_port, port);
unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
if (pinfo->gpios[GPIO_CTS] >= 0) { if (pinfo->gpios[GPIO_CTS]) {
if (gpio_get_value(pinfo->gpios[GPIO_CTS])) if (gpiod_get_value(pinfo->gpios[GPIO_CTS]))
mctrl &= ~TIOCM_CTS; mctrl &= ~TIOCM_CTS;
} }
if (pinfo->gpios[GPIO_DSR] >= 0) { if (pinfo->gpios[GPIO_DSR]) {
if (gpio_get_value(pinfo->gpios[GPIO_DSR])) if (gpiod_get_value(pinfo->gpios[GPIO_DSR]))
mctrl &= ~TIOCM_DSR; mctrl &= ~TIOCM_DSR;
} }
if (pinfo->gpios[GPIO_DCD] >= 0) { if (pinfo->gpios[GPIO_DCD]) {
if (gpio_get_value(pinfo->gpios[GPIO_DCD])) if (gpiod_get_value(pinfo->gpios[GPIO_DCD]))
mctrl &= ~TIOCM_CAR; mctrl &= ~TIOCM_CAR;
} }
if (pinfo->gpios[GPIO_RI] >= 0) { if (pinfo->gpios[GPIO_RI]) {
if (!gpio_get_value(pinfo->gpios[GPIO_RI])) if (!gpiod_get_value(pinfo->gpios[GPIO_RI]))
mctrl |= TIOCM_RNG; mctrl |= TIOCM_RNG;
} }
...@@ -1139,6 +1138,7 @@ static int cpm_uart_init_port(struct device_node *np, ...@@ -1139,6 +1138,7 @@ static int cpm_uart_init_port(struct device_node *np,
{ {
const u32 *data; const u32 *data;
void __iomem *mem, *pram; void __iomem *mem, *pram;
struct device *dev = pinfo->port.dev;
int len; int len;
int ret; int ret;
int i; int i;
...@@ -1211,29 +1211,23 @@ static int cpm_uart_init_port(struct device_node *np, ...@@ -1211,29 +1211,23 @@ static int cpm_uart_init_port(struct device_node *np,
} }
for (i = 0; i < NUM_GPIOS; i++) { for (i = 0; i < NUM_GPIOS; i++) {
int gpio; struct gpio_desc *gpiod;
pinfo->gpios[i] = -1; pinfo->gpios[i] = NULL;
gpio = of_get_gpio(np, i); gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
if (gpio_is_valid(gpio)) { if (gpiod) {
ret = gpio_request(gpio, "cpm_uart");
if (ret) {
pr_err("can't request gpio #%d: %d\n", i, ret);
continue;
}
if (i == GPIO_RTS || i == GPIO_DTR) if (i == GPIO_RTS || i == GPIO_DTR)
ret = gpio_direction_output(gpio, 0); ret = gpiod_direction_output(gpiod, 0);
else else
ret = gpio_direction_input(gpio); ret = gpiod_direction_input(gpiod);
if (ret) { if (ret) {
pr_err("can't set direction for gpio #%d: %d\n", pr_err("can't set direction for gpio #%d: %d\n",
i, ret); i, ret);
gpio_free(gpio);
continue; continue;
} }
pinfo->gpios[i] = gpio; pinfo->gpios[i] = gpiod;
} }
} }
......
...@@ -170,6 +170,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) ...@@ -170,6 +170,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
int __init setup_earlycon(char *buf) int __init setup_earlycon(char *buf)
{ {
const struct earlycon_id **p_match; const struct earlycon_id **p_match;
bool empty_compatible = true;
if (!buf || !buf[0]) if (!buf || !buf[0])
return -EINVAL; return -EINVAL;
...@@ -177,6 +178,7 @@ int __init setup_earlycon(char *buf) ...@@ -177,6 +178,7 @@ int __init setup_earlycon(char *buf)
if (early_con.flags & CON_ENABLED) if (early_con.flags & CON_ENABLED)
return -EALREADY; return -EALREADY;
again:
for (p_match = __earlycon_table; p_match < __earlycon_table_end; for (p_match = __earlycon_table; p_match < __earlycon_table_end;
p_match++) { p_match++) {
const struct earlycon_id *match = *p_match; const struct earlycon_id *match = *p_match;
...@@ -185,6 +187,10 @@ int __init setup_earlycon(char *buf) ...@@ -185,6 +187,10 @@ int __init setup_earlycon(char *buf)
if (strncmp(buf, match->name, len)) if (strncmp(buf, match->name, len))
continue; continue;
/* prefer entries with empty compatible */
if (empty_compatible && *match->compatible)
continue;
if (buf[len]) { if (buf[len]) {
if (buf[len] != ',') if (buf[len] != ',')
continue; continue;
...@@ -195,6 +201,11 @@ int __init setup_earlycon(char *buf) ...@@ -195,6 +201,11 @@ int __init setup_earlycon(char *buf)
return register_earlycon(buf, match); return register_earlycon(buf, match);
} }
if (empty_compatible) {
empty_compatible = false;
goto again;
}
return -ENOENT; return -ENOENT;
} }
......
...@@ -200,7 +200,7 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port) ...@@ -200,7 +200,7 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port)
/* /*
* This is a reserved bit and I only saw it read as 0. But to be * This is a reserved bit and I only saw it read as 0. But to be
* sure not to be confused too much by new devices adhere to the * sure not to be confused too much by new devices adhere to the
* warning in the reference manual that reserverd bits might * warning in the reference manual that reserved bits might
* read as 1 in the future. * read as 1 in the future.
*/ */
rxdata &= ~SW_UARTn_RXDATAX_BERR; rxdata &= ~SW_UARTn_RXDATAX_BERR;
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* icom.h * icom.h
* *
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0 /* SPDX-License-Identifier: GPL-2.0 */
/**************************************************************************** /****************************************************************************
* *
* Driver for the IFX spi modem. * Driver for the IFX spi modem.
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#ifndef _IFX6X60_H #ifndef _IFX6X60_H
#define _IFX6X60_H #define _IFX6X60_H
struct gpio_desc;
#define DRVNAME "ifx6x60" #define DRVNAME "ifx6x60"
#define TTYNAME "ttyIFX" #define TTYNAME "ttyIFX"
...@@ -94,11 +96,12 @@ struct ifx_spi_device { ...@@ -94,11 +96,12 @@ struct ifx_spi_device {
struct { struct {
/* gpio lines */ /* gpio lines */
unsigned short srdy; /* slave-ready gpio */ struct gpio_desc *srdy; /* slave-ready gpio */
unsigned short mrdy; /* master-ready gpio */ struct gpio_desc *mrdy; /* master-ready gpio */
unsigned short reset; /* modem-reset gpio */ struct gpio_desc *reset; /* modem-reset gpio */
unsigned short po; /* modem-on gpio */ struct gpio_desc *po; /* modem-on gpio */
unsigned short reset_out; /* modem-in-reset gpio */ struct gpio_desc *reset_out; /* modem-in-reset gpio */
struct gpio_desc *pmu_reset; /* PMU reset gpio */
/* state/stats */ /* state/stats */
int unack_srdy_int_nb; int unack_srdy_int_nb;
} gpio; } gpio;
......
...@@ -195,6 +195,8 @@ struct imx_port { ...@@ -195,6 +195,8 @@ struct imx_port {
unsigned int have_rtscts:1; unsigned int have_rtscts:1;
unsigned int have_rtsgpio:1; unsigned int have_rtsgpio:1;
unsigned int dte_mode:1; unsigned int dte_mode:1;
unsigned int inverted_tx:1;
unsigned int inverted_rx:1;
struct clk *clk_ipg; struct clk *clk_ipg;
struct clk *clk_per; struct clk *clk_per;
const struct imx_uart_data *devdata; const struct imx_uart_data *devdata;
...@@ -1335,7 +1337,7 @@ static int imx_uart_startup(struct uart_port *port) ...@@ -1335,7 +1337,7 @@ static int imx_uart_startup(struct uart_port *port)
int retval, i; int retval, i;
unsigned long flags; unsigned long flags;
int dma_is_inited = 0; int dma_is_inited = 0;
u32 ucr1, ucr2, ucr4; u32 ucr1, ucr2, ucr3, ucr4;
retval = clk_prepare_enable(sport->clk_per); retval = clk_prepare_enable(sport->clk_per);
if (retval) if (retval)
...@@ -1387,11 +1389,29 @@ static int imx_uart_startup(struct uart_port *port) ...@@ -1387,11 +1389,29 @@ static int imx_uart_startup(struct uart_port *port)
imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr1, UCR1);
ucr4 = imx_uart_readl(sport, UCR4) & ~UCR4_OREN; ucr4 = imx_uart_readl(sport, UCR4) & ~(UCR4_OREN | UCR4_INVR);
if (!sport->dma_is_enabled) if (!sport->dma_is_enabled)
ucr4 |= UCR4_OREN; ucr4 |= UCR4_OREN;
if (sport->inverted_rx)
ucr4 |= UCR4_INVR;
imx_uart_writel(sport, ucr4, UCR4); imx_uart_writel(sport, ucr4, UCR4);
ucr3 = imx_uart_readl(sport, UCR3) & ~UCR3_INVT;
/*
* configure tx polarity before enabling tx
*/
if (sport->inverted_tx)
ucr3 |= UCR3_INVT;
if (!imx_uart_is_imx1(sport)) {
ucr3 |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
if (sport->dte_mode)
/* disable broken interrupts */
ucr3 &= ~(UCR3_RI | UCR3_DCD);
}
imx_uart_writel(sport, ucr3, UCR3);
ucr2 = imx_uart_readl(sport, UCR2) & ~UCR2_ATEN; ucr2 = imx_uart_readl(sport, UCR2) & ~UCR2_ATEN;
ucr2 |= (UCR2_RXEN | UCR2_TXEN); ucr2 |= (UCR2_RXEN | UCR2_TXEN);
if (!sport->have_rtscts) if (!sport->have_rtscts)
...@@ -1404,20 +1424,6 @@ static int imx_uart_startup(struct uart_port *port) ...@@ -1404,20 +1424,6 @@ static int imx_uart_startup(struct uart_port *port)
ucr2 &= ~UCR2_RTSEN; ucr2 &= ~UCR2_RTSEN;
imx_uart_writel(sport, ucr2, UCR2); imx_uart_writel(sport, ucr2, UCR2);
if (!imx_uart_is_imx1(sport)) {
u32 ucr3;
ucr3 = imx_uart_readl(sport, UCR3);
ucr3 |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
if (sport->dte_mode)
/* disable broken interrupts */
ucr3 &= ~(UCR3_RI | UCR3_DCD);
imx_uart_writel(sport, ucr3, UCR3);
}
/* /*
* Enable modem status interrupts * Enable modem status interrupts
*/ */
...@@ -2184,6 +2190,12 @@ static int imx_uart_probe_dt(struct imx_port *sport, ...@@ -2184,6 +2190,12 @@ static int imx_uart_probe_dt(struct imx_port *sport,
if (of_get_property(np, "rts-gpios", NULL)) if (of_get_property(np, "rts-gpios", NULL))
sport->have_rtsgpio = 1; sport->have_rtsgpio = 1;
if (of_get_property(np, "fsl,inverted-tx", NULL))
sport->inverted_tx = 1;
if (of_get_property(np, "fsl,inverted-rx", NULL))
sport->inverted_rx = 1;
return 0; return 0;
} }
#else #else
......
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/************************************************************************ /************************************************************************
* Copyright 2003 Digi International (www.digi.com) * Copyright 2003 Digi International (www.digi.com)
* *
......
This diff is collapsed.
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/gpio.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/ioport.h> #include <linux/ioport.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0+ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* PIC32 Integrated Serial Driver. * PIC32 Integrated Serial Driver.
* *
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment