Re: [PATCH 2/4] tty: atmel_serial: convert tasklets to use new tasklet_setup() API

2020-08-26 Thread Richard Genoud
Le 17/08/2020 à 10:59, Allen Pais a écrit :
> From: Allen Pais 
> 
> In preparation for unconditionally passing the
> struct tasklet_struct pointer to all tasklet
> callbacks, switch to using the new tasklet_setup()
> and from_tasklet() to pass the tasklet pointer explicitly.
> 
> Signed-off-by: Romain Perier 
> Signed-off-by: Allen Pais 
Acked-by: Richard Genoud 

> ---
>  drivers/tty/serial/atmel_serial.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index e43471b33710..a9c47f56e994 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1722,10 +1722,11 @@ static int atmel_prepare_rx_pdc(struct uart_port 
> *port)
>  /*
>   * tasklet handling tty stuff outside the interrupt handler.
>   */
> -static void atmel_tasklet_rx_func(unsigned long data)
> +static void atmel_tasklet_rx_func(struct tasklet_struct *t)
>  {
> - struct uart_port *port = (struct uart_port *)data;
> - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t,
> +   tasklet_rx);
> + struct uart_port *port = _port->uart;
>  
>   /* The interrupt handler does not take the lock */
>   spin_lock(>lock);
> @@ -1733,10 +1734,11 @@ static void atmel_tasklet_rx_func(unsigned long data)
>   spin_unlock(>lock);
>  }
>  
> -static void atmel_tasklet_tx_func(unsigned long data)
> +static void atmel_tasklet_tx_func(struct tasklet_struct *t)
>  {
> - struct uart_port *port = (struct uart_port *)data;
> - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t,
> +   tasklet_tx);
> + struct uart_port *port = _port->uart;
>  
>   /* The interrupt handler does not take the lock */
>   spin_lock(>lock);
> @@ -1911,10 +1913,8 @@ static int atmel_startup(struct uart_port *port)
>   }
>  
>   atomic_set(_port->tasklet_shutdown, 0);
> - tasklet_init(_port->tasklet_rx, atmel_tasklet_rx_func,
> - (unsigned long)port);
> - tasklet_init(_port->tasklet_tx, atmel_tasklet_tx_func,
> - (unsigned long)port);
> + tasklet_setup(_port->tasklet_rx, atmel_tasklet_rx_func);
> + tasklet_setup(_port->tasklet_tx, atmel_tasklet_tx_func);
>  
>   /*
>* Initialize DMA (if necessary)
> 

Thanks !


Re: [PATCH] can: m_can_platform: fix m_can_runtime_suspend()

2020-06-09 Thread Richard Genoud

Hi Dan,

Le 08/06/2020 à 16:27, Dan Murphy a écrit :

Richard

On 6/8/20 4:43 AM, Richard Genoud wrote:

Since commit f524f829b75a ("can: m_can: Create a m_can platform
framework"), the can peripheral on STM32MP1 wasn't working anymore.

The reason was a bad copy/paste maneuver that added a call to
m_can_class_suspend() in m_can_runtime_suspend().


Are you sure it was a copy paste error?

Probably don't want to have an unfounded cause unless you know for 
certain it was this.

I understand.

What makes me think it was a copy-paste error is that the primary goal 
of the patch series "M_CAN Framework" was to introduce the tcan4x5x 
driver into the kernel.
For that, the code has to be split into a re-usable code (m_can.c) and a 
platform code m_can_platform.c

And finally, tcan4x5x.c can be added.
(I'm sure you already know that since you write the patch, it's just to 
be sure that we are on the same page :))


So, when splitting the m_can code into m_can.c and m_can_platform.c, 
there was no reason to change the behavior, even less reason to change 
the behavior in m_can_platform.c, since the main target was tcan4x5x.
(And the behavior changed because the CAN peripheral on the STM32MP1 was 
working before this patch, and not after).


So I went digging into that and I realized that before this patch, 
runtime suspend function was in m_can.c:

static int __maybe_unused m_can_runtime_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *priv = netdev_priv(ndev);

clk_disable_unprepare(priv->cclk);
clk_disable_unprepare(priv->hclk);

return 0;
}

And after, in m_can_platform.c:
static int __maybe_unused m_can_runtime_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *mcan_class = netdev_priv(ndev);

m_can_class_suspend(dev);

clk_disable_unprepare(mcan_class->cclk);
clk_disable_unprepare(mcan_class->hclk);

return 0;
}

Same for runtime resume,
Before:
static int __maybe_unused m_can_runtime_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *priv = netdev_priv(ndev);
int err;

err = clk_prepare_enable(priv->hclk);
if (err)
return err;

err = clk_prepare_enable(priv->cclk);
if (err)
clk_disable_unprepare(priv->hclk);

return err;
}

After:
static int __maybe_unused m_can_runtime_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *mcan_class = netdev_priv(ndev);
int err;

err = clk_prepare_enable(mcan_class->hclk);
if (err)
return err;

err = clk_prepare_enable(mcan_class->cclk);
if (err)
clk_disable_unprepare(mcan_class->hclk);

m_can_class_resume(dev);

return err;
}

Now, the m_class_resume() call has been removed by commit 0704c5743694 
("can: m_can_platform: remove unnecessary m_can_class_resume() call")

cf https://lkml.org/lkml/2019/11/19/965

Then only the m_can_class_suspend() call is left alone. If I remove it, 
the stm32mp1 peripheral works as before the patch. (and the code is 
symmetrical again :))


I read all the iterations I could find about this patch (see note 1), 
and I didn't found any comment on the addition of 
m_can_class_{resume,suspend}() calls.


But I found this in v3 cover letter:
"The m_can platform code will need to be updated as I have not tested 
this code."

and in v3 1/4 comments:
"This patch set is working for the TCAN and at least boots on io-mapped 
devices."


For me, that means that the code in m_can_platform.c was written with 
this sentence in mind :
"I can test everything but this, so let's try not to break things in 
there, keep the changes at a minimum"
And that was really the case for all the file, but the 2 calls to 
m_can_class_{resume,suspend}().


So that's why I have a pretty good confidence in the fact that it was a 
copy-paste error.


And, moreover, if m_can_class_suspend() is called, the CAN device is 
stopped, and all interrupts are disabled (in m_can_stop()), so the 
device can not wake-up by itself (and thus not working anymore).



All this make me think that maybe I should send a v2 of this patch with 
a bigger commit message.

What do you think ?


Thanks !

Richard.




Dan




Note 1: patches v3 to v12 (missing v11)
https://lwn.net/ml/linux-kernel/2019073236.14329-1-dmur...@ti.com/
https://lore.kernel.org/patchwork/patch/1033094/
https://lore.kernel.org/patchwork/cover/1042441/
https://lore.kernel.org/patchwork/patch/1047220/
https://lore.kernel.org/patchwork/patch/1047980/
https://lkml.org/lkml/2019/3/12/362
https://lkml.org/lkml/2019/3/13/512
https://www.spinics.net/lists/netdev/msg557961.html
https://lore.kernel.org/patchwork/patch/1071894/


[PATCH] can: m_can_platform: fix m_can_runtime_suspend()

2020-06-08 Thread Richard Genoud
Since commit f524f829b75a ("can: m_can: Create a m_can platform
framework"), the can peripheral on STM32MP1 wasn't working anymore.

The reason was a bad copy/paste maneuver that added a call to
m_can_class_suspend() in m_can_runtime_suspend().

Tested on STM32MP157C-DK2 and emSBC-Argon

Fixes: f524f829b75a ("can: m_can: Create a m_can platform framework")
Signed-off-by: Richard Genoud 
---
 drivers/net/can/m_can/m_can_platform.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/can/m_can/m_can_platform.c 
b/drivers/net/can/m_can/m_can_platform.c
index 38ea5e600fb8..e6d0cb9ee02f 100644
--- a/drivers/net/can/m_can/m_can_platform.c
+++ b/drivers/net/can/m_can/m_can_platform.c
@@ -144,8 +144,6 @@ static int __maybe_unused m_can_runtime_suspend(struct 
device *dev)
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_classdev *mcan_class = netdev_priv(ndev);
 
-   m_can_class_suspend(dev);
-
clk_disable_unprepare(mcan_class->cclk);
clk_disable_unprepare(mcan_class->hclk);
 


Re: [PATCH v6 2/2] tty: add rpmsg driver

2019-09-05 Thread Richard Genoud
Hi Arnaud,

Le 04/09/2019 à 15:09, Arnaud Pouliquen a écrit :
> This driver exposes a standard tty interface on top of the rpmsg
> framework through a rpmsg service.
> 
> This driver supports multi-instances, offering a /dev/ttyRPMSGx entry
> per rpmsg endpoint.
> 
> Signed-off-by: Arnaud Pouliquen 
> Signed-off-by: Fabien Dessenne 
> ---
>  Documentation/serial/tty_rpmsg.rst |  45 
>  drivers/tty/Kconfig|   9 +
>  drivers/tty/Makefile   |   1 +
>  drivers/tty/rpmsg_tty.c| 418 
> +
>  4 files changed, 473 insertions(+)
>  create mode 100644 Documentation/serial/tty_rpmsg.rst
>  create mode 100644 drivers/tty/rpmsg_tty.c
> 
> diff --git a/Documentation/serial/tty_rpmsg.rst 
> b/Documentation/serial/tty_rpmsg.rst
> new file mode 100644
> index ..fc1d3fba73c5
> --- /dev/null
> +++ b/Documentation/serial/tty_rpmsg.rst
> @@ -0,0 +1,45 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +=
> +The rpmsg TTY
> +=
> +
> +The rpmsg tty driver implements serial communication on the RPMsg bus to 
> makes possible for user-space programs to send and receive rpmsg messages as 
> a standard tty protocol.
> +
> +The remote processor can instantiate a new tty by requesting:
> +- a "rpmsg-tty-raw" RPMsg service, for TTY raw data support without flow 
> control
> +- a "rpmsg-tty-ctrl" RPMSg service, for TTY support with flow control.
> +
> +Information related to the RPMsg and associated tty device is available in
> +/sys/bus/rpmsg/devices/.
> +
> +RPMsg TTY without control
> +-
> +
> +The default end point associated with the "rpmsg-tty-raw" service is directly
> +used for data exchange. No flow control is available.
> +
> +To be compliant with this driver, the remote firmware must create its data 
> end point associated with the "rpmsg-tty-raw" service.
> +
> +RPMsg TTY with control
> +-
> +
> +The default end point associated with the "rpmsg-tty-ctrl" service is 
> reserved for
> +the control. A second endpoint must be created for data exchange.
> +
> +The control channel is used to transmit to the remote processor the CTS 
> status,
> +as well as the end point address for data transfer.
> +
> +To be compatible with this driver, the remote firmware must create or use 
> its end point associated with "rpmsg-tty-ctrl" service, plus a second 
> endpoint for the data flow.
> +On Linux rpmsg_tty probes, the data endpoint address and the CTS (set to 
> disable)
> +is sent to the remote processor.
> +The remote processor has to respect following rules:
> +- It only transmits data when Linux remote cts is enable, otherwise message
> +  could be lost.
> +- It can pause/resume reception by sending a control message (rely on CTS 
> state).
> +
> +Control message structure:
> +struct rpmsg_tty_ctrl {
> + u8 cts; /* remote reception status */
> + u16 d_ept_addr; /* data endpoint address */
> +};
Correct me if I'm wrong, but I think this structure should be packed,
shouldn't it ?
It's working ok on the STM32MP127, between M4 and A7, but the alignment
may be not the same on another architecture ?



> diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
> index c7623f99ac0f..1046bf4aa709 100644
> --- a/drivers/tty/Kconfig
> +++ b/drivers/tty/Kconfig
> @@ -454,6 +454,15 @@ config VCC
>   help
> Support for Sun logical domain consoles.
>  
> +config RPMSG_TTY
> + tristate "RPMSG tty driver"
> + depends on RPMSG
> + help
> +   Say y here to export rpmsg endpoints as tty devices, usually found
> +   in /dev/ttyRPMSGx.
> +   This makes it possible for user-space programs to send and receive
> +   rpmsg messages as a standard tty protocol.
> +
>  config LDISC_AUTOLOAD
>   bool "Automatically load TTY Line Disciplines"
>   default y
> diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
> index 020b1cd9294f..c2465e7ebc2a 100644
> --- a/drivers/tty/Makefile
> +++ b/drivers/tty/Makefile
> @@ -34,5 +34,6 @@ obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
>  obj-$(CONFIG_GOLDFISH_TTY)   += goldfish.o
>  obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o
>  obj-$(CONFIG_VCC)+= vcc.o
> +obj-$(CONFIG_RPMSG_TTY)  += rpmsg_tty.o
>  
>  obj-y += ipwireless/
> diff --git a/drivers/tty/rpmsg_tty.c b/drivers/tty/rpmsg_tty.c
> new file mode 100644
> index ..3e4d0e1a6663
> --- /dev/null
> +++ b/drivers/tty/rpmsg_tty.c
> @@ -0,0 +1,418 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
> + * Authors: Arnaud Pouliquen  for 
> STMicroelectronics.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define MAX_TTY_RPMSG32
> +
> +#define TTY_CH_NAME_RAW  "rpmsg-tty-raw"
> +#define TTY_CH_NAME_WITH_CTS "rpmsg-tty-ctrl"
> +
> +static DEFINE_IDR(tty_idr);  /* tty instance id 

[PATCH v2] tty/serial: atmel: remove unneeded atmel_get_lines_status function

2019-08-26 Thread Richard Genoud
Since commit 18dfef9c7f87 ("serial: atmel: convert to irq handling
provided mctrl-gpio"), the GPIOs interrupts are handled by
mctrl_gpio_irq_handle().
So, atmel_get_lines_status() can be completely killed and replaced by :
atmel_uart_readl(port, ATMEL_US_CSR);

Suggested-by: Uwe Kleine-König 
Acked-by: Uwe Kleine-König 
Signed-off-by: Richard Genoud 
---
 drivers/tty/serial/atmel_serial.c | 48 ++-
 1 file changed, 2 insertions(+), 46 deletions(-)

Changes from v1:
 - point out the right commit (thx Uwe)
 - add Suggested-by/Acked-by

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 9a54c9e6d36e..a8dc8af83f39 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -294,50 +294,6 @@ static void atmel_tasklet_schedule(struct atmel_uart_port 
*atmel_port,
tasklet_schedule(t);
 }
 
-static unsigned int atmel_get_lines_status(struct uart_port *port)
-{
-   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-   unsigned int status, ret = 0;
-
-   status = atmel_uart_readl(port, ATMEL_US_CSR);
-
-   mctrl_gpio_get(atmel_port->gpios, );
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_CTS))) {
-   if (ret & TIOCM_CTS)
-   status &= ~ATMEL_US_CTS;
-   else
-   status |= ATMEL_US_CTS;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_DSR))) {
-   if (ret & TIOCM_DSR)
-   status &= ~ATMEL_US_DSR;
-   else
-   status |= ATMEL_US_DSR;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_RI))) {
-   if (ret & TIOCM_RI)
-   status &= ~ATMEL_US_RI;
-   else
-   status |= ATMEL_US_RI;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_DCD))) {
-   if (ret & TIOCM_CD)
-   status &= ~ATMEL_US_DCD;
-   else
-   status |= ATMEL_US_DCD;
-   }
-
-   return status;
-}
-
 /* Enable or disable the rs485 support */
 static int atmel_config_rs485(struct uart_port *port,
  struct serial_rs485 *rs485conf)
@@ -1453,7 +1409,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
spin_lock(_port->lock_suspended);
 
do {
-   status = atmel_get_lines_status(port);
+   status = atmel_uart_readl(port, ATMEL_US_CSR);
mask = atmel_uart_readl(port, ATMEL_US_IMR);
pending = status & mask;
if (!pending)
@@ -2002,7 +1958,7 @@ static int atmel_startup(struct uart_port *port)
}
 
/* Save current CSR for comparison in atmel_tasklet_func() */
-   atmel_port->irq_status_prev = atmel_get_lines_status(port);
+   atmel_port->irq_status_prev = atmel_uart_readl(port, ATMEL_US_CSR);
 
/*
 * Finally, enable the serial port


[PATCH] tty/serial: atmel: remove unneeded atmel_get_lines_status function

2019-08-23 Thread Richard Genoud
Since commit ce59e48fdbad ("serial: mctrl_gpio: implement interrupt
handling"), the GPIOs interrupts are handled by mctrl_gpio_irq_handle().
So, atmel_get_lines_status() can be completely killed and replaced by :
atmel_uart_readl(port, ATMEL_US_CSR);

Signed-off-by: Richard Genoud 
---
 drivers/tty/serial/atmel_serial.c | 48 ++-
 1 file changed, 2 insertions(+), 46 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 9a54c9e6d36e..a8dc8af83f39 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -294,50 +294,6 @@ static void atmel_tasklet_schedule(struct atmel_uart_port 
*atmel_port,
tasklet_schedule(t);
 }
 
-static unsigned int atmel_get_lines_status(struct uart_port *port)
-{
-   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-   unsigned int status, ret = 0;
-
-   status = atmel_uart_readl(port, ATMEL_US_CSR);
-
-   mctrl_gpio_get(atmel_port->gpios, );
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_CTS))) {
-   if (ret & TIOCM_CTS)
-   status &= ~ATMEL_US_CTS;
-   else
-   status |= ATMEL_US_CTS;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_DSR))) {
-   if (ret & TIOCM_DSR)
-   status &= ~ATMEL_US_DSR;
-   else
-   status |= ATMEL_US_DSR;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_RI))) {
-   if (ret & TIOCM_RI)
-   status &= ~ATMEL_US_RI;
-   else
-   status |= ATMEL_US_RI;
-   }
-
-   if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
-   UART_GPIO_DCD))) {
-   if (ret & TIOCM_CD)
-   status &= ~ATMEL_US_DCD;
-   else
-   status |= ATMEL_US_DCD;
-   }
-
-   return status;
-}
-
 /* Enable or disable the rs485 support */
 static int atmel_config_rs485(struct uart_port *port,
  struct serial_rs485 *rs485conf)
@@ -1453,7 +1409,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
spin_lock(_port->lock_suspended);
 
do {
-   status = atmel_get_lines_status(port);
+   status = atmel_uart_readl(port, ATMEL_US_CSR);
mask = atmel_uart_readl(port, ATMEL_US_IMR);
pending = status & mask;
if (!pending)
@@ -2002,7 +1958,7 @@ static int atmel_startup(struct uart_port *port)
}
 
/* Save current CSR for comparison in atmel_tasklet_func() */
-   atmel_port->irq_status_prev = atmel_get_lines_status(port);
+   atmel_port->irq_status_prev = atmel_uart_readl(port, ATMEL_US_CSR);
 
/*
 * Finally, enable the serial port
-- 
2.19.2



Re: [PATCH v2 2/2] tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped

2019-03-26 Thread Richard Genoud
Le 19/03/2019 à 14:20, Razvan Stefanescu a écrit :
> In half-duplex operation, RX should be started after TX completes.
> 
> If DMA is used, there is a case when the DMA transfer completes but the
> TX FIFO is not emptied, so the RX cannot be restarted just yet.
> 
> Use a boolean variable to store this state and rearm TX interrupt mask
> to be signaled again that the transfer finished. In interrupt transmit
> handler this variable is used to start RX. A warning message is generated
> if RX is activated before TX fifo is cleared.
> 
> Fixes: b389f173aaa1 ("tty/serial: atmel: RS485 half duplex w/DMA: enable
> RX after TX is done")
> Signed-off-by: Razvan Stefanescu 
Acked-by: Richard Genoud 

NB: backport on kernel older than 4.20 will fail because of the iso7816
variables fidi_min/fidi_max.
> ---
> Changelog:
> v2:
>   - start RX and display warning in case of error
>   - add fix info
> 
>  drivers/tty/serial/atmel_serial.c | 25 ++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index b4b89a16a41b..5b2f859c327c 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -166,6 +166,8 @@ struct atmel_uart_port {
>   unsigned intpending_status;
>   spinlock_t  lock_suspended;
>  
> + boolhd_start_rx;/* can start RX during 
> half-duplex operation */
> +
>   /* ISO7816 */
>   unsigned intfidi_min;
>   unsigned intfidi_max;
> @@ -933,8 +935,13 @@ static void atmel_complete_tx_dma(void *arg)
>   if (!uart_circ_empty(xmit))
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
>   else if (atmel_uart_is_half_duplex(port)) {
> - /* DMA done, stop TX, start RX for RS485 */
> - atmel_start_rx(port);
> + /*
> +  * DMA done, re-enable TXEMPTY and signal that we can stop
> +  * TX and start RX for RS485
> +  */
> + atmel_port->hd_start_rx = true;
> + atmel_uart_writel(port, ATMEL_US_IER,
> +   atmel_port->tx_done_mask);
>   }
>  
>   spin_unlock_irqrestore(>lock, flags);
> @@ -1378,9 +1385,20 @@ atmel_handle_transmit(struct uart_port *port, unsigned 
> int pending)
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
>  
>   if (pending & atmel_port->tx_done_mask) {
> - /* Either PDC or interrupt transmission */
>   atmel_uart_writel(port, ATMEL_US_IDR,
> atmel_port->tx_done_mask);
> +
> + /* Start RX if flag was set and FIFO is empty */
> + if (atmel_port->hd_start_rx) {
> + if (!(atmel_uart_readl(port, ATMEL_US_CSR)
> + & ATMEL_US_TXEMPTY))
> + dev_warn(port->dev, "Should start RX, but TX 
> fifo is not empty\n");
> +
> + atmel_port->hd_start_rx = false;
> + atmel_start_rx(port);
> + return;
> + }
> +
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
>   }
>  }
> 



Re: [PATCH v2 1/2] tty/serial: atmel: Add is_half_duplex helper

