aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2020-03-06 13:12:02 +0100
committerDaniel Golle <daniel@makrotopia.org>2020-03-06 13:14:02 +0100
commitca6885456fe2307d8cee850bd1c41e7ebfe74a38 (patch)
tree4c28b15ed81a31bcf4c1b9c532bf49eea2be311e
parenta017773a92d624142a78452bc0c00e6bc6523967 (diff)
downloadupstream-ca6885456fe2307d8cee850bd1c41e7ebfe74a38.tar.gz
upstream-ca6885456fe2307d8cee850bd1c41e7ebfe74a38.tar.bz2
upstream-ca6885456fe2307d8cee850bd1c41e7ebfe74a38.zip
ath79: re-add accidentally dropped patch to kernel 5.4
Patch 0061-tty-serial-ar933x-uart-rs485-gpio.patch wasn't included when adding support for kernel 5.4. Re-add it and refresh patches. Fixes: 53ab9865c2 ("ath79: add support for kernel 5.4") Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-rw-r--r--target/linux/ath79/patches-5.4/0036-GPIO-add-named-gpio-exports.patch8
-rw-r--r--target/linux/ath79/patches-5.4/0061-tty-serial-ar933x-uart-rs485-gpio.patch267
-rw-r--r--target/linux/ath79/patches-5.4/405-mtd-tp-link-partition-parser.patch4
-rw-r--r--target/linux/ath79/patches-5.4/910-unaligned_access_hacks.patch16
4 files changed, 281 insertions, 14 deletions
diff --git a/target/linux/ath79/patches-5.4/0036-GPIO-add-named-gpio-exports.patch b/target/linux/ath79/patches-5.4/0036-GPIO-add-named-gpio-exports.patch
index c07d3d3fea..d4ea379159 100644
--- a/target/linux/ath79/patches-5.4/0036-GPIO-add-named-gpio-exports.patch
+++ b/target/linux/ath79/patches-5.4/0036-GPIO-add-named-gpio-exports.patch
@@ -22,8 +22,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
#include "gpiolib.h"
#include "gpiolib-of.h"
-@@ -895,3 +897,68 @@ void of_gpiochip_remove(struct gpio_chip
- gpiochip_remove_pin_ranges(chip);
+@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip
+ {
of_node_put(chip->of_node);
}
+
@@ -141,7 +141,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
{
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
-@@ -661,6 +661,7 @@ static inline void devm_acpi_dev_remove_
+@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
@@ -149,7 +149,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
-@@ -668,6 +669,13 @@ void gpiod_unexport(struct gpio_desc *de
+@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
diff --git a/target/linux/ath79/patches-5.4/0061-tty-serial-ar933x-uart-rs485-gpio.patch b/target/linux/ath79/patches-5.4/0061-tty-serial-ar933x-uart-rs485-gpio.patch
new file mode 100644
index 0000000000..54811eb4c1
--- /dev/null
+++ b/target/linux/ath79/patches-5.4/0061-tty-serial-ar933x-uart-rs485-gpio.patch
@@ -0,0 +1,267 @@
+From patchwork Fri Feb 21 21:23:31 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 1198835
+Date: Fri, 21 Feb 2020 22:23:31 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
+ Jiri Slaby <jslaby@suse.com>, Petr =?utf-8?q?=C5=A0tetiar?= <ynezz@true.cz>,
+ Chuanhong Guo <gch981213@gmail.com>, Piotr Dymacz <pepe2k@gmail.com>
+Subject: [PATCH v2] serial: ar933x_uart: add RS485 support
+Message-ID: <20200221212331.GA21467@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+Sender: linux-kernel-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <linux-kernel.vger.kernel.org>
+X-Mailing-List: linux-kernel@vger.kernel.org
+
+Emulate half-duplex operation and use mctrl_gpio to add support for
+RS485 tranceiver with transmit/receive switch hooked to RTS GPIO line.
+This is needed to make use of the RS485 port found on Teltonika RUT955.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+v2: use bool to indicate ongoing half-duplex send, use it afterwards
+ to decide whether we've just been in a send operation.
+
+ drivers/tty/serial/Kconfig | 1 +
+ drivers/tty/serial/ar933x_uart.c | 113 +++++++++++++++++++++++++++++--
+ 2 files changed, 108 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/Kconfig
++++ b/drivers/tty/serial/Kconfig
+@@ -1279,6 +1279,7 @@ config SERIAL_AR933X
+ tristate "AR933X serial port support"
+ depends on HAVE_CLK && ATH79
+ select SERIAL_CORE
++ select SERIAL_MCTRL_GPIO if GPIOLIB
+ help
+ 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.
+--- a/drivers/tty/serial/ar933x_uart.c
++++ b/drivers/tty/serial/ar933x_uart.c
+@@ -13,6 +13,7 @@
+ #include <linux/console.h>
+ #include <linux/sysrq.h>
+ #include <linux/delay.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+@@ -29,6 +30,8 @@
+
+ #include <asm/mach-ath79/ar933x_uart.h>
+
++#include "serial_mctrl_gpio.h"
++
+ #define DRIVER_NAME "ar933x-uart"
+
+ #define AR933X_UART_MAX_SCALE 0xff
+@@ -47,6 +50,8 @@ struct ar933x_uart_port {
+ unsigned int min_baud;
+ unsigned int max_baud;
+ struct clk *clk;
++ struct mctrl_gpios *gpios;
++ struct gpio_desc *rts_gpiod;
+ };
+
+ static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
+@@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_i
+ 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)
+ {
+ unsigned int rdata;
+@@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty
+
+ 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)
+ {
++ 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)
+@@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct
+ 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)
+ {
+ struct ar933x_uart_port *up =
+@@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct u
+ struct ar933x_uart_port *up =
+ container_of(port, struct ar933x_uart_port, port);
+
+- up->ier &= ~AR933X_UART_INT_RX_VALID;
+- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
++ ar933x_uart_stop_rx_interrupt(up);
+ }
+
+ static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
+@@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct
+ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
+ {
+ struct circ_buf *xmit = &up->port.state->xmit;
++ struct serial_rs485 *rs485conf = &up->port.rs485;
+ int count;
++ bool half_duplex_send = false;
+
+ if (uart_tx_stopped(&up->port))
+ 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;
+ do {
+ unsigned int rdata;
+@@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&up->port);
+
+- if (!uart_circ_empty(xmit))
++ if (!uart_circ_empty(xmit)) {
+ 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)
+@@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct ua
+ AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
+
+ /* Enable RX interrupts */
+- up->ier = AR933X_UART_INT_RX_VALID;
+- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
++ ar933x_uart_start_rx_interrupt(up);
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+@@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart
+ .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
+ static struct ar933x_uart_port *
+ ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
+@@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct plat
+ goto err_disable_clk;
+ }
+
++ uart_get_rs485_mode(&pdev->dev, &port->rs485);
++
+ port->mapbase = mem_res->start;
+ port->line = id;
+ port->irq = irq_res->start;
+@@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct plat
+ port->regshift = 2;
+ port->fifosize = AR933X_UART_FIFO_SIZE;
+ port->ops = &ar933x_uart_ops;
++ port->rs485_config = ar933x_config_rs485;
+
+ baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
+ up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
+@@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct plat
+ 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->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
+ ar933x_console_ports[up->port.line] = up;
+ #endif
diff --git a/target/linux/ath79/patches-5.4/405-mtd-tp-link-partition-parser.patch b/target/linux/ath79/patches-5.4/405-mtd-tp-link-partition-parser.patch
index 7ea07f376c..11d1869544 100644
--- a/target/linux/ath79/patches-5.4/405-mtd-tp-link-partition-parser.patch
+++ b/target/linux/ath79/patches-5.4/405-mtd-tp-link-partition-parser.patch
@@ -21,5 +21,5 @@
obj-y += parsers/
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
+ obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
+
diff --git a/target/linux/ath79/patches-5.4/910-unaligned_access_hacks.patch b/target/linux/ath79/patches-5.4/910-unaligned_access_hacks.patch
index 950430a2a5..3ac89f1e5c 100644
--- a/target/linux/ath79/patches-5.4/910-unaligned_access_hacks.patch
+++ b/target/linux/ath79/patches-5.4/910-unaligned_access_hacks.patch
@@ -305,7 +305,7 @@
list_for_each_entry(p, head, list) {
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
-@@ -457,48 +457,53 @@ static void tcp_options_write(__be32 *pt
+@@ -460,48 +460,53 @@ static void tcp_options_write(__be32 *pt
u16 options = opts->options; /* mungable copy */
if (unlikely(OPTION_MD5 & options)) {
@@ -382,7 +382,7 @@
}
if (unlikely(opts->num_sack_blocks)) {
-@@ -506,16 +511,17 @@ static void tcp_options_write(__be32 *pt
+@@ -509,16 +514,17 @@ static void tcp_options_write(__be32 *pt
tp->duplicate_sack : tp->selective_acks;
int this_sack;
@@ -406,7 +406,7 @@
}
tp->rx_opt.dsack = 0;
-@@ -528,13 +534,14 @@ static void tcp_options_write(__be32 *pt
+@@ -531,13 +537,14 @@ static void tcp_options_write(__be32 *pt
if (foc->exp) {
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
@@ -706,7 +706,7 @@
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -3953,14 +3953,16 @@ static bool tcp_parse_aligned_timestamp(
+@@ -3958,14 +3958,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
@@ -754,7 +754,7 @@
ptr = ip6hoff + sizeof(struct ipv6hdr);
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
-@@ -274,8 +274,10 @@ static inline bool neigh_key_eq128(const
+@@ -273,8 +273,10 @@ static inline bool neigh_key_eq128(const
const u32 *n32 = (const u32 *)n->primary_key;
const u32 *p32 = pkey;
@@ -780,7 +780,7 @@
* No flags defined yet.
--- a/net/core/utils.c
+++ b/net/core/utils.c
-@@ -443,8 +443,14 @@ void inet_proto_csum_replace16(__sum16 *
+@@ -460,8 +460,14 @@ void inet_proto_csum_replace16(__sum16 *
bool pseudohdr)
{
__be32 diff[] = {
@@ -799,7 +799,7 @@
*sum = csum_fold(csum_partial(diff, sizeof(diff),
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
-@@ -496,7 +496,7 @@ static inline bool is_etherdev_addr(cons
+@@ -489,7 +489,7 @@ static inline bool is_etherdev_addr(cons
* @b: Pointer to Ethernet header
*
* Compare two Ethernet headers, returns 0 if equal.
@@ -808,7 +808,7 @@
* aligned OR the platform can handle unaligned access. This is the
* case for all packets coming into netif_receive_skb or similar
* entry points.
-@@ -519,11 +519,12 @@ static inline unsigned long compare_ethe
+@@ -512,11 +512,12 @@ static inline unsigned long compare_ethe
fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
return fold;
#else