Please consider for 4.19.y - applies cleanly on 4.19.102.
All three patches are already in 5.4.y so no need to apply them there as well.
Thanks, Mathieu
Boris Brezillon (1): spi: spi-mem: Add extra sanity checks on the op param
Brandon Maier (1): gpio: zynq: Report gpio direction at boot
Shubhrajyoti Datta (1): serial: uartps: Add a timeout to the tx empty wait
drivers/gpio/gpio-zynq.c | 23 +++++++++++++ drivers/spi/spi-mem.c | 54 ++++++++++++++++++++++++++---- drivers/tty/serial/xilinx_uartps.c | 14 +++++--- 3 files changed, 81 insertions(+), 10 deletions(-)
From: Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com
commit 277375b864e8147975b064b513f491e2a910e66a upstream
In case the cable is not connected then the target gets into an infinite wait for tx empty. Add a timeout to the tx empty wait.
Reported-by: Jean-Francois Dagenais jeff.dagenais@gmail.com Signed-off-by: Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/tty/serial/xilinx_uartps.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 66d49d511885..7cbee19ea93d 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -26,6 +26,7 @@ #include <linux/of.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/iopoll.h>
#define CDNS_UART_TTY_NAME "ttyPS" #define CDNS_UART_NAME "xuartps" @@ -34,6 +35,7 @@ #define CDNS_UART_NR_PORTS 2 #define CDNS_UART_FIFO_SIZE 64 /* FIFO size */ #define CDNS_UART_REGISTER_SPACE 0x1000 +#define TX_TIMEOUT 500000
/* Rx Trigger level */ static int rx_trigger_level = 56; @@ -681,16 +683,20 @@ static void cdns_uart_set_termios(struct uart_port *port, unsigned int cval = 0; unsigned int baud, minbaud, maxbaud; unsigned long flags; - unsigned int ctrl_reg, mode_reg; + unsigned int ctrl_reg, mode_reg, val; + int err;
spin_lock_irqsave(&port->lock, flags);
/* Wait for the transmit FIFO to empty before making changes */ if (!(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_TX_DIS)) { - while (!(readl(port->membase + CDNS_UART_SR) & - CDNS_UART_SR_TXEMPTY)) { - cpu_relax(); + err = readl_poll_timeout(port->membase + CDNS_UART_SR, + val, (val & CDNS_UART_SR_TXEMPTY), + 1000, TX_TIMEOUT); + if (err) { + dev_err(port->dev, "timed out waiting for tx empty"); + return; } }
From: Brandon Maier Brandon.Maier@collins.com
commit 6169005ceb8c715582eca70df3912cd2b351ede2 upstream
The Zynq's gpios can be configured by the bootloader. But Linux will erroneously report all gpios as inputs unless we implement get_direction().
Signed-off-by: Brandon Maier Brandon.Maier@collins.com Tested-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/gpio/gpio-zynq.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index a9238fb15013..5dec96155814 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -357,6 +357,28 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, return 0; }
+/** + * zynq_gpio_get_direction - Read the direction of the specified GPIO pin + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * + * This function returns the direction of the specified GPIO. + * + * Return: 0 for output, 1 for input + */ +static int zynq_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + u32 reg; + unsigned int bank_num, bank_pin_num; + struct zynq_gpio *gpio = gpiochip_get_data(chip); + + zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); + + reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + + return !(reg & BIT(bank_pin_num)); +} + /** * zynq_gpio_irq_mask - Disable the interrupts for a gpio pin * @irq_data: per irq and chip data passed down to chip functions @@ -829,6 +851,7 @@ static int zynq_gpio_probe(struct platform_device *pdev) chip->free = zynq_gpio_free; chip->direction_input = zynq_gpio_dir_in; chip->direction_output = zynq_gpio_dir_out; + chip->get_direction = zynq_gpio_get_direction; chip->base = of_alias_get_id(pdev->dev.of_node, "gpio"); chip->ngpio = gpio->p_data->ngpio;
From: Boris Brezillon boris.brezillon@bootlin.com
commit 380583227c0c7f52383b0cd5c0e2de93ed31d553 upstream
Some combinations are simply not valid and should be rejected before the op is passed to the SPI controller driver.
Add an spi_mem_check_op() helper and use it in spi_mem_exec_op() and spi_mem_supports_op() to make sure the spi-mem operation is valid.
Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/spi/spi-mem.c | 54 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index eb72dba71d83..cc3d425aae56 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -12,6 +12,8 @@
#include "internals.h"
+#define SPI_MEM_MAX_BUSWIDTH 4 + /** * spi_controller_dma_map_mem_op_data() - DMA-map the buffer attached to a * memory operation @@ -149,6 +151,44 @@ static bool spi_mem_default_supports_op(struct spi_mem *mem, } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+static bool spi_mem_buswidth_is_valid(u8 buswidth) +{ + if (hweight8(buswidth) > 1 || buswidth > SPI_MEM_MAX_BUSWIDTH) + return false; + + return true; +} + +static int spi_mem_check_op(const struct spi_mem_op *op) +{ + if (!op->cmd.buswidth) + return -EINVAL; + + if ((op->addr.nbytes && !op->addr.buswidth) || + (op->dummy.nbytes && !op->dummy.buswidth) || + (op->data.nbytes && !op->data.buswidth)) + return -EINVAL; + + if (spi_mem_buswidth_is_valid(op->cmd.buswidth) || + spi_mem_buswidth_is_valid(op->addr.buswidth) || + spi_mem_buswidth_is_valid(op->dummy.buswidth) || + spi_mem_buswidth_is_valid(op->data.buswidth)) + return -EINVAL; + + return 0; +} + +static bool spi_mem_internal_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct spi_controller *ctlr = mem->spi->controller; + + if (ctlr->mem_ops && ctlr->mem_ops->supports_op) + return ctlr->mem_ops->supports_op(mem, op); + + return spi_mem_default_supports_op(mem, op); +} + /** * spi_mem_supports_op() - Check if a memory device and the controller it is * connected to support a specific memory operation @@ -166,12 +206,10 @@ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); */ bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { - struct spi_controller *ctlr = mem->spi->controller; - - if (ctlr->mem_ops && ctlr->mem_ops->supports_op) - return ctlr->mem_ops->supports_op(mem, op); + if (spi_mem_check_op(op)) + return false;
- return spi_mem_default_supports_op(mem, op); + return spi_mem_internal_supports_op(mem, op); } EXPORT_SYMBOL_GPL(spi_mem_supports_op);
@@ -196,7 +234,11 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) u8 *tmpbuf; int ret;
- if (!spi_mem_supports_op(mem, op)) + ret = spi_mem_check_op(op); + if (ret) + return ret; + + if (!spi_mem_internal_supports_op(mem, op)) return -ENOTSUPP;
if (ctlr->mem_ops) {
On Mon, Feb 10, 2020 at 10:18:24AM -0700, Mathieu Poirier wrote:
Please consider for 4.19.y - applies cleanly on 4.19.102.
All three patches are already in 5.4.y so no need to apply them there as well.
Thanks, Mathieu
Boris Brezillon (1): spi: spi-mem: Add extra sanity checks on the op param
Brandon Maier (1): gpio: zynq: Report gpio direction at boot
Shubhrajyoti Datta (1): serial: uartps: Add a timeout to the tx empty wait
drivers/gpio/gpio-zynq.c | 23 +++++++++++++ drivers/spi/spi-mem.c | 54 ++++++++++++++++++++++++++---- drivers/tty/serial/xilinx_uartps.c | 14 +++++--- 3 files changed, 81 insertions(+), 10 deletions(-)
I've queued them up, thank you.
linux-stable-mirror@lists.linaro.org