2019-03-26 Thread Richard Genoud
Le 19/03/2019 à 14:20, Razvan Stefanescu a écrit :
> Use a helper function to check that a port needs to use half duplex
> communication, replacing several occurrences of multi-line bit checking.
> 
> Fixes: b389f173aaa1 ("tty/serial: atmel: RS485 half duplex w/DMA: enable
> RX after TX is done")
> Signed-off-by: Razvan Stefanescu 
Acked-by: Richard Genoud 

NB: backport on kernel older than 4.20 will fail because of the
SER_ISO7816_ENABLED flag.
> ---
> Changelog:
> v2: 
>   - remove extra check
>   - add fix info
> 
>  drivers/tty/serial/atmel_serial.c | 24 
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 05147fe24343..b4b89a16a41b 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -231,6 +231,13 @@ static inline void atmel_uart_write_char(struct 
> uart_port *port, u8 value)
>   __raw_writeb(value, port->membase + ATMEL_US_THR);
>  }
>  
> +static inline int atmel_uart_is_half_duplex(struct uart_port *port)
> +{
> + return ((port->rs485.flags & SER_RS485_ENABLED) &&
> + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> + (port->iso7816.flags & SER_ISO7816_ENABLED);
> +}
> +
>  #ifdef CONFIG_SERIAL_ATMEL_PDC
>  static bool atmel_use_pdc_rx(struct uart_port *port)
>  {
> @@ -608,10 +615,9 @@ static void atmel_stop_tx(struct uart_port *port)
>   /* Disable interrupts */
>   atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
>  
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED)
> + if (atmel_uart_is_half_duplex(port))
>   atmel_start_rx(port);
> +
>  }
>  
>  /*
> @@ -628,9 +634,7 @@ static void atmel_start_tx(struct uart_port *port)
>   return;
>  
>   if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED)
> + if (atmel_uart_is_half_duplex(port))
>   atmel_stop_rx(port);
>  
>   if (atmel_use_pdc_tx(port))
> @@ -928,9 +932,7 @@ static void atmel_complete_tx_dma(void *arg)
>*/
>   if (!uart_circ_empty(xmit))
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
> - else if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -   !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> -  port->iso7816.flags & SER_ISO7816_ENABLED) {
> + else if (atmel_uart_is_half_duplex(port)) {
>   /* DMA done, stop TX, start RX for RS485 */
>   atmel_start_rx(port);
>   }
> @@ -1508,9 +1510,7 @@ static void atmel_tx_pdc(struct uart_port *port)
>   atmel_uart_writel(port, ATMEL_US_IER,
> atmel_port->tx_done_mask);
>   } else {
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED) {
> + if (atmel_uart_is_half_duplex(port)) {
>   /* DMA done, stop TX, start RX for RS485 */
>   atmel_start_rx(port);
>   }
> 



Re: [PATCH 2/2] tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped

2019-03-18 Thread Richard Genoud
[ adding Gil Weber in Cc: ]
Le 15/03/2019 à 10:23, Razvan Stefanescu a écrit :
> In half-duplex operation, RX should be started after TX completes.
> 
> If DMA is used, there is a case when the DMA transfer completes but the
> TX FIFO is not emptied, so the RX cannot be restarted just yet.
> 
> Use a boolean variable to store this state and rearm TX interrupt mask
> to be signaled again that the transfer finished. In interrupt transmit
> handler this variable is used to start RX.

I was sure I've already seen something like that.
Gil, could you give it a test ?

you can add :
Cc: sta...@vger.kernel.org
Fixes: b389f173aaa1 ("tty/serial: atmel: RS485 half duplex w/DMA: enable RX 
after TX is done")

Since patch 1/2 is needed for this one, I think you should add also
Cc:stable / Fixes: to the previous patch.

> Signed-off-by: Razvan Stefanescu 
> ---
>  drivers/tty/serial/atmel_serial.c | 25 ++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index a6577b1c4461..b0141dcbbb61 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -166,6 +166,8 @@ struct atmel_uart_port {
>   unsigned intpending_status;
>   spinlock_t  lock_suspended;
>  
> + boolhd_start_rx;/* can start RX during 
> half-duplex operation */
> +
>   /* ISO7816 */
>   unsigned intfidi_min;
>   unsigned intfidi_max;
> @@ -934,8 +936,13 @@ static void atmel_complete_tx_dma(void *arg)
>   if (!uart_circ_empty(xmit))
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
>   else if (atmel_uart_is_half_duplex(port)) {
> - /* DMA done, stop TX, start RX for RS485 */
> - atmel_start_rx(port);
> + /*
> +  * DMA done, re-enable TXEMPTY and signal that we can stop
> +  * TX and start RX for RS485
> +  */
> + atmel_port->hd_start_rx = true;
> + atmel_uart_writel(port, ATMEL_US_IER,
> +   atmel_port->tx_done_mask);
>   }
>  
>   spin_unlock_irqrestore(>lock, flags);
> @@ -1379,9 +1386,21 @@ atmel_handle_transmit(struct uart_port *port, unsigned 
> int pending)
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
>  
>   if (pending & atmel_port->tx_done_mask) {
> - /* Either PDC or interrupt transmission */
>   atmel_uart_writel(port, ATMEL_US_IDR,
> atmel_port->tx_done_mask);
> +
> + /* Start RX if flag was set and FIFO is empty */
> + if (atmel_port->hd_start_rx) {
> + if (atmel_uart_readl(port, ATMEL_US_CSR)
> + & ATMEL_US_TXEMPTY) {
> + atmel_port->hd_start_rx = false;
> + atmel_start_rx(port);
> + } else {
> + dev_warn(port->dev, "Should start RX, but TX 
> fifo is not empty\n");
What will happen in this case ?

> + }
> + return;
> + }
> +
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
>   }
>  }
> 

Thanks !


Re: [PATCH 1/2] tty/serial: atmel: Add is_half_duplex helper

2019-03-18 Thread Richard Genoud
[ adding Gil Weber in Cc: ]

Le 15/03/2019 à 10:23, Razvan Stefanescu a écrit :
> Use a helper function to check that a port needs to use half duplex
> communication, replacing several occurrences of multi-line bit checking.
> 
> Signed-off-by: Razvan Stefanescu 
> ---
>  drivers/tty/serial/atmel_serial.c | 27 ++-
>  1 file changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 05147fe24343..a6577b1c4461 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -231,6 +231,13 @@ static inline void atmel_uart_write_char(struct 
> uart_port *port, u8 value)
>   __raw_writeb(value, port->membase + ATMEL_US_THR);
>  }
>  
> +static inline int atmel_uart_is_half_duplex(struct uart_port *port)
> +{
> + return ((port->rs485.flags & SER_RS485_ENABLED) &&
> + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> + (port->iso7816.flags & SER_ISO7816_ENABLED);
> +}
> +
>  #ifdef CONFIG_SERIAL_ATMEL_PDC
>  static bool atmel_use_pdc_rx(struct uart_port *port)
>  {
> @@ -608,10 +615,10 @@ static void atmel_stop_tx(struct uart_port *port)
>   /* Disable interrupts */
>   atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
>  
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED)
> - atmel_start_rx(port);
> + if (atmel_uart_is_half_duplex(port))
> + if (!atomic_read(_port->tasklet_shutdown))
This check wasn't there before.
If it's really needed, please insert it in another patch and explain why
it's needed.

> + atmel_start_rx(port);
> +
>  }
>  
>  /*
> @@ -628,9 +635,7 @@ static void atmel_start_tx(struct uart_port *port)
>   return;
>  
>   if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED)
> + if (atmel_uart_is_half_duplex(port))
>   atmel_stop_rx(port);
>  
>   if (atmel_use_pdc_tx(port))
> @@ -928,9 +933,7 @@ static void atmel_complete_tx_dma(void *arg)
>*/
>   if (!uart_circ_empty(xmit))
>   atmel_tasklet_schedule(atmel_port, _port->tasklet_tx);
> - else if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -   !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> -  port->iso7816.flags & SER_ISO7816_ENABLED) {
> + else if (atmel_uart_is_half_duplex(port)) {
>   /* DMA done, stop TX, start RX for RS485 */
>   atmel_start_rx(port);
>   }
> @@ -1508,9 +1511,7 @@ static void atmel_tx_pdc(struct uart_port *port)
>   atmel_uart_writel(port, ATMEL_US_IER,
> atmel_port->tx_done_mask);
>   } else {
> - if (((port->rs485.flags & SER_RS485_ENABLED) &&
> -  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
> - port->iso7816.flags & SER_ISO7816_ENABLED) {
> + if (atmel_uart_is_half_duplex(port)) {
>   /* DMA done, stop TX, start RX for RS485 */
>   atmel_start_rx(port);
>   }
> 



Re: [PATCH] tty: atmel_serial: fix a NULL pointer dereference

2019-03-18 Thread Richard Genoud
Le 15/03/2019 à 18:16, Kangjie Lu a écrit :
> In case dmaengine_prep_dma_cyclic fails, the fix returns a proper
> error code to avoid NULL pointer dereference.
> 
> Signed-off-by: Kangjie Lu 
> Fixes: 34df42f59a60 ("serial: at91: add rx dma support")
Acked-by: Richard Genoud 

> 
> ---
> V2: simplified the patch as suggested by
> Richard Genoud 
> ---
>  drivers/tty/serial/atmel_serial.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 05147fe24343..41b728d223d1 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1288,6 +1288,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>sg_dma_len(_port->sg_rx)/2,
>DMA_DEV_TO_MEM,
>DMA_PREP_INTERRUPT);
> + if (!desc) {
> + dev_err(port->dev, "Preparing DMA cyclic failed\n");
> + goto chan_err;
> + }
>   desc->callback = atmel_complete_rx_dma;
>   desc->callback_param = port;
>   atmel_port->desc_rx = desc;
> 

Thanks !

Richard


Re: [PATCH v2] tty: atmel_serial: fix a NULL pointer dereference

2019-03-15 Thread Richard Genoud
Le 15/03/2019 à 08:27, Kangjie Lu a écrit :
> Fixes: 34df42f59a60 ("serial: at91: add rx dma support")
The Fixes: tag should be just bellow the Signenf-off-by: tag
> 
> In case dmaengine_prep_dma_cyclic fails, the fix returns a proper
> error code to avoid NULL pointer dereference.
> 
> Signed-off-by: Kangjie Lu 
^^^
here
> 
> ---
> V2: simplified the patch as suggested by
> Richard Genoud 
> ---
>  drivers/tty/serial/atmel_serial.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 05147fe24343..41b728d223d1 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1288,6 +1288,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>sg_dma_len(_port->sg_rx)/2,
>DMA_DEV_TO_MEM,
>DMA_PREP_INTERRUPT);
> + if (!desc) {
> + dev_err(port->dev, "Preparing DMA cyclic failed\n");
> + goto chan_err;
> + }
>   desc->callback = atmel_complete_rx_dma;
>   desc->callback_param = port;
>   atmel_port->desc_rx = desc;
> 

Thanks !

Richard.


Re: [PATCH] tty: atmel_serial: fix a NULL pointer dereference

2019-03-14 Thread Richard Genoud
Hi,

Good catch !
Le 14/03/2019 à 08:17, Kangjie Lu a écrit :
> In case dmaengine_prep_dma_cyclic fails, the fix return a proper
> error code to avoid NULL pointer dereference.
> 
you could add:
Fixes: 34df42f59a60 ("serial: at91: add rx dma support")
So that -stable branches get this.

> Signed-off-by: Kangjie Lu 
> ---
>  drivers/tty/serial/atmel_serial.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 05147fe24343..cf560d05008c 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1237,8 +1237,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>   dma_cap_set(DMA_CYCLIC, mask);
>  
>   atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
> - if (atmel_port->chan_rx == NULL)
> + if (atmel_port->chan_rx == NULL) {
> + ret = -EINVAL;
>   goto chan_err;
> + }
>   dev_info(port->dev, "using %s for rx DMA transfers\n",
>   dma_chan_name(atmel_port->chan_rx));
>  
> @@ -1257,6 +1259,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>  
>   if (!nent) {
>   dev_dbg(port->dev, "need to release resource of dma\n");
> + ret = -EINVAL;
>   goto chan_err;
>   } else {
>   dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
> @@ -1288,6 +1291,11 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>sg_dma_len(_port->sg_rx)/2,
>DMA_DEV_TO_MEM,
>DMA_PREP_INTERRUPT);
> + if (!desc) {
> + dev_err(port->dev, "Preparing DMA cyclic failed\n");
> + ret = -ENOMEM;
IMHO, we don't really know why dmaengine_prep_dma_cyclic() failed, it
could be because it's already in use, or bad value, or...
(and anyway, we just check if the return value is < 0 in atmel _startup.)
Is there a specific reason you choose -ENOMEM ?
If not, maybe keeping this patch smaller with a simple dev_err()+goto
here would be a better choice.

> + goto chan_err;
> + }
>   desc->callback = atmel_complete_rx_dma;
>   desc->callback_param = port;
>   atmel_port->desc_rx = desc;
> @@ -1300,7 +1308,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>   atmel_port->use_dma_rx = 0;
>   if (atmel_port->chan_rx)
>   atmel_release_rx_dma(port);
> - return -EINVAL;
> + return ret;
>  }
>  
>  static void atmel_uart_timer_callback(struct timer_list *t)
> 

Thanks !

Richard.


[PATCH] dmaengine: at_hdmac: fix memory leak in at_dma_xlate()

2018-11-27 Thread Richard Genoud
The leak was found when opening/closing a serial port a great number of
time, increasing kmalloc-32 in slabinfo.

Each time the port was opened, dma_request_slave_channel() was called.
Then, in at_dma_xlate(), atslave was allocated with devm_kzalloc() and
never freed. (Well, it was free at module unload, but that's not what we
want).
So, here, kzalloc is more suited for the job since it has to be freed in
atc_free_chan_resources().

Cc: sta...@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Reported-by: Mario Forner 
Suggested-by: Alexandre Belloni 
Acked-by: Alexandre Belloni 
Signed-off-by: Richard Genoud 
---
 drivers/dma/at_hdmac.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 7cbac6e8c113..1b7f0ca0d5cd 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1641,6 +1641,12 @@ static void atc_free_chan_resources(struct dma_chan 
*chan)
atchan->descs_allocated = 0;
atchan->status = 0;
 
+   /*
+* Free atslave allocated in at_dma_xlate()
+*/
+   kfree(chan->private);
+   chan->private = NULL;
+
dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
 }
 
@@ -1675,7 +1681,7 @@ static struct dma_chan *at_dma_xlate(struct 
of_phandle_args *dma_spec,
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
 
-   atslave = devm_kzalloc(_pdev->dev, sizeof(*atslave), GFP_KERNEL);
+   atslave = kzalloc(sizeof(*atslave), GFP_KERNEL);
if (!atslave)
return NULL;
 


[PATCH] dmaengine: at_hdmac: fix memory leak in at_dma_xlate()

2018-11-27 Thread Richard Genoud
The leak was found when opening/closing a serial port a great number of
time, increasing kmalloc-32 in slabinfo.

Each time the port was opened, dma_request_slave_channel() was called.
Then, in at_dma_xlate(), atslave was allocated with devm_kzalloc() and
never freed. (Well, it was free at module unload, but that's not what we
want).
So, here, kzalloc is more suited for the job since it has to be freed in
atc_free_chan_resources().

Cc: sta...@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Reported-by: Mario Forner 
Suggested-by: Alexandre Belloni 
Acked-by: Alexandre Belloni 
Signed-off-by: Richard Genoud 
---
 drivers/dma/at_hdmac.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 7cbac6e8c113..1b7f0ca0d5cd 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1641,6 +1641,12 @@ static void atc_free_chan_resources(struct dma_chan 
*chan)
atchan->descs_allocated = 0;
atchan->status = 0;
 
+   /*
+* Free atslave allocated in at_dma_xlate()
+*/
+   kfree(chan->private);
+   chan->private = NULL;
+
dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
 }
 
@@ -1675,7 +1681,7 @@ static struct dma_chan *at_dma_xlate(struct 
of_phandle_args *dma_spec,
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
 
-   atslave = devm_kzalloc(_pdev->dev, sizeof(*atslave), GFP_KERNEL);
+   atslave = kzalloc(sizeof(*atslave), GFP_KERNEL);
if (!atslave)
return NULL;
 


[PATCH] dmaengine: at_hdmac: fix module unloading

2018-11-27 Thread Richard Genoud
of_dma_controller_free() was not called on module onloading.
This lead to a soft lockup:
watchdog: BUG: soft lockup - CPU#0 stuck for 23s!
Modules linked in: at_hdmac [last unloaded: at_hdmac]
when of_dma_request_slave_channel() tried to call ofdma->of_dma_xlate().

Cc: sta...@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Signed-off-by: Richard Genoud 
---
 drivers/dma/at_hdmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 1b7f0ca0d5cd..01d936c9fe89 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -2006,6 +2006,8 @@ static int at_dma_remove(struct platform_device *pdev)
struct resource *io;
 
at_dma_off(atdma);
+   if (pdev->dev.of_node)
+   of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(>dma_common);
 
dma_pool_destroy(atdma->memset_pool);


[PATCH] dmaengine: at_hdmac: fix module unloading

2018-11-27 Thread Richard Genoud
of_dma_controller_free() was not called on module onloading.
This lead to a soft lockup:
watchdog: BUG: soft lockup - CPU#0 stuck for 23s!
Modules linked in: at_hdmac [last unloaded: at_hdmac]
when of_dma_request_slave_channel() tried to call ofdma->of_dma_xlate().

Cc: sta...@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Signed-off-by: Richard Genoud 
---
 drivers/dma/at_hdmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 1b7f0ca0d5cd..01d936c9fe89 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -2006,6 +2006,8 @@ static int at_dma_remove(struct platform_device *pdev)
struct resource *io;
 
at_dma_off(atdma);
+   if (pdev->dev.of_node)
+   of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(>dma_common);
 
dma_pool_destroy(atdma->memset_pool);


Re: DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread Richard Genoud
Le 27/11/2018 à 10:58, Alexandre Belloni a écrit :
> Hello Richard,
> 
> On 27/11/2018 10:51:13+0100, richard.gen...@gmail.com wrote:
>> Hi all,
>>
>> I reproduced the memory leak on my board (at91sam9g35-cm) with a 4.20-rc3.
>>
>> It triggered an OOM after a couple of hours running a code like this:
>> #include 
>> #include 
>> #include 
>> #include 
>>
>>
>> int main(int argc, char **argv)
>> {
>>  int fd;
>>  do {
>>  fd = open("/dev/ttyS1", O_RDONLY);
>>  close(fd);
>>  } while (true);
>>  return 0;
>> }
>>
>> As Mario pointed out, this only happens when atmel,use-dma-{r,t}x are
>> used in the device-tree.
>>
>> Adding:
>> CONFIG_DEBUG_SLAB=y
>> CONFIG_DEBUG_SLAB_LEAK=y
>> Doesn't show anything suspect in /proc/slab_allocators
>>
>> From what I found until now, it's something done in :
>> dma_request_slave_channel();
>> that leaks kmalloc-32
>> Mabe I missed something, but it seems that everything DMA related is
>> deallocated in atmel_release_{tx,rx}_dma().
>>
>> Is this ringing a bell ?
>>
> 
> Yes, this is known issue and it has yet to be worked on.
> 

After a talk on freenode, Alex found the problem.
A patch is on its way.

Thanks !


Re: DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread Richard Genoud
Le 27/11/2018 à 10:58, Alexandre Belloni a écrit :
> Hello Richard,
> 
> On 27/11/2018 10:51:13+0100, richard.gen...@gmail.com wrote:
>> Hi all,
>>
>> I reproduced the memory leak on my board (at91sam9g35-cm) with a 4.20-rc3.
>>
>> It triggered an OOM after a couple of hours running a code like this:
>> #include 
>> #include 
>> #include 
>> #include 
>>
>>
>> int main(int argc, char **argv)
>> {
>>  int fd;
>>  do {
>>  fd = open("/dev/ttyS1", O_RDONLY);
>>  close(fd);
>>  } while (true);
>>  return 0;
>> }
>>
>> As Mario pointed out, this only happens when atmel,use-dma-{r,t}x are
>> used in the device-tree.
>>
>> Adding:
>> CONFIG_DEBUG_SLAB=y
>> CONFIG_DEBUG_SLAB_LEAK=y
>> Doesn't show anything suspect in /proc/slab_allocators
>>
>> From what I found until now, it's something done in :
>> dma_request_slave_channel();
>> that leaks kmalloc-32
>> Mabe I missed something, but it seems that everything DMA related is
>> deallocated in atmel_release_{tx,rx}_dma().
>>
>> Is this ringing a bell ?
>>
> 
> Yes, this is known issue and it has yet to be worked on.
> 

After a talk on freenode, Alex found the problem.
A patch is on its way.

Thanks !


DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread richard . genoud
[re-sending with Vinod's correct email address. Sorry for the noise. ]

[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used): 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)  : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used) : 57 / 76 (75.0%)
>  Active / Total Size (% used)   : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%0.03K  21571  124 86284K kmalloc-32
>   7200   7104  98%0.08K144   50   576K kernfs_node_cache
>   6930   5370  77%0.13K231   30   924K dentry 
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown 
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop 
> -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
> try:
> with serial.Serial(port = '/dev/ttyS4'):
> pass
> except Exception as e:
> print e
> finally:
> time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils2.25
> Util-linux  2.25.2
> Mount   2.25.2
> Module-init-tools   18
> E2fsprogs   1.42.12
> Linux C Library 2.19
> Dynamic linker (ldd)2.19
> Linux C++ Library   6.0.20
> Procps  3.3.9
> Net-tools   1.60
> Sh-utils8.23
> Udev215
> Modules Loaded  iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor   : 0
> model name  : ARM926EJ-S rev 5 (v5l)
> BogoMIPS: 198.76
> Features: swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant : 0x0
> CPU part: 0x926
> CPU revision: 5
> 
> Hardware: Atmel AT91SAM9
> Revision: 
> Serial  :   
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf00
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 0030-00307fff : 30.sram
> 0060-006f : /ahb/ohci@0060
> 0070-007f : /ahb/ehci@0070
> 2000-2fff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f000-f0ff : /ahb/apb/spi@f000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f801-f80100ff : /ahb/apb/i2c@f801
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f802-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ec00-edff : at_hdmac
> ee00-efff : at_hdmac
> f200-f3ff : atmel_serial
> f400-f5ff : /ahb/apb/pinctrl@f400/gpio@f400
> f600-f7ff : /ahb/apb/pinctrl@f400/gpio@f600
> f800-f9ff : /ahb/apb/pinctrl@f400/gpio@f800
> fa00-fbff : /ahb/apb/pinctrl@f400/gpio@fa00
> fe10-fe1f : /ahb/apb/shdwc@fe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
> status = "okay";
> compatible = "atmel,at91sam9260-usart";
> reg = <0xf8028000 

DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread richard . genoud
[re-sending with Vinod's correct email address. Sorry for the noise. ]

[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used): 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)  : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used) : 57 / 76 (75.0%)
>  Active / Total Size (% used)   : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%0.03K  21571  124 86284K kmalloc-32
>   7200   7104  98%0.08K144   50   576K kernfs_node_cache
>   6930   5370  77%0.13K231   30   924K dentry 
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown 
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop 
> -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
> try:
> with serial.Serial(port = '/dev/ttyS4'):
> pass
> except Exception as e:
> print e
> finally:
> time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils2.25
> Util-linux  2.25.2
> Mount   2.25.2
> Module-init-tools   18
> E2fsprogs   1.42.12
> Linux C Library 2.19
> Dynamic linker (ldd)2.19
> Linux C++ Library   6.0.20
> Procps  3.3.9
> Net-tools   1.60
> Sh-utils8.23
> Udev215
> Modules Loaded  iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor   : 0
> model name  : ARM926EJ-S rev 5 (v5l)
> BogoMIPS: 198.76
> Features: swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant : 0x0
> CPU part: 0x926
> CPU revision: 5
> 
> Hardware: Atmel AT91SAM9
> Revision: 
> Serial  :   
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf00
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 0030-00307fff : 30.sram
> 0060-006f : /ahb/ohci@0060
> 0070-007f : /ahb/ehci@0070
> 2000-2fff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f000-f0ff : /ahb/apb/spi@f000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f801-f80100ff : /ahb/apb/i2c@f801
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f802-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ec00-edff : at_hdmac
> ee00-efff : at_hdmac
> f200-f3ff : atmel_serial
> f400-f5ff : /ahb/apb/pinctrl@f400/gpio@f400
> f600-f7ff : /ahb/apb/pinctrl@f400/gpio@f600
> f800-f9ff : /ahb/apb/pinctrl@f400/gpio@f800
> fa00-fbff : /ahb/apb/pinctrl@f400/gpio@fa00
> fe10-fe1f : /ahb/apb/shdwc@fe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
> status = "okay";
> compatible = "atmel,at91sam9260-usart";
> reg = <0xf8028000 

DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread richard . genoud
[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used): 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)  : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used) : 57 / 76 (75.0%)
>  Active / Total Size (% used)   : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%0.03K  21571  124 86284K kmalloc-32
>   7200   7104  98%0.08K144   50   576K kernfs_node_cache
>   6930   5370  77%0.13K231   30   924K dentry 
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown 
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop 
> -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
> try:
> with serial.Serial(port = '/dev/ttyS4'):
> pass
> except Exception as e:
> print e
> finally:
> time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils2.25
> Util-linux  2.25.2
> Mount   2.25.2
> Module-init-tools   18
> E2fsprogs   1.42.12
> Linux C Library 2.19
> Dynamic linker (ldd)2.19
> Linux C++ Library   6.0.20
> Procps  3.3.9
> Net-tools   1.60
> Sh-utils8.23
> Udev215
> Modules Loaded  iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor   : 0
> model name  : ARM926EJ-S rev 5 (v5l)
> BogoMIPS: 198.76
> Features: swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant : 0x0
> CPU part: 0x926
> CPU revision: 5
> 
> Hardware: Atmel AT91SAM9
> Revision: 
> Serial  :   
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf00
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 0030-00307fff : 30.sram
> 0060-006f : /ahb/ohci@0060
> 0070-007f : /ahb/ehci@0070
> 2000-2fff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f000-f0ff : /ahb/apb/spi@f000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f801-f80100ff : /ahb/apb/i2c@f801
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f802-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ec00-edff : at_hdmac
> ee00-efff : at_hdmac
> f200-f3ff : atmel_serial
> f400-f5ff : /ahb/apb/pinctrl@f400/gpio@f400
> f600-f7ff : /ahb/apb/pinctrl@f400/gpio@f600
> f800-f9ff : /ahb/apb/pinctrl@f400/gpio@f800
> fa00-fbff : /ahb/apb/pinctrl@f400/gpio@fa00
> fe10-fe1f : /ahb/apb/shdwc@fe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
> status = "okay";
> compatible = "atmel,at91sam9260-usart";
> reg = <0xf8028000 0x200>;
> interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
> pinctrl-names 

DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak

2018-11-27 Thread richard . genoud
[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used): 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)  : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used) : 57 / 76 (75.0%)
>  Active / Total Size (% used)   : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%0.03K  21571  124 86284K kmalloc-32
>   7200   7104  98%0.08K144   50   576K kernfs_node_cache
>   6930   5370  77%0.13K231   30   924K dentry 
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) 
> #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown 
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop 
> -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
> try:
> with serial.Serial(port = '/dev/ttyS4'):
> pass
> except Exception as e:
> print e
> finally:
> time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils2.25
> Util-linux  2.25.2
> Mount   2.25.2
> Module-init-tools   18
> E2fsprogs   1.42.12
> Linux C Library 2.19
> Dynamic linker (ldd)2.19
> Linux C++ Library   6.0.20
> Procps  3.3.9
> Net-tools   1.60
> Sh-utils8.23
> Udev215
> Modules Loaded  iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor   : 0
> model name  : ARM926EJ-S rev 5 (v5l)
> BogoMIPS: 198.76
> Features: swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant : 0x0
> CPU part: 0x926
> CPU revision: 5
> 
> Hardware: Atmel AT91SAM9
> Revision: 
> Serial  :   
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf00
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 0030-00307fff : 30.sram
> 0060-006f : /ahb/ohci@0060
> 0070-007f : /ahb/ehci@0070
> 2000-2fff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f000-f0ff : /ahb/apb/spi@f000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f801-f80100ff : /ahb/apb/i2c@f801
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f802-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ec00-edff : at_hdmac
> ee00-efff : at_hdmac
> f200-f3ff : atmel_serial
> f400-f5ff : /ahb/apb/pinctrl@f400/gpio@f400
> f600-f7ff : /ahb/apb/pinctrl@f400/gpio@f600
> f800-f9ff : /ahb/apb/pinctrl@f400/gpio@f800
> fa00-fbff : /ahb/apb/pinctrl@f400/gpio@fa00
> fe10-fe1f : /ahb/apb/shdwc@fe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
> status = "okay";
> compatible = "atmel,at91sam9260-usart";
> reg = <0xf8028000 0x200>;
> interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
> pinctrl-names 

Re: [PATCH v4 2/2] tty/serial: atmel: add ISO7816 support

2018-09-10 Thread Richard Genoud
Hi, Ludovic,

On 06/09/2018 15:42, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> 
> Signed-off-by: Nicolas Ferre 
> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
> fixes]
> Signed-off-by: Ludovic Desroches 

This seems ok for me.

Acked-by: Richard Genoud 

Thanks !


Re: [PATCH v4 2/2] tty/serial: atmel: add ISO7816 support

2018-09-10 Thread Richard Genoud
Hi, Ludovic,

On 06/09/2018 15:42, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> 
> Signed-off-by: Nicolas Ferre 
> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
> fixes]
> Signed-off-by: Ludovic Desroches 

This seems ok for me.

Acked-by: Richard Genoud 

Thanks !


Re: [PATCH v3 2/2] tty/serial: atmel: add ISO7816 support

2018-09-05 Thread Richard Genoud
[added Nicolas back in the thread, he was removed somehow]

Hi Ludovic !

On 05/09/2018 14:43, Ludovic Desroches wrote:
> Hi Richard,
> 
> On Thu, Aug 09, 2018 at 01:30:35PM +0200, Ludovic Desroches wrote:
>> Hi Richard,
>>
>> On Thu, Aug 09, 2018 at 10:47:17AM +0200, Richard Genoud wrote:
>>> Hi !
>>>
>>> On 07/08/2018 15:00, Ludovic Desroches wrote:
>>>> From: Nicolas Ferre 
>>>>
>>>> When mode is set in atmel_config_iso7816() we backup last RS232 mode
>>>> for coming back to this mode if requested.
>>>> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
>>>> function as well.
>>>>
>>>> Signed-off-by: Nicolas Ferre 
>>>> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, 
>>>> checkpatch fixes]
>>>> Signed-off-by: Ludovic Desroches 
>>>> ---
>>>>  drivers/tty/serial/atmel_serial.c | 211 
>>>> +++---
>>>>  drivers/tty/serial/atmel_serial.h |   6 +-
>>>>  2 files changed, 201 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/atmel_serial.c 
>>>> b/drivers/tty/serial/atmel_serial.c
>>>> index 8e4428725848..4a7ec44b0ace 100644
>>>> --- a/drivers/tty/serial/atmel_serial.c
>>>> +++ b/drivers/tty/serial/atmel_serial.c
>>
>> [...]
>>
>>>>  #if defined(CONFIG_OF)
>>>> +static struct atmel_uart_pdata at91rm9200_pdata = {
>>>> +  .fidi_min = 1,
>>>> +  .fidi_max = 2047,
>>>> +};
>>>> +
>>>> +static struct atmel_uart_pdata at91sam9260_pdata = {
>>>> +  .fidi_min = 1,
>>>> +  .fidi_max = 2047,
>>>> +};
>>>> +
>>>> +static struct atmel_uart_pdata sama5d3_pdata = {
>>>> +  .fidi_min = 3,
>>>> +  .fidi_max = 65535,
>>> Are you sure this is for sama5d3 ?
>>> From the datasheets I have, 65535 is for sama5d4/sama5d2
>>
>> I checked it and I missed it. What a pity... In fact, it's a bit more
>> tricky since the min value for d3 is 3 and no longer 1.
>>
>>> And also, you'll have to s/atmel,at91sam9260-usart/atmel,sama5d2-usart/g
>>> in sama5d{2,4}.dtsi
>>>
>>
>> Yes, I planed to send it later but I can add those patches within this
>> set of patches. 
>>
>>> But I wonder if it could be detected via ATMEL_US_VERSION instead ?
>>>
>>
>> I have not checked, I tend to prefer the compatible string for this kind
>> of thing. But as we already use the version number, I can investigate
>> this solution if it's the one you prefer.
>>
> 
> ping about this question still in suspend in order to prepare a new version.
Well, if we use the compatible string for this, we will have to add :
- atmel,sama5d2-usart
- atmel,sama5d3-usart
- (maybe others ?)
to the already existing :
- atmel,at91sam9260-usart
- atmel,at91rm9200-usart
just for setting different limits on the fidi register.
IMHO, it seems a bit overkill. Moreover, the ATMEL_US_VERSION has
already been read, so...
But if you think adding compatible strings is a better/cleaner solution, just 
convince me ! :)


Re: [PATCH v3 2/2] tty/serial: atmel: add ISO7816 support

2018-09-05 Thread Richard Genoud
[added Nicolas back in the thread, he was removed somehow]

Hi Ludovic !

On 05/09/2018 14:43, Ludovic Desroches wrote:
> Hi Richard,
> 
> On Thu, Aug 09, 2018 at 01:30:35PM +0200, Ludovic Desroches wrote:
>> Hi Richard,
>>
>> On Thu, Aug 09, 2018 at 10:47:17AM +0200, Richard Genoud wrote:
>>> Hi !
>>>
>>> On 07/08/2018 15:00, Ludovic Desroches wrote:
>>>> From: Nicolas Ferre 
>>>>
>>>> When mode is set in atmel_config_iso7816() we backup last RS232 mode
>>>> for coming back to this mode if requested.
>>>> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
>>>> function as well.
>>>>
>>>> Signed-off-by: Nicolas Ferre 
>>>> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, 
>>>> checkpatch fixes]
>>>> Signed-off-by: Ludovic Desroches 
>>>> ---
>>>>  drivers/tty/serial/atmel_serial.c | 211 
>>>> +++---
>>>>  drivers/tty/serial/atmel_serial.h |   6 +-
>>>>  2 files changed, 201 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/atmel_serial.c 
>>>> b/drivers/tty/serial/atmel_serial.c
>>>> index 8e4428725848..4a7ec44b0ace 100644
>>>> --- a/drivers/tty/serial/atmel_serial.c
>>>> +++ b/drivers/tty/serial/atmel_serial.c
>>
>> [...]
>>
>>>>  #if defined(CONFIG_OF)
>>>> +static struct atmel_uart_pdata at91rm9200_pdata = {
>>>> +  .fidi_min = 1,
>>>> +  .fidi_max = 2047,
>>>> +};
>>>> +
>>>> +static struct atmel_uart_pdata at91sam9260_pdata = {
>>>> +  .fidi_min = 1,
>>>> +  .fidi_max = 2047,
>>>> +};
>>>> +
>>>> +static struct atmel_uart_pdata sama5d3_pdata = {
>>>> +  .fidi_min = 3,
>>>> +  .fidi_max = 65535,
>>> Are you sure this is for sama5d3 ?
>>> From the datasheets I have, 65535 is for sama5d4/sama5d2
>>
>> I checked it and I missed it. What a pity... In fact, it's a bit more
>> tricky since the min value for d3 is 3 and no longer 1.
>>
>>> And also, you'll have to s/atmel,at91sam9260-usart/atmel,sama5d2-usart/g
>>> in sama5d{2,4}.dtsi
>>>
>>
>> Yes, I planed to send it later but I can add those patches within this
>> set of patches. 
>>
>>> But I wonder if it could be detected via ATMEL_US_VERSION instead ?
>>>
>>
>> I have not checked, I tend to prefer the compatible string for this kind
>> of thing. But as we already use the version number, I can investigate
>> this solution if it's the one you prefer.
>>
> 
> ping about this question still in suspend in order to prepare a new version.
Well, if we use the compatible string for this, we will have to add :
- atmel,sama5d2-usart
- atmel,sama5d3-usart
- (maybe others ?)
to the already existing :
- atmel,at91sam9260-usart
- atmel,at91rm9200-usart
just for setting different limits on the fidi register.
IMHO, it seems a bit overkill. Moreover, the ATMEL_US_VERSION has
already been read, so...
But if you think adding compatible strings is a better/cleaner solution, just 
convince me ! :)


Re: [PATCH RESEND 2/2] gpio: mvebu: Allow to use non-default PWM counter

2018-08-09 Thread Richard Genoud
Hi,

On 06/08/2018 15:52, Andrew Lunn wrote:
> On Mon, Aug 06, 2018 at 10:29:16AM +0800, Aditya Prayoga wrote:
>> On multiple PWM lines, if the other PWM counter is unused, allocate it
>> to next PWM request. The priority would be:
>> 1. Default counter assigned to the bank
>> 2. Unused counter that is assigned to other bank
>> 3. Fallback to default counter
>>
>> For example on second bank there are three PWM request, first one would
>> use default counter (counter B), second one would try to use counter A,
>> and the third one would use counter B.
> 
> Hi Aditya
> 
> There are only two PWM counters for all the GPIO lines. So you cannot
> support 3 PWM requests. You have to enforce a maximum of two PWMs.
> 
> When i implemented this PWM code, i only needed one PWM. So it took
> the easy option. GPIO bank 0 uses counter A, GPIO bank1 uses counter
> B. For the hardware you have, this is not sufficient, so you need to
> generalise this. Any PWM can use any counter, whatever is available
> when the PWM is requested.
> 
> Rather than have a linked list of PWM, i think it would be better to
> have a static array of two mvebu_pwm structures. Index 0 uses counter
> A, index 1 uses counter B. You can then keep with the concept of
> pwm->pgiod != NULL means the counter is in use. The request() call can
> then find an unused PWM, set pwm->gpiod, and point mvchip->mvpwm to
> one of the two static instances.
> 
> Andrew
> 
I'm not sure that the logic:
1. Default counter assigned to the bank
2. Unused counter that is assigned to other bank
3. Fallback to default counter
is the best one.

I gave the code a try, and I've been a little confused.
I declared:
- fan1 as gpio1 22 
- fan2 as gpio1 11
- fan3 as gpio0 22

and I did:
echo 10 > hwmon1/pwm1  # ok
echo 100 > hwmon2/pwm1 # still ok
echo 200 > hwmon3/pwm1 # hey !! my fan2 is now at 200 (I can see it with the 
scope)
# but
cat hwmon2/pwm1
100
# okay, I want my fan2 back, So I turn off fan3:
echo 0 > hwmon3/pwm1 # fan2 and fan3 are stopped
echo 100 > hwmon2/pwm1 # not working.. fan2 is still at 0 on the scope
but:
cat hwmon2/pwm1
100

IMHO, I would either:
- allow only 2 pwm and no more (but that's a pity)
- allow lots of fans, but once 2 different speeds are set, return EINVAL for 
another different speed (even if it's on another bank)
That way, we'll be able to switch on/off 1, 2, 3 or more fans, as long as they 
have the same speed.
I'll give an example :

echo 10 > hwmon1/pwm1 # ok
echo 100 > hwmon2/pwm1 # still ok
echo 200 > hwmon3/pwm1 # returns EINVAL
echo 10 > hwmon3/pwm1 # ok

The headache will come when we want to change the speed...
echo 50 > hwmon3/pwm1 # should this change the hwmon1 as well or return EINVAL ?
I'd say that it changes hwmon1 as well, as if hwmon1 and hwmon3 were tied.
But, If I then do :
echo 100 > hwmon3/pwm1 # fan2 was already at 100
What should happen ? Do fan1, fan2 and fan3 be set to 100 ?
Or fan1 stay at 10 and fan3 at 100 ? (in this case, fan3 won't be tied to fan1 
anymore, but to fan2)

Hum...
I don't know if anyone followed me on this...
Anyway, I think I convinced myself that only allowing 2 pwm is less confusing 
than anything else :)



Richard.


Re: [PATCH RESEND 2/2] gpio: mvebu: Allow to use non-default PWM counter

2018-08-09 Thread Richard Genoud
Hi,

On 06/08/2018 15:52, Andrew Lunn wrote:
> On Mon, Aug 06, 2018 at 10:29:16AM +0800, Aditya Prayoga wrote:
>> On multiple PWM lines, if the other PWM counter is unused, allocate it
>> to next PWM request. The priority would be:
>> 1. Default counter assigned to the bank
>> 2. Unused counter that is assigned to other bank
>> 3. Fallback to default counter
>>
>> For example on second bank there are three PWM request, first one would
>> use default counter (counter B), second one would try to use counter A,
>> and the third one would use counter B.
> 
> Hi Aditya
> 
> There are only two PWM counters for all the GPIO lines. So you cannot
> support 3 PWM requests. You have to enforce a maximum of two PWMs.
> 
> When i implemented this PWM code, i only needed one PWM. So it took
> the easy option. GPIO bank 0 uses counter A, GPIO bank1 uses counter
> B. For the hardware you have, this is not sufficient, so you need to
> generalise this. Any PWM can use any counter, whatever is available
> when the PWM is requested.
> 
> Rather than have a linked list of PWM, i think it would be better to
> have a static array of two mvebu_pwm structures. Index 0 uses counter
> A, index 1 uses counter B. You can then keep with the concept of
> pwm->pgiod != NULL means the counter is in use. The request() call can
> then find an unused PWM, set pwm->gpiod, and point mvchip->mvpwm to
> one of the two static instances.
> 
> Andrew
> 
I'm not sure that the logic:
1. Default counter assigned to the bank
2. Unused counter that is assigned to other bank
3. Fallback to default counter
is the best one.

I gave the code a try, and I've been a little confused.
I declared:
- fan1 as gpio1 22 
- fan2 as gpio1 11
- fan3 as gpio0 22

and I did:
echo 10 > hwmon1/pwm1  # ok
echo 100 > hwmon2/pwm1 # still ok
echo 200 > hwmon3/pwm1 # hey !! my fan2 is now at 200 (I can see it with the 
scope)
# but
cat hwmon2/pwm1
100
# okay, I want my fan2 back, So I turn off fan3:
echo 0 > hwmon3/pwm1 # fan2 and fan3 are stopped
echo 100 > hwmon2/pwm1 # not working.. fan2 is still at 0 on the scope
but:
cat hwmon2/pwm1
100

IMHO, I would either:
- allow only 2 pwm and no more (but that's a pity)
- allow lots of fans, but once 2 different speeds are set, return EINVAL for 
another different speed (even if it's on another bank)
That way, we'll be able to switch on/off 1, 2, 3 or more fans, as long as they 
have the same speed.
I'll give an example :

echo 10 > hwmon1/pwm1 # ok
echo 100 > hwmon2/pwm1 # still ok
echo 200 > hwmon3/pwm1 # returns EINVAL
echo 10 > hwmon3/pwm1 # ok

The headache will come when we want to change the speed...
echo 50 > hwmon3/pwm1 # should this change the hwmon1 as well or return EINVAL ?
I'd say that it changes hwmon1 as well, as if hwmon1 and hwmon3 were tied.
But, If I then do :
echo 100 > hwmon3/pwm1 # fan2 was already at 100
What should happen ? Do fan1, fan2 and fan3 be set to 100 ?
Or fan1 stay at 10 and fan3 at 100 ? (in this case, fan3 won't be tied to fan1 
anymore, but to fan2)

Hum...
I don't know if anyone followed me on this...
Anyway, I think I convinced myself that only allowing 2 pwm is less confusing 
than anything else :)



Richard.


Re: [PATCH v3 2/2] tty/serial: atmel: add ISO7816 support

2018-08-09 Thread Richard Genoud
Hi !

On 07/08/2018 15:00, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> 
> Signed-off-by: Nicolas Ferre 
> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
> fixes]
> Signed-off-by: Ludovic Desroches 
> ---
>  drivers/tty/serial/atmel_serial.c | 211 
> +++---
>  drivers/tty/serial/atmel_serial.h |   6 +-
>  2 files changed, 201 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 8e4428725848..4a7ec44b0ace 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -83,6 +84,11 @@ static void atmel_stop_rx(struct uart_port *port);
>  
>  #define ATMEL_ISR_PASS_LIMIT 256
>  
> +struct atmel_uart_pdata {
> + unsigned intfidi_min;
> + unsigned intfidi_max;
> +};
> +
>  struct atmel_dma_buffer {
>   unsigned char   *buf;
>   dma_addr_t  dma_addr;
> @@ -114,6 +120,7 @@ struct atmel_uart_char {
>   */
>  struct atmel_uart_port {
>   struct uart_portuart;   /* uart */
> + const struct atmel_uart_pdata *pdata;   /* SoC specific parameters */
>   struct clk  *clk;   /* uart clock */
>   int may_wakeup; /* cached value of 
> device_may_wakeup for times we need to disable it */
>   u32 backup_imr; /* IMR saved during suspend */
> @@ -147,6 +154,8 @@ struct atmel_uart_port {
>   struct circ_buf rx_ring;
>  
>   struct mctrl_gpios  *gpios;
> + u32 backup_mode;/* MR saved during iso7816 
> operations */
> + u32 backup_brgr;/* BRGR saved during iso7816 
> operations */
>   unsigned inttx_done_mask;
>   u32 fifo_size;
>   u32 rts_high;
> @@ -192,10 +201,34 @@ static struct console atmel_console;
>  #endif
>  
>  #if defined(CONFIG_OF)
> +static struct atmel_uart_pdata at91rm9200_pdata = {
> + .fidi_min = 1,
> + .fidi_max = 2047,
> +};
> +
> +static struct atmel_uart_pdata at91sam9260_pdata = {
> + .fidi_min = 1,
> + .fidi_max = 2047,
> +};
> +
> +static struct atmel_uart_pdata sama5d3_pdata = {
> + .fidi_min = 3,
> + .fidi_max = 65535,
Are you sure this is for sama5d3 ?
>From the datasheets I have, 65535 is for sama5d4/sama5d2
And also, you'll have to s/atmel,at91sam9260-usart/atmel,sama5d2-usart/g
in sama5d{2,4}.dtsi

But I wonder if it could be detected via ATMEL_US_VERSION instead ?


> +};
> +
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> - { /* sentinel */ }
> + {
> + .compatible = "atmel,at91rm9200-usart",
> + .data = _pdata,
> + }, {
> + .compatible = "atmel,at91sam9260-usart",
> + .data = _pdata,
> + }, {
> + .compatible = "atmel,sama5d3-usart",
> + .data = _pdata,
> + }, {
> + /* sentinel */
> + }
>  };
>  #endif
>  
> @@ -362,6 +395,127 @@ static int atmel_config_rs485(struct uart_port *port,
>   return 0;
>  }
>  
> +static unsigned int atmel_calc_cd(struct uart_port *port,
> +   struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int cd;
> + u64 mck_rate;
> +
> + mck_rate = (u64)clk_get_rate(atmel_port->clk);
> + do_div(mck_rate, iso7816conf->clk);
> + cd = mck_rate;
> + return cd;
> +}
> +
> +static unsigned int atmel_calc_fidi(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + u64 fidi = 0;
> +
> + if (iso7816conf->sc_fi && iso7816conf->sc_di) {
> + fidi = (u64)iso7816conf->sc_fi;
> + do_div(fidi, iso7816conf->sc_di);
> + }
> + return (u32)fidi;
> +}
> +
> +/* Enable or disable the iso7816 support */
> +/* Called with interrupts disabled */
> +static int atmel_config_iso7816(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int mode;
> + unsigned int cd, fidi;
> + int ret = 0;
> +
> + /* Disable interrupts */
> + atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> +
> + mode = atmel_uart_readl(port, ATMEL_US_MR);
> +
> + if (iso7816conf->flags & SER_ISO7816_ENABLED) {
> + mode &= ~ATMEL_US_USMODE;
> +
> +  

Re: [PATCH v3 2/2] tty/serial: atmel: add ISO7816 support

2018-08-09 Thread Richard Genoud
Hi !

On 07/08/2018 15:00, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> 
> Signed-off-by: Nicolas Ferre 
> [ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
> fixes]
> Signed-off-by: Ludovic Desroches 
> ---
>  drivers/tty/serial/atmel_serial.c | 211 
> +++---
>  drivers/tty/serial/atmel_serial.h |   6 +-
>  2 files changed, 201 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 8e4428725848..4a7ec44b0ace 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -83,6 +84,11 @@ static void atmel_stop_rx(struct uart_port *port);
>  
>  #define ATMEL_ISR_PASS_LIMIT 256
>  
> +struct atmel_uart_pdata {
> + unsigned intfidi_min;
> + unsigned intfidi_max;
> +};
> +
>  struct atmel_dma_buffer {
>   unsigned char   *buf;
>   dma_addr_t  dma_addr;
> @@ -114,6 +120,7 @@ struct atmel_uart_char {
>   */
>  struct atmel_uart_port {
>   struct uart_portuart;   /* uart */
> + const struct atmel_uart_pdata *pdata;   /* SoC specific parameters */
>   struct clk  *clk;   /* uart clock */
>   int may_wakeup; /* cached value of 
> device_may_wakeup for times we need to disable it */
>   u32 backup_imr; /* IMR saved during suspend */
> @@ -147,6 +154,8 @@ struct atmel_uart_port {
>   struct circ_buf rx_ring;
>  
>   struct mctrl_gpios  *gpios;
> + u32 backup_mode;/* MR saved during iso7816 
> operations */
> + u32 backup_brgr;/* BRGR saved during iso7816 
> operations */
>   unsigned inttx_done_mask;
>   u32 fifo_size;
>   u32 rts_high;
> @@ -192,10 +201,34 @@ static struct console atmel_console;
>  #endif
>  
>  #if defined(CONFIG_OF)
> +static struct atmel_uart_pdata at91rm9200_pdata = {
> + .fidi_min = 1,
> + .fidi_max = 2047,
> +};
> +
> +static struct atmel_uart_pdata at91sam9260_pdata = {
> + .fidi_min = 1,
> + .fidi_max = 2047,
> +};
> +
> +static struct atmel_uart_pdata sama5d3_pdata = {
> + .fidi_min = 3,
> + .fidi_max = 65535,
Are you sure this is for sama5d3 ?
>From the datasheets I have, 65535 is for sama5d4/sama5d2
And also, you'll have to s/atmel,at91sam9260-usart/atmel,sama5d2-usart/g
in sama5d{2,4}.dtsi

But I wonder if it could be detected via ATMEL_US_VERSION instead ?


> +};
> +
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> - { /* sentinel */ }
> + {
> + .compatible = "atmel,at91rm9200-usart",
> + .data = _pdata,
> + }, {
> + .compatible = "atmel,at91sam9260-usart",
> + .data = _pdata,
> + }, {
> + .compatible = "atmel,sama5d3-usart",
> + .data = _pdata,
> + }, {
> + /* sentinel */
> + }
>  };
>  #endif
>  
> @@ -362,6 +395,127 @@ static int atmel_config_rs485(struct uart_port *port,
>   return 0;
>  }
>  
> +static unsigned int atmel_calc_cd(struct uart_port *port,
> +   struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int cd;
> + u64 mck_rate;
> +
> + mck_rate = (u64)clk_get_rate(atmel_port->clk);
> + do_div(mck_rate, iso7816conf->clk);
> + cd = mck_rate;
> + return cd;
> +}
> +
> +static unsigned int atmel_calc_fidi(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + u64 fidi = 0;
> +
> + if (iso7816conf->sc_fi && iso7816conf->sc_di) {
> + fidi = (u64)iso7816conf->sc_fi;
> + do_div(fidi, iso7816conf->sc_di);
> + }
> + return (u32)fidi;
> +}
> +
> +/* Enable or disable the iso7816 support */
> +/* Called with interrupts disabled */
> +static int atmel_config_iso7816(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int mode;
> + unsigned int cd, fidi;
> + int ret = 0;
> +
> + /* Disable interrupts */
> + atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> +
> + mode = atmel_uart_readl(port, ATMEL_US_MR);
> +
> + if (iso7816conf->flags & SER_ISO7816_ENABLED) {
> + mode &= ~ATMEL_US_USMODE;
> +
> +  

Re: [PATCH 0/2] gpio: mvebu: Add support for multiple PWM lines

2018-08-03 Thread Richard Genoud
On 03/08/2018 11:42, Richard Genoud wrote:
> On 03/08/2018 11:36, Gregory CLEMENT wrote:
>> Hi Linus and Adita
>>  
>>  On dim., juil. 29 2018, Linus Walleij  wrote:
>>
>>> Hoping for some review from Gergory, Ralph or Richard who all seem
>>> to use this driver!
>>
>> Would it be possible to resend the series adding me in CC?  I would
>> like to comment the patches, but unfortunately it seems that I was in
>> none of the mailing list where the series had been sent.
>>
>> I found the patches on patchwork, and started to have a look on it for
>> example, in the patch "gpio: mvebu: Add support for multiple PWM lines
>> per GPIO chip", I wonder why the id is stored as it was not used at all.
>>
>> Having the patch inlined in an email would male the review easier.
> Same for me :)
> 

Sorry, for the noise, but please use my gmail address.

Thanks !

Richard


Re: [PATCH 0/2] gpio: mvebu: Add support for multiple PWM lines

2018-08-03 Thread Richard Genoud
On 03/08/2018 11:42, Richard Genoud wrote:
> On 03/08/2018 11:36, Gregory CLEMENT wrote:
>> Hi Linus and Adita
>>  
>>  On dim., juil. 29 2018, Linus Walleij  wrote:
>>
>>> Hoping for some review from Gergory, Ralph or Richard who all seem
>>> to use this driver!
>>
>> Would it be possible to resend the series adding me in CC?  I would
>> like to comment the patches, but unfortunately it seems that I was in
>> none of the mailing list where the series had been sent.
>>
>> I found the patches on patchwork, and started to have a look on it for
>> example, in the patch "gpio: mvebu: Add support for multiple PWM lines
>> per GPIO chip", I wonder why the id is stored as it was not used at all.
>>
>> Having the patch inlined in an email would male the review easier.
> Same for me :)
> 

Sorry, for the noise, but please use my gmail address.

Thanks !

Richard


Re: [PATCH 0/2] gpio: mvebu: Add support for multiple PWM lines

2018-08-03 Thread Richard Genoud
On 03/08/2018 11:36, Gregory CLEMENT wrote:
> Hi Linus and Adita
>  
>  On dim., juil. 29 2018, Linus Walleij  wrote:
> 
>> Hoping for some review from Gergory, Ralph or Richard who all seem
>> to use this driver!
> 
> Would it be possible to resend the series adding me in CC?  I would
> like to comment the patches, but unfortunately it seems that I was in
> none of the mailing list where the series had been sent.
> 
> I found the patches on patchwork, and started to have a look on it for
> example, in the patch "gpio: mvebu: Add support for multiple PWM lines
> per GPIO chip", I wonder why the id is stored as it was not used at all.
> 
> Having the patch inlined in an email would male the review easier.
Same for me :)



Re: [PATCH 0/2] gpio: mvebu: Add support for multiple PWM lines

2018-08-03 Thread Richard Genoud
On 03/08/2018 11:36, Gregory CLEMENT wrote:
> Hi Linus and Adita
>  
>  On dim., juil. 29 2018, Linus Walleij  wrote:
> 
>> Hoping for some review from Gergory, Ralph or Richard who all seem
>> to use this driver!
> 
> Would it be possible to resend the series adding me in CC?  I would
> like to comment the patches, but unfortunately it seems that I was in
> none of the mailing list where the series had been sent.
> 
> I found the patches on patchwork, and started to have a look on it for
> example, in the patch "gpio: mvebu: Add support for multiple PWM lines
> per GPIO chip", I wonder why the id is stored as it was not used at all.
> 
> Having the patch inlined in an email would male the review easier.
Same for me :)



Re: [PATCH v2 2/2] tty/serial: atmel: add ISO7816 support

2018-07-27 Thread Richard Genoud
Hi Ludovic,

On 19/07/2018 10:47, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> Report NACK and ITER errors in irq handler.
> 
> Signed-off-by: Nicolas Ferre 
> Signed-off-by: Ludovic Desroches 
> ---
>  drivers/tty/serial/atmel_serial.c | 170 
> +++---
>  drivers/tty/serial/atmel_serial.h |   3 +-
>  2 files changed, 162 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 8e4428725848..cec958f1e7d4 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -147,6 +148,8 @@ struct atmel_uart_port {
>   struct circ_buf rx_ring;
>  
>   struct mctrl_gpios  *gpios;
> + u32 backup_mode;/* MR saved during iso7816 
> operations */
> + u32 backup_brgr;/* BRGR saved during iso7816 
> operations */
>   unsigned inttx_done_mask;
>   u32 fifo_size;
>   u32 rts_high;
> @@ -362,6 +365,132 @@ static int atmel_config_rs485(struct uart_port *port,
>   return 0;
>  }
>  
> +static unsigned int atmel_calc_cd(struct uart_port *port,
> +   struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int cd;
> + u64 mck_rate;
> +
> + mck_rate = (u64)clk_get_rate(atmel_port->clk);
> + do_div(mck_rate, iso7816conf->clk);
> + cd = mck_rate;
> + return cd;
> +}
> +
> +static unsigned int atmel_calc_fidi(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + u64 fidi = 0;
> +
> + if (iso7816conf->sc_fi && iso7816conf->sc_di) {
> + fidi = (u64)iso7816conf->sc_fi;
> + do_div(fidi, iso7816conf->sc_di);
> + }
> + return (u32)fidi;
> +}
> +
> +/* Enable or disable the iso7816 support */
> +/* Called with interrupts disabled */
> +static int atmel_config_iso7816(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int mode, t;
> + unsigned int cd, fidi;
> + int ret = 0;
> +
> + /* Disable RX and TX */
> + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXDIS | ATMEL_US_TXDIS);
> + /* Disable interrupts */
> + atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> +
> + mode = atmel_uart_readl(port, ATMEL_US_MR);
> +
> + if (iso7816conf->flags & SER_ISO7816_ENABLED) {
> + mode &= ~ATMEL_US_USMODE;
> +
> + if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(0)) {
> + mode |= ATMEL_US_USMODE_ISO7816_T0;
> + t = 0;
> + } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(1)) {
> + mode |= ATMEL_US_USMODE_ISO7816_T1;
> + t = 1;
> + } else {
> + dev_warn(port->dev, "ISO7816 Type not supported. 
> Resetting\n");
> + memset(iso7816conf, 0, sizeof(struct serial_iso7816));
> + goto err_out;
> + }
> +
> + dev_dbg(port->dev, "Setting USART to ISO7816 mode T%d\n", t);
> +
> + mode &= ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
> + | ATMEL_US_NBSTOP | ATMEL_US_PAR);
This could be merged in the mode &= line above.

> +
> + /* NACK configuration */
> + if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(0))
> + mode |= ATMEL_US_DSNACK;
> + else
> + mode |= ATMEL_US_INACK;
This could be also part of the if () above.

> + /* select mck clock, and output  */
> + mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
> + /* set parity for normal/inverse mode + max iterations */
> + mode |= ATMEL_US_PAR_EVEN | ATMEL_US_NBSTOP_1 | (3 << 24);
Is this really needed ?
In the documentation, I found:
"The configuration is 8 data bits, even parity and 1 or 2 stop bits,
regardless of the values programmed in the CHRL, MODE9, PAR and CHMODE
fields."
And, for MAX_ITERATIONS, could you add a macro instead of (x << 24) ?
(ATMEL_US_MAX_ITER mask is already defined).
And why 3 ? Should the user-space be allowed to control the max
automatic iteration ? or is it more like a "same-value-for-every-one"
thing ?

Re: [PATCH v2 2/2] tty/serial: atmel: add ISO7816 support

2018-07-27 Thread Richard Genoud
Hi Ludovic,

On 19/07/2018 10:47, Ludovic Desroches wrote:
> From: Nicolas Ferre 
> 
> When mode is set in atmel_config_iso7816() we backup last RS232 mode
> for coming back to this mode if requested.
> Also allow setup of T=0 and T=1 parameter and basic support in set_termios
> function as well.
> Report NACK and ITER errors in irq handler.
> 
> Signed-off-by: Nicolas Ferre 
> Signed-off-by: Ludovic Desroches 
> ---
>  drivers/tty/serial/atmel_serial.c | 170 
> +++---
>  drivers/tty/serial/atmel_serial.h |   3 +-
>  2 files changed, 162 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 8e4428725848..cec958f1e7d4 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -147,6 +148,8 @@ struct atmel_uart_port {
>   struct circ_buf rx_ring;
>  
>   struct mctrl_gpios  *gpios;
> + u32 backup_mode;/* MR saved during iso7816 
> operations */
> + u32 backup_brgr;/* BRGR saved during iso7816 
> operations */
>   unsigned inttx_done_mask;
>   u32 fifo_size;
>   u32 rts_high;
> @@ -362,6 +365,132 @@ static int atmel_config_rs485(struct uart_port *port,
>   return 0;
>  }
>  
> +static unsigned int atmel_calc_cd(struct uart_port *port,
> +   struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int cd;
> + u64 mck_rate;
> +
> + mck_rate = (u64)clk_get_rate(atmel_port->clk);
> + do_div(mck_rate, iso7816conf->clk);
> + cd = mck_rate;
> + return cd;
> +}
> +
> +static unsigned int atmel_calc_fidi(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + u64 fidi = 0;
> +
> + if (iso7816conf->sc_fi && iso7816conf->sc_di) {
> + fidi = (u64)iso7816conf->sc_fi;
> + do_div(fidi, iso7816conf->sc_di);
> + }
> + return (u32)fidi;
> +}
> +
> +/* Enable or disable the iso7816 support */
> +/* Called with interrupts disabled */
> +static int atmel_config_iso7816(struct uart_port *port,
> + struct serial_iso7816 *iso7816conf)
> +{
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + unsigned int mode, t;
> + unsigned int cd, fidi;
> + int ret = 0;
> +
> + /* Disable RX and TX */
> + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXDIS | ATMEL_US_TXDIS);
> + /* Disable interrupts */
> + atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> +
> + mode = atmel_uart_readl(port, ATMEL_US_MR);
> +
> + if (iso7816conf->flags & SER_ISO7816_ENABLED) {
> + mode &= ~ATMEL_US_USMODE;
> +
> + if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(0)) {
> + mode |= ATMEL_US_USMODE_ISO7816_T0;
> + t = 0;
> + } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(1)) {
> + mode |= ATMEL_US_USMODE_ISO7816_T1;
> + t = 1;
> + } else {
> + dev_warn(port->dev, "ISO7816 Type not supported. 
> Resetting\n");
> + memset(iso7816conf, 0, sizeof(struct serial_iso7816));
> + goto err_out;
> + }
> +
> + dev_dbg(port->dev, "Setting USART to ISO7816 mode T%d\n", t);
> +
> + mode &= ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
> + | ATMEL_US_NBSTOP | ATMEL_US_PAR);
This could be merged in the mode &= line above.

> +
> + /* NACK configuration */
> + if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
> + == SER_ISO7816_T(0))
> + mode |= ATMEL_US_DSNACK;
> + else
> + mode |= ATMEL_US_INACK;
This could be also part of the if () above.

> + /* select mck clock, and output  */
> + mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
> + /* set parity for normal/inverse mode + max iterations */
> + mode |= ATMEL_US_PAR_EVEN | ATMEL_US_NBSTOP_1 | (3 << 24);
Is this really needed ?
In the documentation, I found:
"The configuration is 8 data bits, even parity and 1 or 2 stop bits,
regardless of the values programmed in the CHRL, MODE9, PAR and CHMODE
fields."
And, for MAX_ITERATIONS, could you add a macro instead of (x << 24) ?
(ATMEL_US_MAX_ITER mask is already defined).
And why 3 ? Should the user-space be allowed to control the max
automatic iteration ? or is it more like a "same-value-for-every-one"
thing ?

Re: [PATCH v6 6/6] tty/serial: atmel: change the driver to work under at91-usart mfd

2018-06-07 Thread Richard Genoud
   port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
>   port->ops   = _pops;
>   port->fifosize  = 1;
>   port->dev   = >dev;
> - port->mapbase   = pdev->resource[0].start;
> - port->irq   = pdev->resource[1].start;
> + port->mapbase   = mpdev->resource[0].start;
> + port->irq   = mpdev->resource[1].start;
>   port->rs485_config  = atmel_config_rs485;
> - port->membase   = NULL;
> + port->membase   = NULL;
>  
>   memset(_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
>  
>   /* for console, the clock could already be configured */
>   if (!atmel_port->clk) {
> - atmel_port->clk = clk_get(>dev, "usart");
> + atmel_port->clk = clk_get(>dev, "usart");
>   if (IS_ERR(atmel_port->clk)) {
>   ret = PTR_ERR(atmel_port->clk);
>       atmel_port->clk = NULL;
> @@ -2694,13 +2696,22 @@ static void atmel_serial_probe_fifos(struct 
> atmel_uart_port *atmel_port,
>  static int atmel_serial_probe(struct platform_device *pdev)
>  {
>   struct atmel_uart_port *atmel_port;
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
>   void *data;
>   int ret = -ENODEV;
>   bool rs485_enabled;
>  
>   BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
>  
> + /*
> +  * In device tree is no node with "atmel,at91rm9200-usart-serial"
I think you meant :
In device tree *there* is no...

With that,
Acked-by: Richard Genoud 

> +  * as compatible string. This driver is probed by at91-usart mfd driver
> +  * which is just a wrapper over the atmel_serial driver and
> +  * spi-at91-usart driver. All attributes needed by this driver are
> +  * found in of_node of parent.
> +  */
> + pdev->dev.of_node = np;
> +
>   ret = of_alias_get_id(np, "serial");
>   if (ret < 0)
>   /* port id not found in platform data nor device-tree aliases:
> @@ -2835,6 +2846,7 @@ static int atmel_serial_remove(struct platform_device 
> *pdev)
>  
>   clk_put(atmel_port->clk);
>   atmel_port->clk = NULL;
> + pdev->dev.of_node = NULL;
>  
>   return ret;
>  }
> @@ -2845,7 +2857,7 @@ static struct platform_driver atmel_serial_driver = {
>   .suspend= atmel_serial_suspend,
>   .resume = atmel_serial_resume,
>   .driver = {
> - .name   = "atmel_usart",
> + .name   = "atmel_usart_serial",
>   .of_match_table = of_match_ptr(atmel_serial_dt_ids),
>   },
>  };
> 

Thanks !

Richard.


Re: [PATCH v6 6/6] tty/serial: atmel: change the driver to work under at91-usart mfd

2018-06-07 Thread Richard Genoud
   port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
>   port->ops   = _pops;
>   port->fifosize  = 1;
>   port->dev   = >dev;
> - port->mapbase   = pdev->resource[0].start;
> - port->irq   = pdev->resource[1].start;
> + port->mapbase   = mpdev->resource[0].start;
> + port->irq   = mpdev->resource[1].start;
>   port->rs485_config  = atmel_config_rs485;
> - port->membase   = NULL;
> + port->membase   = NULL;
>  
>   memset(_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
>  
>   /* for console, the clock could already be configured */
>   if (!atmel_port->clk) {
> - atmel_port->clk = clk_get(>dev, "usart");
> + atmel_port->clk = clk_get(>dev, "usart");
>   if (IS_ERR(atmel_port->clk)) {
>   ret = PTR_ERR(atmel_port->clk);
>       atmel_port->clk = NULL;
> @@ -2694,13 +2696,22 @@ static void atmel_serial_probe_fifos(struct 
> atmel_uart_port *atmel_port,
>  static int atmel_serial_probe(struct platform_device *pdev)
>  {
>   struct atmel_uart_port *atmel_port;
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
>   void *data;
>   int ret = -ENODEV;
>   bool rs485_enabled;
>  
>   BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
>  
> + /*
> +  * In device tree is no node with "atmel,at91rm9200-usart-serial"
I think you meant :
In device tree *there* is no...

With that,
Acked-by: Richard Genoud 

> +  * as compatible string. This driver is probed by at91-usart mfd driver
> +  * which is just a wrapper over the atmel_serial driver and
> +  * spi-at91-usart driver. All attributes needed by this driver are
> +  * found in of_node of parent.
> +  */
> + pdev->dev.of_node = np;
> +
>   ret = of_alias_get_id(np, "serial");
>   if (ret < 0)
>   /* port id not found in platform data nor device-tree aliases:
> @@ -2835,6 +2846,7 @@ static int atmel_serial_remove(struct platform_device 
> *pdev)
>  
>   clk_put(atmel_port->clk);
>   atmel_port->clk = NULL;
> + pdev->dev.of_node = NULL;
>  
>   return ret;
>  }
> @@ -2845,7 +2857,7 @@ static struct platform_driver atmel_serial_driver = {
>   .suspend= atmel_serial_suspend,
>   .resume = atmel_serial_resume,
>   .driver = {
> - .name   = "atmel_usart",
> + .name   = "atmel_usart_serial",
>   .of_match_table = of_match_ptr(atmel_serial_dt_ids),
>   },
>  };
> 

Thanks !

Richard.


Re: [PATCH v5 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-06-06 Thread Richard Genoud
Typo in the subject:
changed->change


On 04/06/2018 18:59, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 41 ++-
>  2 files changed, 25 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 3682fd3e960c..25e55332f8b1 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -119,6 +119,7 @@ config SERIAL_ATMEL
>   depends on ARCH_AT91 || COMPILE_TEST
>   select SERIAL_CORE
>   select SERIAL_MCTRL_GPIO if GPIOLIB
> + select MFD_AT91_USART
>   help
> This enables the driver for the on-chip UARTs of the Atmel
> AT91 processors.
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index df46a9e88c34..5c74e03396ef 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -193,8 +193,8 @@ static struct console atmel_console;
>  
>  #if defined(CONFIG_OF)
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> + { .compatible = "atmel,at91rm9200-usart-serial" },
> + { .compatible = "atmel,at91sam9260-usart-serial" },
Sorry, I didn't catch that before, but we can drop 
"atmel,at91sam9260-usart-serial" don't we ?
Only "atmel,at91rm9200-usart-serial" is used in the MFD driver.

>   { /* sentinel */ }
>  };
>  #endif
> @@ -915,6 +915,7 @@ static void atmel_tx_dma(struct uart_port *port)
>  static int atmel_prepare_tx_dma(struct uart_port *port)
>  {
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct device *mfd_dev = port->dev->parent;
>   dma_cap_mask_t  mask;
>   struct dma_slave_config config;
>   int ret, nent;
> @@ -922,7 +923,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
>   dma_cap_zero(mask);
>   dma_cap_set(DMA_SLAVE, mask);
>  
> - atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
> + atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx");
>   if (atmel_port->chan_tx == NULL)
>   goto chan_err;
>   dev_info(port->dev, "using %s for tx DMA transfers\n",
> @@ -1093,6 +1094,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
>  static int atmel_prepare_rx_dma(struct uart_port *port)
>  {
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct device *mfd_dev = port->dev->parent;
>   struct dma_async_tx_descriptor *desc;
>   dma_cap_mask_t  mask;
>   struct dma_slave_config config;
> @@ -1104,7 +1106,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>   dma_cap_zero(mask);
>   dma_cap_set(DMA_CYCLIC, mask);
>  
> - atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
> + atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
>   if (atmel_port->chan_rx == NULL)
>   goto chan_err;
>   dev_info(port->dev, "using %s for rx DMA transfers\n",
> @@ -1631,7 +1633,7 @@ static void atmel_tasklet_tx_func(unsigned long data)
>  static void atmel_init_property(struct atmel_uart_port *atmel_port,
>   struct platform_device *pdev)
>  {
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
I think this is not needed anymore (cf atmel_probe())

>  
>   /* DMA/PDC usage specification */
>   if (of_property_read_bool(np, "atmel,use-dma-rx")) {
> @@ -,8 +2224,8 @@ static const char *atmel_type(struct uart_port *port)
>   */
>  static void atmel_release_port(struct uart_port *port)
>  {
> - struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + struct platform_device *mpdev = to_platform_device(port->dev->parent);
> + int size = resource_size(mpdev->resource);
>  
>   release_mem_region(port->mapbase, size);
>  
> @@ -2238,8 +2240,8 @@ static void atmel_release_port(struct uart_port *port)
>   */
>  static int atmel_request_port(struct uart_port *port)
>  {
> - struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + struct platform_device *mpdev = to_platform_device(port->dev->parent);
> + int size = resource_size(mpdev->resource);
>  
>   if (!request_mem_region(port->mapbase, size, "atmel_serial"))
>   return -EBUSY;
> @@ -2341,27 +2343,28 @@ static int atmel_init_port(struct atmel_uart_port 
> *atmel_port,
>  {
>   int ret;
>   struct uart_port *port = _port->uart;
> + struct platform_device *mpdev = to_platform_device(pdev->dev.parent);
>  

Re: [PATCH v5 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-06-06 Thread Richard Genoud
Typo in the subject:
changed->change


On 04/06/2018 18:59, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 41 ++-
>  2 files changed, 25 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 3682fd3e960c..25e55332f8b1 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -119,6 +119,7 @@ config SERIAL_ATMEL
>   depends on ARCH_AT91 || COMPILE_TEST
>   select SERIAL_CORE
>   select SERIAL_MCTRL_GPIO if GPIOLIB
> + select MFD_AT91_USART
>   help
> This enables the driver for the on-chip UARTs of the Atmel
> AT91 processors.
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index df46a9e88c34..5c74e03396ef 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -193,8 +193,8 @@ static struct console atmel_console;
>  
>  #if defined(CONFIG_OF)
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> + { .compatible = "atmel,at91rm9200-usart-serial" },
> + { .compatible = "atmel,at91sam9260-usart-serial" },
Sorry, I didn't catch that before, but we can drop 
"atmel,at91sam9260-usart-serial" don't we ?
Only "atmel,at91rm9200-usart-serial" is used in the MFD driver.

>   { /* sentinel */ }
>  };
>  #endif
> @@ -915,6 +915,7 @@ static void atmel_tx_dma(struct uart_port *port)
>  static int atmel_prepare_tx_dma(struct uart_port *port)
>  {
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct device *mfd_dev = port->dev->parent;
>   dma_cap_mask_t  mask;
>   struct dma_slave_config config;
>   int ret, nent;
> @@ -922,7 +923,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
>   dma_cap_zero(mask);
>   dma_cap_set(DMA_SLAVE, mask);
>  
> - atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
> + atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx");
>   if (atmel_port->chan_tx == NULL)
>   goto chan_err;
>   dev_info(port->dev, "using %s for tx DMA transfers\n",
> @@ -1093,6 +1094,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
>  static int atmel_prepare_rx_dma(struct uart_port *port)
>  {
>   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> + struct device *mfd_dev = port->dev->parent;
>   struct dma_async_tx_descriptor *desc;
>   dma_cap_mask_t  mask;
>   struct dma_slave_config config;
> @@ -1104,7 +1106,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
>   dma_cap_zero(mask);
>   dma_cap_set(DMA_CYCLIC, mask);
>  
> - atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
> + atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
>   if (atmel_port->chan_rx == NULL)
>   goto chan_err;
>   dev_info(port->dev, "using %s for rx DMA transfers\n",
> @@ -1631,7 +1633,7 @@ static void atmel_tasklet_tx_func(unsigned long data)
>  static void atmel_init_property(struct atmel_uart_port *atmel_port,
>   struct platform_device *pdev)
>  {
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
I think this is not needed anymore (cf atmel_probe())

>  
>   /* DMA/PDC usage specification */
>   if (of_property_read_bool(np, "atmel,use-dma-rx")) {
> @@ -,8 +2224,8 @@ static const char *atmel_type(struct uart_port *port)
>   */
>  static void atmel_release_port(struct uart_port *port)
>  {
> - struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + struct platform_device *mpdev = to_platform_device(port->dev->parent);
> + int size = resource_size(mpdev->resource);
>  
>   release_mem_region(port->mapbase, size);
>  
> @@ -2238,8 +2240,8 @@ static void atmel_release_port(struct uart_port *port)
>   */
>  static int atmel_request_port(struct uart_port *port)
>  {
> - struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + struct platform_device *mpdev = to_platform_device(port->dev->parent);
> + int size = resource_size(mpdev->resource);
>  
>   if (!request_mem_region(port->mapbase, size, "atmel_serial"))
>   return -EBUSY;
> @@ -2341,27 +2343,28 @@ static int atmel_init_port(struct atmel_uart_port 
> *atmel_port,
>  {
>   int ret;
>   struct uart_port *port = _port->uart;
> + struct platform_device *mpdev = to_platform_device(pdev->dev.parent);
>  

Re: [PATCH v4 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-28 Thread Richard Genoud
On 25/05/2018 19:19, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 40 +--
>  2 files changed, 23 insertions(+), 18 deletions(-)
the stdout-path property of the chosen node is still broken in this verion.
if :
stdout-path = "serial0:115200n8";
is set in the DTS, the console output should go on serial0 (aka dbgu)
cf Documentation/devicetree/bindings/chosen.txt

With this patch applied, this is not the case anymore.
Adding console=ttyS0,115200 in the chosen node is not the solution here.


regards,
Richard.


Re: [PATCH v4 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-28 Thread Richard Genoud
On 25/05/2018 19:19, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 40 +--
>  2 files changed, 23 insertions(+), 18 deletions(-)
the stdout-path property of the chosen node is still broken in this verion.
if :
stdout-path = "serial0:115200n8";
is set in the DTS, the console output should go on serial0 (aka dbgu)
cf Documentation/devicetree/bindings/chosen.txt

With this patch applied, this is not the case anymore.
Adding console=ttyS0,115200 in the chosen node is not the solution here.


regards,
Richard.


Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-25 Thread Richard Genoud
On 25/05/2018 14:17, Radu Pirea wrote:
> 
> 
> On 05/15/2018 04:14 PM, Richard Genoud wrote:
>> On 15/05/2018 14:47, Radu Pirea wrote:
>>> On Mon, 2018-05-14 at 12:57 +0200, Richard Genoud wrote:
>>>> After your patch, the DMA is not selected anymore:
>>>> atmel_usart_serial atmel_usart_serial.0.auto: TX channel not
>>>> available, switch to pio
>>>> instead of:
>>>> atmel_usart f200.serial: using dma1chan2 for tx DMA transfers
>>>>
>>> Fixed.
>>>> And the kernel doesn't log anymore on the serial console, despite the
>>>> loglevel=8
>>>> (after reverting this series, the kernel logs reappears on the serial
>>>> console)
>>>>
>>> Which serial are you using as console?
>> f200.serial (sam9g35-cm)
>> ( stdout-path = "serial0:115200n8"; in the DTS )
>>
>> With this series applied, all the kernel log goes on the screen.
>> Without, it goes on the serial debug.
>>
> I tested again with archlinux arm and poky-linux4sam release as distros
> and kernel log goes on the serial debug. Can you give me more details
> like cmdline?
I used kernel 4.17-rc6
at91_dt_defconfig
at91sam9g35ek.dtb

Kernel command line: root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 
root=ubi0:rootfs
( the one from the DTS )

Detailed instructions:

git checkout v4.17-rc6 
ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 at91_dt_defconfig
ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 uImage at91sam9g35ek.dtb
cp arch/arm/boot/uImage arch/arm/boot/dts/at91sam9g35ek.dtb /tftpboot/

>From uboot:
tftpboot 0x20007FC0 uImage
tftpboot 0x2640 at91sam9g35ek.dtb
bootm 0x20007FC0 - 0x2640

[ I see the logs on the serial debug ]

git am \[PATCH\ v3\ [1-6]*

ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 uImage at91sam9g35ek.dtb
cp arch/arm/boot/uImage arch/arm/boot/dts/at91sam9g35ek.dtb /tftpboot/

>From uboot:
tftpboot 0x20007FC0 uImage
tftpboot 0x2640 at91sam9g35ek.dtb
bootm 0x20007FC0 - 0x2640

[ I don't see the logs on the serial debug anymore ]


>>>> (tests done on sam9g35)
>>>>
>>> I will consider the rest of suggestions.
>>>> regards,
>>>> Richard
>>



Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-25 Thread Richard Genoud
On 25/05/2018 14:17, Radu Pirea wrote:
> 
> 
> On 05/15/2018 04:14 PM, Richard Genoud wrote:
>> On 15/05/2018 14:47, Radu Pirea wrote:
>>> On Mon, 2018-05-14 at 12:57 +0200, Richard Genoud wrote:
>>>> After your patch, the DMA is not selected anymore:
>>>> atmel_usart_serial atmel_usart_serial.0.auto: TX channel not
>>>> available, switch to pio
>>>> instead of:
>>>> atmel_usart f200.serial: using dma1chan2 for tx DMA transfers
>>>>
>>> Fixed.
>>>> And the kernel doesn't log anymore on the serial console, despite the
>>>> loglevel=8
>>>> (after reverting this series, the kernel logs reappears on the serial
>>>> console)
>>>>
>>> Which serial are you using as console?
>> f200.serial (sam9g35-cm)
>> ( stdout-path = "serial0:115200n8"; in the DTS )
>>
>> With this series applied, all the kernel log goes on the screen.
>> Without, it goes on the serial debug.
>>
> I tested again with archlinux arm and poky-linux4sam release as distros
> and kernel log goes on the serial debug. Can you give me more details
> like cmdline?
I used kernel 4.17-rc6
at91_dt_defconfig
at91sam9g35ek.dtb

Kernel command line: root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 
root=ubi0:rootfs
( the one from the DTS )

Detailed instructions:

git checkout v4.17-rc6 
ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 at91_dt_defconfig
ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 uImage at91sam9g35ek.dtb
cp arch/arm/boot/uImage arch/arm/boot/dts/at91sam9g35ek.dtb /tftpboot/

>From uboot:
tftpboot 0x20007FC0 uImage
tftpboot 0x2640 at91sam9g35ek.dtb
bootm 0x20007FC0 - 0x2640

[ I see the logs on the serial debug ]

git am \[PATCH\ v3\ [1-6]*

ARCH=arm CROSS_COMPILE=path_to_my_Xchain/arm-linux- LOADADDR=0x20008000 make -j 
12 uImage at91sam9g35ek.dtb
cp arch/arm/boot/uImage arch/arm/boot/dts/at91sam9g35ek.dtb /tftpboot/

>From uboot:
tftpboot 0x20007FC0 uImage
tftpboot 0x2640 at91sam9g35ek.dtb
bootm 0x20007FC0 - 0x2640

[ I don't see the logs on the serial debug anymore ]


>>>> (tests done on sam9g35)
>>>>
>>> I will consider the rest of suggestions.
>>>> regards,
>>>> Richard
>>



Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-15 Thread Richard Genoud
On 15/05/2018 14:47, Radu Pirea wrote:
> On Mon, 2018-05-14 at 12:57 +0200, Richard Genoud wrote:
>> After your patch, the DMA is not selected anymore:
>> atmel_usart_serial atmel_usart_serial.0.auto: TX channel not
>> available, switch to pio
>> instead of:
>> atmel_usart f200.serial: using dma1chan2 for tx DMA transfers
>>
> Fixed.
>> And the kernel doesn't log anymore on the serial console, despite the
>> loglevel=8
>> (after reverting this series, the kernel logs reappears on the serial
>> console)
>>
> Which serial are you using as console? 
f200.serial (sam9g35-cm)
( stdout-path = "serial0:115200n8"; in the DTS )

With this series applied, all the kernel log goes on the screen.
Without, it goes on the serial debug.

>> (tests done on sam9g35)
>>
> I will consider the rest of suggestions. 
>> regards,
>> Richard



Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-15 Thread Richard Genoud
On 15/05/2018 14:47, Radu Pirea wrote:
> On Mon, 2018-05-14 at 12:57 +0200, Richard Genoud wrote:
>> After your patch, the DMA is not selected anymore:
>> atmel_usart_serial atmel_usart_serial.0.auto: TX channel not
>> available, switch to pio
>> instead of:
>> atmel_usart f200.serial: using dma1chan2 for tx DMA transfers
>>
> Fixed.
>> And the kernel doesn't log anymore on the serial console, despite the
>> loglevel=8
>> (after reverting this series, the kernel logs reappears on the serial
>> console)
>>
> Which serial are you using as console? 
f200.serial (sam9g35-cm)
( stdout-path = "serial0:115200n8"; in the DTS )

With this series applied, all the kernel log goes on the screen.
Without, it goes on the serial debug.

>> (tests done on sam9g35)
>>
> I will consider the rest of suggestions. 
>> regards,
>> Richard



Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-15 Thread Richard Genoud
On 14/05/2018 18:56, Andy Shevchenko wrote:
> On Mon, May 14, 2018 at 1:57 PM, Richard Genoud
> <richard.gen...@gmail.com> wrote:
>> On 11/05/2018 12:38, Radu Pirea wrote:
>>> This patch modifies the place where resources and device tree properties
>>> are searched.
> 
>> I think it may be simpler with something like:
> 
>> +   int size = mfd_pdev->resource[0].end - mfd_pdev->resource[0].start + 
>> 1;
> 
> Isn't resource_size() macro for this very purpose?
Indeed.
+   int size = resource_size(mfd_pdev->resource);
would be even simpler !

> 
>>> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
>>> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
>>>
>> ditto
> 
> Ditto.
> 

Thanks !

Richard.


Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-15 Thread Richard Genoud
On 14/05/2018 18:56, Andy Shevchenko wrote:
> On Mon, May 14, 2018 at 1:57 PM, Richard Genoud
>  wrote:
>> On 11/05/2018 12:38, Radu Pirea wrote:
>>> This patch modifies the place where resources and device tree properties
>>> are searched.
> 
>> I think it may be simpler with something like:
> 
>> +   int size = mfd_pdev->resource[0].end - mfd_pdev->resource[0].start + 
>> 1;
> 
> Isn't resource_size() macro for this very purpose?
Indeed.
+   int size = resource_size(mfd_pdev->resource);
would be even simpler !

> 
>>> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
>>> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
>>>
>> ditto
> 
> Ditto.
> 

Thanks !

Richard.


Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-14 Thread Richard Genoud
Hi,

On 11/05/2018 12:38, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 29 +++--
>  2 files changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 3682fd3e960c..25e55332f8b1 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -119,6 +119,7 @@ config SERIAL_ATMEL
>   depends on ARCH_AT91 || COMPILE_TEST
>   select SERIAL_CORE
>   select SERIAL_MCTRL_GPIO if GPIOLIB
> + select MFD_AT91_USART
>   help
> This enables the driver for the on-chip UARTs of the Atmel
> AT91 processors.
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index df46a9e88c34..6b4494352853 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -193,8 +193,8 @@ static struct console atmel_console;
>  
>  #if defined(CONFIG_OF)
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> + { .compatible = "atmel,at91rm9200-usart-serial" },
> + { .compatible = "atmel,at91sam9260-usart-serial" },
>   { /* sentinel */ }
>  };
>  #endif
> @@ -1631,7 +1631,7 @@ static void atmel_tasklet_tx_func(unsigned long data)
>  static void atmel_init_property(struct atmel_uart_port *atmel_port,
>   struct platform_device *pdev)
>  {
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
>  
>   /* DMA/PDC usage specification */
>   if (of_property_read_bool(np, "atmel,use-dma-rx")) {
> @@ -2223,7 +2223,8 @@ static const char *atmel_type(struct uart_port *port)
>  static void atmel_release_port(struct uart_port *port)
>  {
>   struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
I think it may be simpler with something like:
+   struct platform_device *mfd_pdev = 
to_platform_device(port->dev->parent);
+   int size = mfd_pdev->resource[0].end - mfd_pdev->resource[0].start + 1;

>  
>   release_mem_region(port->mapbase, size);
>  
> @@ -2239,7 +2240,8 @@ static void atmel_release_port(struct uart_port *port)
>  static int atmel_request_port(struct uart_port *port)
>  {
>   struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
>  
ditto

>   if (!request_mem_region(port->mapbase, size, "atmel_serial"))
>   return -EBUSY;
> @@ -2345,23 +2347,23 @@ static int atmel_init_port(struct atmel_uart_port 
> *atmel_port,
Here, we could also add:
+   struct device *mfd_dev = pdev->dev.parent;
+   struct platform_device *mfd_pdev = to_platform_device(mfd_dev);

>   atmel_init_property(atmel_port, pdev);
>   atmel_set_ops(port);
>  
> - uart_get_rs485_mode(>dev, >rs485);
> + uart_get_rs485_mode(pdev->dev.parent, >rs485);
...and use them here

>  
>   port->iotype= UPIO_MEM;
>   port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
>   port->ops   = _pops;
>   port->fifosize  = 1;
>   port->dev   = >dev;
> - port->mapbase   = pdev->resource[0].start;
> - port->irq   = pdev->resource[1].start;
> + port->mapbase   = 
> to_platform_device(pdev->dev.parent)->resource[0].start;
> + port->irq   = 
> to_platform_device(pdev->dev.parent)->resource[1].start;
and here
I think it would be easier to read.

>   port->rs485_config  = atmel_config_rs485;
> - port->membase   = NULL;
> + port->membase   = NULL;
>  
>   memset(_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
>  
>   /* for console, the clock could already be configured */
>   if (!atmel_port->clk) {
> - atmel_port->clk = clk_get(>dev, "usart");
> + atmel_port->clk = clk_get(pdev->dev.parent, "usart");
and here

>   if (IS_ERR(atmel_port->clk)) {
>   ret = PTR_ERR(atmel_port->clk);
>   atmel_port->clk = NULL;
> @@ -2656,7 +2658,7 @@ static void atmel_serial_probe_fifos(struct 
> atmel_uart_port *atmel_port,
>   atmel_port->rts_low = 0;
>   atmel_port->rts_high = 0;
>  
> - if (of_property_read_u32(pdev->dev.of_node,
> + if 

Re: [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd

2018-05-14 Thread Richard Genoud
Hi,

On 11/05/2018 12:38, Radu Pirea wrote:
> This patch modifies the place where resources and device tree properties
> are searched.
> 
> Signed-off-by: Radu Pirea 
> ---
>  drivers/tty/serial/Kconfig|  1 +
>  drivers/tty/serial/atmel_serial.c | 29 +++--
>  2 files changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 3682fd3e960c..25e55332f8b1 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -119,6 +119,7 @@ config SERIAL_ATMEL
>   depends on ARCH_AT91 || COMPILE_TEST
>   select SERIAL_CORE
>   select SERIAL_MCTRL_GPIO if GPIOLIB
> + select MFD_AT91_USART
>   help
> This enables the driver for the on-chip UARTs of the Atmel
> AT91 processors.
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index df46a9e88c34..6b4494352853 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -193,8 +193,8 @@ static struct console atmel_console;
>  
>  #if defined(CONFIG_OF)
>  static const struct of_device_id atmel_serial_dt_ids[] = {
> - { .compatible = "atmel,at91rm9200-usart" },
> - { .compatible = "atmel,at91sam9260-usart" },
> + { .compatible = "atmel,at91rm9200-usart-serial" },
> + { .compatible = "atmel,at91sam9260-usart-serial" },
>   { /* sentinel */ }
>  };
>  #endif
> @@ -1631,7 +1631,7 @@ static void atmel_tasklet_tx_func(unsigned long data)
>  static void atmel_init_property(struct atmel_uart_port *atmel_port,
>   struct platform_device *pdev)
>  {
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.parent->of_node;
>  
>   /* DMA/PDC usage specification */
>   if (of_property_read_bool(np, "atmel,use-dma-rx")) {
> @@ -2223,7 +2223,8 @@ static const char *atmel_type(struct uart_port *port)
>  static void atmel_release_port(struct uart_port *port)
>  {
>   struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
I think it may be simpler with something like:
+   struct platform_device *mfd_pdev = 
to_platform_device(port->dev->parent);
+   int size = mfd_pdev->resource[0].end - mfd_pdev->resource[0].start + 1;

>  
>   release_mem_region(port->mapbase, size);
>  
> @@ -2239,7 +2240,8 @@ static void atmel_release_port(struct uart_port *port)
>  static int atmel_request_port(struct uart_port *port)
>  {
>   struct platform_device *pdev = to_platform_device(port->dev);
> - int size = pdev->resource[0].end - pdev->resource[0].start + 1;
> + int size = to_platform_device(pdev->dev.parent)->resource[0].end -
> + to_platform_device(pdev->dev.parent)->resource[0].start + 1;
>  
ditto

>   if (!request_mem_region(port->mapbase, size, "atmel_serial"))
>   return -EBUSY;
> @@ -2345,23 +2347,23 @@ static int atmel_init_port(struct atmel_uart_port 
> *atmel_port,
Here, we could also add:
+   struct device *mfd_dev = pdev->dev.parent;
+   struct platform_device *mfd_pdev = to_platform_device(mfd_dev);

>   atmel_init_property(atmel_port, pdev);
>   atmel_set_ops(port);
>  
> - uart_get_rs485_mode(>dev, >rs485);
> + uart_get_rs485_mode(pdev->dev.parent, >rs485);
...and use them here

>  
>   port->iotype= UPIO_MEM;
>   port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
>   port->ops   = _pops;
>   port->fifosize  = 1;
>   port->dev   = >dev;
> - port->mapbase   = pdev->resource[0].start;
> - port->irq   = pdev->resource[1].start;
> + port->mapbase   = 
> to_platform_device(pdev->dev.parent)->resource[0].start;
> + port->irq   = 
> to_platform_device(pdev->dev.parent)->resource[1].start;
and here
I think it would be easier to read.

>   port->rs485_config  = atmel_config_rs485;
> - port->membase   = NULL;
> + port->membase   = NULL;
>  
>   memset(_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
>  
>   /* for console, the clock could already be configured */
>   if (!atmel_port->clk) {
> - atmel_port->clk = clk_get(>dev, "usart");
> + atmel_port->clk = clk_get(pdev->dev.parent, "usart");
and here

>   if (IS_ERR(atmel_port->clk)) {
>   ret = PTR_ERR(atmel_port->clk);
>   atmel_port->clk = NULL;
> @@ -2656,7 +2658,7 @@ static void atmel_serial_probe_fifos(struct 
> atmel_uart_port *atmel_port,
>   atmel_port->rts_low = 0;
>   atmel_port->rts_high = 0;
>  
> - if (of_property_read_u32(pdev->dev.of_node,
> + if 

[PATCH v2] clk: mvebu: armada-38x: add support for missing clocks

2018-03-13 Thread Richard Genoud
Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
or 1333MHz (industrial).

They have also some dip-switches to select a different clock (666, 800,
1066, 1200).

The funny thing is that the recovery button is on the MPP34 fq selector.
So, when booting an industrial board with this button down, the frequency
666MHz is selected (and the kernel didn't boot).

This patch add all the missing clocks.

The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).

Fixes: 0e85aeced4d6 ("clk: mvebu: add clock support for Armada 380/385")
Cc: <sta...@vger.kernel.org> # 3.16.x: 9593f4f56cf5: clk: mvebu: armada-38x: 
add support for 1866MHz variants
Cc: <sta...@vger.kernel.org> # 3.16.x

Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
Acked-by: Gregory CLEMENT <gregory.clem...@bootlin.com>
---
 drivers/clk/mvebu/armada-38x.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
index 394aa6f03f01..9ff4ea63932d 100644
--- a/drivers/clk/mvebu/armada-38x.c
+++ b/drivers/clk/mvebu/armada-38x.c
@@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
*sar)
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-   0, 0, 0, 0,
-   1066 * 1000 * 1000, 0, 0, 0,
+   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
1332 * 1000 * 1000, 0, 0, 0,
1600 * 1000 * 1000, 0, 0, 0,
-   1866 * 1000 * 1000,
+   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -76,11 +76,11 @@ static const struct coreclk_ratio 
armada_38x_coreclk_ratios[] __initconst = {
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-   {0, 1}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {1, 2},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst 
= {
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {7, 15},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},


[PATCH v2] clk: mvebu: armada-38x: add support for missing clocks

2018-03-13 Thread Richard Genoud
Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
or 1333MHz (industrial).

They have also some dip-switches to select a different clock (666, 800,
1066, 1200).

The funny thing is that the recovery button is on the MPP34 fq selector.
So, when booting an industrial board with this button down, the frequency
666MHz is selected (and the kernel didn't boot).

This patch add all the missing clocks.

The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).

Fixes: 0e85aeced4d6 ("clk: mvebu: add clock support for Armada 380/385")
Cc:  # 3.16.x: 9593f4f56cf5: clk: mvebu: armada-38x: 
add support for 1866MHz variants
Cc:  # 3.16.x

Signed-off-by: Richard Genoud 
Acked-by: Gregory CLEMENT 
---
 drivers/clk/mvebu/armada-38x.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
index 394aa6f03f01..9ff4ea63932d 100644
--- a/drivers/clk/mvebu/armada-38x.c
+++ b/drivers/clk/mvebu/armada-38x.c
@@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
*sar)
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-   0, 0, 0, 0,
-   1066 * 1000 * 1000, 0, 0, 0,
+   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
1332 * 1000 * 1000, 0, 0, 0,
1600 * 1000 * 1000, 0, 0, 0,
-   1866 * 1000 * 1000,
+   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -76,11 +76,11 @@ static const struct coreclk_ratio 
armada_38x_coreclk_ratios[] __initconst = {
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-   {0, 1}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {1, 2},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst 
= {
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {7, 15},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},


Re: [PATCH] clk: mvebu: armada-38x: add support for missing clocks

2018-03-13 Thread Richard Genoud
On 08/03/2018 14:23, Gregory CLEMENT wrote:
> Hi,
>  
>  On jeu., mars 08 2018, Gregory CLEMENT <gregory.clem...@bootlin.com> wrote:
> 
>> Hi Richard,
>>  
>>  On jeu., mars 08 2018, Richard Genoud <richard.gen...@gmail.com> wrote:
>>
>>> Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
>>> or 1333MHz (industrial).
>>>
>>> They have also some dip-switches to select a different clock (666, 800,
>>> 1066, 1200).
>>
>> The patch looks goo and it will also be usefull for any other board
>> using these frequencies, thanks for this. I have only one small comment,
>> see below.
> 
> 
> I forgot to mention that you can add my
> 
> Acked-by: Gregory CLEMENT <gregory.clem...@bootlin.com>
> 
> Thanks,
> 
> Gregory
> 
>>
>>
>>>
>>> The funny thing is that the recovery button is on the MPP34 fq selector.
>>> So, when booting an industrial board with this button down, the frequency
>>> 666MHz is selected (and the kernel didn't boot).
>>>
>>> This patch add all the missing clocks.
>>>
>>> The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).
>>>
>>> Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
>>> ---
>>>  drivers/clk/mvebu/armada-38x.c | 14 +++---
>>>  1 file changed, 7 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
>>> index 394aa6f03f01..9ff4ea63932d 100644
>>> --- a/drivers/clk/mvebu/armada-38x.c
>>> +++ b/drivers/clk/mvebu/armada-38x.c
>>> @@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
>>> *sar)
>>>  }
>>>  
>>>  static const u32 armada_38x_cpu_frequencies[] __initconst = {
>>> -   0, 0, 0, 0,
>>> -   1066 * 1000 * 1000, 0, 0, 0,
>>> +   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
>>> +   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
>>> 1332 * 1000 * 1000, 0, 0, 0,
>>> 1600 * 1000 * 1000, 0, 0, 0,
>>> -   1866 * 1000 * 1000,
>>> +   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
>>
>> Maybe you could add a comment here to say that the 2GHz mode didn't have
>> been tested.
Well, if I add a comment there saying "2GHz mode hasn't been tested",
I'm afraid it will stay there forever, even after being tested.
(if it's working, nobody will look at it, and if it's not, it's in the commit 
message anyway).

I was also thinking that this could go in -stable since it fixes a hang.
In this case, commit 9593f4f56cf5 ("clk: mvebu: armada-38x: add support for 
1866MHz variants")
should also go with it.



Thanks !

>>
>> Thanks,
>> Gregory
>>
>>
>>>  };
>>>  
>>>  static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
>>> @@ -76,11 +76,11 @@ static const struct coreclk_ratio 
>>> armada_38x_coreclk_ratios[] __initconst = {
>>>  };
>>>  
>>>  static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
>>> -   {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {1, 2}, {0, 1},
>>> +   {1, 2}, {0, 1}, {1, 2}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {0, 1}, {1, 2},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> @@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] 
>>> __initconst = {
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {0, 1}, {7, 15},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>
>> -- 
>> Gregory Clement, Bootlin (formerly Free Electrons)
>> Embedded Linux and Kernel engineering
>> http://bootlin.com
> 



Re: [PATCH] clk: mvebu: armada-38x: add support for missing clocks

2018-03-13 Thread Richard Genoud
On 08/03/2018 14:23, Gregory CLEMENT wrote:
> Hi,
>  
>  On jeu., mars 08 2018, Gregory CLEMENT  wrote:
> 
>> Hi Richard,
>>  
>>  On jeu., mars 08 2018, Richard Genoud  wrote:
>>
>>> Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
>>> or 1333MHz (industrial).
>>>
>>> They have also some dip-switches to select a different clock (666, 800,
>>> 1066, 1200).
>>
>> The patch looks goo and it will also be usefull for any other board
>> using these frequencies, thanks for this. I have only one small comment,
>> see below.
> 
> 
> I forgot to mention that you can add my
> 
> Acked-by: Gregory CLEMENT 
> 
> Thanks,
> 
> Gregory
> 
>>
>>
>>>
>>> The funny thing is that the recovery button is on the MPP34 fq selector.
>>> So, when booting an industrial board with this button down, the frequency
>>> 666MHz is selected (and the kernel didn't boot).
>>>
>>> This patch add all the missing clocks.
>>>
>>> The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).
>>>
>>> Signed-off-by: Richard Genoud 
>>> ---
>>>  drivers/clk/mvebu/armada-38x.c | 14 +++---
>>>  1 file changed, 7 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
>>> index 394aa6f03f01..9ff4ea63932d 100644
>>> --- a/drivers/clk/mvebu/armada-38x.c
>>> +++ b/drivers/clk/mvebu/armada-38x.c
>>> @@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
>>> *sar)
>>>  }
>>>  
>>>  static const u32 armada_38x_cpu_frequencies[] __initconst = {
>>> -   0, 0, 0, 0,
>>> -   1066 * 1000 * 1000, 0, 0, 0,
>>> +   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
>>> +   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
>>> 1332 * 1000 * 1000, 0, 0, 0,
>>> 1600 * 1000 * 1000, 0, 0, 0,
>>> -   1866 * 1000 * 1000,
>>> +   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
>>
>> Maybe you could add a comment here to say that the 2GHz mode didn't have
>> been tested.
Well, if I add a comment there saying "2GHz mode hasn't been tested",
I'm afraid it will stay there forever, even after being tested.
(if it's working, nobody will look at it, and if it's not, it's in the commit 
message anyway).

I was also thinking that this could go in -stable since it fixes a hang.
In this case, commit 9593f4f56cf5 ("clk: mvebu: armada-38x: add support for 
1866MHz variants")
should also go with it.



Thanks !

>>
>> Thanks,
>> Gregory
>>
>>
>>>  };
>>>  
>>>  static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
>>> @@ -76,11 +76,11 @@ static const struct coreclk_ratio 
>>> armada_38x_coreclk_ratios[] __initconst = {
>>>  };
>>>  
>>>  static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
>>> -   {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {1, 2}, {0, 1},
>>> +   {1, 2}, {0, 1}, {1, 2}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {0, 1}, {1, 2},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> @@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] 
>>> __initconst = {
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> -   {1, 2}, {0, 1}, {0, 1}, {0, 1},
>>> +   {1, 2}, {0, 1}, {0, 1}, {7, 15},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>> {0, 1}, {0, 1}, {0, 1}, {0, 1},
>>
>> -- 
>> Gregory Clement, Bootlin (formerly Free Electrons)
>> Embedded Linux and Kernel engineering
>> http://bootlin.com
> 



[PATCH] clk: mvebu: armada-38x: add support for missing clocks

2018-03-08 Thread Richard Genoud
Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
or 1333MHz (industrial).

They have also some dip-switches to select a different clock (666, 800,
1066, 1200).

The funny thing is that the recovery button is on the MPP34 fq selector.
So, when booting an industrial board with this button down, the frequency
666MHz is selected (and the kernel didn't boot).

This patch add all the missing clocks.

The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).

Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
---
 drivers/clk/mvebu/armada-38x.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
index 394aa6f03f01..9ff4ea63932d 100644
--- a/drivers/clk/mvebu/armada-38x.c
+++ b/drivers/clk/mvebu/armada-38x.c
@@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
*sar)
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-   0, 0, 0, 0,
-   1066 * 1000 * 1000, 0, 0, 0,
+   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
1332 * 1000 * 1000, 0, 0, 0,
1600 * 1000 * 1000, 0, 0, 0,
-   1866 * 1000 * 1000,
+   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -76,11 +76,11 @@ static const struct coreclk_ratio 
armada_38x_coreclk_ratios[] __initconst = {
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-   {0, 1}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {1, 2},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst 
= {
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {7, 15},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},


[PATCH] clk: mvebu: armada-38x: add support for missing clocks

2018-03-08 Thread Richard Genoud
Clearfog boards can come with a CPU clocked at 1600MHz (commercial)
or 1333MHz (industrial).

They have also some dip-switches to select a different clock (666, 800,
1066, 1200).

The funny thing is that the recovery button is on the MPP34 fq selector.
So, when booting an industrial board with this button down, the frequency
666MHz is selected (and the kernel didn't boot).

This patch add all the missing clocks.

The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).

Signed-off-by: Richard Genoud 
---
 drivers/clk/mvebu/armada-38x.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
index 394aa6f03f01..9ff4ea63932d 100644
--- a/drivers/clk/mvebu/armada-38x.c
+++ b/drivers/clk/mvebu/armada-38x.c
@@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
*sar)
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-   0, 0, 0, 0,
-   1066 * 1000 * 1000, 0, 0, 0,
+   666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+   1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
1332 * 1000 * 1000, 0, 0, 0,
1600 * 1000 * 1000, 0, 0, 0,
-   1866 * 1000 * 1000,
+   1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -76,11 +76,11 @@ static const struct coreclk_ratio 
armada_38x_coreclk_ratios[] __initconst = {
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-   {0, 1}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
+   {1, 2}, {0, 1}, {1, 2}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {1, 2},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst 
= {
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {0, 1},
-   {1, 2}, {0, 1}, {0, 1}, {0, 1},
+   {1, 2}, {0, 1}, {0, 1}, {7, 15},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1},


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-08 Thread Richard Genoud
Le mercredi 08 novembre 2017 à 11:37 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 12:01:23PM +0100, Richard Genoud wrote:
> > Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a
> > écrit :
> > > On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > > > 3 short articles how to configure and use ftrace are here:
> > > > > https://lwn.net/Articles/365835/
> > > > > https://lwn.net/Articles/366796/
> > > > > https://lwn.net/Articles/370423/
> > > > > 
> > > > 
> > > > I tried with ftrace, but I don't think there's a way to dump
> > > > the
> > > > trace
> > > > when there's a soft lock-up
> > > > (I can't do anything after the unbind, even the heartbeat led
> > > > stopped blinking).
> > > > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but
> > > > there's no
> > > > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> > > 
> > > You should configure function trace with rt2x* functions. After
> > > that
> > > start tracing, unbind the device, then stop tracing and provide
> > > trace
> > > output.
> > 
> > Ok, I found a way to display the trace (after the unbind, the board
> > is
> > frozen and I can't type anything).
> > Adding
> > CONFIG_SOFTLOCKUP_DETECTOR=y
> > CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
> > along with echo 1 > /proc/sys/kernel/ftrace_dump_on_oops does the
> > trick
> 
> No, that not I wanted you to do. Please remove those options and just
> do
> below on tracing directory.
> 
> echo 0 > tracing_on 
> cat trace >  /dev/null
> echo "function_graph" > current_tracer 
> echo "rt2*" > set_ftrace_filter 
> echo 1 > tracing_on
> echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
> echo 0 > tracing_on
> cat trace > ~/trace.txt

Well, there's clearly a misunderstanding here :
After the command "echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind"
I can't type *anything*
The only thing I can do is plug off the board.
This command never returns, so I can't stop the tracing...

Or I missed something ?

(maybe if there was more than one CPU on the board, I could do
something, but that's not the case)

> 
> and provide trace.txt to me (can be in private email if big).
> 
> Thanks
> Stanislaw

Thanks,
Richard.


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-08 Thread Richard Genoud
Le mercredi 08 novembre 2017 à 11:37 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 12:01:23PM +0100, Richard Genoud wrote:
> > Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a
> > écrit :
> > > On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > > > 3 short articles how to configure and use ftrace are here:
> > > > > https://lwn.net/Articles/365835/
> > > > > https://lwn.net/Articles/366796/
> > > > > https://lwn.net/Articles/370423/
> > > > > 
> > > > 
> > > > I tried with ftrace, but I don't think there's a way to dump
> > > > the
> > > > trace
> > > > when there's a soft lock-up
> > > > (I can't do anything after the unbind, even the heartbeat led
> > > > stopped blinking).
> > > > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but
> > > > there's no
> > > > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> > > 
> > > You should configure function trace with rt2x* functions. After
> > > that
> > > start tracing, unbind the device, then stop tracing and provide
> > > trace
> > > output.
> > 
> > Ok, I found a way to display the trace (after the unbind, the board
> > is
> > frozen and I can't type anything).
> > Adding
> > CONFIG_SOFTLOCKUP_DETECTOR=y
> > CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
> > along with echo 1 > /proc/sys/kernel/ftrace_dump_on_oops does the
> > trick
> 
> No, that not I wanted you to do. Please remove those options and just
> do
> below on tracing directory.
> 
> echo 0 > tracing_on 
> cat trace >  /dev/null
> echo "function_graph" > current_tracer 
> echo "rt2*" > set_ftrace_filter 
> echo 1 > tracing_on
> echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
> echo 0 > tracing_on
> cat trace > ~/trace.txt

Well, there's clearly a misunderstanding here :
After the command "echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind"
I can't type *anything*
The only thing I can do is plug off the board.
This command never returns, so I can't stop the tracing...

Or I missed something ?

(maybe if there was more than one CPU on the board, I could do
something, but that's not the case)

> 
> and provide trace.txt to me (can be in private email if big).
> 
> Thanks
> Stanislaw

Thanks,
Richard.


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > 3 short articles how to configure and use ftrace are here:
> > > https://lwn.net/Articles/365835/
> > > https://lwn.net/Articles/366796/
> > > https://lwn.net/Articles/370423/
> > > 
> > 
> > I tried with ftrace, but I don't think there's a way to dump the
> > trace
> > when there's a soft lock-up
> > (I can't do anything after the unbind, even the heartbeat led
> > stopped blinking).
> > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
> > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> 
> You should configure function trace with rt2x* functions. After that
> start tracing, unbind the device, then stop tracing and provide trace
> output.
Here is another trace, with rt2* as function filter.
(sorry for the noise)

Dumping ftrace buffer:
-
CPU:0 [LOST 3606923 EVENTS]
 0)   0.000 us|  } /* rt2x00usb_clear_entry */
 0)   0.000 us|} /* rt2x00lib_rxdone */
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}

> 
> Thanks
> Stanislaw


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > 3 short articles how to configure and use ftrace are here:
> > > https://lwn.net/Articles/365835/
> > > https://lwn.net/Articles/366796/
> > > https://lwn.net/Articles/370423/
> > > 
> > 
> > I tried with ftrace, but I don't think there's a way to dump the
> > trace
> > when there's a soft lock-up
> > (I can't do anything after the unbind, even the heartbeat led
> > stopped blinking).
> > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
> > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> 
> You should configure function trace with rt2x* functions. After that
> start tracing, unbind the device, then stop tracing and provide trace
> output.
Here is another trace, with rt2* as function filter.
(sorry for the noise)

Dumping ftrace buffer:
-
CPU:0 [LOST 3606923 EVENTS]
 0)   0.000 us|  } /* rt2x00usb_clear_entry */
 0)   0.000 us|} /* rt2x00lib_rxdone */
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|rt2x00queue_get_entry();
 0)   |rt2x00lib_rxdone() {
 0)   0.000 us|  rt2x00queue_index_inc();
 0)   |  rt2x00usb_clear_entry() {
 0)   |rt2x00usb_kick_rx_entry() {
 0)   |  rt2x00lib_dmastart() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   |  rt2x00lib_dmadone() {
 0)   0.000 us|rt2x00queue_index_inc();
 0)   0.000 us|  }
 0)   0.000 us|}
 0)   0.000 us|  }
 0)   0.000 us|}

> 
> Thanks
> Stanislaw


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > 3 short articles how to configure and use ftrace are here:
> > > https://lwn.net/Articles/365835/
> > > https://lwn.net/Articles/366796/
> > > https://lwn.net/Articles/370423/
> > > 
> > 
> > I tried with ftrace, but I don't think there's a way to dump the
> > trace
> > when there's a soft lock-up
> > (I can't do anything after the unbind, even the heartbeat led
> > stopped blinking).
> > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
> > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> 
> You should configure function trace with rt2x* functions. After that
> start tracing, unbind the device, then stop tracing and provide trace
> output.
Ok, I found a way to display the trace (after the unbind, the board is
frozen and I can't type anything).
Adding
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
along with echo 1 > /proc/sys/kernel/ftrace_dump_on_oops does the trick

(trace is after the stack dump)

# cd /sys/kernel/debug/tracing/
# echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
# 
# echo rt2x00usb* > set_ftrace_filter
# echo 0 > tracing_on
# echo function > current_tracer
# echo 1 > tracing_on
# echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
[board frozen]
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/u2:3:188]
CPU: 0 PID: 188 Comm: kworker/u2:3 Not tainted 4.14.0-rc8-00040-g53fb1fe423ba 
#13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
task: c7b34400 task.stack: c7b4e000
PC is at rb_commit+0x1a8/0x2e4
LR is at ring_buffer_unlock_commit+0x20/0xa4
pc : []lr : []psr: 8013
sp : c7b4fda8  ip :   fp : c7b4fdc4
r10: c664ee34  r9 : c7b2ed18  r8 : 6013
r7 : 001c4851  r6 : c780a0e0  r5 : c7319340  r4 : 8a48
r3 : c7319340  r2 : c664e000  r1 : 0e38  r0 : 0e24
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: 2727  DAC: 0053
CPU: 0 PID: 188 Comm: kworker/u2:3 Not tainted 4.14.0-rc8-00040-g53fb1fe423ba 
#13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (show_regs+0x1c/0x20)
[] (show_regs) from [] (watchdog_timer_fn+0x148/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_times+0x38/0x6c)
[] (update_process_times) from [] 
(tick_nohz_handler+0xc0/0x10c)
[] (tick_nohz_handler) from [] (ch2_irq+0x30/0x38)
[] (ch2_irq) from [] (__handle_irq_event_percpu+0x74/0x1dc)
[] (__handle_irq_event_percpu) from [] 
(handle_irq_event_percpu+0x2c/0x68)
[] (handle_irq_event_percpu) from [] 
(handle_irq_event+0x38/0x4c)
[] (handle_irq_event) from [] 
(handle_fasteoi_irq+0xa0/0x114)
[] (handle_fasteoi_irq) from [] 
(generic_handle_irq+0x28/0x38)
[] (generic_handle_irq) from [] 
(__handle_domain_irq+0x90/0xb8)
[] (__handle_domain_irq) from [] (aic_handle+0xb0/0xb8)
[] (aic_handle) from [] (__irq_svc+0x68/0x84)
Exception stack(0xc7b4fd58 to 0xc7b4fda0)
fd40:   0e24 0e38
fd60: c664e000 c7319340 8a48 c7319340 c780a0e0 001c4851 6013 c7b2ed18
fd80: c664ee34 c7b4fdc4  c7b4fda8 c006d724 c006c694 8013 
[] (__irq_svc) from [] (rb_commit+0x1a8/0x2e4)
[] (rb_commit) from [] (ring_buffer_unlock_commit+0x20/0xa4)
[] (ring_buffer_unlock_commit) from [] 
(trace_function+0xe0/0xf0)
[] (trace_function) from [] (function_trace_call+0xbc/0x11c)
[] (function_trace_call) from [] (ftrace_graph_call+0x0/0xc)
[] (ftrace_graph_call) from [] 
(rt2x00usb_kick_rx_entry+0x14/0x118)
[] (rt2x00usb_kick_rx_entry) from [] 
(rt2x00usb_clear_entry+0x30/0x34)
[] (rt2x00usb_clear_entry) from [] 
(rt2x00lib_rxdone+0x58c/0x5b8)
[] (rt2x00lib_rxdone) from [] 
(rt2x00usb_work_rxdone+0x60/0x7c)
[] (rt2x00usb_work_rxdone) from [] 
(process_one_work+0x1e4/0x3a0)
[] (process_one_work) from [] (worker_thread+0x2c8/0x45c)
[] (worker_thread) from [] (kthread+0x114/0x130)
[] (kthread) from [] (ret_from_fork+0x14/0x2c)
Kernel panic - not syncing: softlockup: hung tasks
CPU: 0 PID: 188 Comm: kworker/u2:3 Tainted: G L  
4.14.0-rc8-00040-g53fb1fe423ba #13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (panic+0xc8/0x260)
[] (panic) from [] (watchdog_timer_fn+0x180/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_tim

Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
Le mardi 07 novembre 2017 à 11:13 +0100, Stanislaw Gruszka a écrit :
> On Tue, Nov 07, 2017 at 11:06:39AM +0100, Richard Genoud wrote:
> > > 3 short articles how to configure and use ftrace are here:
> > > https://lwn.net/Articles/365835/
> > > https://lwn.net/Articles/366796/
> > > https://lwn.net/Articles/370423/
> > > 
> > 
> > I tried with ftrace, but I don't think there's a way to dump the
> > trace
> > when there's a soft lock-up
> > (I can't do anything after the unbind, even the heartbeat led
> > stopped blinking).
> > I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
> > /proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)
> 
> You should configure function trace with rt2x* functions. After that
> start tracing, unbind the device, then stop tracing and provide trace
> output.
Ok, I found a way to display the trace (after the unbind, the board is
frozen and I can't type anything).
Adding
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
along with echo 1 > /proc/sys/kernel/ftrace_dump_on_oops does the trick

(trace is after the stack dump)

# cd /sys/kernel/debug/tracing/
# echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
# 
# echo rt2x00usb* > set_ftrace_filter
# echo 0 > tracing_on
# echo function > current_tracer
# echo 1 > tracing_on
# echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
[board frozen]
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/u2:3:188]
CPU: 0 PID: 188 Comm: kworker/u2:3 Not tainted 4.14.0-rc8-00040-g53fb1fe423ba 
#13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
task: c7b34400 task.stack: c7b4e000
PC is at rb_commit+0x1a8/0x2e4
LR is at ring_buffer_unlock_commit+0x20/0xa4
pc : []lr : []psr: 8013
sp : c7b4fda8  ip :   fp : c7b4fdc4
r10: c664ee34  r9 : c7b2ed18  r8 : 6013
r7 : 001c4851  r6 : c780a0e0  r5 : c7319340  r4 : 8a48
r3 : c7319340  r2 : c664e000  r1 : 0e38  r0 : 0e24
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: 2727  DAC: 0053
CPU: 0 PID: 188 Comm: kworker/u2:3 Not tainted 4.14.0-rc8-00040-g53fb1fe423ba 
#13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (show_regs+0x1c/0x20)
[] (show_regs) from [] (watchdog_timer_fn+0x148/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_times+0x38/0x6c)
[] (update_process_times) from [] 
(tick_nohz_handler+0xc0/0x10c)
[] (tick_nohz_handler) from [] (ch2_irq+0x30/0x38)
[] (ch2_irq) from [] (__handle_irq_event_percpu+0x74/0x1dc)
[] (__handle_irq_event_percpu) from [] 
(handle_irq_event_percpu+0x2c/0x68)
[] (handle_irq_event_percpu) from [] 
(handle_irq_event+0x38/0x4c)
[] (handle_irq_event) from [] 
(handle_fasteoi_irq+0xa0/0x114)
[] (handle_fasteoi_irq) from [] 
(generic_handle_irq+0x28/0x38)
[] (generic_handle_irq) from [] 
(__handle_domain_irq+0x90/0xb8)
[] (__handle_domain_irq) from [] (aic_handle+0xb0/0xb8)
[] (aic_handle) from [] (__irq_svc+0x68/0x84)
Exception stack(0xc7b4fd58 to 0xc7b4fda0)
fd40:   0e24 0e38
fd60: c664e000 c7319340 8a48 c7319340 c780a0e0 001c4851 6013 c7b2ed18
fd80: c664ee34 c7b4fdc4  c7b4fda8 c006d724 c006c694 8013 
[] (__irq_svc) from [] (rb_commit+0x1a8/0x2e4)
[] (rb_commit) from [] (ring_buffer_unlock_commit+0x20/0xa4)
[] (ring_buffer_unlock_commit) from [] 
(trace_function+0xe0/0xf0)
[] (trace_function) from [] (function_trace_call+0xbc/0x11c)
[] (function_trace_call) from [] (ftrace_graph_call+0x0/0xc)
[] (ftrace_graph_call) from [] 
(rt2x00usb_kick_rx_entry+0x14/0x118)
[] (rt2x00usb_kick_rx_entry) from [] 
(rt2x00usb_clear_entry+0x30/0x34)
[] (rt2x00usb_clear_entry) from [] 
(rt2x00lib_rxdone+0x58c/0x5b8)
[] (rt2x00lib_rxdone) from [] 
(rt2x00usb_work_rxdone+0x60/0x7c)
[] (rt2x00usb_work_rxdone) from [] 
(process_one_work+0x1e4/0x3a0)
[] (process_one_work) from [] (worker_thread+0x2c8/0x45c)
[] (worker_thread) from [] (kthread+0x114/0x130)
[] (kthread) from [] (ret_from_fork+0x14/0x2c)
Kernel panic - not syncing: softlockup: hung tasks
CPU: 0 PID: 188 Comm: kworker/u2:3 Tainted: G L  
4.14.0-rc8-00040-g53fb1fe423ba #13
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (panic+0xc8/0x260)
[] (panic) from [] (watchdog_timer_fn+0x180/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_tim

Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
2017-11-07 9:53 GMT+01:00 Stanislaw Gruszka <sgrus...@redhat.com>:
> Hi
Hi !
>
> On Mon, Nov 06, 2017 at 04:57:09PM +0100, Richard Genoud wrote:
>> I get a soft lock-up while unbinding the USB driver on a TP-Link TL-WN727Nv3 
>> (chipset 5370):
>>
>> # echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
>> watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u2:3:308]
> ...
>> I can trigger this each time.
>
> I can not reproduce this on my system (I'm using 4.14.0-rc6, but I don't
> think it's an issue). I think the problem may be caused by usb
> host controler driver, which can be different on your system.
>
> Does ftrace work on your platform ? If so could you use ftrace
> to provide rt2x00 functions trace when the  probllem happen ?
>
> 3 short articles how to configure and use ftrace are here:
> https://lwn.net/Articles/365835/
> https://lwn.net/Articles/366796/
> https://lwn.net/Articles/370423/
>
I tried with ftrace, but I don't think there's a way to dump the trace
when there's a soft lock-up
(I can't do anything after the unbind, even the heartbeat led stopped blinking).
I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
/proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)

Or I missed something in ftrace ?

Thanks !
Richard.

> Thanks
> Stanislaw


Re: Soft lockup in rt2x00usb_work_rxdone()

2017-11-07 Thread Richard Genoud
2017-11-07 9:53 GMT+01:00 Stanislaw Gruszka :
> Hi
Hi !
>
> On Mon, Nov 06, 2017 at 04:57:09PM +0100, Richard Genoud wrote:
>> I get a soft lock-up while unbinding the USB driver on a TP-Link TL-WN727Nv3 
>> (chipset 5370):
>>
>> # echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
>> watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u2:3:308]
> ...
>> I can trigger this each time.
>
> I can not reproduce this on my system (I'm using 4.14.0-rc6, but I don't
> think it's an issue). I think the problem may be caused by usb
> host controler driver, which can be different on your system.
>
> Does ftrace work on your platform ? If so could you use ftrace
> to provide rt2x00 functions trace when the  probllem happen ?
>
> 3 short articles how to configure and use ftrace are here:
> https://lwn.net/Articles/365835/
> https://lwn.net/Articles/366796/
> https://lwn.net/Articles/370423/
>
I tried with ftrace, but I don't think there's a way to dump the trace
when there's a soft lock-up
(I can't do anything after the unbind, even the heartbeat led stopped blinking).
I saw the /proc/sys/kernel/ftrace_dump_on_oops file, but there's no
/proc/sys/kernel/ftrace_dump_on_soft_lock-up file :)

Or I missed something in ftrace ?

Thanks !
Richard.

> Thanks
> Stanislaw


Soft lockup in rt2x00usb_work_rxdone()

2017-11-06 Thread Richard Genoud
Hi,

I get a soft lock-up while unbinding the USB driver on a TP-Link TL-WN727Nv3 
(chipset 5370):

# echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u2:3:308]
CPU: 0 PID: 308 Comm: kworker/u2:3 Not tainted 4.14.0-rc8 #11
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
task: c7b91000 task.stack: c7bee000
PC is at rt2x00lib_rxdone+0x590/0x5b8
LR is at rt2x00lib_dmadone+0x54/0x58
pc : []lr : []psr: 8013
sp : c7befebc  ip : 0052  fp : c7befee4
r10:   r9 : c79b2b58  r8 : 
r7 : c7816d00  r6 : c780e200  r5 : c79c68dc  r4 : c7134ce0
r3 : 0001  r2 : c70bc200  r1 : a55f  r0 : 
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: 261b8000  DAC: 0053
CPU: 0 PID: 308 Comm: kworker/u2:3 Not tainted 4.14.0-rc8 #11
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (show_regs+0x1c/0x20)
[] (show_regs) from [] (watchdog_timer_fn+0x148/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_times+0x38/0x6c)
[] (update_process_times) from [] 
(tick_nohz_handler+0xc0/0x10c)
[] (tick_nohz_handler) from [] (ch2_irq+0x30/0x38)
[] (ch2_irq) from [] (__handle_irq_event_percpu+0x74/0x1dc)
[] (__handle_irq_event_percpu) from [] 
(handle_irq_event_percpu+0x2c/0x68)
[] (handle_irq_event_percpu) from [] 
(handle_irq_event+0x38/0x4c)
[] (handle_irq_event) from [] 
(handle_fasteoi_irq+0xa0/0x114)
[] (handle_fasteoi_irq) from [] 
(generic_handle_irq+0x28/0x38)
[] (generic_handle_irq) from [] 
(__handle_domain_irq+0x90/0xb8)
[] (__handle_domain_irq) from [] (aic_handle+0xb0/0xb8)
[] (aic_handle) from [] (__irq_svc+0x68/0x84)
Exception stack(0xc7befe68 to 0xc7befeb0)
fe60:    a55f c70bc200 0001 c7134ce0 c79c68dc
fe80: c780e200 c7816d00  c79b2b58  c7befee4 0052 c7befebc
fea0: c0331fdc c0332978 8013 
[] (__irq_svc) from [] (rt2x00lib_rxdone+0x590/0x5b8)
[] (rt2x00lib_rxdone) from [] 
(rt2x00usb_work_rxdone+0x60/0x7c)
[] (rt2x00usb_work_rxdone) from [] 
(process_one_work+0x1e4/0x3a0)
[] (process_one_work) from [] (worker_thread+0x2c8/0x45c)
[] (worker_thread) from [] (kthread+0x114/0x130)
[] (kthread) from [] (ret_from_fork+0x14/0x2c)

I can trigger this each time.

NB: if the wifi is deactivated properly before the unbind, there's no problem :

# ifconfig wlan0 down ; echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
wlan0: deauthenticating from 06:18:d6:91:9e:29 by local choice (Reason: 
3=DEAUTH_LEAVING)



Full dmesg:
 
## Booting kernel from Legacy Image at 20007fc0 ...
   Image Name:   Linux-4.14.0-rc8
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:4522192 Bytes = 4.3 MiB
   Load Address: 20008000
   Entry Point:  20008000
## Flattened Device Tree blob at 2640
   Booting using the fdt blob at 0x2640
   XIP Kernel Image ... OK
   Loading Device Tree to 27df2000, end 27dfcbb3 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.14.0-rc8 (rgenoud@lnx-rg) (gcc version 4.7.3 (GCC)) #11 Mon Nov 
6 16:22:49 CET 2017
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
CPU: VIVT data cache, VIVT instruction cache
OF: fdt: Machine model: Paratronic LNS
Memory policy: Data cache writeback
On node 0 totalpages: 32768
free_area_init_node: node 0, pgdat c08a4b78, node_mem_map c7efb000
  Normal zone: 256 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 32768 pages, LIFO batch:7
random: fast init done
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0 
Built 1 zonelists, mobility grouping on.  Total pages: 32512
Kernel command line: loglevel=8 ro root=ubi0:rootfs rootfstype=ubifs 
ubi.mtd=ubi lpj=995328 ubi.fm_autoconvert=1 panic=2 
mtdparts=atmel_nand:256M(all),128k@0(dtb),10112k(kernel),251392k(ubi),512k(bbt)ro
 atmel-nand-controller.use_dma=0 spidev.bufsiz=53200 video=320x240-32
PID hash table entries: 512 (order: -1, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 120624K/131072K available (5847K kernel code, 475K rwdata, 1504K 
rodata, 480K init, 245K bss, 10448K reserved, 0K cma-reserved)
Virtual kernel memory layout:
vector  : 0x - 0x1000   (   4 kB)
fixmap  : 0xffc0 - 0xfff0   (3072 kB)
vmalloc : 0xc880 - 0xff80   ( 880 MB)
lowmem  : 0xc000 - 0xc800   ( 128 MB)
  .text : 0xc0008000 - 0xc05be200   (5849 kB)
  .init : 0xc07be000 - 0xc0836000   ( 480 kB)
  .data : 0xc0836000 - 0xc08accd0   ( 476 kB)
   .bss : 0xc08b20e8 - 0xc08ef77c   ( 246 kB)
ftrace: allocating 23621 entries in 70 pages
NR_IRQS: 16, 

Soft lockup in rt2x00usb_work_rxdone()

2017-11-06 Thread Richard Genoud
Hi,

I get a soft lock-up while unbinding the USB driver on a TP-Link TL-WN727Nv3 
(chipset 5370):

# echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u2:3:308]
CPU: 0 PID: 308 Comm: kworker/u2:3 Not tainted 4.14.0-rc8 #11
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
task: c7b91000 task.stack: c7bee000
PC is at rt2x00lib_rxdone+0x590/0x5b8
LR is at rt2x00lib_dmadone+0x54/0x58
pc : []lr : []psr: 8013
sp : c7befebc  ip : 0052  fp : c7befee4
r10:   r9 : c79b2b58  r8 : 
r7 : c7816d00  r6 : c780e200  r5 : c79c68dc  r4 : c7134ce0
r3 : 0001  r2 : c70bc200  r1 : a55f  r0 : 
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: 261b8000  DAC: 0053
CPU: 0 PID: 308 Comm: kworker/u2:3 Not tainted 4.14.0-rc8 #11
Hardware name: Atmel AT91SAM9
Workqueue: phy0 rt2x00usb_work_rxdone
[] (unwind_backtrace) from [] (show_stack+0x20/0x24)
[] (show_stack) from [] (dump_stack+0x20/0x28)
[] (dump_stack) from [] (show_regs+0x1c/0x20)
[] (show_regs) from [] (watchdog_timer_fn+0x148/0x1ac)
[] (watchdog_timer_fn) from [] 
(hrtimer_run_queues+0x128/0x250)
[] (hrtimer_run_queues) from [] (run_local_timers+0x18/0x68)
[] (run_local_timers) from [] 
(update_process_times+0x38/0x6c)
[] (update_process_times) from [] 
(tick_nohz_handler+0xc0/0x10c)
[] (tick_nohz_handler) from [] (ch2_irq+0x30/0x38)
[] (ch2_irq) from [] (__handle_irq_event_percpu+0x74/0x1dc)
[] (__handle_irq_event_percpu) from [] 
(handle_irq_event_percpu+0x2c/0x68)
[] (handle_irq_event_percpu) from [] 
(handle_irq_event+0x38/0x4c)
[] (handle_irq_event) from [] 
(handle_fasteoi_irq+0xa0/0x114)
[] (handle_fasteoi_irq) from [] 
(generic_handle_irq+0x28/0x38)
[] (generic_handle_irq) from [] 
(__handle_domain_irq+0x90/0xb8)
[] (__handle_domain_irq) from [] (aic_handle+0xb0/0xb8)
[] (aic_handle) from [] (__irq_svc+0x68/0x84)
Exception stack(0xc7befe68 to 0xc7befeb0)
fe60:    a55f c70bc200 0001 c7134ce0 c79c68dc
fe80: c780e200 c7816d00  c79b2b58  c7befee4 0052 c7befebc
fea0: c0331fdc c0332978 8013 
[] (__irq_svc) from [] (rt2x00lib_rxdone+0x590/0x5b8)
[] (rt2x00lib_rxdone) from [] 
(rt2x00usb_work_rxdone+0x60/0x7c)
[] (rt2x00usb_work_rxdone) from [] 
(process_one_work+0x1e4/0x3a0)
[] (process_one_work) from [] (worker_thread+0x2c8/0x45c)
[] (worker_thread) from [] (kthread+0x114/0x130)
[] (kthread) from [] (ret_from_fork+0x14/0x2c)

I can trigger this each time.

NB: if the wifi is deactivated properly before the unbind, there's no problem :

# ifconfig wlan0 down ; echo 1-2.2 > /sys/bus/usb/drivers/usb/unbind
wlan0: deauthenticating from 06:18:d6:91:9e:29 by local choice (Reason: 
3=DEAUTH_LEAVING)



Full dmesg:
 
## Booting kernel from Legacy Image at 20007fc0 ...
   Image Name:   Linux-4.14.0-rc8
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:4522192 Bytes = 4.3 MiB
   Load Address: 20008000
   Entry Point:  20008000
## Flattened Device Tree blob at 2640
   Booting using the fdt blob at 0x2640
   XIP Kernel Image ... OK
   Loading Device Tree to 27df2000, end 27dfcbb3 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.14.0-rc8 (rgenoud@lnx-rg) (gcc version 4.7.3 (GCC)) #11 Mon Nov 
6 16:22:49 CET 2017
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
CPU: VIVT data cache, VIVT instruction cache
OF: fdt: Machine model: Paratronic LNS
Memory policy: Data cache writeback
On node 0 totalpages: 32768
free_area_init_node: node 0, pgdat c08a4b78, node_mem_map c7efb000
  Normal zone: 256 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 32768 pages, LIFO batch:7
random: fast init done
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0 
Built 1 zonelists, mobility grouping on.  Total pages: 32512
Kernel command line: loglevel=8 ro root=ubi0:rootfs rootfstype=ubifs 
ubi.mtd=ubi lpj=995328 ubi.fm_autoconvert=1 panic=2 
mtdparts=atmel_nand:256M(all),128k@0(dtb),10112k(kernel),251392k(ubi),512k(bbt)ro
 atmel-nand-controller.use_dma=0 spidev.bufsiz=53200 video=320x240-32
PID hash table entries: 512 (order: -1, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 120624K/131072K available (5847K kernel code, 475K rwdata, 1504K 
rodata, 480K init, 245K bss, 10448K reserved, 0K cma-reserved)
Virtual kernel memory layout:
vector  : 0x - 0x1000   (   4 kB)
fixmap  : 0xffc0 - 0xfff0   (3072 kB)
vmalloc : 0xc880 - 0xff80   ( 880 MB)
lowmem  : 0xc000 - 0xc800   ( 128 MB)
  .text : 0xc0008000 - 0xc05be200   (5849 kB)
  .init : 0xc07be000 - 0xc0836000   ( 480 kB)
  .data : 0xc0836000 - 0xc08accd0   ( 476 kB)
   .bss : 0xc08b20e8 - 0xc08ef77c   ( 246 kB)
ftrace: allocating 23621 entries in 70 pages
NR_IRQS: 16, 

[PATCH] tty/serial: atmel: Convert timers to use timer_setup()

2017-10-24 Thread Richard Genoud
Le mardi 24 octobre 2017 à 03:00 -0700, Kees Cook a écrit :
> In preparation for unconditionally passing the struct timer_list
> pointer to
> all timer callbacks, switch to using the new timer_setup() and
> from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Richard Genoud <richard.gen...@gmail.com>
> Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
> Cc: Jiri Slaby <jsl...@suse.com>
> Cc: linux-ser...@vger.kernel.org
> Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Richard Genoud <richard.gen...@gmail.com>

Thanks !

> ---
>  drivers/tty/serial/atmel_serial.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c
> b/drivers/tty/serial/atmel_serial.c
> index 82d9c8eae04f..68d8685e5a50 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1185,10 +1185,11 @@ static int atmel_prepare_rx_dma(struct
> uart_port *port)
>   return -EINVAL;
>  }
>  
> -static void atmel_uart_timer_callback(unsigned long data)
> +static void atmel_uart_timer_callback(struct timer_list *t)
>  {
> - struct uart_port *port = (void *)data;
> - struct atmel_uart_port *atmel_port =
> to_atmel_uart_port(port);
> + struct atmel_uart_port *atmel_port = from_timer(atmel_port,
> t,
> + uart_timer);
> + struct uart_port *port = _port->uart;
>  
>   if (!atomic_read(_port->tasklet_shutdown)) {
>   tasklet_schedule(_port->tasklet_rx);
> @@ -1852,9 +1853,7 @@ static int atmel_startup(struct uart_port
> *port)
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN |
> ATMEL_US_RXEN);
>   atmel_port->tx_stopped = false;
>  
> - setup_timer(_port->uart_timer,
> - atmel_uart_timer_callback,
> - (unsigned long)port);
> + timer_setup(_port->uart_timer,
> atmel_uart_timer_callback, 0);
>  
>   if (atmel_use_pdc_rx(port)) {
>   /* set UART timeout */
> -- 
> 2.7.4
> 
> 


[PATCH] tty/serial: atmel: Convert timers to use timer_setup()

2017-10-24 Thread Richard Genoud
Le mardi 24 octobre 2017 à 03:00 -0700, Kees Cook a écrit :
> In preparation for unconditionally passing the struct timer_list
> pointer to
> all timer callbacks, switch to using the new timer_setup() and
> from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Richard Genoud 
> Cc: Greg Kroah-Hartman 
> Cc: Jiri Slaby 
> Cc: linux-ser...@vger.kernel.org
> Signed-off-by: Kees Cook 
Acked-by: Richard Genoud 

Thanks !

> ---
>  drivers/tty/serial/atmel_serial.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c
> b/drivers/tty/serial/atmel_serial.c
> index 82d9c8eae04f..68d8685e5a50 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1185,10 +1185,11 @@ static int atmel_prepare_rx_dma(struct
> uart_port *port)
>   return -EINVAL;
>  }
>  
> -static void atmel_uart_timer_callback(unsigned long data)
> +static void atmel_uart_timer_callback(struct timer_list *t)
>  {
> - struct uart_port *port = (void *)data;
> - struct atmel_uart_port *atmel_port =
> to_atmel_uart_port(port);
> + struct atmel_uart_port *atmel_port = from_timer(atmel_port,
> t,
> + uart_timer);
> + struct uart_port *port = _port->uart;
>  
>   if (!atomic_read(_port->tasklet_shutdown)) {
>   tasklet_schedule(_port->tasklet_rx);
> @@ -1852,9 +1853,7 @@ static int atmel_startup(struct uart_port
> *port)
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN |
> ATMEL_US_RXEN);
>   atmel_port->tx_stopped = false;
>  
> - setup_timer(_port->uart_timer,
> - atmel_uart_timer_callback,
> - (unsigned long)port);
> + timer_setup(_port->uart_timer,
> atmel_uart_timer_callback, 0);
>  
>   if (atmel_use_pdc_rx(port)) {
>   /* set UART timeout */
> -- 
> 2.7.4
> 
> 


[PATCH] mtd: nand: atmel: fix buffer overflow in atmel_pmecc_user

2017-09-27 Thread Richard Genoud
When calculating the size needed by struct atmel_pmecc_user *user,
the dmu and delta buffer sizes were forgotten.
This lead to a memory corruption (especially with a large ecc_strength).

Link: http://lkml.kernel.org/r/1506503157.3016.5.ca...@gmail.com
Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
Cc: Nicolas Ferre <nicolas.fe...@microchip.com>
Cc: sta...@vger.kernel.org
Reported-by: Richard Genoud <richard.gen...@gmail.com>
Pointed-at-by: Boris Brezillon <boris.brezil...@free-electrons.com>
Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
---
 drivers/mtd/nand/atmel/pmecc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
index 146af8218314..8268636675ef 100644
--- a/drivers/mtd/nand/atmel/pmecc.c
+++ b/drivers/mtd/nand/atmel/pmecc.c
@@ -363,7 +363,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
size += (req->ecc.strength + 1) * sizeof(u16);
/* Reserve space for mu, dmu and delta. */
size = ALIGN(size, sizeof(s32));
-   size += (req->ecc.strength + 1) * sizeof(s32);
+   size += (req->ecc.strength + 1) * sizeof(s32) * 3;
 
user = kzalloc(size, GFP_KERNEL);
if (!user)


[PATCH] mtd: nand: atmel: fix buffer overflow in atmel_pmecc_user

2017-09-27 Thread Richard Genoud
When calculating the size needed by struct atmel_pmecc_user *user,
the dmu and delta buffer sizes were forgotten.
This lead to a memory corruption (especially with a large ecc_strength).

Link: http://lkml.kernel.org/r/1506503157.3016.5.ca...@gmail.com
Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
Cc: Nicolas Ferre 
Cc: sta...@vger.kernel.org
Reported-by: Richard Genoud 
Pointed-at-by: Boris Brezillon 
Signed-off-by: Richard Genoud 
---
 drivers/mtd/nand/atmel/pmecc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
index 146af8218314..8268636675ef 100644
--- a/drivers/mtd/nand/atmel/pmecc.c
+++ b/drivers/mtd/nand/atmel/pmecc.c
@@ -363,7 +363,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
size += (req->ecc.strength + 1) * sizeof(u16);
/* Reserve space for mu, dmu and delta. */
size = ALIGN(size, sizeof(s32));
-   size += (req->ecc.strength + 1) * sizeof(s32);
+   size += (req->ecc.strength + 1) * sizeof(s32) * 3;
 
user = kzalloc(size, GFP_KERNEL);
if (!user)


Re: atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
2017-09-27 12:15 GMT+02:00 Richard Genoud <richard.gen...@gmail.com>:
> 2017-09-27 12:04 GMT+02:00 Boris Brezillon 
> <boris.brezil...@free-electrons.com>:
>> On Wed, 27 Sep 2017 11:05:57 +0200
>> Richard Genoud <richard.gen...@gmail.com> wrote:
>>
>>> Hi Boris, Nicolas !
>>>
>>> Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand 
>>> driver")
>>> strange things happen when nand-ecc-strength = <4>; (previously 
>>> atmel,pmecc-cap).
>>>
>>> I first saw that a NULL pointer dereference happened when "udevadm trigger" 
>>> was launched.
>>> With strace, I nailed it down to :
>>>
>>> sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent
>>> [   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
>>> address 0001
>>> [   86.704285] pgd = c717c000
>>> [   86.707072] [0001] *pgd=c06d9a70, *pte=, 
>>> *ppte=
>>> [   86.713979] Internal error: Oops: 17 [#3] ARM
>>> [   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
>>> 4.11.0-rc1-00056-gf88fc122cc34-dirty #75
>>> [   86.727443] Hardware name: Atmel AT91SAM9
>>> [   86.731424] task: c7880b60 task.stack: c7884000
>>> [   86.735926] PC is at strlen+0x14/0x2c
>>> [   86.739556] LR is at kobject_get_path+0x34/0xac
>>> [   86.744046] pc : []lr : []psr: 2013
>>> [   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
>>> [   86.755439] r10: 0002  r9 :   r8 : c7885f78
>>> [   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
>>> [   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
>>> [   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>>> none
>>> [   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
>>> [   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
>>> [   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
>>> [   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
>>> c7ab2308 c78c2b00
>>> [   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
>>> c00a53b4 0074
>>> [   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
>>> 081f 0007
>>> [   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
>>> c7885e54 c7885e48
>>> [   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
>>> c7885e9c 0002
>>> [   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
>>> c7885e9c c7885e88
>>> [   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
>>> c01281e4 c0128f8c
>>> [   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
>>> c7885f78 0007
>>> [   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
>>> 081f 00107d00
>>> [   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
>>> c7885f04 c00091e4
>>> [   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
>>> bec504d0 b6e8bbec
>>> [   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
>>> c7885f74 c7885f48
>>> [   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
>>> c7215c20 c7215c20
>>> [   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
>>>  
>>> [   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
>>>  c7885fa8
>>> [   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
>>> 0007 
>>> [   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
>>>  000e9124
>>> [   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
>>>  
>>> [   86.942277] [] (strlen) from [] 
>>> (kobject_get_path+0x34/0xac)
>>> [   86.949620] [] (kobject_get_path) from [] 
>>> (kobject_uevent_env+0xcc/0x4b4)
>>> [   86.958083] [] (kobject_uevent_env) from [] 
>>> (kobject_uevent+0x14/0x18)
>>> [   86.966287] [] (kobject_uevent) from [] 
>>> (uevent_store+0x44/0x64)
>>> [   86.973987] [] (uevent_store) from [] 
>>> (dev_attr_store+0x28/0x34)
>>> [   86.981672] [] (dev_attr_store) from [] 
>>> (sysfs_kf_write+0x4c/0x58)

Re: atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
2017-09-27 12:15 GMT+02:00 Richard Genoud :
> 2017-09-27 12:04 GMT+02:00 Boris Brezillon 
> :
>> On Wed, 27 Sep 2017 11:05:57 +0200
>> Richard Genoud  wrote:
>>
>>> Hi Boris, Nicolas !
>>>
>>> Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand 
>>> driver")
>>> strange things happen when nand-ecc-strength = <4>; (previously 
>>> atmel,pmecc-cap).
>>>
>>> I first saw that a NULL pointer dereference happened when "udevadm trigger" 
>>> was launched.
>>> With strace, I nailed it down to :
>>>
>>> sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent
>>> [   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
>>> address 0001
>>> [   86.704285] pgd = c717c000
>>> [   86.707072] [0001] *pgd=c06d9a70, *pte=, 
>>> *ppte=
>>> [   86.713979] Internal error: Oops: 17 [#3] ARM
>>> [   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
>>> 4.11.0-rc1-00056-gf88fc122cc34-dirty #75
>>> [   86.727443] Hardware name: Atmel AT91SAM9
>>> [   86.731424] task: c7880b60 task.stack: c7884000
>>> [   86.735926] PC is at strlen+0x14/0x2c
>>> [   86.739556] LR is at kobject_get_path+0x34/0xac
>>> [   86.744046] pc : []lr : []psr: 2013
>>> [   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
>>> [   86.755439] r10: 0002  r9 :   r8 : c7885f78
>>> [   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
>>> [   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
>>> [   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>>> none
>>> [   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
>>> [   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
>>> [   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
>>> [   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
>>> c7ab2308 c78c2b00
>>> [   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
>>> c00a53b4 0074
>>> [   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
>>> 081f 0007
>>> [   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
>>> c7885e54 c7885e48
>>> [   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
>>> c7885e9c 0002
>>> [   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
>>> c7885e9c c7885e88
>>> [   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
>>> c01281e4 c0128f8c
>>> [   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
>>> c7885f78 0007
>>> [   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
>>> 081f 00107d00
>>> [   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
>>> c7885f04 c00091e4
>>> [   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
>>> bec504d0 b6e8bbec
>>> [   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
>>> c7885f74 c7885f48
>>> [   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
>>> c7215c20 c7215c20
>>> [   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
>>>  
>>> [   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
>>>  c7885fa8
>>> [   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
>>> 0007 
>>> [   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
>>>  000e9124
>>> [   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
>>>  
>>> [   86.942277] [] (strlen) from [] 
>>> (kobject_get_path+0x34/0xac)
>>> [   86.949620] [] (kobject_get_path) from [] 
>>> (kobject_uevent_env+0xcc/0x4b4)
>>> [   86.958083] [] (kobject_uevent_env) from [] 
>>> (kobject_uevent+0x14/0x18)
>>> [   86.966287] [] (kobject_uevent) from [] 
>>> (uevent_store+0x44/0x64)
>>> [   86.973987] [] (uevent_store) from [] 
>>> (dev_attr_store+0x28/0x34)
>>> [   86.981672] [] (dev_attr_store) from [] 
>>> (sysfs_kf_write+0x4c/0x58)
>>> [   86.989525] [] (sysfs_kf_write) from [] 
>>> (kernfs_fop_write+0x12c/0x1c4)
>

Re: atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
2017-09-27 12:04 GMT+02:00 Boris Brezillon <boris.brezil...@free-electrons.com>:
> On Wed, 27 Sep 2017 11:05:57 +0200
> Richard Genoud <richard.gen...@gmail.com> wrote:
>
>> Hi Boris, Nicolas !
>>
>> Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
>> strange things happen when nand-ecc-strength = <4>; (previously 
>> atmel,pmecc-cap).
>>
>> I first saw that a NULL pointer dereference happened when "udevadm trigger" 
>> was launched.
>> With strace, I nailed it down to :
>>
>> sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent
>> [   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
>> address 0001
>> [   86.704285] pgd = c717c000
>> [   86.707072] [0001] *pgd=c06d9a70, *pte=, 
>> *ppte=
>> [   86.713979] Internal error: Oops: 17 [#3] ARM
>> [   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
>> 4.11.0-rc1-00056-gf88fc122cc34-dirty #75
>> [   86.727443] Hardware name: Atmel AT91SAM9
>> [   86.731424] task: c7880b60 task.stack: c7884000
>> [   86.735926] PC is at strlen+0x14/0x2c
>> [   86.739556] LR is at kobject_get_path+0x34/0xac
>> [   86.744046] pc : []lr : []psr: 2013
>> [   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
>> [   86.755439] r10: 0002  r9 :   r8 : c7885f78
>> [   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
>> [   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
>> [   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>> none
>> [   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
>> [   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
>> [   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
>> [   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
>> c7ab2308 c78c2b00
>> [   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
>> c00a53b4 0074
>> [   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
>> 081f 0007
>> [   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
>> c7885e54 c7885e48
>> [   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
>> c7885e9c 0002
>> [   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
>> c7885e9c c7885e88
>> [   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
>> c01281e4 c0128f8c
>> [   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
>> c7885f78 0007
>> [   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
>> 081f 00107d00
>> [   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
>> c7885f04 c00091e4
>> [   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
>> bec504d0 b6e8bbec
>> [   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
>> c7885f74 c7885f48
>> [   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
>> c7215c20 c7215c20
>> [   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
>>  
>> [   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
>>  c7885fa8
>> [   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
>> 0007 
>> [   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
>>  000e9124
>> [   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
>>  
>> [   86.942277] [] (strlen) from [] 
>> (kobject_get_path+0x34/0xac)
>> [   86.949620] [] (kobject_get_path) from [] 
>> (kobject_uevent_env+0xcc/0x4b4)
>> [   86.958083] [] (kobject_uevent_env) from [] 
>> (kobject_uevent+0x14/0x18)
>> [   86.966287] [] (kobject_uevent) from [] 
>> (uevent_store+0x44/0x64)
>> [   86.973987] [] (uevent_store) from [] 
>> (dev_attr_store+0x28/0x34)
>> [   86.981672] [] (dev_attr_store) from [] 
>> (sysfs_kf_write+0x4c/0x58)
>> [   86.989525] [] (sysfs_kf_write) from [] 
>> (kernfs_fop_write+0x12c/0x1c4)
>> [   86.997737] [] (kernfs_fop_write) from [] 
>> (__vfs_write+0x3c/0x11c)
>> [   87.005596] [] (__vfs_write) from [] 
>> (vfs_write+0xc0/0x164)
>> [   87.012855] [] (vfs_write) from [] 
>> (SyS_write+0x4c/0x8c)
>> [   87.019854] [] (SyS_write) from [] 
>> (ret_fast_syscall+0x0/0x38)
>> [   

Re: atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
2017-09-27 12:04 GMT+02:00 Boris Brezillon :
> On Wed, 27 Sep 2017 11:05:57 +0200
> Richard Genoud  wrote:
>
>> Hi Boris, Nicolas !
>>
>> Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
>> strange things happen when nand-ecc-strength = <4>; (previously 
>> atmel,pmecc-cap).
>>
>> I first saw that a NULL pointer dereference happened when "udevadm trigger" 
>> was launched.
>> With strace, I nailed it down to :
>>
>> sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent
>> [   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
>> address 0001
>> [   86.704285] pgd = c717c000
>> [   86.707072] [0001] *pgd=c06d9a70, *pte=, 
>> *ppte=
>> [   86.713979] Internal error: Oops: 17 [#3] ARM
>> [   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
>> 4.11.0-rc1-00056-gf88fc122cc34-dirty #75
>> [   86.727443] Hardware name: Atmel AT91SAM9
>> [   86.731424] task: c7880b60 task.stack: c7884000
>> [   86.735926] PC is at strlen+0x14/0x2c
>> [   86.739556] LR is at kobject_get_path+0x34/0xac
>> [   86.744046] pc : []lr : []psr: 2013
>> [   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
>> [   86.755439] r10: 0002  r9 :   r8 : c7885f78
>> [   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
>> [   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
>> [   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>> none
>> [   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
>> [   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
>> [   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
>> [   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
>> c7ab2308 c78c2b00
>> [   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
>> c00a53b4 0074
>> [   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
>> 081f 0007
>> [   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
>> c7885e54 c7885e48
>> [   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
>> c7885e9c 0002
>> [   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
>> c7885e9c c7885e88
>> [   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
>> c01281e4 c0128f8c
>> [   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
>> c7885f78 0007
>> [   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
>> 081f 00107d00
>> [   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
>> c7885f04 c00091e4
>> [   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
>> bec504d0 b6e8bbec
>> [   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
>> c7885f74 c7885f48
>> [   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
>> c7215c20 c7215c20
>> [   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
>>  
>> [   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
>>  c7885fa8
>> [   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
>> 0007 
>> [   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
>>  000e9124
>> [   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
>>  
>> [   86.942277] [] (strlen) from [] 
>> (kobject_get_path+0x34/0xac)
>> [   86.949620] [] (kobject_get_path) from [] 
>> (kobject_uevent_env+0xcc/0x4b4)
>> [   86.958083] [] (kobject_uevent_env) from [] 
>> (kobject_uevent+0x14/0x18)
>> [   86.966287] [] (kobject_uevent) from [] 
>> (uevent_store+0x44/0x64)
>> [   86.973987] [] (uevent_store) from [] 
>> (dev_attr_store+0x28/0x34)
>> [   86.981672] [] (dev_attr_store) from [] 
>> (sysfs_kf_write+0x4c/0x58)
>> [   86.989525] [] (sysfs_kf_write) from [] 
>> (kernfs_fop_write+0x12c/0x1c4)
>> [   86.997737] [] (kernfs_fop_write) from [] 
>> (__vfs_write+0x3c/0x11c)
>> [   87.005596] [] (__vfs_write) from [] 
>> (vfs_write+0xc0/0x164)
>> [   87.012855] [] (vfs_write) from [] 
>> (SyS_write+0x4c/0x8c)
>> [   87.019854] [] (SyS_write) from [] 
>> (ret_fast_syscall+0x0/0x38)
>> [   87.027364] Code: e92dd800 e24cb004 e1a03000 e1a02003 (e5d21000)
>> 

atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
Hi Boris, Nicolas !

Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
strange things happen when nand-ecc-strength = <4>; (previously 
atmel,pmecc-cap).

I first saw that a NULL pointer dereference happened when "udevadm trigger" was 
launched.
With strace, I nailed it down to :

sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent 
[   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
address 0001
[   86.704285] pgd = c717c000
[   86.707072] [0001] *pgd=c06d9a70, *pte=, *ppte=
[   86.713979] Internal error: Oops: 17 [#3] ARM
[   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
4.11.0-rc1-00056-gf88fc122cc34-dirty #75
[   86.727443] Hardware name: Atmel AT91SAM9
[   86.731424] task: c7880b60 task.stack: c7884000
[   86.735926] PC is at strlen+0x14/0x2c
[   86.739556] LR is at kobject_get_path+0x34/0xac
[   86.744046] pc : []lr : []psr: 2013
[   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
[   86.755439] r10: 0002  r9 :   r8 : c7885f78
[   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
[   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
[   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
[   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
[   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
[   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
c7ab2308 c78c2b00
[   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
c00a53b4 0074
[   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
081f 0007
[   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
c7885e54 c7885e48
[   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
c7885e9c 0002
[   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
c7885e9c c7885e88
[   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
c01281e4 c0128f8c
[   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
c7885f78 0007
[   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
081f 00107d00
[   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
c7885f04 c00091e4
[   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
bec504d0 b6e8bbec
[   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
c7885f74 c7885f48
[   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
c7215c20 c7215c20
[   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
 
[   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
 c7885fa8
[   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
0007 
[   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
 000e9124
[   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
 
[   86.942277] [] (strlen) from [] 
(kobject_get_path+0x34/0xac)
[   86.949620] [] (kobject_get_path) from [] 
(kobject_uevent_env+0xcc/0x4b4)
[   86.958083] [] (kobject_uevent_env) from [] 
(kobject_uevent+0x14/0x18)
[   86.966287] [] (kobject_uevent) from [] 
(uevent_store+0x44/0x64)
[   86.973987] [] (uevent_store) from [] 
(dev_attr_store+0x28/0x34)
[   86.981672] [] (dev_attr_store) from [] 
(sysfs_kf_write+0x4c/0x58)
[   86.989525] [] (sysfs_kf_write) from [] 
(kernfs_fop_write+0x12c/0x1c4)
[   86.997737] [] (kernfs_fop_write) from [] 
(__vfs_write+0x3c/0x11c)
[   87.005596] [] (__vfs_write) from [] 
(vfs_write+0xc0/0x164)
[   87.012855] [] (vfs_write) from [] (SyS_write+0x4c/0x8c)
[   87.019854] [] (SyS_write) from [] 
(ret_fast_syscall+0x0/0x38)
[   87.027364] Code: e92dd800 e24cb004 e1a03000 e1a02003 (e5d21000) 
[   87.033544] ---[ end trace 29af93c3c072b1f4 ]---
[   87.039277] Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x000b

This is fun because it really doesn't seem to have anything to do with 
atmel-nand...

I first found that on my custom board, built around an at91sam9g35-cm, but I 
managed to trigger it
on an at91sam9g35-ek board, with a 4.13.3 kernel.

NB: I couldn't trigger this with ecc-strength = 2

So, here is my configuration:
- at91sam9g35-ek board with the image 
ftp://www.at91.com/pub/demo/linux4sam_5.6/linux4sam-poky-at91sam9x5ek-5.6.zip
I flashed this image a first time as is, and then I flashed only the rfs with 
eccType 0xc0902405.

- Kernel 4.13.3 with the quick'n dirty patch:
--- a/arch/arm/boot/dts/at91sam9x5cm.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -56,7 +56,7 @@
cs-gpios = < 4 GPIO_ACTIVE_HIGH>;
nand-bus-width = <8>;

atmel_nand: kernel panic when ecc_strength==4

2017-09-27 Thread Richard Genoud
Hi Boris, Nicolas !

Since commit f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
strange things happen when nand-ecc-strength = <4>; (previously 
atmel,pmecc-cap).

I first saw that a NULL pointer dereference happened when "udevadm trigger" was 
launched.
With strace, I nailed it down to :

sh-4.3# echo change > /sys/devices/virtual/bdi/mtd-1/uevent 
[   86.696275] Unable to handle kernel NULL pointer dereference at virtual 
address 0001
[   86.704285] pgd = c717c000
[   86.707072] [0001] *pgd=c06d9a70, *pte=, *ppte=
[   86.713979] Internal error: Oops: 17 [#3] ARM
[   86.718306] CPU: 0 PID: 1 Comm: sh Tainted: G  D W   
4.11.0-rc1-00056-gf88fc122cc34-dirty #75
[   86.727443] Hardware name: Atmel AT91SAM9
[   86.731424] task: c7880b60 task.stack: c7884000
[   86.735926] PC is at strlen+0x14/0x2c
[   86.739556] LR is at kobject_get_path+0x34/0xac
[   86.744046] pc : []lr : []psr: 2013
[   86.744046] sp : c7885dc0  ip : c7885dd0  fp : c7885dcc
[   86.755439] r10: 0002  r9 :   r8 : c7885f78
[   86.760627] r7 : 014000c0  r6 : c7ab2308  r5 : 0001  r4 : c7ab2308
[   86.767106] r3 : 0001  r2 : 0001  r1 : 014000c0  r0 : 0001
[   86.773588] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   86.780672] Control: 0005317f  Table: 2717c000  DAC: 0051
[   86.786372] Process sh (pid: 1, stack limit = 0xc7884190)
[   86.791730] Stack: (0xc7885dc0 to 0xc7886000)
[   86.796075] 5dc0: c7885df4 c7885dd0 c0235020 c023bc04 c0728bf8 c79f1000 
c7ab2308 c78c2b00
[   86.804195] 5de0: c04f4610 c7885f78 c7885e44 c7885df8 c0236244 c0234ffc 
c00a53b4 0074
[   86.812315] 5e00: 00107000 c7885ea8 c7885e64 c05d604b c717b420 c05b4aa8 
081f 0007
[   86.820438] 5e20: c7ab2300 c7199ea0 c79baae0 c7885f78 c7199eb0 0007 
c7885e54 c7885e48
[   86.828559] 5e40: c0236640 c0236188 c7885e74 c7885e58 c02a5834 c023663c 
c7885e9c 0002
[   86.836681] 5e60: c7bf1f50 c79baae0 c7885e84 c7885e78 c02a37b8 c02a5800 
c7885e9c c7885e88
[   86.844801] 5e80: c0128fc8 c02a37a0   c7885ed4 c7885ea0 
c01281e4 c0128f8c
[   86.852922] 5ea0:   c7880b60 c01280b8 00106cf8 c7215c20 
c7885f78 0007
[   86.861045] 5ec0: c7884000 00106cf8 c7885f44 c7885ed8 c00caec0 c01280c8 
081f 00107d00
[   86.869167] 5ee0: c06d0f7c c7885fb0 00053177 1180 0178 c7885fac 
c7885f04 c00091e4
[   86.877288] 5f00: c001128c c000e088 0158 c00cb114 12bc  
bec504d0 b6e8bbec
[   86.885409] 5f20: c7215c20 c7215c20  0007 00106cf8 c7885f78 
c7885f74 c7885f48
[   86.893531] 5f40: c00cb160 c00cae94 c00e6e04 c00e6568   
c7215c20 c7215c20
[   86.901652] 5f60: 0007 00106cf8 c7885fa4 c7885f78 c00cb2dc c00cb0b0 
 
[   86.909773] 5f80: 0007 00106cf8 b6e8dd50 0004 c000a544  
 c7885fa8
[   86.917895] 5fa0: c000a3a0 c00cb2a0 0007 00106cf8 0001 00106cf8 
0007 
[   86.926015] 5fc0: 0007 00106cf8 b6e8dd50 0004 0007 0004 
 000e9124
[   86.934139] 5fe0:  bec50a3c b6db63d0 b6e107ac 6010 0001 
 
[   86.942277] [] (strlen) from [] 
(kobject_get_path+0x34/0xac)
[   86.949620] [] (kobject_get_path) from [] 
(kobject_uevent_env+0xcc/0x4b4)
[   86.958083] [] (kobject_uevent_env) from [] 
(kobject_uevent+0x14/0x18)
[   86.966287] [] (kobject_uevent) from [] 
(uevent_store+0x44/0x64)
[   86.973987] [] (uevent_store) from [] 
(dev_attr_store+0x28/0x34)
[   86.981672] [] (dev_attr_store) from [] 
(sysfs_kf_write+0x4c/0x58)
[   86.989525] [] (sysfs_kf_write) from [] 
(kernfs_fop_write+0x12c/0x1c4)
[   86.997737] [] (kernfs_fop_write) from [] 
(__vfs_write+0x3c/0x11c)
[   87.005596] [] (__vfs_write) from [] 
(vfs_write+0xc0/0x164)
[   87.012855] [] (vfs_write) from [] (SyS_write+0x4c/0x8c)
[   87.019854] [] (SyS_write) from [] 
(ret_fast_syscall+0x0/0x38)
[   87.027364] Code: e92dd800 e24cb004 e1a03000 e1a02003 (e5d21000) 
[   87.033544] ---[ end trace 29af93c3c072b1f4 ]---
[   87.039277] Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x000b

This is fun because it really doesn't seem to have anything to do with 
atmel-nand...

I first found that on my custom board, built around an at91sam9g35-cm, but I 
managed to trigger it
on an at91sam9g35-ek board, with a 4.13.3 kernel.

NB: I couldn't trigger this with ecc-strength = 2

So, here is my configuration:
- at91sam9g35-ek board with the image 
ftp://www.at91.com/pub/demo/linux4sam_5.6/linux4sam-poky-at91sam9x5ek-5.6.zip
I flashed this image a first time as is, and then I flashed only the rfs with 
eccType 0xc0902405.

- Kernel 4.13.3 with the quick'n dirty patch:
--- a/arch/arm/boot/dts/at91sam9x5cm.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -56,7 +56,7 @@
cs-gpios = < 4 GPIO_ACTIVE_HIGH>;
nand-bus-width = <8>;

Re: [PATCH v2 9/9] tty/serial: atmel: Prevent a warning on suspend

2017-09-20 Thread Richard Genoud
On 15/09/2017 16:04, Romain Izard wrote:
> The atmel serial port driver reported the following warning on suspend:
> atmel_usart f802.serial: ttyS1: Unable to drain transmitter
> 
> As the ATMEL_US_TXEMPTY status bit in ATMEL_US_CSR is always cleared
> when the transmitter is disabled, we need to know the transmitter's
> state to return the real fifo state. And as ATMEL_US_CR is write-only,
> it is necessary to save the state of the transmitter in a local
> variable, and update the variable when TXEN and TXDIS is written in
> ATMEL_US_CR.
> 
> After those changes, atmel_tx_empty can return "empty" on suspend, the
> warning in uart_suspend_port disappears, and suspending is 20ms shorter
> for each enabled Atmel serial port.
> 
> Signed-off-by: Romain Izard <romain.izard@gmail.com>
> ---
>  drivers/tty/serial/atmel_serial.c | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 7551cab438ff..783af6648be0 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -171,6 +171,7 @@ struct atmel_uart_port {
>   boolhas_hw_timer;
>   struct timer_list   uart_timer;
>  
> + booltx_stopped;
>   boolsuspended;
>   unsigned intpending;
>   unsigned intpending_status;
> @@ -380,6 +381,10 @@ static int atmel_config_rs485(struct uart_port *port,
>   */
>  static u_int atmel_tx_empty(struct uart_port *port)
>  {
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> +
> + if (atmel_port->tx_stopped)
> + return TIOCSER_TEMT;
>   return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ?
>   TIOCSER_TEMT :
>   0;
> @@ -485,6 +490,7 @@ static void atmel_stop_tx(struct uart_port *port)
>* is fully transmitted.
>*/
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
> + atmel_port->tx_stopped = true;
>  
>   /* Disable interrupts */
>   atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> @@ -492,6 +498,7 @@ static void atmel_stop_tx(struct uart_port *port)
>   if ((port->rs485.flags & SER_RS485_ENABLED) &&
>   !(port->rs485.flags & SER_RS485_RX_DURING_TX))
>   atmel_start_rx(port);
> +
>  }
This line feed is not needed.
Otherwise,

Acked-by: Richard Genoud <richard.gen...@gmail.com>

>  
>  /*
> @@ -521,6 +528,7 @@ static void atmel_start_tx(struct uart_port *port)
>  
>   /* re-enable the transmitter */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
> + atmel_port->tx_stopped = false;
>  }
>  
>  /*
> @@ -1866,6 +1874,7 @@ static int atmel_startup(struct uart_port *port)
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
>   /* enable xmit & rcvr */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
> + atmel_port->tx_stopped = false;
>  
>   setup_timer(_port->uart_timer,
>   atmel_uart_timer_callback,
> @@ -2122,6 +2131,7 @@ static void atmel_set_termios(struct uart_port *port, 
> struct ktermios *termios,
>  
>   /* disable receiver and transmitter */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
> + atmel_port->tx_stopped = true;
>  
>   /* mode */
>   if (port->rs485.flags & SER_RS485_ENABLED) {
> @@ -2207,6 +2217,7 @@ static void atmel_set_termios(struct uart_port *port, 
> struct ktermios *termios,
>   atmel_uart_writel(port, ATMEL_US_BRGR, quot);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
> + atmel_port->tx_stopped = false;
>  
>   /* restore interrupts */
>   atmel_uart_writel(port, ATMEL_US_IER, imr);
> @@ -2450,6 +2461,7 @@ static void atmel_console_write(struct console *co, 
> const char *s, u_int count)
>  
>   /* Make sure that tx path is actually able to send characters */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
> + atmel_port->tx_stopped = false;
>  
>   uart_console_write(port, s, count, atmel_console_putchar);
>  
> @@ -2511,6 +2523,7 @@ static int __init atmel_console_setup(struct console 
> *co, char *options)
>  {
>   int ret;
>   struct uart_port *port = _ports[co->index].uart;
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
>

Re: [PATCH v2 9/9] tty/serial: atmel: Prevent a warning on suspend

2017-09-20 Thread Richard Genoud
On 15/09/2017 16:04, Romain Izard wrote:
> The atmel serial port driver reported the following warning on suspend:
> atmel_usart f802.serial: ttyS1: Unable to drain transmitter
> 
> As the ATMEL_US_TXEMPTY status bit in ATMEL_US_CSR is always cleared
> when the transmitter is disabled, we need to know the transmitter's
> state to return the real fifo state. And as ATMEL_US_CR is write-only,
> it is necessary to save the state of the transmitter in a local
> variable, and update the variable when TXEN and TXDIS is written in
> ATMEL_US_CR.
> 
> After those changes, atmel_tx_empty can return "empty" on suspend, the
> warning in uart_suspend_port disappears, and suspending is 20ms shorter
> for each enabled Atmel serial port.
> 
> Signed-off-by: Romain Izard 
> ---
>  drivers/tty/serial/atmel_serial.c | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 7551cab438ff..783af6648be0 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -171,6 +171,7 @@ struct atmel_uart_port {
>   boolhas_hw_timer;
>   struct timer_list   uart_timer;
>  
> + booltx_stopped;
>   boolsuspended;
>   unsigned intpending;
>   unsigned intpending_status;
> @@ -380,6 +381,10 @@ static int atmel_config_rs485(struct uart_port *port,
>   */
>  static u_int atmel_tx_empty(struct uart_port *port)
>  {
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> +
> + if (atmel_port->tx_stopped)
> + return TIOCSER_TEMT;
>   return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ?
>   TIOCSER_TEMT :
>   0;
> @@ -485,6 +490,7 @@ static void atmel_stop_tx(struct uart_port *port)
>* is fully transmitted.
>*/
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
> + atmel_port->tx_stopped = true;
>  
>   /* Disable interrupts */
>   atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
> @@ -492,6 +498,7 @@ static void atmel_stop_tx(struct uart_port *port)
>   if ((port->rs485.flags & SER_RS485_ENABLED) &&
>   !(port->rs485.flags & SER_RS485_RX_DURING_TX))
>   atmel_start_rx(port);
> +
>  }
This line feed is not needed.
Otherwise,

Acked-by: Richard Genoud 

>  
>  /*
> @@ -521,6 +528,7 @@ static void atmel_start_tx(struct uart_port *port)
>  
>   /* re-enable the transmitter */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
> + atmel_port->tx_stopped = false;
>  }
>  
>  /*
> @@ -1866,6 +1874,7 @@ static int atmel_startup(struct uart_port *port)
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
>   /* enable xmit & rcvr */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
> + atmel_port->tx_stopped = false;
>  
>   setup_timer(_port->uart_timer,
>   atmel_uart_timer_callback,
> @@ -2122,6 +2131,7 @@ static void atmel_set_termios(struct uart_port *port, 
> struct ktermios *termios,
>  
>   /* disable receiver and transmitter */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
> + atmel_port->tx_stopped = true;
>  
>   /* mode */
>   if (port->rs485.flags & SER_RS485_ENABLED) {
> @@ -2207,6 +2217,7 @@ static void atmel_set_termios(struct uart_port *port, 
> struct ktermios *termios,
>   atmel_uart_writel(port, ATMEL_US_BRGR, quot);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
> + atmel_port->tx_stopped = false;
>  
>   /* restore interrupts */
>   atmel_uart_writel(port, ATMEL_US_IER, imr);
> @@ -2450,6 +2461,7 @@ static void atmel_console_write(struct console *co, 
> const char *s, u_int count)
>  
>   /* Make sure that tx path is actually able to send characters */
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
> + atmel_port->tx_stopped = false;
>  
>   uart_console_write(port, s, count, atmel_console_putchar);
>  
> @@ -2511,6 +2523,7 @@ static int __init atmel_console_setup(struct console 
> *co, char *options)
>  {
>   int ret;
>   struct uart_port *port = _ports[co->index].uart;
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
>   int baud = 115200;
>   int bits = 8;
>   int parity = 'n';
> @@ -2528,6 +2541,7 @@ static int __init atmel_console_setup(struct console 
> *co, char *options)
>   atmel_uart_writel(port, ATMEL_US_IDR, -1);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
>   atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
> + atmel_port->tx_stopped = false;
>  
>   if (options)
>   uart_parse_options(options, , , , );
> 



Re: [PATCH v2] ARM: zImage: Fix stack overflow in merge_fdt_bootargs()

2017-07-26 Thread Richard Genoud
2017-07-22 15:02 GMT+02:00 Rask Ingemann Lambertsen <r...@formelder.dk>:
> This function is called very early on from head.S and currently sets up a
> stack frame of more than 1024 bytes:
>
> atags_to_fdt.c: In function ‘merge_fdt_bootargs’:
> atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 
> 1024 bytes [-Wframe-larger-than=]
>
> This causes a crash and failure to boot with some combinations of kernel
> version, gcc version and dtb, such as kernel version 4.1-rc1 or 4.1.0,
> gcc version 5.4.1 20161019 (Debian 5.4.1-3) and tegra20-trimslice.dtb.
>
> With this patch, merge_fdt_bootargs() is rewritten to not use a large buffer,
> thereby solving the problem of the stack overflow.
>
> As a side effect of this rewrite, you no longer get a space added in front
> of the kernel command line when no bootargs property was found in the FDT.
>
> Signed-off-by: Rask Ingemann Lambertsen <r...@formelder.dk>
> Tested-by: Pavel Machek <pa...@ucw.cz>
> Tested-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
> Fixes: d0f34a11ddab ("ARM: 7437/1: zImage: Allow DTB command line 
> concatenation with ATAG_CMDLINE")
seems good to me !
Reviewed-by: Richard Genoud <richard.gen...@gmail.com>

> ---
>
> I have tested that this works properly when
> a) only the FDT bootargs are provided,
> b) only the ATAG command line is provided, and
> c) both the FDT bootargs and the ATAG command line are provided.
>
> Changes from v1 to v2:
> The original "bootargs" NUL terminator is changed into a space only when
> appenprop_string() succeeds. Commented by Richard Genoud.
>
>  arch/arm/boot/compressed/atags_to_fdt.c | 59 
> +
>  1 file changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/arch/arm/boot/compressed/atags_to_fdt.c 
> b/arch/arm/boot/compressed/atags_to_fdt.c
> index 9448aa0c6686..87a5fba5a28e 100644
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -55,6 +55,29 @@ static const void *getprop(const void *fdt, const char 
> *node_path,
> return fdt_getprop(fdt, offset, property, len);
>  }
>
> +static int appendprop_string(void *fdt, const char *node_path,
> +const char *property, const char *string)
> +{
> +   int offset = node_offset(fdt, node_path);
> +
> +   if (offset < 0)
> +   return offset;
> +   return fdt_appendprop_string(fdt, offset, property, string);
> +}
> +
> +static int setprop_inplace_partial(void *fdt, const char *node_path,
> +  const char *property, unsigned int idx,
> +  const void *val, int len)
> +{
> +   int offset = node_offset(fdt, node_path);
> +
> +   if (offset < 0)
> +   return offset;
> +   return fdt_setprop_inplace_namelen_partial(fdt, offset, property,
> +  strlen(property), idx,
> +  val, len);
> +}
> +
>  static uint32_t get_cell_size(const void *fdt)
>  {
> int len;
> @@ -66,35 +89,27 @@ static uint32_t get_cell_size(const void *fdt)
> return cell_size;
>  }
>
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> -{
> -   char cmdline[COMMAND_LINE_SIZE];
> -   const char *fdt_bootargs;
> -   char *ptr = cmdline;
> -   int len = 0;
> -
> -   /* copy the fdt command line into the buffer */
> -   fdt_bootargs = getprop(fdt, "/chosen", "bootargs", );
> -   if (fdt_bootargs)
> -   if (len < COMMAND_LINE_SIZE) {
> -   memcpy(ptr, fdt_bootargs, len);
> -   /* len is the length of the string
> -* including the NULL terminator */
> -   ptr += len - 1;
> -   }
> -
> -   /* and append the ATAG_CMDLINE */
> -   if (fdt_cmdline) {
> -   len = strlen(fdt_cmdline);
> -   if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
> -   *ptr++ = ' ';
> -   memcpy(ptr, fdt_cmdline, len);
> -   ptr += len;
> -   }
> -   }
> -   *ptr = '\0';
> -
> -   setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +/* This is called early on from head.S, so it can't use much stack. */
> +static void merge_fdt_bootargs(void *fdt, const char *atag_cmdline)
> +{
> +   const char *fdt_bootargs;
> +   int len = 0;
> +
> +   /* With no ATAG

Re: [PATCH v2] ARM: zImage: Fix stack overflow in merge_fdt_bootargs()

2017-07-26 Thread Richard Genoud
2017-07-22 15:02 GMT+02:00 Rask Ingemann Lambertsen :
> This function is called very early on from head.S and currently sets up a
> stack frame of more than 1024 bytes:
>
> atags_to_fdt.c: In function ‘merge_fdt_bootargs’:
> atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 
> 1024 bytes [-Wframe-larger-than=]
>
> This causes a crash and failure to boot with some combinations of kernel
> version, gcc version and dtb, such as kernel version 4.1-rc1 or 4.1.0,
> gcc version 5.4.1 20161019 (Debian 5.4.1-3) and tegra20-trimslice.dtb.
>
> With this patch, merge_fdt_bootargs() is rewritten to not use a large buffer,
> thereby solving the problem of the stack overflow.
>
> As a side effect of this rewrite, you no longer get a space added in front
> of the kernel command line when no bootargs property was found in the FDT.
>
> Signed-off-by: Rask Ingemann Lambertsen 
> Tested-by: Pavel Machek 
> Tested-by: Sebastian Reichel 
> Fixes: d0f34a11ddab ("ARM: 7437/1: zImage: Allow DTB command line 
> concatenation with ATAG_CMDLINE")
seems good to me !
Reviewed-by: Richard Genoud 

> ---
>
> I have tested that this works properly when
> a) only the FDT bootargs are provided,
> b) only the ATAG command line is provided, and
> c) both the FDT bootargs and the ATAG command line are provided.
>
> Changes from v1 to v2:
> The original "bootargs" NUL terminator is changed into a space only when
> appenprop_string() succeeds. Commented by Richard Genoud.
>
>  arch/arm/boot/compressed/atags_to_fdt.c | 59 
> +
>  1 file changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/arch/arm/boot/compressed/atags_to_fdt.c 
> b/arch/arm/boot/compressed/atags_to_fdt.c
> index 9448aa0c6686..87a5fba5a28e 100644
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -55,6 +55,29 @@ static const void *getprop(const void *fdt, const char 
> *node_path,
> return fdt_getprop(fdt, offset, property, len);
>  }
>
> +static int appendprop_string(void *fdt, const char *node_path,
> +const char *property, const char *string)
> +{
> +   int offset = node_offset(fdt, node_path);
> +
> +   if (offset < 0)
> +   return offset;
> +   return fdt_appendprop_string(fdt, offset, property, string);
> +}
> +
> +static int setprop_inplace_partial(void *fdt, const char *node_path,
> +  const char *property, unsigned int idx,
> +  const void *val, int len)
> +{
> +   int offset = node_offset(fdt, node_path);
> +
> +   if (offset < 0)
> +   return offset;
> +   return fdt_setprop_inplace_namelen_partial(fdt, offset, property,
> +  strlen(property), idx,
> +  val, len);
> +}
> +
>  static uint32_t get_cell_size(const void *fdt)
>  {
> int len;
> @@ -66,35 +89,27 @@ static uint32_t get_cell_size(const void *fdt)
> return cell_size;
>  }
>
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> -{
> -   char cmdline[COMMAND_LINE_SIZE];
> -   const char *fdt_bootargs;
> -   char *ptr = cmdline;
> -   int len = 0;
> -
> -   /* copy the fdt command line into the buffer */
> -   fdt_bootargs = getprop(fdt, "/chosen", "bootargs", );
> -   if (fdt_bootargs)
> -   if (len < COMMAND_LINE_SIZE) {
> -   memcpy(ptr, fdt_bootargs, len);
> -   /* len is the length of the string
> -* including the NULL terminator */
> -   ptr += len - 1;
> -   }
> -
> -   /* and append the ATAG_CMDLINE */
> -   if (fdt_cmdline) {
> -   len = strlen(fdt_cmdline);
> -   if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
> -   *ptr++ = ' ';
> -   memcpy(ptr, fdt_cmdline, len);
> -   ptr += len;
> -   }
> -   }
> -   *ptr = '\0';
> -
> -   setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +/* This is called early on from head.S, so it can't use much stack. */
> +static void merge_fdt_bootargs(void *fdt, const char *atag_cmdline)
> +{
> +   const char *fdt_bootargs;
> +   int len = 0;
> +
> +   /* With no ATAG command line or an empty one, there is nothing to do. 
> */
> +   if (!atag_cmdline || strlen(atag_cmdline) == 0)
> +   r

Re: [PATCH] ARM: zImage: Fix stack overflow in merge_fdt_bootargs()

2017-07-18 Thread Richard Genoud
On 16/07/2017 23:43, Rask Ingemann Lambertsen wrote:
> This function is called very early on from head.S and currently sets up a
> stack frame of more than 1024 bytes:
> 
> atags_to_fdt.c: In function ‘merge_fdt_bootargs’:
> atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 
> 1024 bytes [-Wframe-larger-than=]
> 
> This causes a crash and failure to boot with some combinations of kernel
> version, gcc version and dtb, such as kernel version 4.1-rc1 of 4.1.0,
> gcc version 5.4.1 20161019 (Debian 5.4.1-3) and tegra20-trimslice.dtb.
> 
> With this patch, merge_fdt_bootargs() is rewritten to not use a large buffer,
> thereby solving the problem of the stack overflow.
> 
> As a side effect of this rewrite, you no longer get a space added in front
> of the kernel command line when no bootargs property was found in the fdt.
> 
> Signed-off-by: Rask Ingemann Lambertsen 
> Fixes: d0f34a11ddab ("ARM: 7437/1: zImage: Allow DTB command line 
> concatenation with ATAG_CMDLINE")
> ---
> 
> I have tested that this works properly when
> a) only the FDT bootargs are provided,
> b) only the ATAG command line is provided, and
> c) both the FDT bootargs and the ATAG command line are provided.
> 
>  arch/arm/boot/compressed/atags_to_fdt.c | 59 
> +++--
>  1 file changed, 35 insertions(+), 24 deletions(-)

Thanks for fixing that !

> 
> diff --git a/arch/arm/boot/compressed/atags_to_fdt.c 
> b/arch/arm/boot/compressed/atags_to_fdt.c
> index 9448aa0c6686..ede23ef2e889 100644
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -55,6 +55,27 @@ static const void *getprop(const void *fdt, const char 
> *node_path,
>   return fdt_getprop(fdt, offset, property, len);
>  }
>  
> +static void *getprop_w(void *fdt, const char *node_path,
> +const char *property, int *len)
> +{
> + int offset = fdt_path_offset(fdt, node_path);
> +
> + if (offset == -FDT_ERR_NOTFOUND)
> + return NULL;
> +
> + return fdt_getprop_w(fdt, offset, property, len);
> +}
> +
> +static int appendprop_string(void *fdt, const char *node_path,
> +  const char *property, const char *string)
> +{
> + int offset = node_offset(fdt, node_path);
> +
> + if (offset < 0)
> + return offset;
> + return fdt_appendprop_string(fdt, offset, property, string);
> +}
> +
>  static uint32_t get_cell_size(const void *fdt)
>  {
>   int len;
> @@ -66,35 +87,25 @@ static uint32_t get_cell_size(const void *fdt)
>   return cell_size;
>  }
>  
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> -{
> - char cmdline[COMMAND_LINE_SIZE];
> - const char *fdt_bootargs;
> - char *ptr = cmdline;
> - int len = 0;
> -
> - /* copy the fdt command line into the buffer */
> - fdt_bootargs = getprop(fdt, "/chosen", "bootargs", );
> - if (fdt_bootargs)
> - if (len < COMMAND_LINE_SIZE) {
> - memcpy(ptr, fdt_bootargs, len);
> - /* len is the length of the string
> -  * including the NULL terminator */
> - ptr += len - 1;
> - }
> -
> - /* and append the ATAG_CMDLINE */
> - if (fdt_cmdline) {
> - len = strlen(fdt_cmdline);
> - if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
> - *ptr++ = ' ';
> - memcpy(ptr, fdt_cmdline, len);
> - ptr += len;
> - }
> - }
> - *ptr = '\0';
> -
> - setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +/* This is called early on from head.S, so it can't use much stack. */
> +static void merge_fdt_bootargs(void *fdt, const char *atag_cmdline)
> +{
> + char *fdt_bootargs;
> + int len = 0;
> +
> + /* With no ATAG command line or an empty one, there is nothing to do. */
> + if (!atag_cmdline || strlen(atag_cmdline) == 0)
> + return;
> +
> + fdt_bootargs = getprop_w(fdt, "/chosen", "bootargs", );
> +
> + /* With no FDT command line or an empty one, just use the ATAG one. */
> + if (!fdt_bootargs || len <= 1) {
> + setprop_string(fdt, "/chosen", "bootargs", atag_cmdline);
> + return;
> + }
> + fdt_bootargs[len - 1] = ' ';
> + appendprop_string(fdt, "/chosen", "bootargs", atag_cmdline);
Let's say appendprop_string() fails for whatever reason, the /chosen
string won't be null terminated anymore.
Won't it cause some problems ?

>  }
>  
>  /*
> 

Richard.


Re: [PATCH] ARM: zImage: Fix stack overflow in merge_fdt_bootargs()

2017-07-18 Thread Richard Genoud
On 16/07/2017 23:43, Rask Ingemann Lambertsen wrote:
> This function is called very early on from head.S and currently sets up a
> stack frame of more than 1024 bytes:
> 
> atags_to_fdt.c: In function ‘merge_fdt_bootargs’:
> atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 
> 1024 bytes [-Wframe-larger-than=]
> 
> This causes a crash and failure to boot with some combinations of kernel
> version, gcc version and dtb, such as kernel version 4.1-rc1 of 4.1.0,
> gcc version 5.4.1 20161019 (Debian 5.4.1-3) and tegra20-trimslice.dtb.
> 
> With this patch, merge_fdt_bootargs() is rewritten to not use a large buffer,
> thereby solving the problem of the stack overflow.
> 
> As a side effect of this rewrite, you no longer get a space added in front
> of the kernel command line when no bootargs property was found in the fdt.
> 
> Signed-off-by: Rask Ingemann Lambertsen 
> Fixes: d0f34a11ddab ("ARM: 7437/1: zImage: Allow DTB command line 
> concatenation with ATAG_CMDLINE")
> ---
> 
> I have tested that this works properly when
> a) only the FDT bootargs are provided,
> b) only the ATAG command line is provided, and
> c) both the FDT bootargs and the ATAG command line are provided.
> 
>  arch/arm/boot/compressed/atags_to_fdt.c | 59 
> +++--
>  1 file changed, 35 insertions(+), 24 deletions(-)

Thanks for fixing that !

> 
> diff --git a/arch/arm/boot/compressed/atags_to_fdt.c 
> b/arch/arm/boot/compressed/atags_to_fdt.c
> index 9448aa0c6686..ede23ef2e889 100644
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -55,6 +55,27 @@ static const void *getprop(const void *fdt, const char 
> *node_path,
>   return fdt_getprop(fdt, offset, property, len);
>  }
>  
> +static void *getprop_w(void *fdt, const char *node_path,
> +const char *property, int *len)
> +{
> + int offset = fdt_path_offset(fdt, node_path);
> +
> + if (offset == -FDT_ERR_NOTFOUND)
> + return NULL;
> +
> + return fdt_getprop_w(fdt, offset, property, len);
> +}
> +
> +static int appendprop_string(void *fdt, const char *node_path,
> +  const char *property, const char *string)
> +{
> + int offset = node_offset(fdt, node_path);
> +
> + if (offset < 0)
> + return offset;
> + return fdt_appendprop_string(fdt, offset, property, string);
> +}
> +
>  static uint32_t get_cell_size(const void *fdt)
>  {
>   int len;
> @@ -66,35 +87,25 @@ static uint32_t get_cell_size(const void *fdt)
>   return cell_size;
>  }
>  
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> -{
> - char cmdline[COMMAND_LINE_SIZE];
> - const char *fdt_bootargs;
> - char *ptr = cmdline;
> - int len = 0;
> -
> - /* copy the fdt command line into the buffer */
> - fdt_bootargs = getprop(fdt, "/chosen", "bootargs", );
> - if (fdt_bootargs)
> - if (len < COMMAND_LINE_SIZE) {
> - memcpy(ptr, fdt_bootargs, len);
> - /* len is the length of the string
> -  * including the NULL terminator */
> - ptr += len - 1;
> - }
> -
> - /* and append the ATAG_CMDLINE */
> - if (fdt_cmdline) {
> - len = strlen(fdt_cmdline);
> - if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
> - *ptr++ = ' ';
> - memcpy(ptr, fdt_cmdline, len);
> - ptr += len;
> - }
> - }
> - *ptr = '\0';
> -
> - setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +/* This is called early on from head.S, so it can't use much stack. */
> +static void merge_fdt_bootargs(void *fdt, const char *atag_cmdline)
> +{
> + char *fdt_bootargs;
> + int len = 0;
> +
> + /* With no ATAG command line or an empty one, there is nothing to do. */
> + if (!atag_cmdline || strlen(atag_cmdline) == 0)
> + return;
> +
> + fdt_bootargs = getprop_w(fdt, "/chosen", "bootargs", );
> +
> + /* With no FDT command line or an empty one, just use the ATAG one. */
> + if (!fdt_bootargs || len <= 1) {
> + setprop_string(fdt, "/chosen", "bootargs", atag_cmdline);
> + return;
> + }
> + fdt_bootargs[len - 1] = ' ';
> + appendprop_string(fdt, "/chosen", "bootargs", atag_cmdline);
Let's say appendprop_string() fails for whatever reason, the /chosen
string won't be null terminated anymore.
Won't it cause some problems ?

>  }
>  
>  /*
> 

Richard.


Re: [PATCH 3.10 219/268] tty/serial: atmel: fix race condition (TX+DMA)

2017-06-20 Thread Richard Genoud
Hi Willy,

You can drop this patch.

There's nothing to fix on 3.10.x since the DMA TX support has been
introduced in 3.12.

Thanks !


2017-06-19 20:31 GMT+02:00 Willy Tarreau <w...@1wt.eu>:
> From: Richard Genoud <richard.gen...@gmail.com>
>
> commit 31ca2c63fdc0aee725cbd4f207c1256f5deaabde upstream.
>
> If uart_flush_buffer() is called between atmel_tx_dma() and
> atmel_complete_tx_dma(), the circular buffer has been cleared, but not
> atmel_port->tx_len.
> That leads to a circular buffer overflow (dumping (UART_XMIT_SIZE -
> atmel_port->tx_len) bytes).
>
> Tested-by: Nicolas Ferre <nicolas.fe...@microchip.com>
> [rg] backport to 3.12
> Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
> Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
> Signed-off-by: Willy Tarreau <w...@1wt.eu>
> ---
>  drivers/tty/serial/atmel_serial.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 82127ac..41d1df5 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1090,6 +1090,11 @@ static void atmel_flush_buffer(struct uart_port *port)
> UART_PUT_TCR(port, 0);
> atmel_port->pdc_tx.ofs = 0;
> }
> +   /*
> +* in uart_flush_buffer(), the xmit circular buffer has just
> +* been cleared, so we have to reset its length accordingly.
> +*/
> +   sg_dma_len(_port->sg_tx) = 0;
>  }
>
>  /*
> --
> 2.8.0.rc2.1.gbe9624a
>


Re: [PATCH 3.10 219/268] tty/serial: atmel: fix race condition (TX+DMA)

2017-06-20 Thread Richard Genoud
Hi Willy,

You can drop this patch.

There's nothing to fix on 3.10.x since the DMA TX support has been
introduced in 3.12.

Thanks !


2017-06-19 20:31 GMT+02:00 Willy Tarreau :
> From: Richard Genoud 
>
> commit 31ca2c63fdc0aee725cbd4f207c1256f5deaabde upstream.
>
> If uart_flush_buffer() is called between atmel_tx_dma() and
> atmel_complete_tx_dma(), the circular buffer has been cleared, but not
> atmel_port->tx_len.
> That leads to a circular buffer overflow (dumping (UART_XMIT_SIZE -
> atmel_port->tx_len) bytes).
>
> Tested-by: Nicolas Ferre 
> [rg] backport to 3.12
> Signed-off-by: Richard Genoud 
> Signed-off-by: Greg Kroah-Hartman 
> Signed-off-by: Willy Tarreau 
> ---
>  drivers/tty/serial/atmel_serial.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/tty/serial/atmel_serial.c 
> b/drivers/tty/serial/atmel_serial.c
> index 82127ac..41d1df5 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -1090,6 +1090,11 @@ static void atmel_flush_buffer(struct uart_port *port)
> UART_PUT_TCR(port, 0);
> atmel_port->pdc_tx.ofs = 0;
> }
> +   /*
> +* in uart_flush_buffer(), the xmit circular buffer has just
> +* been cleared, so we have to reset its length accordingly.
> +*/
> +   sg_dma_len(_port->sg_tx) = 0;
>  }
>
>  /*
> --
> 2.8.0.rc2.1.gbe9624a
>


[PATCH] kbuild: fix header installation under fakechroot environment

2017-06-15 Thread Richard Genoud
Since commit fcc8487d477a ("uapi: export all headers under uapi
directories") fakechroot make bindeb-pkg fails, mismatching files for
directories:
touch: cannot touch 'usr/include/video/uvesafb.h/.install': Not a
directory

This due to a bug in fakechroot:
when using the function $(wildcard $(srcdir)/*/.) in a makefile, under a
fakechroot environment, not only directories but also files are
returned.

To circumvent that, we are using the functions:
$(sort $(dir $(wildcard $(srcdir)/*/

And thanks to Yamada Masahiro who figured out the right
filter-out/patsubst order !

Fixes: fcc8487d477a ("uapi: export all headers under uapi directories")
Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
---
 scripts/Makefile.headersinst | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index ce753a408c56..c583a1e1bd3c 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -14,7 +14,15 @@ __headers:
 include scripts/Kbuild.include
 
 srcdir:= $(srctree)/$(obj)
-subdirs   := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+
+# When make is run under a fakechroot environment, the function
+# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular
+# files. So, we are using a combination of sort/dir/wildcard which works
+# with fakechroot.
+subdirs   := $(patsubst $(srcdir)/%/,%,\
+$(filter-out $(srcdir)/,\
+$(sort $(dir $(wildcard $(srcdir)/*/)
+
 # caller may set destination dir (when installing to asm/)
 _dst  := $(if $(dst),$(dst),$(obj))
 


[PATCH] kbuild: fix header installation under fakechroot environment

2017-06-15 Thread Richard Genoud
Since commit fcc8487d477a ("uapi: export all headers under uapi
directories") fakechroot make bindeb-pkg fails, mismatching files for
directories:
touch: cannot touch 'usr/include/video/uvesafb.h/.install': Not a
directory

This due to a bug in fakechroot:
when using the function $(wildcard $(srcdir)/*/.) in a makefile, under a
fakechroot environment, not only directories but also files are
returned.

To circumvent that, we are using the functions:
$(sort $(dir $(wildcard $(srcdir)/*/

And thanks to Yamada Masahiro who figured out the right
filter-out/patsubst order !

Fixes: fcc8487d477a ("uapi: export all headers under uapi directories")
Signed-off-by: Richard Genoud 
---
 scripts/Makefile.headersinst | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index ce753a408c56..c583a1e1bd3c 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -14,7 +14,15 @@ __headers:
 include scripts/Kbuild.include
 
 srcdir:= $(srctree)/$(obj)
-subdirs   := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+
+# When make is run under a fakechroot environment, the function
+# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular
+# files. So, we are using a combination of sort/dir/wildcard which works
+# with fakechroot.
+subdirs   := $(patsubst $(srcdir)/%/,%,\
+$(filter-out $(srcdir)/,\
+$(sort $(dir $(wildcard $(srcdir)/*/)
+
 # caller may set destination dir (when installing to asm/)
 _dst  := $(if $(dst),$(dst),$(obj))
 


Re: [PATCH] tty/serial: Kconfig: remove AVR32

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:35, Alexandre Belloni wrote:
> AVR32 is now removed from the kernel, removed the config symbol that
> doesn't exist anymore. Also take the opportunity to reword the help to
> include sama5.
> 
> Signed-off-by: Alexandre Belloni <alexandre.bell...@free-electrons.com>

Acked-by: Richard Genoud <richard.gen...@gmail.com>

100 lines removed with the 4 patches, that's nice !

Thanks !


Re: [PATCH] tty/serial: Kconfig: remove AVR32

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:35, Alexandre Belloni wrote:
> AVR32 is now removed from the kernel, removed the config symbol that
> doesn't exist anymore. Also take the opportunity to reword the help to
> include sama5.
> 
> Signed-off-by: Alexandre Belloni 

Acked-by: Richard Genoud 

100 lines removed with the 4 patches, that's nice !

Thanks !


Re: [PATCH] tty/serial: remove AVR32 specific access wrappers

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:25, Alexandre Belloni wrote:
> Now that AVR32 is gone, the specific wrappers for that architecture are
> unnecessary and will not be compiled anymore.
> 
> Signed-off-by: Alexandre Belloni <alexandre.bell...@free-electrons.com>

Acked-by: Richard Genoud <richard.gen...@gmail.com>



Re: [PATCH] tty/serial: remove AVR32 specific access wrappers

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:25, Alexandre Belloni wrote:
> Now that AVR32 is gone, the specific wrappers for that architecture are
> unnecessary and will not be compiled anymore.
> 
> Signed-off-by: Alexandre Belloni 

Acked-by: Richard Genoud 



Re: [PATCH v2 2/2] tty/serial: atmel: make the driver DT only

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:24, Alexandre Belloni wrote:
> Now that AVR32 is gone, platform_data are not used to initialize the driver
> anymore, remove that path from the driver. Also remove the now unused
> struct atmel_uart_data.
> 
> Signed-off-by: Alexandre Belloni <alexandre.bell...@free-electrons.com>
> ---
>  drivers/tty/serial/atmel_serial.c   | 96 
> +
>  include/linux/platform_data/atmel.h | 10 
>  2 files changed, 33 insertions(+), 73 deletions(-)

Acked-by: Richard Genoud <richard.gen...@gmail.com>




Re: [PATCH v2 2/2] tty/serial: atmel: make the driver DT only

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:24, Alexandre Belloni wrote:
> Now that AVR32 is gone, platform_data are not used to initialize the driver
> anymore, remove that path from the driver. Also remove the now unused
> struct atmel_uart_data.
> 
> Signed-off-by: Alexandre Belloni 
> ---
>  drivers/tty/serial/atmel_serial.c   | 96 
> +
>  include/linux/platform_data/atmel.h | 10 
>  2 files changed, 33 insertions(+), 73 deletions(-)

Acked-by: Richard Genoud 




Re: [PATCH v2 1/2] tty/serial: atmel: remove atmel_default_console_device handling

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:24, Alexandre Belloni wrote:
> atmel_default_console_device was only used by AVR32, in particular
> arch/avr32/mach-at32ap/at32ap700x.c which is now gone. Remove it from the
> driver.
> 
> Signed-off-by: Alexandre Belloni <alexandre.bell...@free-electrons.com>
> ---
> 
> Changes in v2:
>  - added an empty line as suggested by Andy
>  - properly based the patch on v4.12-rc1
> 
>  drivers/tty/serial/atmel_serial.c | 43 
> ---
>  1 file changed, 43 deletions(-)
> 

Acked-by: Richard Genoud <richard.gen...@gmail.com>


Thanks !


Re: [PATCH v2 1/2] tty/serial: atmel: remove atmel_default_console_device handling

2017-06-14 Thread Richard Genoud
On 13/06/2017 22:24, Alexandre Belloni wrote:
> atmel_default_console_device was only used by AVR32, in particular
> arch/avr32/mach-at32ap/at32ap700x.c which is now gone. Remove it from the
> driver.
> 
> Signed-off-by: Alexandre Belloni 
> ---
> 
> Changes in v2:
>  - added an empty line as suggested by Andy
>  - properly based the patch on v4.12-rc1
> 
>  drivers/tty/serial/atmel_serial.c | 43 
> ---
>  1 file changed, 43 deletions(-)
> 

Acked-by: Richard Genoud 


Thanks !


Re: [PATCH] gpio: mvebu: change compatible string for PWM support

2017-06-09 Thread Richard Genoud
2017-06-09 9:42 GMT+02:00 Linus Walleij :
> On Thu, Jun 1, 2017 at 10:08 PM, Ralph Sennhauser
>  wrote:
>
>> As it turns out more than just Armada 370 and XP support using GPIO
>> lines as PWM lines. For example the Armada 38x family has the same
>> hardware support. As such "marvell,armada-370-xp-gpio" for the
>> compatible string is a misnomer.
>>
>> Change the compatible string to "marvell,armada-370-gpio" before the
>> driver makes it out of the -rc stage. This also follows the practice of
>> using only the first device family supported as part of the name.
>>
>> Also update the documentation and comments in the code accordingly.
>>
>> Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
>> Signed-off-by: Ralph Sennhauser 
>
> Patch applied for next with the tags.
You mean for fixes right ?
The goal was to correct "marvell,armada-370-xp-gpio" before 4.12 is out.

>
> Yours,
> Linus Walleij

Regards,
Richard


Re: [PATCH] gpio: mvebu: change compatible string for PWM support

2017-06-09 Thread Richard Genoud
2017-06-09 9:42 GMT+02:00 Linus Walleij :
> On Thu, Jun 1, 2017 at 10:08 PM, Ralph Sennhauser
>  wrote:
>
>> As it turns out more than just Armada 370 and XP support using GPIO
>> lines as PWM lines. For example the Armada 38x family has the same
>> hardware support. As such "marvell,armada-370-xp-gpio" for the
>> compatible string is a misnomer.
>>
>> Change the compatible string to "marvell,armada-370-gpio" before the
>> driver makes it out of the -rc stage. This also follows the practice of
>> using only the first device family supported as part of the name.
>>
>> Also update the documentation and comments in the code accordingly.
>>
>> Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
>> Signed-off-by: Ralph Sennhauser 
>
> Patch applied for next with the tags.
You mean for fixes right ?
The goal was to correct "marvell,armada-370-xp-gpio" before 4.12 is out.

>
> Yours,
> Linus Walleij

Regards,
Richard


Re: [PATCHv2 1/2] gpio: mvebu: fix blink counter register selection

2017-06-09 Thread Richard Genoud
2017-06-09 9:37 GMT+02:00 Linus Walleij <linus.wall...@linaro.org>:
> On Thu, Jun 1, 2017 at 2:18 PM, Richard Genoud <richard.gen...@gmail.com> 
> wrote:
>
>> The blink counter A was always selected because 0 was forced in the
>> blink select counter register.
>> The variable 'set' was obviously there to be used as the register value,
>> selecting the B counter when id==1 and A counter when id==0.
>>
>> Tested on clearfog-pro (Marvell 88F6828)
>>
>> Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
>> Reviewed-by: Gregory CLEMENT <gregory.clem...@free-electrons.com>
>> Reviewed-by: Ralph Sennhauser <ralph.sennhau...@gmail.com>
>> Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
>
> Patch applied for fixes.
>
> It appears this will clash with patches on the development branch :(
>
> I might screw up the merges so help me check the end result
> later.
Ok, no problem !

>
> Yours,
> Linus Walleij
Thanks !
Richard.


Re: [PATCHv2 1/2] gpio: mvebu: fix blink counter register selection

2017-06-09 Thread Richard Genoud
2017-06-09 9:37 GMT+02:00 Linus Walleij :
> On Thu, Jun 1, 2017 at 2:18 PM, Richard Genoud  
> wrote:
>
>> The blink counter A was always selected because 0 was forced in the
>> blink select counter register.
>> The variable 'set' was obviously there to be used as the register value,
>> selecting the B counter when id==1 and A counter when id==0.
>>
>> Tested on clearfog-pro (Marvell 88F6828)
>>
>> Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
>> Reviewed-by: Gregory CLEMENT 
>> Reviewed-by: Ralph Sennhauser 
>> Signed-off-by: Richard Genoud 
>
> Patch applied for fixes.
>
> It appears this will clash with patches on the development branch :(
>
> I might screw up the merges so help me check the end result
> later.
Ok, no problem !

>
> Yours,
> Linus Walleij
Thanks !
Richard.


[PATCHv2 2/2] gpio: mvebu: fix gpio bank registration when pwm is used

2017-06-01 Thread Richard Genoud
If more than one gpio bank has the "pwm" property, only one will be
registered successfully, all the others will fail with:
mvebu-gpio: probe of f1018140.gpio failed with error -17

That's because in alloc_pwms(), the chip->base (aka "int pwm"), was not
set (thus, ==0) ; and 0 is a meaningful start value in alloc_pwm().
What was intended is mvpwm->chip->base = -1.
Like that, the numbering will be done auto-magically

Moreover, as the region might be already occupied by another pwm, we
shouldn't force:
mvpwm->chip->base = 0
nor
mvpwm->chip->base = id * MVEBU_MAX_GPIO_PER_BANK;

Tested on clearfog-pro (Marvell 88F6828)

Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
Signed-off-by: Richard Genoud <richard.gen...@gmail.com>
---
 drivers/gpio/gpio-mvebu.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index cdef2c78cb3b..5104b6398139 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -768,6 +768,13 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
mvpwm->chip.dev = dev;
mvpwm->chip.ops = _pwm_ops;
mvpwm->chip.npwm = mvchip->chip.ngpio;
+   /*
+* There may already be some PWM allocated, so we can't force
+* mvpwm->chip.base to a fixed point like mvchip->chip.base.
+* So, we let pwmchip_add() do the numbering and take the next free
+* region.
+*/
+   mvpwm->chip.base = -1;
 
spin_lock_init(>lock);
 


  1   2   3   4   5   6   7   8   9   >