[PATCH v5 0/2] add ISO7816 support

2018-09-26 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices
in Microchip SoCs have an ISO7816 mode. It allows to let the USART
managing the CLK and I/O signals of a smart card.

Changes:
- v5
  - rebase on tty-next.
  - add documentation for the new ioctls (mimic rs485 one).
  - fix a switch/case identation
- v4
  - use the IP version number instead of the compatible string to set
  min and max values for fidi.
  - remove a useless macro for fidi.
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard.
  - keep max iteration hard coded. Will see later if the user need to
set this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function.
  - use IOCTL macros to generate the IOCTL number.
  - check that reserved field is not used.
  - remove debug logs.
  - check that the iso7816_config is right before doing any action.
  - change the error from nack and max iteration status to a debug
message.
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
about the need of adding a lock or not.

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 Documentation/serial/serial-iso7816.txt |  83 ++
 arch/alpha/include/uapi/asm/ioctls.h|   2 +
 arch/mips/include/uapi/asm/ioctls.h |   2 +
 arch/parisc/include/uapi/asm/ioctls.h   |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h  |   2 +
 arch/sh/include/uapi/asm/ioctls.h   |   2 +
 arch/sparc/include/uapi/asm/ioctls.h|   2 +
 arch/xtensa/include/uapi/asm/ioctls.h   |   2 +
 drivers/tty/serial/atmel_serial.c   | 190 ++--
 drivers/tty/serial/atmel_serial.h   |   3 +-
 drivers/tty/serial/serial_core.c|  60 ++
 include/linux/serial_core.h |   3 +
 include/uapi/asm-generic/ioctls.h   |   2 +
 include/uapi/linux/serial.h |  17 +++
 14 files changed, 360 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/serial/serial-iso7816.txt

-- 
2.12.2



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

2018-09-26 Thread Ludovic Desroches
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 
Acked-by: Richard Genoud 
---
 drivers/tty/serial/atmel_serial.c | 190 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 2 files changed, 181 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 267d4d1de3f8..05147fe24343 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;
@@ -163,6 +166,10 @@ struct atmel_uart_port {
unsigned intpending_status;
spinlock_t  lock_suspended;
 
+   /* ISO7816 */
+   unsigned intfidi_min;
+   unsigned intfidi_max;
+
 #ifdef CONFIG_PM
struct {
u32 cr;
@@ -361,6 +368,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;
+
+   if (iso7816conf->tg > 255) {
+   dev_err(port->dev, "ISO7816: Timeguard exceeding 
255\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T0 | ATMEL_US_DSNACK;
+   } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+  == SER_ISO7816_T(1)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T1 | ATMEL_US_INACK;
+   } else {
+   dev_err(port->dev, "ISO7816: Type not supported\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   mode &= ~(ATMEL_US_USCLKS | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
+   /* 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 | 
ATMEL_US_MAX_ITER(3);
+
+   cd = atmel_calc_cd(port, iso7816conf);
+   fidi = atmel_calc_fidi(port, iso7816conf);
+   if (fidi == 0) {
+   dev_warn(port->dev, "ISO7816 fidi = 0, Generator 
generates no signal\n");
+   } else if (fidi < atmel_port->fidi_min
+  || fidi > atmel_port->fidi_max) {
+   dev_err(port->dev, "ISO7816 fidi = %u, value not 
supp

[PATCH v5 1/2] tty/serial_core: add ISO7816 infrastructure

2018-09-26 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816
(smart cards).

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 Documentation/serial/serial-iso7816.txt | 83 +
 arch/alpha/include/uapi/asm/ioctls.h|  2 +
 arch/mips/include/uapi/asm/ioctls.h |  2 +
 arch/parisc/include/uapi/asm/ioctls.h   |  2 +
 arch/powerpc/include/uapi/asm/ioctls.h  |  2 +
 arch/sh/include/uapi/asm/ioctls.h   |  2 +
 arch/sparc/include/uapi/asm/ioctls.h|  2 +
 arch/xtensa/include/uapi/asm/ioctls.h   |  2 +
 drivers/tty/serial/serial_core.c| 60 
 include/linux/serial_core.h |  3 ++
 include/uapi/asm-generic/ioctls.h   |  2 +
 include/uapi/linux/serial.h | 17 +++
 12 files changed, 179 insertions(+)
 create mode 100644 Documentation/serial/serial-iso7816.txt

diff --git a/Documentation/serial/serial-iso7816.txt 
b/Documentation/serial/serial-iso7816.txt
new file mode 100644
index ..3193d24a2b0f
--- /dev/null
+++ b/Documentation/serial/serial-iso7816.txt
@@ -0,0 +1,83 @@
+ISO7816 SERIAL COMMUNICATIONS
+
+1. INTRODUCTION
+
+  ISO/IEC7816 is a series of standards specifying integrated circuit cards 
(ICC)
+  also known as smart cards.
+
+2. HARDWARE-RELATED CONSIDERATIONS
+
+  Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of
+  handling communication with a smart card.
+
+  For these microcontrollers, the Linux driver should be made capable of
+  working in both modes, and proper ioctls (see later) should be made
+  available at user-level to allow switching from one mode to the other, and
+  vice versa.
+
+3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL
+
+  The Linux kernel provides the serial_iso7816 structure (see [1]) to handle
+  ISO7816 communications. This data structure is used to set and configure
+  ISO7816 parameters in ioctls.
+
+  Any driver for devices capable of working both as RS232 and ISO7816 should
+  implement the iso7816_config callback in the uart_port structure. The
+  serial_core calls iso7816_config to do the device specific part in response
+  to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config
+  callback receives a pointer to struct serial_iso7816.
+
+4. USAGE FROM USER-LEVEL
+
+  From user-level, ISO7816 configuration can be get/set using the previous
+  ioctls. For instance, to set ISO7816 you can use the following code:
+
+   #include 
+
+   /* Include definition for ISO7816 ioctls: TIOCSISO7816 and TIOCGISO7816 
*/
+   #include 
+
+   /* Open your specific device (e.g., /dev/mydevice): */
+   int fd = open ("/dev/mydevice", O_RDWR);
+   if (fd < 0) {
+   /* Error handling. See errno. */
+   }
+
+   struct serial_iso7816 iso7816conf;
+
+   /* Reserved fields as to be zeroed */
+   memset(, 0, sizeof(iso7816conf));
+
+   /* Enable ISO7816 mode: */
+   iso7816conf.flags |= SER_ISO7816_ENABLED;
+
+   /* Select the protocol: */
+   /* T=0 */
+   iso7816conf.flags |= SER_ISO7816_T(0);
+   /* or T=1 */
+   iso7816conf.flags |= SER_ISO7816_T(1);
+
+   /* Set the guard time: */
+   iso7816conf.tg = 2;
+
+   /* Set the clock frequency*/
+   iso7816conf.clk = 3571200;
+
+   /* Set transmission factors: */
+   iso7816conf.sc_fi = 372;
+   iso7816conf.sc_di = 1;
+
+   if (ioctl(fd_usart, TIOCSISO7816, ) < 0) {
+   /* Error handling. See errno. */
+   }
+
+   /* Use read() and write() syscalls here... */
+
+   /* Close the device when finished: */
+   if (close (fd) < 0) {
+   /* Error handling. See errno. */
+   }
+
+5. REFERENCES
+
+ [1]include/uapi/linux/serial.h
diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get e

[PATCH v5 0/2] add ISO7816 support

2018-09-26 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices
in Microchip SoCs have an ISO7816 mode. It allows to let the USART
managing the CLK and I/O signals of a smart card.

Changes:
- v5
  - rebase on tty-next.
  - add documentation for the new ioctls (mimic rs485 one).
  - fix a switch/case identation
- v4
  - use the IP version number instead of the compatible string to set
  min and max values for fidi.
  - remove a useless macro for fidi.
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard.
  - keep max iteration hard coded. Will see later if the user need to
set this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function.
  - use IOCTL macros to generate the IOCTL number.
  - check that reserved field is not used.
  - remove debug logs.
  - check that the iso7816_config is right before doing any action.
  - change the error from nack and max iteration status to a debug
message.
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
about the need of adding a lock or not.

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 Documentation/serial/serial-iso7816.txt |  83 ++
 arch/alpha/include/uapi/asm/ioctls.h|   2 +
 arch/mips/include/uapi/asm/ioctls.h |   2 +
 arch/parisc/include/uapi/asm/ioctls.h   |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h  |   2 +
 arch/sh/include/uapi/asm/ioctls.h   |   2 +
 arch/sparc/include/uapi/asm/ioctls.h|   2 +
 arch/xtensa/include/uapi/asm/ioctls.h   |   2 +
 drivers/tty/serial/atmel_serial.c   | 190 ++--
 drivers/tty/serial/atmel_serial.h   |   3 +-
 drivers/tty/serial/serial_core.c|  60 ++
 include/linux/serial_core.h |   3 +
 include/uapi/asm-generic/ioctls.h   |   2 +
 include/uapi/linux/serial.h |  17 +++
 14 files changed, 360 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/serial/serial-iso7816.txt

-- 
2.12.2



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

2018-09-26 Thread Ludovic Desroches
On Tue, Sep 18, 2018 at 03:28:56PM +0200, Greg KH wrote:
> On Thu, Sep 06, 2018 at 03:42:14PM +0200, 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 
> > Acked-by: Richard Genoud 
> > ---
> >  drivers/tty/serial/atmel_serial.c | 190 
> > +++---
> >  drivers/tty/serial/atmel_serial.h |   3 +-
> >  2 files changed, 181 insertions(+), 12 deletions(-)
> 
> This doesn't apply to my tree :(
> 

I am rebasing it on tty-next.

> Also, shouldn't this new ioctl be documented somewhere?
> 

v5 is coming.

Regards

Ludovic


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

2018-09-26 Thread Ludovic Desroches
On Tue, Sep 18, 2018 at 03:28:56PM +0200, Greg KH wrote:
> On Thu, Sep 06, 2018 at 03:42:14PM +0200, 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 
> > Acked-by: Richard Genoud 
> > ---
> >  drivers/tty/serial/atmel_serial.c | 190 
> > +++---
> >  drivers/tty/serial/atmel_serial.h |   3 +-
> >  2 files changed, 181 insertions(+), 12 deletions(-)
> 
> This doesn't apply to my tree :(
> 

I am rebasing it on tty-next.

> Also, shouldn't this new ioctl be documented somewhere?
> 

v5 is coming.

Regards

Ludovic


Re: [GIT PULL] ARM: at91: SoC for 4.20

2018-09-26 Thread Ludovic Desroches
On Tue, Sep 25, 2018 at 01:38:12PM -0700, Olof Johansson wrote:
> On Tue, Sep 25, 2018 at 12:37:35PM +0200, Alexandre Belloni wrote:
> > Arnd, Olof,
> > 
> > Most changes are shuffling around the maintainers entries. There are
> > also two PM non urgent fixes.
> > 
> > This one as a trivial conflict with the staging tree solved in linux-next.
> > 
> > The following changes since commit 5b394b2ddf0347bef56e50c69a58773c94343ff3:
> > 
> >   Linux 4.19-rc1 (2018-08-26 14:11:59 -0700)
> > 
> > are available in the Git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux 
> > tags/at91-4.20-soc
> > 
> > for you to fetch changes up to 34d2a7db77ad837cfb88bd01b33fd1f3855ce9c0:
> > 
> >   MAINTAINERS: sdhci: move the Microchip entry to proper location 
> > (2018-09-25 12:26:31 +0200)
> > 
> > 
> > AT91 SoC for 4.20
> > 
> >  - rename MAINTAINERS entries and change maintainers
> >  - two pm cleanups
> 
> Merged, thanks.  Welcome aboard as maintainer, Ludovic!

Thanks!

Ludovic

> 
> 
> -Olof


Re: [GIT PULL] ARM: at91: SoC for 4.20

2018-09-26 Thread Ludovic Desroches
On Tue, Sep 25, 2018 at 01:38:12PM -0700, Olof Johansson wrote:
> On Tue, Sep 25, 2018 at 12:37:35PM +0200, Alexandre Belloni wrote:
> > Arnd, Olof,
> > 
> > Most changes are shuffling around the maintainers entries. There are
> > also two PM non urgent fixes.
> > 
> > This one as a trivial conflict with the staging tree solved in linux-next.
> > 
> > The following changes since commit 5b394b2ddf0347bef56e50c69a58773c94343ff3:
> > 
> >   Linux 4.19-rc1 (2018-08-26 14:11:59 -0700)
> > 
> > are available in the Git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux 
> > tags/at91-4.20-soc
> > 
> > for you to fetch changes up to 34d2a7db77ad837cfb88bd01b33fd1f3855ce9c0:
> > 
> >   MAINTAINERS: sdhci: move the Microchip entry to proper location 
> > (2018-09-25 12:26:31 +0200)
> > 
> > 
> > AT91 SoC for 4.20
> > 
> >  - rename MAINTAINERS entries and change maintainers
> >  - two pm cleanups
> 
> Merged, thanks.  Welcome aboard as maintainer, Ludovic!

Thanks!

Ludovic

> 
> 
> -Olof


Re: [PATCH v2 2/2] iio: adc: at91: fix wrong channel number in triggered buffer mode

2018-09-25 Thread Ludovic Desroches
On Mon, Sep 24, 2018 at 10:51:44AM +0300, Eugen Hristev wrote:
> When channels are registered, the hardware channel number is not the
> actual iio channel number.
> This is because the driver is probed with a certain number of accessible
> channels. Some pins are routed and some not, depending on the description of
> the board in the DT.
> Because of that, channels 0,1,2,3 can correspond to hardware channels
> 2,3,4,5 for example.
> In the buffered triggered case, we need to do the translation accordingly.
> Fixed the channel number to stop reading the wrong channel.
> 
> Fixes 0e589d5fb "ARM: AT91: IIO: Add AT91 ADC driver."
> Cc: Maxime Ripard 
> Signed-off-by: Eugen Hristev 
Acked-by: Ludovic Desroches 

> ---
> Changes in v2:
> - Added 'const' spec to the declaration to avoid build warning
> 
>  drivers/iio/adc/at91_adc.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
> index e3be88e..75d2f73 100644
> --- a/drivers/iio/adc/at91_adc.c
> +++ b/drivers/iio/adc/at91_adc.c
> @@ -248,12 +248,14 @@ static irqreturn_t at91_adc_trigger_handler(int irq, 
> void *p)
>   struct iio_poll_func *pf = p;
>   struct iio_dev *idev = pf->indio_dev;
>   struct at91_adc_state *st = iio_priv(idev);
> + struct iio_chan_spec const *chan;
>   int i, j = 0;
>  
>   for (i = 0; i < idev->masklength; i++) {
>   if (!test_bit(i, idev->active_scan_mask))
>   continue;
> - st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i));
> + chan = idev->channels + i;
> + st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, 
> chan->channel));
>   j++;
>   }
>  
> -- 
> 2.7.4
> 


Re: [PATCH v2 2/2] iio: adc: at91: fix wrong channel number in triggered buffer mode

2018-09-25 Thread Ludovic Desroches
On Mon, Sep 24, 2018 at 10:51:44AM +0300, Eugen Hristev wrote:
> When channels are registered, the hardware channel number is not the
> actual iio channel number.
> This is because the driver is probed with a certain number of accessible
> channels. Some pins are routed and some not, depending on the description of
> the board in the DT.
> Because of that, channels 0,1,2,3 can correspond to hardware channels
> 2,3,4,5 for example.
> In the buffered triggered case, we need to do the translation accordingly.
> Fixed the channel number to stop reading the wrong channel.
> 
> Fixes 0e589d5fb "ARM: AT91: IIO: Add AT91 ADC driver."
> Cc: Maxime Ripard 
> Signed-off-by: Eugen Hristev 
Acked-by: Ludovic Desroches 

> ---
> Changes in v2:
> - Added 'const' spec to the declaration to avoid build warning
> 
>  drivers/iio/adc/at91_adc.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
> index e3be88e..75d2f73 100644
> --- a/drivers/iio/adc/at91_adc.c
> +++ b/drivers/iio/adc/at91_adc.c
> @@ -248,12 +248,14 @@ static irqreturn_t at91_adc_trigger_handler(int irq, 
> void *p)
>   struct iio_poll_func *pf = p;
>   struct iio_dev *idev = pf->indio_dev;
>   struct at91_adc_state *st = iio_priv(idev);
> + struct iio_chan_spec const *chan;
>   int i, j = 0;
>  
>   for (i = 0; i < idev->masklength; i++) {
>   if (!test_bit(i, idev->active_scan_mask))
>   continue;
> - st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i));
> + chan = idev->channels + i;
> + st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, 
> chan->channel));
>   j++;
>   }
>  
> -- 
> 2.7.4
> 


Re: [PATCH v2 1/2] iio: adc: at91: fix acking DRDY irq on simple conversions

2018-09-25 Thread Ludovic Desroches
On Mon, Sep 24, 2018 at 10:51:43AM +0300, Eugen Hristev wrote:
> When doing simple conversions, the driver did not acknowledge the DRDY irq.
> If this irq status is not acked, it will be left pending, and as soon as a
> trigger is enabled, the irq handler will be called, it doesn't know why
> this status has occurred because no channel is pending, and then it will go
> int a irq loop and board will hang.
> To avoid this situation, read the LCDR after a raw conversion is done.
> 
> Fixes 0e589d5fb ("ARM: AT91: IIO: Add AT91 ADC driver.")
> Cc: Maxime Ripard 
> Signed-off-by: Eugen Hristev 
Acked-by: Ludovic Desroches  

> ---
> Hello Jonathan,
> 
> I moved this LCDR read/acknowledge into the IRQ handler after the conversion
> value is being read.
> Sorry about the noise to stable@vger, removed from message.
> 
> Thanks,
> Eugen
> 
>  drivers/iio/adc/at91_adc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
> index 44b5168..e3be88e 100644
> --- a/drivers/iio/adc/at91_adc.c
> +++ b/drivers/iio/adc/at91_adc.c
> @@ -279,6 +279,8 @@ static void handle_adc_eoc_trigger(int irq, struct 
> iio_dev *idev)
>   iio_trigger_poll(idev->trig);
>   } else {
>   st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, 
> st->chnb));
> + /* Needed to ACK the DRDY interruption */
> + at91_adc_readl(st, AT91_ADC_LCDR);
>   st->done = true;
>   wake_up_interruptible(>wq_data_avail);
>   }
> -- 
> 2.7.4
> 


Re: [PATCH v2 1/2] iio: adc: at91: fix acking DRDY irq on simple conversions

2018-09-25 Thread Ludovic Desroches
On Mon, Sep 24, 2018 at 10:51:43AM +0300, Eugen Hristev wrote:
> When doing simple conversions, the driver did not acknowledge the DRDY irq.
> If this irq status is not acked, it will be left pending, and as soon as a
> trigger is enabled, the irq handler will be called, it doesn't know why
> this status has occurred because no channel is pending, and then it will go
> int a irq loop and board will hang.
> To avoid this situation, read the LCDR after a raw conversion is done.
> 
> Fixes 0e589d5fb ("ARM: AT91: IIO: Add AT91 ADC driver.")
> Cc: Maxime Ripard 
> Signed-off-by: Eugen Hristev 
Acked-by: Ludovic Desroches  

> ---
> Hello Jonathan,
> 
> I moved this LCDR read/acknowledge into the IRQ handler after the conversion
> value is being read.
> Sorry about the noise to stable@vger, removed from message.
> 
> Thanks,
> Eugen
> 
>  drivers/iio/adc/at91_adc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
> index 44b5168..e3be88e 100644
> --- a/drivers/iio/adc/at91_adc.c
> +++ b/drivers/iio/adc/at91_adc.c
> @@ -279,6 +279,8 @@ static void handle_adc_eoc_trigger(int irq, struct 
> iio_dev *idev)
>   iio_trigger_poll(idev->trig);
>   } else {
>   st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, 
> st->chnb));
> + /* Needed to ACK the DRDY interruption */
> + at91_adc_readl(st, AT91_ADC_LCDR);
>   st->done = true;
>   wake_up_interruptible(>wq_data_avail);
>   }
> -- 
> 2.7.4
> 


[PATCH] pinctrl: at91: don't use the same irqchip with multiple gpiochips

2018-09-13 Thread Ludovic Desroches
Sharing the same irqchip with multiple gpiochips is not a good
practice. For instance, when installing hooks, we change the state
of the irqchip. The initial state of the irqchip for the second
gpiochip to register is then disrupted.

Signed-off-by: Ludovic Desroches 
---
Hi,

This patch fixes the issue encountered in linux-next because of
"gpiolib: override irq_enable/disable". As discussed [1], the gpiolib
can do some extra checks but sharing the same irqchip with multiple
gpiochips is seen as a bad practice.

[1] https://www.spinics.net/lists/arm-kernel/msg676097.html

 drivers/pinctrl/pinctrl-at91.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index cfd8239f2727..911ea0fe2a41 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1574,16 +1574,6 @@ void at91_pinctrl_gpio_resume(void)
 #define gpio_irq_set_wake  NULL
 #endif /* CONFIG_PM */
 
-static struct irq_chip gpio_irqchip = {
-   .name   = "GPIO",
-   .irq_ack= gpio_irq_ack,
-   .irq_disable= gpio_irq_mask,
-   .irq_mask   = gpio_irq_mask,
-   .irq_unmask = gpio_irq_unmask,
-   /* .irq_set_type is set dynamically */
-   .irq_set_wake   = gpio_irq_set_wake,
-};
-
 static void gpio_irq_handler(struct irq_desc *desc)
 {
struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -1624,12 +1614,22 @@ static int at91_gpio_of_irq_setup(struct 
platform_device *pdev,
struct gpio_chip*gpiochip_prev = NULL;
struct at91_gpio_chip   *prev = NULL;
struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
+   struct irq_chip *gpio_irqchip;
int ret, i;
 
+   gpio_irqchip = devm_kzalloc(>dev, sizeof(*gpio_irqchip), 
GFP_KERNEL);
+   if (!gpio_irqchip)
+   return -ENOMEM;
+
at91_gpio->pioc_hwirq = irqd_to_hwirq(d);
 
-   /* Setup proper .irq_set_type function */
-   gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type;
+   gpio_irqchip->name = "GPIO";
+   gpio_irqchip->irq_ack = gpio_irq_ack;
+   gpio_irqchip->irq_disable = gpio_irq_mask;
+   gpio_irqchip->irq_mask = gpio_irq_mask;
+   gpio_irqchip->irq_unmask = gpio_irq_unmask;
+   gpio_irqchip->irq_set_wake = gpio_irq_set_wake,
+   gpio_irqchip->irq_set_type = at91_gpio->ops->irq_type;
 
/* Disable irqs of this PIO controller */
writel_relaxed(~0, at91_gpio->regbase + PIO_IDR);
@@ -1640,7 +1640,7 @@ static int at91_gpio_of_irq_setup(struct platform_device 
*pdev,
 * interrupt.
 */
ret = gpiochip_irqchip_add(_gpio->chip,
-  _irqchip,
+  gpio_irqchip,
   0,
   handle_edge_irq,
   IRQ_TYPE_NONE);
@@ -1658,7 +1658,7 @@ static int at91_gpio_of_irq_setup(struct platform_device 
*pdev,
if (!gpiochip_prev) {
/* Then register the chain on the parent IRQ */
gpiochip_set_chained_irqchip(_gpio->chip,
-_irqchip,
+gpio_irqchip,
 at91_gpio->pioc_virq,
 gpio_irq_handler);
return 0;
-- 
2.12.2



[PATCH] pinctrl: at91: don't use the same irqchip with multiple gpiochips

2018-09-13 Thread Ludovic Desroches
Sharing the same irqchip with multiple gpiochips is not a good
practice. For instance, when installing hooks, we change the state
of the irqchip. The initial state of the irqchip for the second
gpiochip to register is then disrupted.

Signed-off-by: Ludovic Desroches 
---
Hi,

This patch fixes the issue encountered in linux-next because of
"gpiolib: override irq_enable/disable". As discussed [1], the gpiolib
can do some extra checks but sharing the same irqchip with multiple
gpiochips is seen as a bad practice.

[1] https://www.spinics.net/lists/arm-kernel/msg676097.html

 drivers/pinctrl/pinctrl-at91.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index cfd8239f2727..911ea0fe2a41 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1574,16 +1574,6 @@ void at91_pinctrl_gpio_resume(void)
 #define gpio_irq_set_wake  NULL
 #endif /* CONFIG_PM */
 
-static struct irq_chip gpio_irqchip = {
-   .name   = "GPIO",
-   .irq_ack= gpio_irq_ack,
-   .irq_disable= gpio_irq_mask,
-   .irq_mask   = gpio_irq_mask,
-   .irq_unmask = gpio_irq_unmask,
-   /* .irq_set_type is set dynamically */
-   .irq_set_wake   = gpio_irq_set_wake,
-};
-
 static void gpio_irq_handler(struct irq_desc *desc)
 {
struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -1624,12 +1614,22 @@ static int at91_gpio_of_irq_setup(struct 
platform_device *pdev,
struct gpio_chip*gpiochip_prev = NULL;
struct at91_gpio_chip   *prev = NULL;
struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
+   struct irq_chip *gpio_irqchip;
int ret, i;
 
+   gpio_irqchip = devm_kzalloc(>dev, sizeof(*gpio_irqchip), 
GFP_KERNEL);
+   if (!gpio_irqchip)
+   return -ENOMEM;
+
at91_gpio->pioc_hwirq = irqd_to_hwirq(d);
 
-   /* Setup proper .irq_set_type function */
-   gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type;
+   gpio_irqchip->name = "GPIO";
+   gpio_irqchip->irq_ack = gpio_irq_ack;
+   gpio_irqchip->irq_disable = gpio_irq_mask;
+   gpio_irqchip->irq_mask = gpio_irq_mask;
+   gpio_irqchip->irq_unmask = gpio_irq_unmask;
+   gpio_irqchip->irq_set_wake = gpio_irq_set_wake,
+   gpio_irqchip->irq_set_type = at91_gpio->ops->irq_type;
 
/* Disable irqs of this PIO controller */
writel_relaxed(~0, at91_gpio->regbase + PIO_IDR);
@@ -1640,7 +1640,7 @@ static int at91_gpio_of_irq_setup(struct platform_device 
*pdev,
 * interrupt.
 */
ret = gpiochip_irqchip_add(_gpio->chip,
-  _irqchip,
+  gpio_irqchip,
   0,
   handle_edge_irq,
   IRQ_TYPE_NONE);
@@ -1658,7 +1658,7 @@ static int at91_gpio_of_irq_setup(struct platform_device 
*pdev,
if (!gpiochip_prev) {
/* Then register the chain on the parent IRQ */
gpiochip_set_chained_irqchip(_gpio->chip,
-_irqchip,
+gpio_irqchip,
 at91_gpio->pioc_virq,
 gpio_irq_handler);
return 0;
-- 
2.12.2



Re: [PATCH] ARM: dts: at91: sama5d4: add labels to soc dtsi for derivative boards

2018-09-07 Thread Ludovic Desroches
Hi Eugen,

On Fri, Sep 07, 2018 at 04:38:09PM +0300, Eugen Hristev wrote:
> This adds labels to commonly used device-tree nodes so that derivative
> boards can avoid ahb/apb hierarchy.
> 
> Signed-off-by: Eugen Hristev 
> ---
> 
> Hello,
> 
> This was already done for SoC sama5d3 and sam9x5, in commit:
> "fc37204432d" ("ARM: dts: at91: add labels to soc dtsi for derivative boards")
> 
> This commit will do basically the same thing for sama5d4 SoC.

Even if it's a mimic of what has been done for other SoCs, it could be
worth doing it for all peripherals: trng, aes, tdes and sha are still
missing a label.

Otherwise
Acked-by: Ludovic Desroches 

Regards

Ludovic

> 
> Based on top of at91-next branch of at91.git
> 
> Thanks.
> 
>  arch/arm/boot/dts/sama5d4.dtsi | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
> index 92a35a1..7371f2a 100644
> --- a/arch/arm/boot/dts/sama5d4.dtsi
> +++ b/arch/arm/boot/dts/sama5d4.dtsi
> @@ -1323,13 +1323,13 @@
>   };
>   };
>  
> - rstc@fc068600 {
> + reset_controller: rstc@fc068600 {
>   compatible = "atmel,sama5d3-rstc", 
> "atmel,at91sam9g45-rstc";
>   reg = <0xfc068600 0x10>;
>   clocks = <>;
>   };
>  
> - shdwc@fc068610 {
> + shutdown_controller: shdwc@fc068610 {
>   compatible = "atmel,at91sam9x5-shdwc";
>   reg = <0xfc068610 0x10>;
>   clocks = <>;
> @@ -1342,7 +1342,7 @@
>   clocks = <>;
>   };
>  
> - watchdog@fc068640 {
> + watchdog: watchdog@fc068640 {
>   compatible = "atmel,sama5d4-wdt";
>   reg = <0xfc068640 0x10>;
>   interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
> @@ -1376,7 +1376,7 @@
>   };
>  
>  
> - pinctrl@fc06a000 {
> + pinctrl: pinctrl@fc06a000 {
>   #address-cells = <1>;
>   #size-cells = <1>;
>   compatible = "atmel,sama5d3-pinctrl", 
> "atmel,at91sam9x5-pinctrl", "simple-bus";
> -- 
> 2.7.4
> 


Re: [PATCH] ARM: dts: at91: sama5d4: add labels to soc dtsi for derivative boards

2018-09-07 Thread Ludovic Desroches
Hi Eugen,

On Fri, Sep 07, 2018 at 04:38:09PM +0300, Eugen Hristev wrote:
> This adds labels to commonly used device-tree nodes so that derivative
> boards can avoid ahb/apb hierarchy.
> 
> Signed-off-by: Eugen Hristev 
> ---
> 
> Hello,
> 
> This was already done for SoC sama5d3 and sam9x5, in commit:
> "fc37204432d" ("ARM: dts: at91: add labels to soc dtsi for derivative boards")
> 
> This commit will do basically the same thing for sama5d4 SoC.

Even if it's a mimic of what has been done for other SoCs, it could be
worth doing it for all peripherals: trng, aes, tdes and sha are still
missing a label.

Otherwise
Acked-by: Ludovic Desroches 

Regards

Ludovic

> 
> Based on top of at91-next branch of at91.git
> 
> Thanks.
> 
>  arch/arm/boot/dts/sama5d4.dtsi | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
> index 92a35a1..7371f2a 100644
> --- a/arch/arm/boot/dts/sama5d4.dtsi
> +++ b/arch/arm/boot/dts/sama5d4.dtsi
> @@ -1323,13 +1323,13 @@
>   };
>   };
>  
> - rstc@fc068600 {
> + reset_controller: rstc@fc068600 {
>   compatible = "atmel,sama5d3-rstc", 
> "atmel,at91sam9g45-rstc";
>   reg = <0xfc068600 0x10>;
>   clocks = <>;
>   };
>  
> - shdwc@fc068610 {
> + shutdown_controller: shdwc@fc068610 {
>   compatible = "atmel,at91sam9x5-shdwc";
>   reg = <0xfc068610 0x10>;
>   clocks = <>;
> @@ -1342,7 +1342,7 @@
>   clocks = <>;
>   };
>  
> - watchdog@fc068640 {
> + watchdog: watchdog@fc068640 {
>   compatible = "atmel,sama5d4-wdt";
>   reg = <0xfc068640 0x10>;
>   interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
> @@ -1376,7 +1376,7 @@
>   };
>  
>  
> - pinctrl@fc06a000 {
> + pinctrl: pinctrl@fc06a000 {
>   #address-cells = <1>;
>   #size-cells = <1>;
>   compatible = "atmel,sama5d3-pinctrl", 
> "atmel,at91sam9x5-pinctrl", "simple-bus";
> -- 
> 2.7.4
> 


[PATCH] ARM: dts: at91: sama5d2_ptc_ek: fix nand pinctrl

2018-09-07 Thread Ludovic Desroches
The drive strength has to be set to medium otherwise some data
corruption may happen.

Signed-off-by: Ludovic Desroches 
---

Hi,

This fix depends on the support of the drive-strength for the atmel pio4
pinctroller. It has been added in v4.19 but I omitted to send it at the
same time.

Ludovic

 arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts 
b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index b10dccd0958f..3b1baa8605a7 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -11,6 +11,7 @@
 #include "sama5d2-pinfunc.h"
 #include 
 #include 
+#include 
 
 / {
model = "Atmel SAMA5D2 PTC EK";
@@ -299,6 +300,7 @@
 ,
 ;
bias-pull-up;
+   atmel,drive-strength = 
;
};
 
ale_cle_rdy_cs {
-- 
2.12.2



[PATCH] ARM: dts: at91: sama5d2_ptc_ek: fix nand pinctrl

2018-09-07 Thread Ludovic Desroches
The drive strength has to be set to medium otherwise some data
corruption may happen.

Signed-off-by: Ludovic Desroches 
---

Hi,

This fix depends on the support of the drive-strength for the atmel pio4
pinctroller. It has been added in v4.19 but I omitted to send it at the
same time.

Ludovic

 arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts 
b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index b10dccd0958f..3b1baa8605a7 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -11,6 +11,7 @@
 #include "sama5d2-pinfunc.h"
 #include 
 #include 
+#include 
 
 / {
model = "Atmel SAMA5D2 PTC EK";
@@ -299,6 +300,7 @@
 ,
 ;
bias-pull-up;
+   atmel,drive-strength = 
;
};
 
ale_cle_rdy_cs {
-- 
2.12.2



[PATCH v4 0/2] add ISO7816 support

2018-09-06 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v4
  - use the IP version number instead of the compatible string to set
  min and max values for fidi.
  - remove a useless macro for fidi.
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard.
  - keep max iteration hard coded. Will see later if the user need to set
  this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function.
  - use IOCTL macros to generate the IOCTL number.
  - check that reserved field is not used.
  - remove debug logs.
  - check that the iso7816_config is right before doing any action.
  - change the error from nack and max iteration status to a debug message.
  - remove patch 3 as it concerns both rs485 and iso7816 to think more.
  about the need of adding a lock or not.

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/parisc/include/uapi/asm/ioctls.h  |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 190 +++--
 drivers/tty/serial/atmel_serial.h  |   3 +-
 drivers/tty/serial/serial_core.c   |  60 +++
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 +++
 13 files changed, 277 insertions(+), 12 deletions(-)

-- 
2.12.2



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

2018-09-06 Thread Ludovic Desroches
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 | 190 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 2 files changed, 181 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 8e4428725848..a6a6c3334759 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;
@@ -163,6 +166,10 @@ struct atmel_uart_port {
unsigned intpending_status;
spinlock_t  lock_suspended;
 
+   /* ISO7816 */
+   unsigned intfidi_min;
+   unsigned intfidi_max;
+
 #ifdef CONFIG_PM
struct {
u32 cr;
@@ -362,6 +369,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;
+
+   if (iso7816conf->tg > 255) {
+   dev_err(port->dev, "ISO7816: Timeguard exceeding 
255\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T0 | ATMEL_US_DSNACK;
+   } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+  == SER_ISO7816_T(1)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T1 | ATMEL_US_INACK;
+   } else {
+   dev_err(port->dev, "ISO7816: Type not supported\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   mode &= ~(ATMEL_US_USCLKS | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
+   /* 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 | 
ATMEL_US_MAX_ITER(3);
+
+   cd = atmel_calc_cd(port, iso7816conf);
+   fidi = atmel_calc_fidi(port, iso7816conf);
+   if (fidi == 0) {
+   dev_warn(port->dev, "ISO7816 fidi = 0, Generator 
generates no signal\n");
+   } else if (fidi < atmel_port->fidi_min
+  || fidi > atmel_port->fidi_max) {
+   dev_err(port->dev, "ISO7816 fidi = %u, value not 
supported\n&qu

[PATCH v4 0/2] add ISO7816 support

2018-09-06 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v4
  - use the IP version number instead of the compatible string to set
  min and max values for fidi.
  - remove a useless macro for fidi.
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard.
  - keep max iteration hard coded. Will see later if the user need to set
  this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function.
  - use IOCTL macros to generate the IOCTL number.
  - check that reserved field is not used.
  - remove debug logs.
  - check that the iso7816_config is right before doing any action.
  - change the error from nack and max iteration status to a debug message.
  - remove patch 3 as it concerns both rs485 and iso7816 to think more.
  about the need of adding a lock or not.

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/parisc/include/uapi/asm/ioctls.h  |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 190 +++--
 drivers/tty/serial/atmel_serial.h  |   3 +-
 drivers/tty/serial/serial_core.c   |  60 +++
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 +++
 13 files changed, 277 insertions(+), 12 deletions(-)

-- 
2.12.2



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

2018-09-06 Thread Ludovic Desroches
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 | 190 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 2 files changed, 181 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 8e4428725848..a6a6c3334759 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;
@@ -163,6 +166,10 @@ struct atmel_uart_port {
unsigned intpending_status;
spinlock_t  lock_suspended;
 
+   /* ISO7816 */
+   unsigned intfidi_min;
+   unsigned intfidi_max;
+
 #ifdef CONFIG_PM
struct {
u32 cr;
@@ -362,6 +369,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;
+
+   if (iso7816conf->tg > 255) {
+   dev_err(port->dev, "ISO7816: Timeguard exceeding 
255\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T0 | ATMEL_US_DSNACK;
+   } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+  == SER_ISO7816_T(1)) {
+   mode |= ATMEL_US_USMODE_ISO7816_T1 | ATMEL_US_INACK;
+   } else {
+   dev_err(port->dev, "ISO7816: Type not supported\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   mode &= ~(ATMEL_US_USCLKS | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
+   /* 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 | 
ATMEL_US_MAX_ITER(3);
+
+   cd = atmel_calc_cd(port, iso7816conf);
+   fidi = atmel_calc_fidi(port, iso7816conf);
+   if (fidi == 0) {
+   dev_warn(port->dev, "ISO7816 fidi = 0, Generator 
generates no signal\n");
+   } else if (fidi < atmel_port->fidi_min
+  || fidi > atmel_port->fidi_max) {
+   dev_err(port->dev, "ISO7816 fidi = %u, value not 
supported\n&qu

[PATCH v4 1/2] tty/serial_core: add ISO7816 infrastructure

2018-09-06 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816
(smart cards).

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/parisc/include/uapi/asm/ioctls.h  |  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 11 files changed, 96 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/parisc/include/uapi/asm/ioctls.h 
b/arch/parisc/include/uapi/asm/ioctls.h
index aafb1c0ca0af..82d1148c6379 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -62,6 +62,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX   0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX0x5451
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa

[PATCH v4 1/2] tty/serial_core: add ISO7816 infrastructure

2018-09-06 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816
(smart cards).

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/parisc/include/uapi/asm/ioctls.h  |  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 11 files changed, 96 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/parisc/include/uapi/asm/ioctls.h 
b/arch/parisc/include/uapi/asm/ioctls.h
index aafb1c0ca0af..82d1148c6379 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -62,6 +62,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX   0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX0x5451
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa

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

2018-09-05 Thread Ludovic Desroches
On Wed, Sep 05, 2018 at 03:53:02PM +0200, Richard Genoud wrote:
> [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 ! :)

I won't try to convince you since we already use the ATMEL_US_VERSION.
IMHO we should use the compatible string from the beginning but we
didn't have the necessary DT experience at this time to figure out it
was probably better than relying on the version number which can be not
incrimented by error.

I'll check the values of the ATMEL_US_VERSION and use it if everything
is okay.

Regards

Ludovic


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

2018-09-05 Thread Ludovic Desroches
On Wed, Sep 05, 2018 at 03:53:02PM +0200, Richard Genoud wrote:
> [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 ! :)

I won't try to convince you since we already use the ATMEL_US_VERSION.
IMHO we should use the compatible string from the beginning but we
didn't have the necessary DT experience at this time to figure out it
was probably better than relying on the version number which can be not
incrimented by error.

I'll check the values of the ATMEL_US_VERSION and use it if everything
is okay.

Regards

Ludovic


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

2018-09-05 Thread Ludovic Desroches
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.

Regards

Ludovic


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

2018-09-05 Thread Ludovic Desroches
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.

Regards

Ludovic


Re: [PATCH 3/3] dmaengine: at_xdmac: move spin_lock_bh to spin_lock in tasklet

2018-08-20 Thread Ludovic Desroches
On Fri, Aug 17, 2018 at 06:03:43AM -0700, Barry Song wrote:
> as you are already in a tasklet, it is unnecessary to call spin_lock_bh.
> 
> Signed-off-by: Barry Song <21cn...@gmail.com>
Acked-by: Ludovic Desroches  

Thanks
> ---
>  drivers/dma/at_xdmac.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> index 4bf7256..4e55768 100644
> --- a/drivers/dma/at_xdmac.c
> +++ b/drivers/dma/at_xdmac.c
> @@ -1600,7 +1600,7 @@ static void at_xdmac_tasklet(unsigned long data)
>   if (atchan->status & AT_XDMAC_CIS_ROIS)
>   dev_err(chan2dev(>chan), "request overflow 
> error!!!");
>  
> - spin_lock_bh(>lock);
> + spin_lock(>lock);
>   desc = list_first_entry(>xfers_list,
>   struct at_xdmac_desc,
>   xfer_node);
> @@ -1610,7 +1610,7 @@ static void at_xdmac_tasklet(unsigned long data)
>   txd = >tx_dma_desc;
>  
>   at_xdmac_remove_xfer(atchan, desc);
> - spin_unlock_bh(>lock);
> + spin_unlock(>lock);
>  
>   if (!at_xdmac_chan_is_cyclic(atchan)) {
>   dma_cookie_complete(txd);
> -- 
> 2.7.4
> 


Re: [PATCH 3/3] dmaengine: at_xdmac: move spin_lock_bh to spin_lock in tasklet

2018-08-20 Thread Ludovic Desroches
On Fri, Aug 17, 2018 at 06:03:43AM -0700, Barry Song wrote:
> as you are already in a tasklet, it is unnecessary to call spin_lock_bh.
> 
> Signed-off-by: Barry Song <21cn...@gmail.com>
Acked-by: Ludovic Desroches  

Thanks
> ---
>  drivers/dma/at_xdmac.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> index 4bf7256..4e55768 100644
> --- a/drivers/dma/at_xdmac.c
> +++ b/drivers/dma/at_xdmac.c
> @@ -1600,7 +1600,7 @@ static void at_xdmac_tasklet(unsigned long data)
>   if (atchan->status & AT_XDMAC_CIS_ROIS)
>   dev_err(chan2dev(>chan), "request overflow 
> error!!!");
>  
> - spin_lock_bh(>lock);
> + spin_lock(>lock);
>   desc = list_first_entry(>xfers_list,
>   struct at_xdmac_desc,
>   xfer_node);
> @@ -1610,7 +1610,7 @@ static void at_xdmac_tasklet(unsigned long data)
>   txd = >tx_dma_desc;
>  
>   at_xdmac_remove_xfer(atchan, desc);
> - spin_unlock_bh(>lock);
> + spin_unlock(>lock);
>  
>   if (!at_xdmac_chan_is_cyclic(atchan)) {
>   dma_cookie_complete(txd);
> -- 
> 2.7.4
> 


[PATCH 1/2] mmc: atmel-mci: fix bad logic of sg_copy_{from,to}_buffer conversion

2018-08-20 Thread Ludovic Desroches
The conversion to sg_copy_{from,to}_buffer has been done in the wrong
way. sg_copy_to_buffer is a copy from an SG list to a linear buffer so
it can't replace memcpy(buf + offset, , remaining) where buf is
the virtual address of the SG. Same for sg_copy_to_buffer but in the
opposite way.

Signed-off-by: Ludovic Desroches 
Suggested-by: Douglas Gilbert 
Fixes: 5b4277814e3f ("mmc: atmel-mci: use sg_copy_{from,to}_buffer")
---
 drivers/mmc/host/atmel-mci.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 5aa2c9404e92..be53044086c7 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1976,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
do {
value = atmci_readl(host, ATMCI_RDR);
if (likely(offset + 4 <= sg->length)) {
-   sg_pcopy_to_buffer(sg, 1, , sizeof(u32), offset);
+   sg_pcopy_from_buffer(sg, 1, , sizeof(u32), 
offset);
 
offset += 4;
nbytes += 4;
@@ -1993,7 +1993,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
} else {
unsigned int remaining = sg->length - offset;
 
-   sg_pcopy_to_buffer(sg, 1, , remaining, offset);
+   sg_pcopy_from_buffer(sg, 1, , remaining, offset);
nbytes += remaining;
 
flush_dcache_page(sg_page(sg));
@@ -2003,7 +2003,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
goto done;
 
offset = 4 - remaining;
-   sg_pcopy_to_buffer(sg, 1, (u8 *) + remaining,
+   sg_pcopy_from_buffer(sg, 1, (u8 *) + remaining,
offset, 0);
nbytes += offset;
}
@@ -2042,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
 
do {
if (likely(offset + 4 <= sg->length)) {
-   sg_pcopy_from_buffer(sg, 1, , sizeof(u32), 
offset);
+   sg_pcopy_to_buffer(sg, 1, , sizeof(u32), offset);
atmci_writel(host, ATMCI_TDR, value);
 
offset += 4;
@@ -2059,7 +2059,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
unsigned int remaining = sg->length - offset;
 
value = 0;
-   sg_pcopy_from_buffer(sg, 1, , remaining, offset);
+   sg_pcopy_to_buffer(sg, 1, , remaining, offset);
nbytes += remaining;
 
host->sg = sg = sg_next(sg);
@@ -2070,7 +2070,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
}
 
offset = 4 - remaining;
-   sg_pcopy_from_buffer(sg, 1, (u8 *) + remaining,
+   sg_pcopy_to_buffer(sg, 1, (u8 *) + remaining,
offset, 0);
atmci_writel(host, ATMCI_TDR, value);
nbytes += offset;
-- 
2.12.2



[PATCH 2/2] mmc: android-goldfish: fix bad logic of sg_copy_{from,to}_buffer conversion

2018-08-20 Thread Ludovic Desroches
The conversion to sg_copy_{from,to}_buffer has been done in the wrong
way. sg_copy_to_buffer is a copy from an SG list to a linear buffer so
it can't replace memcpy(dest, host->virt_base, data->sg->length) where
dest is the virtual address of the SG. Same for sg_copy_from_buffer
but in the opposite way.

Signed-off-by: Ludovic Desroches 
Suggested-by: Douglas Gilbert 
Fixes: 53d7e098ba08 ("mmc: android-goldfish: use sg_copy_{from,to}_buffer")
---
 drivers/mmc/host/android-goldfish.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/android-goldfish.c 
b/drivers/mmc/host/android-goldfish.c
index 294de177632c..61e4e2a213c9 100644
--- a/drivers/mmc/host/android-goldfish.c
+++ b/drivers/mmc/host/android-goldfish.c
@@ -217,7 +217,7 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host 
*host,
 * We don't really have DMA, so we need
 * to copy from our platform driver buffer
 */
-   sg_copy_to_buffer(data->sg, 1, host->virt_base,
+   sg_copy_from_buffer(data->sg, 1, host->virt_base,
data->sg->length);
}
host->data->bytes_xfered += data->sg->length;
@@ -393,7 +393,7 @@ static void goldfish_mmc_prepare_data(struct 
goldfish_mmc_host *host,
 * We don't really have DMA, so we need to copy to our
 * platform driver buffer
 */
-   sg_copy_from_buffer(data->sg, 1, host->virt_base,
+   sg_copy_to_buffer(data->sg, 1, host->virt_base,
data->sg->length);
}
 }
-- 
2.12.2



[PATCH 1/2] mmc: atmel-mci: fix bad logic of sg_copy_{from,to}_buffer conversion

2018-08-20 Thread Ludovic Desroches
The conversion to sg_copy_{from,to}_buffer has been done in the wrong
way. sg_copy_to_buffer is a copy from an SG list to a linear buffer so
it can't replace memcpy(buf + offset, , remaining) where buf is
the virtual address of the SG. Same for sg_copy_to_buffer but in the
opposite way.

Signed-off-by: Ludovic Desroches 
Suggested-by: Douglas Gilbert 
Fixes: 5b4277814e3f ("mmc: atmel-mci: use sg_copy_{from,to}_buffer")
---
 drivers/mmc/host/atmel-mci.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 5aa2c9404e92..be53044086c7 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1976,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
do {
value = atmci_readl(host, ATMCI_RDR);
if (likely(offset + 4 <= sg->length)) {
-   sg_pcopy_to_buffer(sg, 1, , sizeof(u32), offset);
+   sg_pcopy_from_buffer(sg, 1, , sizeof(u32), 
offset);
 
offset += 4;
nbytes += 4;
@@ -1993,7 +1993,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
} else {
unsigned int remaining = sg->length - offset;
 
-   sg_pcopy_to_buffer(sg, 1, , remaining, offset);
+   sg_pcopy_from_buffer(sg, 1, , remaining, offset);
nbytes += remaining;
 
flush_dcache_page(sg_page(sg));
@@ -2003,7 +2003,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
goto done;
 
offset = 4 - remaining;
-   sg_pcopy_to_buffer(sg, 1, (u8 *) + remaining,
+   sg_pcopy_from_buffer(sg, 1, (u8 *) + remaining,
offset, 0);
nbytes += offset;
}
@@ -2042,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
 
do {
if (likely(offset + 4 <= sg->length)) {
-   sg_pcopy_from_buffer(sg, 1, , sizeof(u32), 
offset);
+   sg_pcopy_to_buffer(sg, 1, , sizeof(u32), offset);
atmci_writel(host, ATMCI_TDR, value);
 
offset += 4;
@@ -2059,7 +2059,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
unsigned int remaining = sg->length - offset;
 
value = 0;
-   sg_pcopy_from_buffer(sg, 1, , remaining, offset);
+   sg_pcopy_to_buffer(sg, 1, , remaining, offset);
nbytes += remaining;
 
host->sg = sg = sg_next(sg);
@@ -2070,7 +2070,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
}
 
offset = 4 - remaining;
-   sg_pcopy_from_buffer(sg, 1, (u8 *) + remaining,
+   sg_pcopy_to_buffer(sg, 1, (u8 *) + remaining,
offset, 0);
atmci_writel(host, ATMCI_TDR, value);
nbytes += offset;
-- 
2.12.2



[PATCH 2/2] mmc: android-goldfish: fix bad logic of sg_copy_{from,to}_buffer conversion

2018-08-20 Thread Ludovic Desroches
The conversion to sg_copy_{from,to}_buffer has been done in the wrong
way. sg_copy_to_buffer is a copy from an SG list to a linear buffer so
it can't replace memcpy(dest, host->virt_base, data->sg->length) where
dest is the virtual address of the SG. Same for sg_copy_from_buffer
but in the opposite way.

Signed-off-by: Ludovic Desroches 
Suggested-by: Douglas Gilbert 
Fixes: 53d7e098ba08 ("mmc: android-goldfish: use sg_copy_{from,to}_buffer")
---
 drivers/mmc/host/android-goldfish.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/android-goldfish.c 
b/drivers/mmc/host/android-goldfish.c
index 294de177632c..61e4e2a213c9 100644
--- a/drivers/mmc/host/android-goldfish.c
+++ b/drivers/mmc/host/android-goldfish.c
@@ -217,7 +217,7 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host 
*host,
 * We don't really have DMA, so we need
 * to copy from our platform driver buffer
 */
-   sg_copy_to_buffer(data->sg, 1, host->virt_base,
+   sg_copy_from_buffer(data->sg, 1, host->virt_base,
data->sg->length);
}
host->data->bytes_xfered += data->sg->length;
@@ -393,7 +393,7 @@ static void goldfish_mmc_prepare_data(struct 
goldfish_mmc_host *host,
 * We don't really have DMA, so we need to copy to our
 * platform driver buffer
 */
-   sg_copy_from_buffer(data->sg, 1, host->virt_base,
+   sg_copy_to_buffer(data->sg, 1, host->virt_base,
data->sg->length);
}
 }
-- 
2.12.2



[PATCH 0/2] atmel-mci and maybe android-goldfish broken on 4.18

2018-08-20 Thread Ludovic Desroches
Hi,

Dougas Gilbert noticed that atmel-mci was broken with the 4.18 release.
He found the culprit commit which is 5b4277814e3fd
("[PATCH 2/7] mmc: atmel-mci: use sg_copy_{from,to}_buffer"). The from/to
logic was inverted: sg_copy_to_buffer copies from an SG list to a linear
buffer so it can't replace a memcpy where the destination is the virtual
address of an SG buffer.

This patch was part of "make more host drivers highmem safe v2". It seems
there is the same logical error within the android-goldfish driver but I
couldn't check it on real hardware.

Ludovic Desroches (2):
  mmc: atmel-mci: fix bad logic of sg_copy_{from,to}_buffer conversion
  mmc: android-goldfish: fix bad logic of sg_copy_{from,to}_buffer
conversion

 drivers/mmc/host/android-goldfish.c |  4 ++--
 drivers/mmc/host/atmel-mci.c| 12 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

-- 
2.12.2



[PATCH 0/2] atmel-mci and maybe android-goldfish broken on 4.18

2018-08-20 Thread Ludovic Desroches
Hi,

Dougas Gilbert noticed that atmel-mci was broken with the 4.18 release.
He found the culprit commit which is 5b4277814e3fd
("[PATCH 2/7] mmc: atmel-mci: use sg_copy_{from,to}_buffer"). The from/to
logic was inverted: sg_copy_to_buffer copies from an SG list to a linear
buffer so it can't replace a memcpy where the destination is the virtual
address of an SG buffer.

This patch was part of "make more host drivers highmem safe v2". It seems
there is the same logical error within the android-goldfish driver but I
couldn't check it on real hardware.

Ludovic Desroches (2):
  mmc: atmel-mci: fix bad logic of sg_copy_{from,to}_buffer conversion
  mmc: android-goldfish: fix bad logic of sg_copy_{from,to}_buffer
conversion

 drivers/mmc/host/android-goldfish.c |  4 ++--
 drivers/mmc/host/atmel-mci.c| 12 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

-- 
2.12.2



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

2018-08-09 Thread Ludovic Desroches
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.


Regards

Ludovic


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

2018-08-09 Thread Ludovic Desroches
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.


Regards

Ludovic


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

2018-08-07 Thread Ludovic Desroches
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,
+};
+
 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;
+
+   if (iso7816conf->tg > 255) {
+   dev_err(port->dev, "ISO7816: Timeguard exceeding 
255\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if ((iso7816conf->flags & SER_IS

[PATCH v3 1/2] tty/serial_core: add ISO7816 infrastructure

2018-08-07 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/parisc/include/uapi/asm/ioctls.h  |  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 11 files changed, 96 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/parisc/include/uapi/asm/ioctls.h 
b/arch/parisc/include/uapi/asm/ioctls.h
index aafb1c0ca0af..82d1148c6379 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -62,6 +62,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX   0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX0x5451
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa/include/uapi

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

2018-08-07 Thread Ludovic Desroches
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,
+};
+
 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;
+
+   if (iso7816conf->tg > 255) {
+   dev_err(port->dev, "ISO7816: Timeguard exceeding 
255\n");
+   memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if ((iso7816conf->flags & SER_IS

[PATCH v3 1/2] tty/serial_core: add ISO7816 infrastructure

2018-08-07 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/parisc/include/uapi/asm/ioctls.h  |  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 11 files changed, 96 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/parisc/include/uapi/asm/ioctls.h 
b/arch/parisc/include/uapi/asm/ioctls.h
index aafb1c0ca0af..82d1148c6379 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -62,6 +62,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX   0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX0x5451
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa/include/uapi

[PATCH v3 0/2] add ISO7816 support

2018-08-07 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard
  - keep max iteration hard coded. Will see later if the user need to set
  this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function
  - use IOCTL macros to generate the IOCTL number
  - check that reserved field is not used
  - remove debug logs
  - check that the iso7816_config is right before doing any action
  - change the error from nack and max iteration status to a debug message
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
  about the need of adding a lock or not


Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/parisc/include/uapi/asm/ioctls.h  |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 211 ++---
 drivers/tty/serial/atmel_serial.h  |   6 +-
 drivers/tty/serial/serial_core.c   |  60 ++
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 +++
 13 files changed, 297 insertions(+), 16 deletions(-)

-- 
2.12.2



[PATCH v3 0/2] add ISO7816 support

2018-08-07 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v3
  - add IOCTLs to parisc arch.
  - rework atmel_config_iso7816 according to the comments by Richard
  - keep max iteration hard coded. Will see later if the user need to set
  this value. It may also concern the normal/inverse mode.
  - improve the checking of the value from the user space.
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function
  - use IOCTL macros to generate the IOCTL number
  - check that reserved field is not used
  - remove debug logs
  - check that the iso7816_config is right before doing any action
  - change the error from nack and max iteration status to a debug message
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
  about the need of adding a lock or not


Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/parisc/include/uapi/asm/ioctls.h  |   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 211 ++---
 drivers/tty/serial/atmel_serial.h  |   6 +-
 drivers/tty/serial/serial_core.c   |  60 ++
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 +++
 13 files changed, 297 insertions(+), 16 deletions(-)

-- 
2.12.2



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

2018-08-03 Thread Ludovic Desroches
Hi Richard,

On Fri, Jul 27, 2018 at 04:39:17PM +0200, Richard Genoud wrote:
> 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.
> 

Ok

> > +
> > +   /* NACK configuration */
> > +   if ((is

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

2018-08-03 Thread Ludovic Desroches
Hi Richard,

On Fri, Jul 27, 2018 at 04:39:17PM +0200, Richard Genoud wrote:
> 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.
> 

Ok

> > +
> > +   /* NACK configuration */
> > +   if ((is

Re: [PATCH v3 0/3] i2c: at91: slave mode support

2018-07-30 Thread Ludovic Desroches
On Sat, Jul 21, 2018 at 12:41:41AM +0200, Wolfram Sang wrote:
> > [Ludovic Desroches]
> > Changes in v3:
> >  - rebase (cherry-pick was enough)
> 
> Thanks for the rebase. I wonder, though, I recall to had more
> complicated issues. However...
> 
> >  - fix checkpatch errors
> >  - tests:
> >- hangs with a SAMA5D4 (master and slave on different busses) after about
> >100 transfers. It's the firs time I do this test.
> >- some mismatches with a SAMA5D4 as slave and a SAMA5D2 as master
> >I don't know if it's a regression. I don't remember having seen this
> >behavior previously.
> >I think it's worth taking those patches even if there are some possible
> >bugs. It'll allow to get more people using it and so to consolidate the
> >slave mode support.
> 
> I really want to see those patches go upstream, too. But I am also not a
> big fan of delivering the user something with known issues. Especially
> not when they affect the main feature to be added. My rationale here is
> that someone who is able to fix the issues remaining will also be able
> to pick up and apply patches.
> 
> Maybe, maybe if it was to be enabled by a special
> I2C_AT91_SLAVE_EXPERIMANTEL symbol with lots of explanations. I need to
> think twice about that, though.
> 

I understand your point. The experimental mentionning could be a good
trade-off. Let me know once you make up your mind.

> Speaking of Kconfig, I think this series needs to place a
> 
>   select I2C_SLAVE
> 
> somewhere.
> 

Ok I'll update it if we go further with this set of patches.

Regards

Ludovic


Re: [PATCH v3 0/3] i2c: at91: slave mode support

2018-07-30 Thread Ludovic Desroches
On Sat, Jul 21, 2018 at 12:41:41AM +0200, Wolfram Sang wrote:
> > [Ludovic Desroches]
> > Changes in v3:
> >  - rebase (cherry-pick was enough)
> 
> Thanks for the rebase. I wonder, though, I recall to had more
> complicated issues. However...
> 
> >  - fix checkpatch errors
> >  - tests:
> >- hangs with a SAMA5D4 (master and slave on different busses) after about
> >100 transfers. It's the firs time I do this test.
> >- some mismatches with a SAMA5D4 as slave and a SAMA5D2 as master
> >I don't know if it's a regression. I don't remember having seen this
> >behavior previously.
> >I think it's worth taking those patches even if there are some possible
> >bugs. It'll allow to get more people using it and so to consolidate the
> >slave mode support.
> 
> I really want to see those patches go upstream, too. But I am also not a
> big fan of delivering the user something with known issues. Especially
> not when they affect the main feature to be added. My rationale here is
> that someone who is able to fix the issues remaining will also be able
> to pick up and apply patches.
> 
> Maybe, maybe if it was to be enabled by a special
> I2C_AT91_SLAVE_EXPERIMANTEL symbol with lots of explanations. I need to
> think twice about that, though.
> 

I understand your point. The experimental mentionning could be a good
trade-off. Let me know once you make up your mind.

> Speaking of Kconfig, I think this series needs to place a
> 
>   select I2C_SLAVE
> 
> somewhere.
> 

Ok I'll update it if we go further with this set of patches.

Regards

Ludovic


Re: [PATCH v2 0/2] add ISO7816 support

2018-07-19 Thread Ludovic Desroches
Hi Neil,

On Thu, Jul 19, 2018 at 10:59:47AM +0200, Neil Armstrong wrote:
> Hi Ludovic,
> 
> On 19/07/2018 10:47, Ludovic Desroches wrote:
> > Hi,
> > 
> > This patchset adds support for the ISO7816 standard. The USART devices in
> > Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
> > the CLK and I/O signals of a smart card.
> 
> Wow, I would have loved to have this at the time...
> I'm curious, do you have an example of userspace code using this ?
> The ATR rx needs a very weird handling, I'm curious how you managed it.
> 

Unfortunately, I have nothing I can give you at the moment. I am doing
some experiments. Before going further, I need to have the interface
with the kernel accepted.

Of course, I can give more details about the experiments I am doing.
First of all, I am not used to ISO7816 so every feedback are
appreciated.

On the userspace part, there is the PCSC Lite library. It needs a
userspace driver. From what I've seen, most of the readers are managed
by the CCID driver. This driver handle different hardware capabilities.
Some hardware are very close to what we provide with our SoC ie. just
sending the data on the line and not manage the procedure bytes.

The CCID driver includes a lot of things related to the ISO7816 protocol
so I tried to plug my code into it to reuse this code. The issue is that I am
not a CCID device. At the moment, I am writing my own PCSC driver and I am
copying/pasting code I need. The USART only manages the CLK and I/O
signals. Others one are handled by the PCSC driver with the help of
GPIOs.

At a time, I was thinking about a CCID driver (which interprets the CCID
header and interacts with the device handling ISO7816) in the kernel to easily
interface with the PCSC CCID driver but I am not sure it's the right way
to go.

Regards

Ludovic


> Thanks,
> Neil
> 
> > 
> > Changes:
> > - v2
> >   - uart_get_iso7816_config: check there is an iso7816_config function
> >   - use IOCTL macros to generate the IOCTL number
> >   - check that reserved field is not used
> >   - remove debug logs
> >   - check that the iso7816_config is right before doing any action
> >   - change the error from nack and max iteration status to a debug message
> >   - remove patch 3 as it concerns both rs485 and iso7816 to think more
> >   about the need of adding a lock or not
> > 
> > Nicolas Ferre (2):
> >   tty/serial_core: add ISO7816 infrastructure
> >   tty/serial: atmel: add ISO7816 support
> > 
> >  arch/alpha/include/uapi/asm/ioctls.h   |   2 +
> >  arch/mips/include/uapi/asm/ioctls.h|   2 +
> >  arch/powerpc/include/uapi/asm/ioctls.h |   2 +
> >  arch/sh/include/uapi/asm/ioctls.h  |   2 +
> >  arch/sparc/include/uapi/asm/ioctls.h   |   2 +
> >  arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
> >  drivers/tty/serial/atmel_serial.c  | 170 
> > +++--
> >  drivers/tty/serial/atmel_serial.h  |   3 +-
> >  drivers/tty/serial/serial_core.c   |  60 
> >  include/linux/serial_core.h|   3 +
> >  include/uapi/asm-generic/ioctls.h  |   2 +
> >  include/uapi/linux/serial.h|  17 
> >  12 files changed, 256 insertions(+), 11 deletions(-)
> > 
> 


Re: [PATCH v2 0/2] add ISO7816 support

2018-07-19 Thread Ludovic Desroches
Hi Neil,

On Thu, Jul 19, 2018 at 10:59:47AM +0200, Neil Armstrong wrote:
> Hi Ludovic,
> 
> On 19/07/2018 10:47, Ludovic Desroches wrote:
> > Hi,
> > 
> > This patchset adds support for the ISO7816 standard. The USART devices in
> > Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
> > the CLK and I/O signals of a smart card.
> 
> Wow, I would have loved to have this at the time...
> I'm curious, do you have an example of userspace code using this ?
> The ATR rx needs a very weird handling, I'm curious how you managed it.
> 

Unfortunately, I have nothing I can give you at the moment. I am doing
some experiments. Before going further, I need to have the interface
with the kernel accepted.

Of course, I can give more details about the experiments I am doing.
First of all, I am not used to ISO7816 so every feedback are
appreciated.

On the userspace part, there is the PCSC Lite library. It needs a
userspace driver. From what I've seen, most of the readers are managed
by the CCID driver. This driver handle different hardware capabilities.
Some hardware are very close to what we provide with our SoC ie. just
sending the data on the line and not manage the procedure bytes.

The CCID driver includes a lot of things related to the ISO7816 protocol
so I tried to plug my code into it to reuse this code. The issue is that I am
not a CCID device. At the moment, I am writing my own PCSC driver and I am
copying/pasting code I need. The USART only manages the CLK and I/O
signals. Others one are handled by the PCSC driver with the help of
GPIOs.

At a time, I was thinking about a CCID driver (which interprets the CCID
header and interacts with the device handling ISO7816) in the kernel to easily
interface with the PCSC CCID driver but I am not sure it's the right way
to go.

Regards

Ludovic


> Thanks,
> Neil
> 
> > 
> > Changes:
> > - v2
> >   - uart_get_iso7816_config: check there is an iso7816_config function
> >   - use IOCTL macros to generate the IOCTL number
> >   - check that reserved field is not used
> >   - remove debug logs
> >   - check that the iso7816_config is right before doing any action
> >   - change the error from nack and max iteration status to a debug message
> >   - remove patch 3 as it concerns both rs485 and iso7816 to think more
> >   about the need of adding a lock or not
> > 
> > Nicolas Ferre (2):
> >   tty/serial_core: add ISO7816 infrastructure
> >   tty/serial: atmel: add ISO7816 support
> > 
> >  arch/alpha/include/uapi/asm/ioctls.h   |   2 +
> >  arch/mips/include/uapi/asm/ioctls.h|   2 +
> >  arch/powerpc/include/uapi/asm/ioctls.h |   2 +
> >  arch/sh/include/uapi/asm/ioctls.h  |   2 +
> >  arch/sparc/include/uapi/asm/ioctls.h   |   2 +
> >  arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
> >  drivers/tty/serial/atmel_serial.c  | 170 
> > +++--
> >  drivers/tty/serial/atmel_serial.h  |   3 +-
> >  drivers/tty/serial/serial_core.c   |  60 
> >  include/linux/serial_core.h|   3 +
> >  include/uapi/asm-generic/ioctls.h  |   2 +
> >  include/uapi/linux/serial.h|  17 
> >  12 files changed, 256 insertions(+), 11 deletions(-)
> > 
> 


[PATCH v2 1/2] tty/serial_core: add ISO7816 infrastructure

2018-07-19 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 10 files changed, 94 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h 
b/arch/xtensa/include/uapi/asm/ioctls.h
index ec43609cbfc5..6d4a87296c95 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -107,6 +107,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83)
 #define TIOCSERGWILD   _IOR('T', 84,  int)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9c14a453f73c..af8d5b12fba9 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c

[PATCH v2 0/2] add ISO7816 support

2018-07-19 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function
  - use IOCTL macros to generate the IOCTL number
  - check that reserved field is not used
  - remove debug logs
  - check that the iso7816_config is right before doing any action
  - change the error from nack and max iteration status to a debug message
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
  about the need of adding a lock or not

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 170 +++--
 drivers/tty/serial/atmel_serial.h  |   3 +-
 drivers/tty/serial/serial_core.c   |  60 
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 
 12 files changed, 256 insertions(+), 11 deletions(-)

-- 
2.12.2



[PATCH v2 1/2] tty/serial_core: add ISO7816 infrastructure

2018-07-19 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
Signed-off-by: Ludovic Desroches 
---
 arch/alpha/include/uapi/asm/ioctls.h   |  2 ++
 arch/mips/include/uapi/asm/ioctls.h|  2 ++
 arch/powerpc/include/uapi/asm/ioctls.h |  2 ++
 arch/sh/include/uapi/asm/ioctls.h  |  2 ++
 arch/sparc/include/uapi/asm/ioctls.h   |  2 ++
 arch/xtensa/include/uapi/asm/ioctls.h  |  2 ++
 drivers/tty/serial/serial_core.c   | 60 ++
 include/linux/serial_core.h|  3 ++
 include/uapi/asm-generic/ioctls.h  |  2 ++
 include/uapi/linux/serial.h| 17 ++
 10 files changed, 94 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/ioctls.h 
b/arch/alpha/include/uapi/asm/ioctls.h
index 3729d92d3fa8..1e9121c9b3c7 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/mips/include/uapi/asm/ioctls.h 
b/arch/mips/include/uapi/asm/ioctls.h
index 890245a9f0c4..16aa8a766aec 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY  0x5480  /* become controlling tty */
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h 
b/arch/powerpc/include/uapi/asm/ioctls.h
index 41b1a5c15734..2c145da3b774 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -102,6 +102,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
diff --git a/arch/sh/include/uapi/asm/ioctls.h 
b/arch/sh/include/uapi/asm/ioctls.h
index cc62f6f98103..11866d4f60e1 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h 
b/arch/sparc/include/uapi/asm/ioctls.h
index 2df52711e170..7fd2f5873c9e 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -27,6 +27,8 @@
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h 
b/arch/xtensa/include/uapi/asm/ioctls.h
index ec43609cbfc5..6d4a87296c95 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -107,6 +107,8 @@
 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL  _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER_IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83)
 #define TIOCSERGWILD   _IOR('T', 84,  int)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9c14a453f73c..af8d5b12fba9 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c

[PATCH v2 0/2] add ISO7816 support

2018-07-19 Thread Ludovic Desroches
Hi,

This patchset adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Changes:
- v2
  - uart_get_iso7816_config: check there is an iso7816_config function
  - use IOCTL macros to generate the IOCTL number
  - check that reserved field is not used
  - remove debug logs
  - check that the iso7816_config is right before doing any action
  - change the error from nack and max iteration status to a debug message
  - remove patch 3 as it concerns both rs485 and iso7816 to think more
  about the need of adding a lock or not

Nicolas Ferre (2):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support

 arch/alpha/include/uapi/asm/ioctls.h   |   2 +
 arch/mips/include/uapi/asm/ioctls.h|   2 +
 arch/powerpc/include/uapi/asm/ioctls.h |   2 +
 arch/sh/include/uapi/asm/ioctls.h  |   2 +
 arch/sparc/include/uapi/asm/ioctls.h   |   2 +
 arch/xtensa/include/uapi/asm/ioctls.h  |   2 +
 drivers/tty/serial/atmel_serial.c  | 170 +++--
 drivers/tty/serial/atmel_serial.h  |   3 +-
 drivers/tty/serial/serial_core.c   |  60 
 include/linux/serial_core.h|   3 +
 include/uapi/asm-generic/ioctls.h  |   2 +
 include/uapi/linux/serial.h|  17 
 12 files changed, 256 insertions(+), 11 deletions(-)

-- 
2.12.2



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

2018-07-19 Thread Ludovic Desroches
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);
+
+   /* NACK configuration */
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0))
+   mode |= ATMEL_US_DSNACK;
+   else
+   mode |= ATMEL_US_INACK;
+   /* 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);
+
+   cd = atmel_calc_cd(port, iso7816conf);
+   fidi = atmel_calc_fidi(port, iso7816conf);
+   if (fidi < 0) {
+   dev_warn(port->dev, "ISO7816 fidi = 0, Generator 
generates no signal\n");
+   } else if (fidi == 1 || fidi == 2) {
+   dev_err(port->dev, "ISO7816 fidi = %u, value not 
supported\n", fidi);
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if (!(port->iso7816.flags & SER_ISO7816_ENABLED)) {
+   /* port 

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

2018-07-19 Thread Ludovic Desroches
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);
+
+   /* NACK configuration */
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0))
+   mode |= ATMEL_US_DSNACK;
+   else
+   mode |= ATMEL_US_INACK;
+   /* 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);
+
+   cd = atmel_calc_cd(port, iso7816conf);
+   fidi = atmel_calc_fidi(port, iso7816conf);
+   if (fidi < 0) {
+   dev_warn(port->dev, "ISO7816 fidi = 0, Generator 
generates no signal\n");
+   } else if (fidi == 1 || fidi == 2) {
+   dev_err(port->dev, "ISO7816 fidi = %u, value not 
supported\n", fidi);
+   ret = -EINVAL;
+   goto err_out;
+   }
+
+   if (!(port->iso7816.flags & SER_ISO7816_ENABLED)) {
+   /* port 

[PATCH v3 3/3] i2c: at91: added slave mode support

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

Slave mode driver is based on the concept of i2c-designware driver.

Signed-off-by: Juergen Fitschen 
Signed-off-by: Ludovic Desroches 
---
 drivers/i2c/busses/Makefile |   3 +
 drivers/i2c/busses/i2c-at91-core.c  |  13 +++-
 drivers/i2c/busses/i2c-at91-slave.c | 147 
 drivers/i2c/busses/i2c-at91.h   |  30 +++-
 4 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-slave.c

diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 378daa860ed4..1ab8b51a7657 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -35,6 +35,9 @@ obj-$(CONFIG_I2C_ALTERA)  += i2c-altera.o
 obj-$(CONFIG_I2C_ASPEED)   += i2c-aspeed.o
 obj-$(CONFIG_I2C_AT91) += i2c-at91.o
 i2c-at91-objs  := i2c-at91-core.o i2c-at91-master.o
+ifeq ($(CONFIG_I2C_SLAVE),y)
+   i2c-at91-objs   += i2c-at91-slave.o
+endif
 obj-$(CONFIG_I2C_AU1550)   += i2c-au1550.o
 obj-$(CONFIG_I2C_AXXIA)+= i2c-axxia.o
 obj-$(CONFIG_I2C_BCM2835)  += i2c-bcm2835.o
diff --git a/drivers/i2c/busses/i2c-at91-core.c 
b/drivers/i2c/busses/i2c-at91-core.c
index 5d9c6c81e6ab..c74283fa567f 100644
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -60,8 +60,10 @@ void at91_init_twi_bus(struct at91_twi_dev *dev)
 {
at91_disable_twi_interrupts(dev);
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
-
-   at91_init_twi_bus_master(dev);
+   if (dev->slave_detected)
+   at91_init_twi_bus_slave(dev);
+   else
+   at91_init_twi_bus_master(dev);
 }
 
 static struct at91_twi_pdata at91rm9200_config = {
@@ -243,7 +245,12 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->adapter.timeout = AT91_I2C_TIMEOUT;
dev->adapter.dev.of_node = pdev->dev.of_node;
 
-   rc = at91_twi_probe_master(pdev, phy_addr, dev);
+   dev->slave_detected = i2c_detect_slave_mode(>dev);
+
+   if (dev->slave_detected)
+   rc = at91_twi_probe_slave(pdev, phy_addr, dev);
+   else
+   rc = at91_twi_probe_master(pdev, phy_addr, dev);
if (rc)
return rc;
 
diff --git a/drivers/i2c/busses/i2c-at91-slave.c 
b/drivers/i2c/busses/i2c-at91-slave.c
new file mode 100644
index ..4b4808e0c8f7
--- /dev/null
+++ b/drivers/i2c/busses/i2c-at91-slave.c
@@ -0,0 +1,147 @@
+/*
+ *  i2c slave support for Atmel's AT91 Two-Wire Interface (TWI)
+ *
+ *  Copyright (C) 2017 Juergen Fitschen 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "i2c-at91.h"
+
+static irqreturn_t atmel_twi_interrupt_slave(int irq, void *dev_id)
+{
+   struct at91_twi_dev *dev = dev_id;
+   const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
+   const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
+   u8 value;
+
+   if (!irqstatus)
+   return IRQ_NONE;
+
+   /* slave address has been detected on I2C bus */
+   if (irqstatus & AT91_TWI_SVACC) {
+   if (status & AT91_TWI_SVREAD) {
+   i2c_slave_event(dev->slave,
+   I2C_SLAVE_READ_REQUESTED, );
+   writeb_relaxed(value, dev->base + AT91_TWI_THR);
+   at91_twi_write(dev, AT91_TWI_IER,
+  AT91_TWI_TXRDY | AT91_TWI_EOSACC);
+   } else {
+   i2c_slave_event(dev->slave,
+   I2C_SLAVE_WRITE_REQUESTED, );
+   at91_twi_write(dev, AT91_TWI_IER,
+  AT91_TWI_RXRDY | AT91_TWI_EOSACC);
+   }
+   at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_SVACC);
+   }
+
+   /* byte transmitted to remote master */
+   if (irqstatus & AT91_TWI_TXRDY) {
+   i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED, );
+   writeb_relaxed(value, dev->base + AT91_TWI_THR);
+   }
+
+   /* byte received from remote master */
+   if (irqstatus & AT91_TWI_RXRDY) {
+   value = readb_relaxed(dev->base + AT91_TWI_RHR);
+   i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED, );
+   }
+
+   /* master sent stop */
+   if (irqstatus & AT91_TWI_EOSACC) {
+   at91_twi_write(dev, AT91_TWI_IDR,
+  AT91_TWI_TXRDY | AT91_TWI_RXRDY | 
AT91_TWI_EOSACC);
+   at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_SVACC);
+   i2c_slave

[PATCH v3 1/3] i2c: at91: segregate master mode specific code from probe and init func

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

In order to implement slave mode support for the at91 hardware we have to
segregate all master mode specific function parts from the general parts.
The upcoming slave mode patch will call its sepcific probe resp. init
function instead of the master mode functions after the shared general
code has been executed.

This concept has been influenced by the i2c-designware driver.

Signed-off-by: Juergen Fitschen 
Signed-off-by: Ludovic Desroches 
---
 drivers/i2c/busses/i2c-at91.c | 90 ++-
 1 file changed, 55 insertions(+), 35 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 3f3e8b3bf5ff..bc74184462c6 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -174,10 +174,8 @@ static void at91_twi_irq_restore(struct at91_twi_dev *dev)
at91_twi_write(dev, AT91_TWI_IER, dev->imr);
 }
 
-static void at91_init_twi_bus(struct at91_twi_dev *dev)
+static void at91_init_twi_bus_master(struct at91_twi_dev *dev)
 {
-   at91_disable_twi_interrupts(dev);
-   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
/* FIFO should be enabled immediately after the software reset */
if (dev->fifo_size)
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);
@@ -186,6 +184,14 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev)
at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
 }
 
+static void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+   at91_disable_twi_interrupts(dev);
+   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+
+   at91_init_twi_bus_master(dev);
+}
+
 /*
  * Calculate symmetric clock as stated in datasheet:
  * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
@@ -1046,18 +1052,56 @@ static struct at91_twi_pdata *at91_twi_get_driver_data(
return (struct at91_twi_pdata *) 
platform_get_device_id(pdev)->driver_data;
 }
 
+static int at91_twi_probe_master(struct platform_device *pdev,
+u32 phy_addr, struct at91_twi_dev *dev)
+{
+   int rc;
+   u32 bus_clk_rate;
+
+   init_completion(>cmd_complete);
+
+   rc = devm_request_irq(>dev, dev->irq, atmel_twi_interrupt, 0,
+ dev_name(dev->dev), dev);
+   if (rc) {
+   dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
+   return rc;
+   }
+
+   if (dev->dev->of_node) {
+   rc = at91_twi_configure_dma(dev, phy_addr);
+   if (rc == -EPROBE_DEFER)
+   return rc;
+   }
+
+   if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size",
+ >fifo_size)) {
+   dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
+   }
+
+   rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
+ _clk_rate);
+   if (rc)
+   bus_clk_rate = DEFAULT_TWI_CLK_HZ;
+
+   at91_calc_twi_clock(dev, bus_clk_rate);
+
+   dev->adapter.algo = _twi_algorithm;
+   dev->adapter.quirks = _twi_quirks;
+
+   return 0;
+}
+
 static int at91_twi_probe(struct platform_device *pdev)
 {
struct at91_twi_dev *dev;
struct resource *mem;
int rc;
u32 phy_addr;
-   u32 bus_clk_rate;
 
dev = devm_kzalloc(>dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
-   init_completion(>cmd_complete);
+
dev->dev = >dev;
 
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1077,13 +1121,6 @@ static int at91_twi_probe(struct platform_device *pdev)
if (dev->irq < 0)
return dev->irq;
 
-   rc = devm_request_irq(>dev, dev->irq, atmel_twi_interrupt, 0,
-dev_name(dev->dev), dev);
-   if (rc) {
-   dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
-   return rc;
-   }
-
platform_set_drvdata(pdev, dev);
 
dev->clk = devm_clk_get(dev->dev, NULL);
@@ -1095,38 +1132,21 @@ static int at91_twi_probe(struct platform_device *pdev)
if (rc)
return rc;
 
-   if (dev->dev->of_node) {
-   rc = at91_twi_configure_dma(dev, phy_addr);
-   if (rc == -EPROBE_DEFER) {
-   clk_disable_unprepare(dev->clk);
-   return rc;
-   }
-   }
-
-   if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size",
- >fifo_size)) {
-   dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
-   }
-
-   rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
- 

[PATCH v3 0/3] i2c: at91: slave mode support

2018-07-16 Thread Ludovic Desroches
[Ludovic Desroches: see 'Changes in v3' section]

Based on the discussion we had on the i2c-linux list [1], I wrote a patch for
AT91 hardware and tried to fulfill the Linux I2C slave interface description
[2] as good as possible. This enables aforementioned hardware to act as an I2C
slave that can be accessed by a remote I2C master.

I have tested this patchset successfully on an ATSAMA5D27.

 ^  3.3V   ^  3.3V
+---+| | +---+
| Slave: ATSAMA5D27 |   +-+   +-+| Master: ATSAMA5D35|
| with i2c-slave-eeprom |   | | 100k  | | 100k   | with i2cset   |
+---+-+-+   +-+   +-++-+-+---+
| |  | |   | |
| +--+-|---(SDA)---+ |
+--+---(SCL)-+

Schematic: Connection of slave and master with 100kOhm pullup resistors.

On the master the following BASH script has been used to stress the slave.

root@emblinux:~# cat ./stress.sh
#!/bin/bash
I=0
while true
do
if i2cset -y -r 1 0x64 0 $I w | grep mismatch
then
echo "$(date): Error in transmission ${I}"
fi
((I++))
if [ $I -eq 65536 ]
then
I=0
echo "$(date): Sent 65536 transmissions"
fi
done

After running the script for some time I had the following output. To me this
looks promising :)

root@emblinux:~# ./stress.sh
Thu Nov  9 13:58:45 CTE 2017: Sent 65536 transmissions
Thu Nov  9 14:35:20 CTE 2017: Sent 65536 transmissions
Thu Nov  9 15:12:11 CTE 2017: Sent 65536 transmissions
Thu Nov  9 15:49:04 CTE 2017: Sent 65536 transmissions
Thu Nov  9 16:26:00 CTE 2017: Sent 65536 transmissions
Thu Nov  9 17:03:07 UTC 2017: Sent 65536 transmissions
Thu Nov  9 17:40:15 UTC 2017: Sent 65536 transmissions

If you have some hardware with an at91-i2c interface included at hand, 
I really
would appreciate if you can run the test script on your hardware and 
test this
driver.

Best regards
  Juergen


[Ludovic Desroches]
Changes in v3:
 - rebase (cherry-pick was enough)
 - fix checkpatch errors
 - tests:
   - hangs with a SAMA5D4 (master and slave on different busses) after about
   100 transfers. It's the firs time I do this test.
   - some mismatches with a SAMA5D4 as slave and a SAMA5D2 as master
   I don't know if it's a regression. I don't remember having seen this
   behavior previously.
   I think it's worth taking those patches even if there are some possible
   bugs. It'll allow to get more people using it and so to consolidate the
   slave mode support.

Changes in v2:
 - Implemented all suggestions made by Ludovic. (Thank you!)
 - Reworked the IRQ handler completely. Have a look in patch 3 fort further
   details.

[1] https://marc.info/?t=15082400481=1=1
[2] https://www.kernel.org/doc/Documentation/i2c/slave-interface

Juergen Fitschen (3):
  i2c: at91: segregate master mode specific code from probe and init
func
  i2c: at91: split driver into core and master file
  i2c: at91: added slave mode support

 MAINTAINERS|   3 +-
 drivers/i2c/busses/Makefile|   4 +
 drivers/i2c/busses/i2c-at91-core.c | 380 +
 .../i2c/busses/{i2c-at91.c => i2c-at91-master.c}   | 453 +
 drivers/i2c/busses/i2c-at91-slave.c| 147 +++
 drivers/i2c/busses/i2c-at91.h  | 179 
 6 files changed, 719 insertions(+), 447 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-core.c
 rename drivers/i2c/busses/{i2c-at91.c => i2c-at91-master.c} (67%)
 create mode 100644 drivers/i2c/busses/i2c-at91-slave.c
 create mode 100644 drivers/i2c/busses/i2c-at91.h

-- 
2.12.2



[PATCH v3 2/3] i2c: at91: split driver into core and master file

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

The single file i2c-at91.c has been split into core code (i2c-at91-core.c)
and master mode specific code (i2c-at91-master.c). This should enhance
maintainability and reduce ifdeffery for slave mode related code.

The code itself hasn't been touched. Shared functions only had to be made
non-static. Furthermore, includes have been cleaned up.

Signed-off-by: Juergen Fitschen 
[ludovic.desroc...@microchip.com: fix checkpatch errors]
Signed-off-by: Ludovic Desroches 
---
 MAINTAINERS|   3 +-
 drivers/i2c/busses/Makefile|   1 +
 drivers/i2c/busses/i2c-at91-core.c | 373 
 .../i2c/busses/{i2c-at91.c => i2c-at91-master.c}   | 467 +
 drivers/i2c/busses/i2c-at91.h  | 151 +++
 5 files changed, 531 insertions(+), 464 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-core.c
 rename drivers/i2c/busses/{i2c-at91.c => i2c-at91-master.c} (67%)
 create mode 100644 drivers/i2c/busses/i2c-at91.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e98e206b0d..14a87595b482 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2426,7 +2426,8 @@ ATMEL I2C DRIVER
 M: Ludovic Desroches 
 L: linux-...@vger.kernel.org
 S: Supported
-F: drivers/i2c/busses/i2c-at91.c
+F: drivers/i2c/busses/i2c-at91.h
+F: drivers/i2c/busses/i2c-at91-*.c
 
 ATMEL ISI DRIVER
 M: Ludovic Desroches 
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 5a869144a0c5..378daa860ed4 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_I2C_POWERMAC)+= i2c-powermac.o
 obj-$(CONFIG_I2C_ALTERA)   += i2c-altera.o
 obj-$(CONFIG_I2C_ASPEED)   += i2c-aspeed.o
 obj-$(CONFIG_I2C_AT91) += i2c-at91.o
+i2c-at91-objs  := i2c-at91-core.o i2c-at91-master.o
 obj-$(CONFIG_I2C_AU1550)   += i2c-au1550.o
 obj-$(CONFIG_I2C_AXXIA)+= i2c-axxia.o
 obj-$(CONFIG_I2C_BCM2835)  += i2c-bcm2835.o
diff --git a/drivers/i2c/busses/i2c-at91-core.c 
b/drivers/i2c/busses/i2c-at91-core.c
new file mode 100644
index ..5d9c6c81e6ab
--- /dev/null
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -0,0 +1,373 @@
+/*
+ *  i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
+ *
+ *  Copyright (C) 2011 Weinmann Medical GmbH
+ *  Author: Nikolaus Voss 
+ *
+ *  Evolved from original work by:
+ *  Copyright (C) 2004 Rick Bronson
+ *  Converted to 2.6 by Andrew Victor 
+ *
+ *  Borrowed heavily from original work by:
+ *  Copyright (C) 2000 Philip Edelbrock 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "i2c-at91.h"
+
+unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
+{
+   return readl_relaxed(dev->base + reg);
+}
+
+void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
+{
+   writel_relaxed(val, dev->base + reg);
+}
+
+void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
+{
+   at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_INT_MASK);
+}
+
+void at91_twi_irq_save(struct at91_twi_dev *dev)
+{
+   dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & AT91_TWI_INT_MASK;
+   at91_disable_twi_interrupts(dev);
+}
+
+void at91_twi_irq_restore(struct at91_twi_dev *dev)
+{
+   at91_twi_write(dev, AT91_TWI_IER, dev->imr);
+}
+
+void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+   at91_disable_twi_interrupts(dev);
+   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+
+   at91_init_twi_bus_master(dev);
+}
+
+static struct at91_twi_pdata at91rm9200_config = {
+   .clk_max_div = 5,
+   .clk_offset = 3,
+   .has_unre_flag = true,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9261_config = {
+   .clk_max_div = 5,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9260_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9g20_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9g10_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static const struct plat

[PATCH v3 3/3] i2c: at91: added slave mode support

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

Slave mode driver is based on the concept of i2c-designware driver.

Signed-off-by: Juergen Fitschen 
Signed-off-by: Ludovic Desroches 
---
 drivers/i2c/busses/Makefile |   3 +
 drivers/i2c/busses/i2c-at91-core.c  |  13 +++-
 drivers/i2c/busses/i2c-at91-slave.c | 147 
 drivers/i2c/busses/i2c-at91.h   |  30 +++-
 4 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-slave.c

diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 378daa860ed4..1ab8b51a7657 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -35,6 +35,9 @@ obj-$(CONFIG_I2C_ALTERA)  += i2c-altera.o
 obj-$(CONFIG_I2C_ASPEED)   += i2c-aspeed.o
 obj-$(CONFIG_I2C_AT91) += i2c-at91.o
 i2c-at91-objs  := i2c-at91-core.o i2c-at91-master.o
+ifeq ($(CONFIG_I2C_SLAVE),y)
+   i2c-at91-objs   += i2c-at91-slave.o
+endif
 obj-$(CONFIG_I2C_AU1550)   += i2c-au1550.o
 obj-$(CONFIG_I2C_AXXIA)+= i2c-axxia.o
 obj-$(CONFIG_I2C_BCM2835)  += i2c-bcm2835.o
diff --git a/drivers/i2c/busses/i2c-at91-core.c 
b/drivers/i2c/busses/i2c-at91-core.c
index 5d9c6c81e6ab..c74283fa567f 100644
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -60,8 +60,10 @@ void at91_init_twi_bus(struct at91_twi_dev *dev)
 {
at91_disable_twi_interrupts(dev);
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
-
-   at91_init_twi_bus_master(dev);
+   if (dev->slave_detected)
+   at91_init_twi_bus_slave(dev);
+   else
+   at91_init_twi_bus_master(dev);
 }
 
 static struct at91_twi_pdata at91rm9200_config = {
@@ -243,7 +245,12 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->adapter.timeout = AT91_I2C_TIMEOUT;
dev->adapter.dev.of_node = pdev->dev.of_node;
 
-   rc = at91_twi_probe_master(pdev, phy_addr, dev);
+   dev->slave_detected = i2c_detect_slave_mode(>dev);
+
+   if (dev->slave_detected)
+   rc = at91_twi_probe_slave(pdev, phy_addr, dev);
+   else
+   rc = at91_twi_probe_master(pdev, phy_addr, dev);
if (rc)
return rc;
 
diff --git a/drivers/i2c/busses/i2c-at91-slave.c 
b/drivers/i2c/busses/i2c-at91-slave.c
new file mode 100644
index ..4b4808e0c8f7
--- /dev/null
+++ b/drivers/i2c/busses/i2c-at91-slave.c
@@ -0,0 +1,147 @@
+/*
+ *  i2c slave support for Atmel's AT91 Two-Wire Interface (TWI)
+ *
+ *  Copyright (C) 2017 Juergen Fitschen 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "i2c-at91.h"
+
+static irqreturn_t atmel_twi_interrupt_slave(int irq, void *dev_id)
+{
+   struct at91_twi_dev *dev = dev_id;
+   const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
+   const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
+   u8 value;
+
+   if (!irqstatus)
+   return IRQ_NONE;
+
+   /* slave address has been detected on I2C bus */
+   if (irqstatus & AT91_TWI_SVACC) {
+   if (status & AT91_TWI_SVREAD) {
+   i2c_slave_event(dev->slave,
+   I2C_SLAVE_READ_REQUESTED, );
+   writeb_relaxed(value, dev->base + AT91_TWI_THR);
+   at91_twi_write(dev, AT91_TWI_IER,
+  AT91_TWI_TXRDY | AT91_TWI_EOSACC);
+   } else {
+   i2c_slave_event(dev->slave,
+   I2C_SLAVE_WRITE_REQUESTED, );
+   at91_twi_write(dev, AT91_TWI_IER,
+  AT91_TWI_RXRDY | AT91_TWI_EOSACC);
+   }
+   at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_SVACC);
+   }
+
+   /* byte transmitted to remote master */
+   if (irqstatus & AT91_TWI_TXRDY) {
+   i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED, );
+   writeb_relaxed(value, dev->base + AT91_TWI_THR);
+   }
+
+   /* byte received from remote master */
+   if (irqstatus & AT91_TWI_RXRDY) {
+   value = readb_relaxed(dev->base + AT91_TWI_RHR);
+   i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED, );
+   }
+
+   /* master sent stop */
+   if (irqstatus & AT91_TWI_EOSACC) {
+   at91_twi_write(dev, AT91_TWI_IDR,
+  AT91_TWI_TXRDY | AT91_TWI_RXRDY | 
AT91_TWI_EOSACC);
+   at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_SVACC);
+   i2c_slave

[PATCH v3 1/3] i2c: at91: segregate master mode specific code from probe and init func

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

In order to implement slave mode support for the at91 hardware we have to
segregate all master mode specific function parts from the general parts.
The upcoming slave mode patch will call its sepcific probe resp. init
function instead of the master mode functions after the shared general
code has been executed.

This concept has been influenced by the i2c-designware driver.

Signed-off-by: Juergen Fitschen 
Signed-off-by: Ludovic Desroches 
---
 drivers/i2c/busses/i2c-at91.c | 90 ++-
 1 file changed, 55 insertions(+), 35 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 3f3e8b3bf5ff..bc74184462c6 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -174,10 +174,8 @@ static void at91_twi_irq_restore(struct at91_twi_dev *dev)
at91_twi_write(dev, AT91_TWI_IER, dev->imr);
 }
 
-static void at91_init_twi_bus(struct at91_twi_dev *dev)
+static void at91_init_twi_bus_master(struct at91_twi_dev *dev)
 {
-   at91_disable_twi_interrupts(dev);
-   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
/* FIFO should be enabled immediately after the software reset */
if (dev->fifo_size)
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);
@@ -186,6 +184,14 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev)
at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
 }
 
+static void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+   at91_disable_twi_interrupts(dev);
+   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+
+   at91_init_twi_bus_master(dev);
+}
+
 /*
  * Calculate symmetric clock as stated in datasheet:
  * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
@@ -1046,18 +1052,56 @@ static struct at91_twi_pdata *at91_twi_get_driver_data(
return (struct at91_twi_pdata *) 
platform_get_device_id(pdev)->driver_data;
 }
 
+static int at91_twi_probe_master(struct platform_device *pdev,
+u32 phy_addr, struct at91_twi_dev *dev)
+{
+   int rc;
+   u32 bus_clk_rate;
+
+   init_completion(>cmd_complete);
+
+   rc = devm_request_irq(>dev, dev->irq, atmel_twi_interrupt, 0,
+ dev_name(dev->dev), dev);
+   if (rc) {
+   dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
+   return rc;
+   }
+
+   if (dev->dev->of_node) {
+   rc = at91_twi_configure_dma(dev, phy_addr);
+   if (rc == -EPROBE_DEFER)
+   return rc;
+   }
+
+   if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size",
+ >fifo_size)) {
+   dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
+   }
+
+   rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
+ _clk_rate);
+   if (rc)
+   bus_clk_rate = DEFAULT_TWI_CLK_HZ;
+
+   at91_calc_twi_clock(dev, bus_clk_rate);
+
+   dev->adapter.algo = _twi_algorithm;
+   dev->adapter.quirks = _twi_quirks;
+
+   return 0;
+}
+
 static int at91_twi_probe(struct platform_device *pdev)
 {
struct at91_twi_dev *dev;
struct resource *mem;
int rc;
u32 phy_addr;
-   u32 bus_clk_rate;
 
dev = devm_kzalloc(>dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
-   init_completion(>cmd_complete);
+
dev->dev = >dev;
 
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1077,13 +1121,6 @@ static int at91_twi_probe(struct platform_device *pdev)
if (dev->irq < 0)
return dev->irq;
 
-   rc = devm_request_irq(>dev, dev->irq, atmel_twi_interrupt, 0,
-dev_name(dev->dev), dev);
-   if (rc) {
-   dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
-   return rc;
-   }
-
platform_set_drvdata(pdev, dev);
 
dev->clk = devm_clk_get(dev->dev, NULL);
@@ -1095,38 +1132,21 @@ static int at91_twi_probe(struct platform_device *pdev)
if (rc)
return rc;
 
-   if (dev->dev->of_node) {
-   rc = at91_twi_configure_dma(dev, phy_addr);
-   if (rc == -EPROBE_DEFER) {
-   clk_disable_unprepare(dev->clk);
-   return rc;
-   }
-   }
-
-   if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size",
- >fifo_size)) {
-   dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
-   }
-
-   rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
- 

[PATCH v3 0/3] i2c: at91: slave mode support

2018-07-16 Thread Ludovic Desroches
[Ludovic Desroches: see 'Changes in v3' section]

Based on the discussion we had on the i2c-linux list [1], I wrote a patch for
AT91 hardware and tried to fulfill the Linux I2C slave interface description
[2] as good as possible. This enables aforementioned hardware to act as an I2C
slave that can be accessed by a remote I2C master.

I have tested this patchset successfully on an ATSAMA5D27.

 ^  3.3V   ^  3.3V
+---+| | +---+
| Slave: ATSAMA5D27 |   +-+   +-+| Master: ATSAMA5D35|
| with i2c-slave-eeprom |   | | 100k  | | 100k   | with i2cset   |
+---+-+-+   +-+   +-++-+-+---+
| |  | |   | |
| +--+-|---(SDA)---+ |
+--+---(SCL)-+

Schematic: Connection of slave and master with 100kOhm pullup resistors.

On the master the following BASH script has been used to stress the slave.

root@emblinux:~# cat ./stress.sh
#!/bin/bash
I=0
while true
do
if i2cset -y -r 1 0x64 0 $I w | grep mismatch
then
echo "$(date): Error in transmission ${I}"
fi
((I++))
if [ $I -eq 65536 ]
then
I=0
echo "$(date): Sent 65536 transmissions"
fi
done

After running the script for some time I had the following output. To me this
looks promising :)

root@emblinux:~# ./stress.sh
Thu Nov  9 13:58:45 CTE 2017: Sent 65536 transmissions
Thu Nov  9 14:35:20 CTE 2017: Sent 65536 transmissions
Thu Nov  9 15:12:11 CTE 2017: Sent 65536 transmissions
Thu Nov  9 15:49:04 CTE 2017: Sent 65536 transmissions
Thu Nov  9 16:26:00 CTE 2017: Sent 65536 transmissions
Thu Nov  9 17:03:07 UTC 2017: Sent 65536 transmissions
Thu Nov  9 17:40:15 UTC 2017: Sent 65536 transmissions

If you have some hardware with an at91-i2c interface included at hand, 
I really
would appreciate if you can run the test script on your hardware and 
test this
driver.

Best regards
  Juergen


[Ludovic Desroches]
Changes in v3:
 - rebase (cherry-pick was enough)
 - fix checkpatch errors
 - tests:
   - hangs with a SAMA5D4 (master and slave on different busses) after about
   100 transfers. It's the firs time I do this test.
   - some mismatches with a SAMA5D4 as slave and a SAMA5D2 as master
   I don't know if it's a regression. I don't remember having seen this
   behavior previously.
   I think it's worth taking those patches even if there are some possible
   bugs. It'll allow to get more people using it and so to consolidate the
   slave mode support.

Changes in v2:
 - Implemented all suggestions made by Ludovic. (Thank you!)
 - Reworked the IRQ handler completely. Have a look in patch 3 fort further
   details.

[1] https://marc.info/?t=15082400481=1=1
[2] https://www.kernel.org/doc/Documentation/i2c/slave-interface

Juergen Fitschen (3):
  i2c: at91: segregate master mode specific code from probe and init
func
  i2c: at91: split driver into core and master file
  i2c: at91: added slave mode support

 MAINTAINERS|   3 +-
 drivers/i2c/busses/Makefile|   4 +
 drivers/i2c/busses/i2c-at91-core.c | 380 +
 .../i2c/busses/{i2c-at91.c => i2c-at91-master.c}   | 453 +
 drivers/i2c/busses/i2c-at91-slave.c| 147 +++
 drivers/i2c/busses/i2c-at91.h  | 179 
 6 files changed, 719 insertions(+), 447 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-core.c
 rename drivers/i2c/busses/{i2c-at91.c => i2c-at91-master.c} (67%)
 create mode 100644 drivers/i2c/busses/i2c-at91-slave.c
 create mode 100644 drivers/i2c/busses/i2c-at91.h

-- 
2.12.2



[PATCH v3 2/3] i2c: at91: split driver into core and master file

2018-07-16 Thread Ludovic Desroches
From: Juergen Fitschen 

The single file i2c-at91.c has been split into core code (i2c-at91-core.c)
and master mode specific code (i2c-at91-master.c). This should enhance
maintainability and reduce ifdeffery for slave mode related code.

The code itself hasn't been touched. Shared functions only had to be made
non-static. Furthermore, includes have been cleaned up.

Signed-off-by: Juergen Fitschen 
[ludovic.desroc...@microchip.com: fix checkpatch errors]
Signed-off-by: Ludovic Desroches 
---
 MAINTAINERS|   3 +-
 drivers/i2c/busses/Makefile|   1 +
 drivers/i2c/busses/i2c-at91-core.c | 373 
 .../i2c/busses/{i2c-at91.c => i2c-at91-master.c}   | 467 +
 drivers/i2c/busses/i2c-at91.h  | 151 +++
 5 files changed, 531 insertions(+), 464 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-at91-core.c
 rename drivers/i2c/busses/{i2c-at91.c => i2c-at91-master.c} (67%)
 create mode 100644 drivers/i2c/busses/i2c-at91.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e98e206b0d..14a87595b482 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2426,7 +2426,8 @@ ATMEL I2C DRIVER
 M: Ludovic Desroches 
 L: linux-...@vger.kernel.org
 S: Supported
-F: drivers/i2c/busses/i2c-at91.c
+F: drivers/i2c/busses/i2c-at91.h
+F: drivers/i2c/busses/i2c-at91-*.c
 
 ATMEL ISI DRIVER
 M: Ludovic Desroches 
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 5a869144a0c5..378daa860ed4 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_I2C_POWERMAC)+= i2c-powermac.o
 obj-$(CONFIG_I2C_ALTERA)   += i2c-altera.o
 obj-$(CONFIG_I2C_ASPEED)   += i2c-aspeed.o
 obj-$(CONFIG_I2C_AT91) += i2c-at91.o
+i2c-at91-objs  := i2c-at91-core.o i2c-at91-master.o
 obj-$(CONFIG_I2C_AU1550)   += i2c-au1550.o
 obj-$(CONFIG_I2C_AXXIA)+= i2c-axxia.o
 obj-$(CONFIG_I2C_BCM2835)  += i2c-bcm2835.o
diff --git a/drivers/i2c/busses/i2c-at91-core.c 
b/drivers/i2c/busses/i2c-at91-core.c
new file mode 100644
index ..5d9c6c81e6ab
--- /dev/null
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -0,0 +1,373 @@
+/*
+ *  i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
+ *
+ *  Copyright (C) 2011 Weinmann Medical GmbH
+ *  Author: Nikolaus Voss 
+ *
+ *  Evolved from original work by:
+ *  Copyright (C) 2004 Rick Bronson
+ *  Converted to 2.6 by Andrew Victor 
+ *
+ *  Borrowed heavily from original work by:
+ *  Copyright (C) 2000 Philip Edelbrock 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "i2c-at91.h"
+
+unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
+{
+   return readl_relaxed(dev->base + reg);
+}
+
+void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
+{
+   writel_relaxed(val, dev->base + reg);
+}
+
+void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
+{
+   at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_INT_MASK);
+}
+
+void at91_twi_irq_save(struct at91_twi_dev *dev)
+{
+   dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & AT91_TWI_INT_MASK;
+   at91_disable_twi_interrupts(dev);
+}
+
+void at91_twi_irq_restore(struct at91_twi_dev *dev)
+{
+   at91_twi_write(dev, AT91_TWI_IER, dev->imr);
+}
+
+void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+   at91_disable_twi_interrupts(dev);
+   at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+
+   at91_init_twi_bus_master(dev);
+}
+
+static struct at91_twi_pdata at91rm9200_config = {
+   .clk_max_div = 5,
+   .clk_offset = 3,
+   .has_unre_flag = true,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9261_config = {
+   .clk_max_div = 5,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9260_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9g20_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static struct at91_twi_pdata at91sam9g10_config = {
+   .clk_max_div = 7,
+   .clk_offset = 4,
+   .has_unre_flag = false,
+   .has_alt_cmd = false,
+   .has_hold_field = false,
+};
+
+static const struct plat

Re: [PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 04:58:08PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:16:36PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > Add the ISO7816 ioctl and associated accessors and data structure.
> > Drivers can then use this common implementation to handle ISO7816.
> > 
> > Signed-off-by: Nicolas Ferre 
> > [ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
> > checkpatch fixes]
> > Signed-off-by: Ludovic Desroches 
> > ---
> >  drivers/tty/serial/serial_core.c  | 49 
> > +++
> >  include/linux/serial_core.h   |  3 +++
> >  include/uapi/asm-generic/ioctls.h |  2 ++
> >  include/uapi/linux/serial.h   | 17 ++
> >  4 files changed, 71 insertions(+)
> 
> Note, kbuild found build issues with this, please fix up.
> 
> Also, here's some comments:
> 
> > 
> > diff --git a/drivers/tty/serial/serial_core.c 
> > b/drivers/tty/serial/serial_core.c
> > index 9c14a453f73c..c89ac59f6f8c 100644
> > --- a/drivers/tty/serial/serial_core.c
> > +++ b/drivers/tty/serial/serial_core.c
> > @@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port 
> > *port,
> > return 0;
> >  }
> >  
> > +static int uart_get_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816)
> > +{
> > +   unsigned long flags;
> > +   struct serial_iso7816 aux;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   aux = port->iso7816;
> 
> Don't you want to check to see if there is a function for iso7816 before
> copying it?  Otherwise it's just empty, right?

I'll add the check.

> 
> > +   if (!port->iso7816_config)
> > +   return -ENOIOCTLCMD;
> 
> Why this error value?
> 

It was a mimic of RS485.

> > --- a/include/uapi/asm-generic/ioctls.h
> > +++ b/include/uapi/asm-generic/ioctls.h
> > @@ -66,6 +66,8 @@
> >  #ifndef TIOCSRS485
> >  #define TIOCSRS485 0x542F
> >  #endif
> > +#define TIOCGISO7816   0x5430
> > +#define TIOCSISO7816   0x5431
> 
> Where did you get these numbers from?

I will use the macros to create numbers. Any rules about nr choice?

Regards

Ludovic

> 
> thanks,
> 
> greg k-h


Re: [PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 04:58:08PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:16:36PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > Add the ISO7816 ioctl and associated accessors and data structure.
> > Drivers can then use this common implementation to handle ISO7816.
> > 
> > Signed-off-by: Nicolas Ferre 
> > [ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
> > checkpatch fixes]
> > Signed-off-by: Ludovic Desroches 
> > ---
> >  drivers/tty/serial/serial_core.c  | 49 
> > +++
> >  include/linux/serial_core.h   |  3 +++
> >  include/uapi/asm-generic/ioctls.h |  2 ++
> >  include/uapi/linux/serial.h   | 17 ++
> >  4 files changed, 71 insertions(+)
> 
> Note, kbuild found build issues with this, please fix up.
> 
> Also, here's some comments:
> 
> > 
> > diff --git a/drivers/tty/serial/serial_core.c 
> > b/drivers/tty/serial/serial_core.c
> > index 9c14a453f73c..c89ac59f6f8c 100644
> > --- a/drivers/tty/serial/serial_core.c
> > +++ b/drivers/tty/serial/serial_core.c
> > @@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port 
> > *port,
> > return 0;
> >  }
> >  
> > +static int uart_get_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816)
> > +{
> > +   unsigned long flags;
> > +   struct serial_iso7816 aux;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   aux = port->iso7816;
> 
> Don't you want to check to see if there is a function for iso7816 before
> copying it?  Otherwise it's just empty, right?

I'll add the check.

> 
> > +   if (!port->iso7816_config)
> > +   return -ENOIOCTLCMD;
> 
> Why this error value?
> 

It was a mimic of RS485.

> > --- a/include/uapi/asm-generic/ioctls.h
> > +++ b/include/uapi/asm-generic/ioctls.h
> > @@ -66,6 +66,8 @@
> >  #ifndef TIOCSRS485
> >  #define TIOCSRS485 0x542F
> >  #endif
> > +#define TIOCGISO7816   0x5430
> > +#define TIOCSISO7816   0x5431
> 
> Where did you get these numbers from?

I will use the macros to create numbers. Any rules about nr choice?

Regards

Ludovic

> 
> thanks,
> 
> greg k-h


Re: [PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 05:02:29PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:16:36PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > Add the ISO7816 ioctl and associated accessors and data structure.
> > Drivers can then use this common implementation to handle ISO7816.
> > 
> > Signed-off-by: Nicolas Ferre 
> > [ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
> > checkpatch fixes]
> > Signed-off-by: Ludovic Desroches 
> > ---
> >  drivers/tty/serial/serial_core.c  | 49 
> > +++
> >  include/linux/serial_core.h   |  3 +++
> >  include/uapi/asm-generic/ioctls.h |  2 ++
> >  include/uapi/linux/serial.h   | 17 ++
> >  4 files changed, 71 insertions(+)
> > 
> > diff --git a/drivers/tty/serial/serial_core.c 
> > b/drivers/tty/serial/serial_core.c
> > index 9c14a453f73c..c89ac59f6f8c 100644
> > --- a/drivers/tty/serial/serial_core.c
> > +++ b/drivers/tty/serial/serial_core.c
> > @@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port 
> > *port,
> > return 0;
> >  }
> >  
> > +static int uart_get_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816)
> > +{
> > +   unsigned long flags;
> > +   struct serial_iso7816 aux;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   aux = port->iso7816;
> > +   spin_unlock_irqrestore(>lock, flags);
> > +
> > +   if (copy_to_user(iso7816, , sizeof(aux)))
> > +   return -EFAULT;
> > +
> > +   return 0;
> > +}
> > +
> > +static int uart_set_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816_user)
> > +{
> > +   struct serial_iso7816 iso7816;
> > +   int ret;
> > +   unsigned long flags;
> > +
> > +   if (!port->iso7816_config)
> > +   return -ENOIOCTLCMD;
> > +
> > +   if (copy_from_user(, iso7816_user, sizeof(*iso7816_user)))
> > +   return -EFAULT;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   ret = port->iso7816_config(port, );
> > +   spin_unlock_irqrestore(>lock, flags);
> > +   if (ret)
> > +   return ret;
> > +
> > +   if (copy_to_user(iso7816_user, >iso7816, sizeof(port->iso7816)))
> > +   return -EFAULT;
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * Called via sys_ioctl.  We can use spin_lock_irq() here.
> >   */
> > @@ -1385,6 +1426,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, 
> > unsigned long arg)
> > case TIOCSRS485:
> > ret = uart_set_rs485_config(uport, uarg);
> > break;
> > +
> > +   case TIOCSISO7816:
> > +   ret = uart_set_iso7816_config(state->uart_port, uarg);
> > +   break;
> > +
> > +   case TIOCGISO7816:
> > +   ret = uart_get_iso7816_config(state->uart_port, uarg);
> > +   break;
> > default:
> > if (uport->ops->ioctl)
> > ret = uport->ops->ioctl(uport, cmd, arg);
> > diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> > index 06ea4eeb09ab..d6e7747ffd46 100644
> > --- a/include/linux/serial_core.h
> > +++ b/include/linux/serial_core.h
> > @@ -137,6 +137,8 @@ struct uart_port {
> > void(*handle_break)(struct uart_port *);
> > int (*rs485_config)(struct uart_port *,
> > struct serial_rs485 *rs485);
> > +   int (*iso7816_config)(struct uart_port *,
> > + struct serial_iso7816 
> > *iso7816);
> > unsigned intirq;/* irq number */
> > unsigned long   irqflags;   /* irq flags  */
> > unsigned intuartclk;/* base uart clock */
> > @@ -253,6 +255,7 @@ struct uart_port {
> > struct attribute_group  *attr_group;/* port specific 
> > attributes */
> > const struct attribute_group **tty_groups;  /* all attributes 
> > (serial core use only) */
> > struct serial_rs485 rs485;
> > +   struct serial_iso7816   iso7816;
> > void*private_data;  /* generic platform 
> > data pointer */
> >  };
> >  
> > diff --git a/inclu

Re: [PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 05:02:29PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:16:36PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > Add the ISO7816 ioctl and associated accessors and data structure.
> > Drivers can then use this common implementation to handle ISO7816.
> > 
> > Signed-off-by: Nicolas Ferre 
> > [ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
> > checkpatch fixes]
> > Signed-off-by: Ludovic Desroches 
> > ---
> >  drivers/tty/serial/serial_core.c  | 49 
> > +++
> >  include/linux/serial_core.h   |  3 +++
> >  include/uapi/asm-generic/ioctls.h |  2 ++
> >  include/uapi/linux/serial.h   | 17 ++
> >  4 files changed, 71 insertions(+)
> > 
> > diff --git a/drivers/tty/serial/serial_core.c 
> > b/drivers/tty/serial/serial_core.c
> > index 9c14a453f73c..c89ac59f6f8c 100644
> > --- a/drivers/tty/serial/serial_core.c
> > +++ b/drivers/tty/serial/serial_core.c
> > @@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port 
> > *port,
> > return 0;
> >  }
> >  
> > +static int uart_get_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816)
> > +{
> > +   unsigned long flags;
> > +   struct serial_iso7816 aux;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   aux = port->iso7816;
> > +   spin_unlock_irqrestore(>lock, flags);
> > +
> > +   if (copy_to_user(iso7816, , sizeof(aux)))
> > +   return -EFAULT;
> > +
> > +   return 0;
> > +}
> > +
> > +static int uart_set_iso7816_config(struct uart_port *port,
> > +  struct serial_iso7816 __user *iso7816_user)
> > +{
> > +   struct serial_iso7816 iso7816;
> > +   int ret;
> > +   unsigned long flags;
> > +
> > +   if (!port->iso7816_config)
> > +   return -ENOIOCTLCMD;
> > +
> > +   if (copy_from_user(, iso7816_user, sizeof(*iso7816_user)))
> > +   return -EFAULT;
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +   ret = port->iso7816_config(port, );
> > +   spin_unlock_irqrestore(>lock, flags);
> > +   if (ret)
> > +   return ret;
> > +
> > +   if (copy_to_user(iso7816_user, >iso7816, sizeof(port->iso7816)))
> > +   return -EFAULT;
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * Called via sys_ioctl.  We can use spin_lock_irq() here.
> >   */
> > @@ -1385,6 +1426,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, 
> > unsigned long arg)
> > case TIOCSRS485:
> > ret = uart_set_rs485_config(uport, uarg);
> > break;
> > +
> > +   case TIOCSISO7816:
> > +   ret = uart_set_iso7816_config(state->uart_port, uarg);
> > +   break;
> > +
> > +   case TIOCGISO7816:
> > +   ret = uart_get_iso7816_config(state->uart_port, uarg);
> > +   break;
> > default:
> > if (uport->ops->ioctl)
> > ret = uport->ops->ioctl(uport, cmd, arg);
> > diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> > index 06ea4eeb09ab..d6e7747ffd46 100644
> > --- a/include/linux/serial_core.h
> > +++ b/include/linux/serial_core.h
> > @@ -137,6 +137,8 @@ struct uart_port {
> > void(*handle_break)(struct uart_port *);
> > int (*rs485_config)(struct uart_port *,
> > struct serial_rs485 *rs485);
> > +   int (*iso7816_config)(struct uart_port *,
> > + struct serial_iso7816 
> > *iso7816);
> > unsigned intirq;/* irq number */
> > unsigned long   irqflags;   /* irq flags  */
> > unsigned intuartclk;/* base uart clock */
> > @@ -253,6 +255,7 @@ struct uart_port {
> > struct attribute_group  *attr_group;/* port specific 
> > attributes */
> > const struct attribute_group **tty_groups;  /* all attributes 
> > (serial core use only) */
> > struct serial_rs485 rs485;
> > +   struct serial_iso7816   iso7816;
> > void*private_data;  /* generic platform 
> > data pointer */
> >  };
> >  
> > diff --git a/inclu

Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 11:56:24PM +0200, Wolfram Sang wrote:
> 
> > Yes sure, you can add my Ack. I would be pleased to see the slave
> > support taken.
> 
> Sadly, I can't get it to apply cleanly. Could you rebase and retest?
> 

Ok I'll handle it and add my Acked-by.

Ludovic


Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-13 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 11:56:24PM +0200, Wolfram Sang wrote:
> 
> > Yes sure, you can add my Ack. I would be pleased to see the slave
> > support taken.
> 
> Sadly, I can't get it to apply cleanly. Could you rebase and retest?
> 

Ok I'll handle it and add my Acked-by.

Ludovic


Re: [PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-12 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 04:58:27PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:26:23PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
> > Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
> > calling atmel_stop_tx() by using the atomic information tasklet_shutdown
> > that is already in place for this purpose.
> > 
> > Signed-off-by: Nicolas Ferre 
> > ---
> >  drivers/tty/serial/atmel_serial.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> Did you send this patch twice?
> 
> confused,

Yes sorry, as I didn't receive patch 3/3, I resend it. At the end, it
was sent twice.

Regards

Ludovic

> 
> greg k-h
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-12 Thread Ludovic Desroches
On Thu, Jul 12, 2018 at 04:58:27PM +0200, Greg KH wrote:
> On Wed, Jul 11, 2018 at 03:26:23PM +0200, Ludovic Desroches wrote:
> > From: Nicolas Ferre 
> > 
> > In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
> > Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
> > calling atmel_stop_tx() by using the atomic information tasklet_shutdown
> > that is already in place for this purpose.
> > 
> > Signed-off-by: Nicolas Ferre 
> > ---
> >  drivers/tty/serial/atmel_serial.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> Did you send this patch twice?
> 
> confused,

Yes sorry, as I didn't receive patch 3/3, I resend it. At the end, it
was sent twice.

Regards

Ludovic

> 
> greg k-h
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH] ARM: dts: at91: fix typo for PIN_PB22

2018-07-12 Thread Ludovic Desroches
Hi Claudiu,

On Wed, Jul 11, 2018 at 07:25:37PM +0300, Claudiu Beznea wrote:
> Fix typo for PIN_PB22 on TD function.

In fact, this typo is present in several places in this file. It could
be worth fixing all those occurences in a single patch.

Regards

Ludovic

> 
> Signed-off-by: Claudiu Beznea 
> ---
>  arch/arm/boot/dts/sama5d2-pinfunc.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h 
> b/arch/arm/boot/dts/sama5d2-pinfunc.h
> index e57191fb83de..ac61491c9d7f 100644
> --- a/arch/arm/boot/dts/sama5d2-pinfunc.h
> +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
> @@ -375,7 +375,7 @@
>  #define PIN_PB22__GPIO   PINMUX_PIN(PIN_PB22, 0, 0)
>  #define PIN_PB22__LCDDAT11   PINMUX_PIN(PIN_PB22, 1, 1)
>  #define PIN_PB22__A11PINMUX_PIN(PIN_PB22, 2, 1)
> -#define PIN_PB22__TDOPINMUX_PIN(PIN_PB22, 3, 1)
> +#define PIN_PB22__TD0PINMUX_PIN(PIN_PB22, 3, 1)
>  #define PIN_PB22__TIOA2  PINMUX_PIN(PIN_PB22, 4, 2)
>  #define PIN_PB22__FLEXCOM3_IO1   PINMUX_PIN(PIN_PB22, 5, 3)
>  #define PIN_PB22__GMDC   PINMUX_PIN(PIN_PB22, 6, 3)
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: dts: at91: fix typo for PIN_PB22

2018-07-12 Thread Ludovic Desroches
Hi Claudiu,

On Wed, Jul 11, 2018 at 07:25:37PM +0300, Claudiu Beznea wrote:
> Fix typo for PIN_PB22 on TD function.

In fact, this typo is present in several places in this file. It could
be worth fixing all those occurences in a single patch.

Regards

Ludovic

> 
> Signed-off-by: Claudiu Beznea 
> ---
>  arch/arm/boot/dts/sama5d2-pinfunc.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h 
> b/arch/arm/boot/dts/sama5d2-pinfunc.h
> index e57191fb83de..ac61491c9d7f 100644
> --- a/arch/arm/boot/dts/sama5d2-pinfunc.h
> +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
> @@ -375,7 +375,7 @@
>  #define PIN_PB22__GPIO   PINMUX_PIN(PIN_PB22, 0, 0)
>  #define PIN_PB22__LCDDAT11   PINMUX_PIN(PIN_PB22, 1, 1)
>  #define PIN_PB22__A11PINMUX_PIN(PIN_PB22, 2, 1)
> -#define PIN_PB22__TDOPINMUX_PIN(PIN_PB22, 3, 1)
> +#define PIN_PB22__TD0PINMUX_PIN(PIN_PB22, 3, 1)
>  #define PIN_PB22__TIOA2  PINMUX_PIN(PIN_PB22, 4, 2)
>  #define PIN_PB22__FLEXCOM3_IO1   PINMUX_PIN(PIN_PB22, 5, 3)
>  #define PIN_PB22__GMDC   PINMUX_PIN(PIN_PB22, 6, 3)
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
calling atmel_stop_tx() by using the atomic information tasklet_shutdown
that is already in place for this purpose.

Signed-off-by: Nicolas Ferre 
---
 drivers/tty/serial/atmel_serial.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 0118b219f3a8..e4f877e1f3c6 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -617,7 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
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 (!atomic_read(_port->tasklet_shutdown))
+   atmel_start_rx(port);
+
 }
 
 /*
-- 
2.12.2



[PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
calling atmel_stop_tx() by using the atomic information tasklet_shutdown
that is already in place for this purpose.

Signed-off-by: Nicolas Ferre 
---
 drivers/tty/serial/atmel_serial.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 0118b219f3a8..e4f877e1f3c6 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -617,7 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
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 (!atomic_read(_port->tasklet_shutdown))
+   atmel_start_rx(port);
+
 }
 
 /*
-- 
2.12.2



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

2018-07-11 Thread Ludovic Desroches
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 
[ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
fixes]
Signed-off-by: Ludovic Desroches 
---
 drivers/tty/serial/atmel_serial.c | 175 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 2 files changed, 167 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 8e4428725848..0118b219f3a8 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,136 @@ 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);
+   dev_dbg(port->dev, "ISO7816 mck_rate = %lld\n", mck_rate);
+   do_div(mck_rate, iso7816conf->clk);
+   cd = mck_rate;
+   dev_dbg(port->dev, "ISO7816 clk = %d. CD = %d\n", iso7816conf->clk, cd);
+   return cd;
+}
+
+static unsigned int atmel_calc_fidi(struct uart_port *port,
+   struct serial_iso7816 *iso7816conf)
+{
+   u64 fidi = 0;
+
+   dev_dbg(port->dev, "ISO7816 fi(%d) / di(%d)\n",
+   iso7816conf->sc_fi, iso7816conf->sc_di);
+   if (iso7816conf->sc_fi && iso7816conf->sc_di) {
+   fidi = (u64)iso7816conf->sc_fi;
+   do_div(fidi, iso7816conf->sc_di);
+   }
+   dev_dbg(port->dev, "ISO7816 fidi = 0x%x\n", (u32)fidi);
+   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 (!(port->iso7816.flags & SER_ISO7816_ENABLED)) {
+   /* port not yet in iso7816 mode: store configuration */
+   atmel_port->backup_mode = mode;
+   atmel_port->backup_brgr = atmel_uart_readl(port, ATMEL_US_BRGR);
+   }
+
+   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);
+
+   /* NACK configuration */
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0))
+   mode |= ATMEL_US_DSNACK;
+   else
+   mode |= ATMEL_US_INACK;
+   /* select mck clock, and output  */
+   mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
+   /* set pa

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

2018-07-11 Thread Ludovic Desroches
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 
[ludovic.desroc...@microchip.com: rebase, add check on fidi ratio, checkpatch 
fixes]
Signed-off-by: Ludovic Desroches 
---
 drivers/tty/serial/atmel_serial.c | 175 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 2 files changed, 167 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 8e4428725848..0118b219f3a8 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,136 @@ 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);
+   dev_dbg(port->dev, "ISO7816 mck_rate = %lld\n", mck_rate);
+   do_div(mck_rate, iso7816conf->clk);
+   cd = mck_rate;
+   dev_dbg(port->dev, "ISO7816 clk = %d. CD = %d\n", iso7816conf->clk, cd);
+   return cd;
+}
+
+static unsigned int atmel_calc_fidi(struct uart_port *port,
+   struct serial_iso7816 *iso7816conf)
+{
+   u64 fidi = 0;
+
+   dev_dbg(port->dev, "ISO7816 fi(%d) / di(%d)\n",
+   iso7816conf->sc_fi, iso7816conf->sc_di);
+   if (iso7816conf->sc_fi && iso7816conf->sc_di) {
+   fidi = (u64)iso7816conf->sc_fi;
+   do_div(fidi, iso7816conf->sc_di);
+   }
+   dev_dbg(port->dev, "ISO7816 fidi = 0x%x\n", (u32)fidi);
+   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 (!(port->iso7816.flags & SER_ISO7816_ENABLED)) {
+   /* port not yet in iso7816 mode: store configuration */
+   atmel_port->backup_mode = mode;
+   atmel_port->backup_brgr = atmel_uart_readl(port, ATMEL_US_BRGR);
+   }
+
+   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);
+
+   /* NACK configuration */
+   if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+   == SER_ISO7816_T(0))
+   mode |= ATMEL_US_DSNACK;
+   else
+   mode |= ATMEL_US_INACK;
+   /* select mck clock, and output  */
+   mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
+   /* set pa

[PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 drivers/tty/serial/serial_core.c  | 49 +++
 include/linux/serial_core.h   |  3 +++
 include/uapi/asm-generic/ioctls.h |  2 ++
 include/uapi/linux/serial.h   | 17 ++
 4 files changed, 71 insertions(+)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9c14a453f73c..c89ac59f6f8c 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port *port,
return 0;
 }
 
+static int uart_get_iso7816_config(struct uart_port *port,
+  struct serial_iso7816 __user *iso7816)
+{
+   unsigned long flags;
+   struct serial_iso7816 aux;
+
+   spin_lock_irqsave(>lock, flags);
+   aux = port->iso7816;
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (copy_to_user(iso7816, , sizeof(aux)))
+   return -EFAULT;
+
+   return 0;
+}
+
+static int uart_set_iso7816_config(struct uart_port *port,
+  struct serial_iso7816 __user *iso7816_user)
+{
+   struct serial_iso7816 iso7816;
+   int ret;
+   unsigned long flags;
+
+   if (!port->iso7816_config)
+   return -ENOIOCTLCMD;
+
+   if (copy_from_user(, iso7816_user, sizeof(*iso7816_user)))
+   return -EFAULT;
+
+   spin_lock_irqsave(>lock, flags);
+   ret = port->iso7816_config(port, );
+   spin_unlock_irqrestore(>lock, flags);
+   if (ret)
+   return ret;
+
+   if (copy_to_user(iso7816_user, >iso7816, sizeof(port->iso7816)))
+   return -EFAULT;
+
+   return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1385,6 +1426,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, 
unsigned long arg)
case TIOCSRS485:
ret = uart_set_rs485_config(uport, uarg);
break;
+
+   case TIOCSISO7816:
+   ret = uart_set_iso7816_config(state->uart_port, uarg);
+   break;
+
+   case TIOCGISO7816:
+   ret = uart_get_iso7816_config(state->uart_port, uarg);
+   break;
default:
if (uport->ops->ioctl)
ret = uport->ops->ioctl(uport, cmd, arg);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 06ea4eeb09ab..d6e7747ffd46 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -137,6 +137,8 @@ struct uart_port {
void(*handle_break)(struct uart_port *);
int (*rs485_config)(struct uart_port *,
struct serial_rs485 *rs485);
+   int (*iso7816_config)(struct uart_port *,
+ struct serial_iso7816 
*iso7816);
unsigned intirq;/* irq number */
unsigned long   irqflags;   /* irq flags  */
unsigned intuartclk;/* base uart clock */
@@ -253,6 +255,7 @@ struct uart_port {
struct attribute_group  *attr_group;/* port specific 
attributes */
const struct attribute_group **tty_groups;  /* all attributes 
(serial core use only) */
struct serial_rs485 rs485;
+   struct serial_iso7816   iso7816;
void*private_data;  /* generic platform 
data pointer */
 };
 
diff --git a/include/uapi/asm-generic/ioctls.h 
b/include/uapi/asm-generic/ioctls.h
index 040651735662..0e5c79726c2d 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -66,6 +66,8 @@
 #ifndef TIOCSRS485
 #define TIOCSRS485 0x542F
 #endif
+#define TIOCGISO7816   0x5430
+#define TIOCSISO7816   0x5431
 #define TIOCGPTN   _IOR('T', 0x30, unsigned int) /* Get Pty Number (of 
pty-mux device) */
 #define TIOCSPTLCK _IOW('T', 0x31, int)  /* Lock/unlock Pty */
 #define TIOCGDEV   _IOR('T', 0x32, unsigned int) /* Get primary device 
node of /dev/console */
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index 3fdd0dee8b41..93eb3c496ff1 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -132,4 +132,21 @@ struct serial_rs485 {
   are a royal PITA .. */
 };
 
+/*
+ * Serial interface for controlling ISO7816 settings on chips with suitable
+ * support. Set with TIOCSISO7816 and get with TIOCGISO7816 if supported by
+ * your platform

[PATCH 0/3] add ISO7816 support

2018-07-11 Thread Ludovic Desroches
Hi,

This set of patches adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Nicolas Ferre (3):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support
  tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

 drivers/tty/serial/atmel_serial.c | 179 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 drivers/tty/serial/serial_core.c  |  49 +++
 include/linux/serial_core.h   |   3 +
 include/uapi/asm-generic/ioctls.h |   2 +
 include/uapi/linux/serial.h   |  17 
 6 files changed, 241 insertions(+), 12 deletions(-)

-- 
2.12.2



[PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
calling atmel_stop_tx() by using the atomic information tasklet_shutdown
that is already in place for this purpose.

Signed-off-by: Nicolas Ferre 
---
 drivers/tty/serial/atmel_serial.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 0118b219f3a8..e4f877e1f3c6 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -617,7 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
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 (!atomic_read(_port->tasklet_shutdown))
+   atmel_start_rx(port);
+
 }
 
 /*
-- 
2.12.2



[PATCH 1/3] tty/serial_core: add ISO7816 infrastructure

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

Add the ISO7816 ioctl and associated accessors and data structure.
Drivers can then use this common implementation to handle ISO7816.

Signed-off-by: Nicolas Ferre 
[ludovic.desroc...@microchip.com: squash and rebase, removal of gpios, 
checkpatch fixes]
Signed-off-by: Ludovic Desroches 
---
 drivers/tty/serial/serial_core.c  | 49 +++
 include/linux/serial_core.h   |  3 +++
 include/uapi/asm-generic/ioctls.h |  2 ++
 include/uapi/linux/serial.h   | 17 ++
 4 files changed, 71 insertions(+)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9c14a453f73c..c89ac59f6f8c 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1301,6 +1301,47 @@ static int uart_set_rs485_config(struct uart_port *port,
return 0;
 }
 
+static int uart_get_iso7816_config(struct uart_port *port,
+  struct serial_iso7816 __user *iso7816)
+{
+   unsigned long flags;
+   struct serial_iso7816 aux;
+
+   spin_lock_irqsave(>lock, flags);
+   aux = port->iso7816;
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (copy_to_user(iso7816, , sizeof(aux)))
+   return -EFAULT;
+
+   return 0;
+}
+
+static int uart_set_iso7816_config(struct uart_port *port,
+  struct serial_iso7816 __user *iso7816_user)
+{
+   struct serial_iso7816 iso7816;
+   int ret;
+   unsigned long flags;
+
+   if (!port->iso7816_config)
+   return -ENOIOCTLCMD;
+
+   if (copy_from_user(, iso7816_user, sizeof(*iso7816_user)))
+   return -EFAULT;
+
+   spin_lock_irqsave(>lock, flags);
+   ret = port->iso7816_config(port, );
+   spin_unlock_irqrestore(>lock, flags);
+   if (ret)
+   return ret;
+
+   if (copy_to_user(iso7816_user, >iso7816, sizeof(port->iso7816)))
+   return -EFAULT;
+
+   return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1385,6 +1426,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, 
unsigned long arg)
case TIOCSRS485:
ret = uart_set_rs485_config(uport, uarg);
break;
+
+   case TIOCSISO7816:
+   ret = uart_set_iso7816_config(state->uart_port, uarg);
+   break;
+
+   case TIOCGISO7816:
+   ret = uart_get_iso7816_config(state->uart_port, uarg);
+   break;
default:
if (uport->ops->ioctl)
ret = uport->ops->ioctl(uport, cmd, arg);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 06ea4eeb09ab..d6e7747ffd46 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -137,6 +137,8 @@ struct uart_port {
void(*handle_break)(struct uart_port *);
int (*rs485_config)(struct uart_port *,
struct serial_rs485 *rs485);
+   int (*iso7816_config)(struct uart_port *,
+ struct serial_iso7816 
*iso7816);
unsigned intirq;/* irq number */
unsigned long   irqflags;   /* irq flags  */
unsigned intuartclk;/* base uart clock */
@@ -253,6 +255,7 @@ struct uart_port {
struct attribute_group  *attr_group;/* port specific 
attributes */
const struct attribute_group **tty_groups;  /* all attributes 
(serial core use only) */
struct serial_rs485 rs485;
+   struct serial_iso7816   iso7816;
void*private_data;  /* generic platform 
data pointer */
 };
 
diff --git a/include/uapi/asm-generic/ioctls.h 
b/include/uapi/asm-generic/ioctls.h
index 040651735662..0e5c79726c2d 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -66,6 +66,8 @@
 #ifndef TIOCSRS485
 #define TIOCSRS485 0x542F
 #endif
+#define TIOCGISO7816   0x5430
+#define TIOCSISO7816   0x5431
 #define TIOCGPTN   _IOR('T', 0x30, unsigned int) /* Get Pty Number (of 
pty-mux device) */
 #define TIOCSPTLCK _IOW('T', 0x31, int)  /* Lock/unlock Pty */
 #define TIOCGDEV   _IOR('T', 0x32, unsigned int) /* Get primary device 
node of /dev/console */
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index 3fdd0dee8b41..93eb3c496ff1 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -132,4 +132,21 @@ struct serial_rs485 {
   are a royal PITA .. */
 };
 
+/*
+ * Serial interface for controlling ISO7816 settings on chips with suitable
+ * support. Set with TIOCSISO7816 and get with TIOCGISO7816 if supported by
+ * your platform

[PATCH 0/3] add ISO7816 support

2018-07-11 Thread Ludovic Desroches
Hi,

This set of patches adds support for the ISO7816 standard. The USART devices in
Microchip SoCs have an ISO7816 mode. It allows to let the USART managing
the CLK and I/O signals of a smart card.

Nicolas Ferre (3):
  tty/serial_core: add ISO7816 infrastructure
  tty/serial: atmel: add ISO7816 support
  tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

 drivers/tty/serial/atmel_serial.c | 179 +++---
 drivers/tty/serial/atmel_serial.h |   3 +-
 drivers/tty/serial/serial_core.c  |  49 +++
 include/linux/serial_core.h   |   3 +
 include/uapi/asm-generic/ioctls.h |   2 +
 include/uapi/linux/serial.h   |  17 
 6 files changed, 241 insertions(+), 12 deletions(-)

-- 
2.12.2



[PATCH 3/3] tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode

2018-07-11 Thread Ludovic Desroches
From: Nicolas Ferre 

In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
calling atmel_stop_tx() by using the atomic information tasklet_shutdown
that is already in place for this purpose.

Signed-off-by: Nicolas Ferre 
---
 drivers/tty/serial/atmel_serial.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 0118b219f3a8..e4f877e1f3c6 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -617,7 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
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 (!atomic_read(_port->tasklet_shutdown))
+   atmel_start_rx(port);
+
 }
 
 /*
-- 
2.12.2



Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-10 Thread Ludovic Desroches
On Mon, Jul 09, 2018 at 05:51:36PM +0200, Wolfram Sang wrote:
> 
> > Sorry for having not catched it. If I remember well, it was the only
> > issue I had while testing the slave support.
> > 
> > > 
> > > BTW maybe I asked already and forgot: is this IP core capable of being
> > > master and slave on the same bus?
> > > 
> > 
> > No the master and slave modes are exclusive.
> 
> Pity.
> 
> But thanks for the heads up, any tag you want to give? Ack or Rev?
> 

Yes sure, you can add my Ack. I would be pleased to see the slave
support taken.

Regards

Ludovic


Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-10 Thread Ludovic Desroches
On Mon, Jul 09, 2018 at 05:51:36PM +0200, Wolfram Sang wrote:
> 
> > Sorry for having not catched it. If I remember well, it was the only
> > issue I had while testing the slave support.
> > 
> > > 
> > > BTW maybe I asked already and forgot: is this IP core capable of being
> > > master and slave on the same bus?
> > > 
> > 
> > No the master and slave modes are exclusive.
> 
> Pity.
> 
> But thanks for the heads up, any tag you want to give? Ack or Rev?
> 

Yes sure, you can add my Ack. I would be pleased to see the slave
support taken.

Regards

Ludovic


Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-09 Thread Ludovic Desroches
Sorry for the delay to answer. I changed my email filters. Unfortunately
there was a bug and I missed message from this mailing list...

On Sat, Jun 02, 2018 at 11:35:13PM +0200, Wolfram Sang wrote:
> On Thu, Nov 09, 2017 at 06:22:29PM +0100, Juergen Fitschen wrote:
> > Slave mode driver is based on the concept of i2c-designware driver.
> > 
> > Signed-off-by: Juergen Fitschen 
> 
> I lost the original mail where Ludovic said:
> 
> "I tested it quickly on a sama5d2 xplained board: I used an i2c-gpio
> master and the eeprom driver. It works pretty well. I tried to increase
> the size of the eeprom by adding:
> + { "slave-24c64", 65536 / 8 },"
> 
> That won't work. The comment at the beginning of the file says:
> 
>  * ... It is prepared to simulate bigger EEPROMs with an internal 16 bit
>  * pointer, yet implementation is deferred until the need actually arises.
> 
> So,  no EEPROMs > 256 byte for now.

Sorry for having not catched it. If I remember well, it was the only
issue I had while testing the slave support.

> 
> BTW maybe I asked already and forgot: is this IP core capable of being
> master and slave on the same bus?
> 

No the master and slave modes are exclusive.

Regards

Ludovic


Re: [v2,3/3] i2c: at91: added slave mode support

2018-07-09 Thread Ludovic Desroches
Sorry for the delay to answer. I changed my email filters. Unfortunately
there was a bug and I missed message from this mailing list...

On Sat, Jun 02, 2018 at 11:35:13PM +0200, Wolfram Sang wrote:
> On Thu, Nov 09, 2017 at 06:22:29PM +0100, Juergen Fitschen wrote:
> > Slave mode driver is based on the concept of i2c-designware driver.
> > 
> > Signed-off-by: Juergen Fitschen 
> 
> I lost the original mail where Ludovic said:
> 
> "I tested it quickly on a sama5d2 xplained board: I used an i2c-gpio
> master and the eeprom driver. It works pretty well. I tried to increase
> the size of the eeprom by adding:
> + { "slave-24c64", 65536 / 8 },"
> 
> That won't work. The comment at the beginning of the file says:
> 
>  * ... It is prepared to simulate bigger EEPROMs with an internal 16 bit
>  * pointer, yet implementation is deferred until the need actually arises.
> 
> So,  no EEPROMs > 256 byte for now.

Sorry for having not catched it. If I remember well, it was the only
issue I had while testing the slave support.

> 
> BTW maybe I asked already and forgot: is this IP core capable of being
> master and slave on the same bus?
> 

No the master and slave modes are exclusive.

Regards

Ludovic


[PATCH v2] pinctrl: at91-pio4: add support for drive strength

2018-06-29 Thread Ludovic Desroches
Add support for the drive strength configuration. Usually, this value is
expressed in mA. Since the numeric value depends on VDDIOP voltage, a
value we can't retrieve at runtime, the controller uses low, medium and
high to define the drive strength.

The PIO controller accepts two values for the low drive configuration: 0
and 1. Most of the time, we don't care about the drive strength. So we
keep the default value which is 0. The drive strength is advertised
through the sysfs only when it has been explicitly set in the device
tree i.e. if its value is different from 0.

Signed-off-by: Ludovic Desroches 
---

Changes:
- v2: use atmel,drive-strength property instead of drive-strengh one
since it is not expressend in mA and there is no way to retrieve this
value at runtime.
- v1: https://www.spinics.net/lists/linux-gpio/msg27789.html

 .../bindings/pinctrl/atmel,at91-pio4-pinctrl.txt   |  3 ++
 drivers/pinctrl/pinctrl-at91-pio4.c| 42 ++
 include/dt-bindings/pinctrl/at91.h |  4 +++
 3 files changed, 49 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
index 61ac75706cc9..04d16fb69eb7 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -36,6 +36,8 @@ Optional properties:
 - GENERIC_PINCONFIG: generic pinconfig options to use, bias-disable,
 bias-pull-down, bias-pull-up, drive-open-drain, input-schmitt-enable,
 input-debounce, output-low, output-high.
+- atmel,drive-strength: 0 or 1 for low drive, 2 for medium drive and 3 for
+high drive. The default value is low drive.
 
 Example:
 
@@ -66,6 +68,7 @@ Example:
pinmux = ,
 ;
bias-pull-up;
+   atmel,drive-strength = ;
};
 
pinctrl_sdmmc1_default: sdmmc1_default {
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c 
b/drivers/pinctrl/pinctrl-at91-pio4.c
index 67e4d9ffa6b1..8f061971a7d1 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -14,6 +14,7 @@
  * GNU General Public License for more details.
  */
 
+#include 
 #include 
 #include 
 /* FIXME: needed for gpio_to_irq(), get rid of this */
@@ -49,6 +50,8 @@
 #defineATMEL_PIO_IFSCEN_MASK   BIT(13)
 #defineATMEL_PIO_OPD_MASK  BIT(14)
 #defineATMEL_PIO_SCHMITT_MASK  BIT(15)
+#defineATMEL_PIO_DRVSTR_MASK   GENMASK(17, 16)
+#defineATMEL_PIO_DRVSTR_OFFSET 16
 #defineATMEL_PIO_CFGR_EVTSEL_MASK  GENMASK(26, 24)
 #defineATMEL_PIO_CFGR_EVTSEL_FALLING   (0 << 24)
 #defineATMEL_PIO_CFGR_EVTSEL_RISING(1 << 24)
@@ -75,6 +78,9 @@
 #define ATMEL_GET_PIN_FUNC(pinfunc)((pinfunc >> 16) & 0xf)
 #define ATMEL_GET_PIN_IOSET(pinfunc)   ((pinfunc >> 20) & 0xf)
 
+/* Custom pinconf parameters */
+#define ATMEL_PIN_CONFIG_DRIVE_STRENGTH(PIN_CONFIG_END + 1)
+
 struct atmel_pioctrl_data {
unsigned nbanks;
 };
@@ -139,6 +145,10 @@ static const char * const atmel_functions[] = {
"GPIO", "A", "B", "C", "D", "E", "F", "G"
 };
 
+static const struct pinconf_generic_params atmel_custom_bindings[] = {
+   {"atmel,drive-strength", ATMEL_PIN_CONFIG_DRIVE_STRENGTH, 0},
+};
+
 /* --- GPIO --- */
 static unsigned int atmel_gpio_read(struct atmel_pioctrl *atmel_pioctrl,
unsigned int bank, unsigned int reg)
@@ -692,6 +702,11 @@ static int atmel_conf_pin_config_group_get(struct 
pinctrl_dev *pctldev,
return -EINVAL;
arg = 1;
break;
+   case ATMEL_PIN_CONFIG_DRIVE_STRENGTH:
+   if (!(res & ATMEL_PIO_DRVSTR_MASK))
+   return -EINVAL;
+   arg = (res & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET;
+   break;
default:
return -ENOTSUPP;
}
@@ -777,6 +792,18 @@ static int atmel_conf_pin_config_group_set(struct 
pinctrl_dev *pctldev,
ATMEL_PIO_SODR);
}
break;
+   case ATMEL_PIN_CONFIG_DRIVE_STRENGTH:
+   switch (arg) {
+   case ATMEL_PIO_DRVSTR_LO:
+   case ATMEL_PIO_DRVSTR_ME:
+   case ATMEL_PIO_DRVSTR_HI:
+   conf &= (~ATMEL_PIO_DRVSTR_MASK);
+   conf |= arg << ATMEL_PIO_DRVSTR_OFFSET;
+

[PATCH v2] pinctrl: at91-pio4: add support for drive strength

2018-06-29 Thread Ludovic Desroches
Add support for the drive strength configuration. Usually, this value is
expressed in mA. Since the numeric value depends on VDDIOP voltage, a
value we can't retrieve at runtime, the controller uses low, medium and
high to define the drive strength.

The PIO controller accepts two values for the low drive configuration: 0
and 1. Most of the time, we don't care about the drive strength. So we
keep the default value which is 0. The drive strength is advertised
through the sysfs only when it has been explicitly set in the device
tree i.e. if its value is different from 0.

Signed-off-by: Ludovic Desroches 
---

Changes:
- v2: use atmel,drive-strength property instead of drive-strengh one
since it is not expressend in mA and there is no way to retrieve this
value at runtime.
- v1: https://www.spinics.net/lists/linux-gpio/msg27789.html

 .../bindings/pinctrl/atmel,at91-pio4-pinctrl.txt   |  3 ++
 drivers/pinctrl/pinctrl-at91-pio4.c| 42 ++
 include/dt-bindings/pinctrl/at91.h |  4 +++
 3 files changed, 49 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
index 61ac75706cc9..04d16fb69eb7 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -36,6 +36,8 @@ Optional properties:
 - GENERIC_PINCONFIG: generic pinconfig options to use, bias-disable,
 bias-pull-down, bias-pull-up, drive-open-drain, input-schmitt-enable,
 input-debounce, output-low, output-high.
+- atmel,drive-strength: 0 or 1 for low drive, 2 for medium drive and 3 for
+high drive. The default value is low drive.
 
 Example:
 
@@ -66,6 +68,7 @@ Example:
pinmux = ,
 ;
bias-pull-up;
+   atmel,drive-strength = ;
};
 
pinctrl_sdmmc1_default: sdmmc1_default {
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c 
b/drivers/pinctrl/pinctrl-at91-pio4.c
index 67e4d9ffa6b1..8f061971a7d1 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -14,6 +14,7 @@
  * GNU General Public License for more details.
  */
 
+#include 
 #include 
 #include 
 /* FIXME: needed for gpio_to_irq(), get rid of this */
@@ -49,6 +50,8 @@
 #defineATMEL_PIO_IFSCEN_MASK   BIT(13)
 #defineATMEL_PIO_OPD_MASK  BIT(14)
 #defineATMEL_PIO_SCHMITT_MASK  BIT(15)
+#defineATMEL_PIO_DRVSTR_MASK   GENMASK(17, 16)
+#defineATMEL_PIO_DRVSTR_OFFSET 16
 #defineATMEL_PIO_CFGR_EVTSEL_MASK  GENMASK(26, 24)
 #defineATMEL_PIO_CFGR_EVTSEL_FALLING   (0 << 24)
 #defineATMEL_PIO_CFGR_EVTSEL_RISING(1 << 24)
@@ -75,6 +78,9 @@
 #define ATMEL_GET_PIN_FUNC(pinfunc)((pinfunc >> 16) & 0xf)
 #define ATMEL_GET_PIN_IOSET(pinfunc)   ((pinfunc >> 20) & 0xf)
 
+/* Custom pinconf parameters */
+#define ATMEL_PIN_CONFIG_DRIVE_STRENGTH(PIN_CONFIG_END + 1)
+
 struct atmel_pioctrl_data {
unsigned nbanks;
 };
@@ -139,6 +145,10 @@ static const char * const atmel_functions[] = {
"GPIO", "A", "B", "C", "D", "E", "F", "G"
 };
 
+static const struct pinconf_generic_params atmel_custom_bindings[] = {
+   {"atmel,drive-strength", ATMEL_PIN_CONFIG_DRIVE_STRENGTH, 0},
+};
+
 /* --- GPIO --- */
 static unsigned int atmel_gpio_read(struct atmel_pioctrl *atmel_pioctrl,
unsigned int bank, unsigned int reg)
@@ -692,6 +702,11 @@ static int atmel_conf_pin_config_group_get(struct 
pinctrl_dev *pctldev,
return -EINVAL;
arg = 1;
break;
+   case ATMEL_PIN_CONFIG_DRIVE_STRENGTH:
+   if (!(res & ATMEL_PIO_DRVSTR_MASK))
+   return -EINVAL;
+   arg = (res & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET;
+   break;
default:
return -ENOTSUPP;
}
@@ -777,6 +792,18 @@ static int atmel_conf_pin_config_group_set(struct 
pinctrl_dev *pctldev,
ATMEL_PIO_SODR);
}
break;
+   case ATMEL_PIN_CONFIG_DRIVE_STRENGTH:
+   switch (arg) {
+   case ATMEL_PIO_DRVSTR_LO:
+   case ATMEL_PIO_DRVSTR_ME:
+   case ATMEL_PIO_DRVSTR_HI:
+   conf &= (~ATMEL_PIO_DRVSTR_MASK);
+   conf |= arg << ATMEL_PIO_DRVSTR_OFFSET;
+

Re: [PATCH v7 3/6] mfd: at91-usart: added mfd driver for usart

2018-06-14 Thread Ludovic Desroches
On Wed, Jun 13, 2018 at 07:36:18PM +0300, Radu Pirea wrote:
> This mfd driver is just a wrapper over atmel_serial driver and
> spi-at91-usart driver. Selection of one of the drivers is based on a
> property from device tree. If the property is not specified, the default
> driver is atmel_serial.
> 
> Signed-off-by: Radu Pirea 
> Acked-by: Rob Herring 
> Reviewed-by: Andy Shevchenko 
> Acked-for-MFD-by: Lee Jones 
> ---
>  drivers/mfd/Kconfig  |  9 ++
>  drivers/mfd/Makefile |  1 +
>  drivers/mfd/at91-usart.c | 69 
>  3 files changed, 79 insertions(+)
>  create mode 100644 drivers/mfd/at91-usart.c
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index b860eb5aa194..a886672b960d 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -99,6 +99,15 @@ config MFD_AAT2870_CORE
> additional drivers must be enabled in order to use the
> functionality of the device.
>  
> +config MFD_AT91_USART
> + tristate "AT91 USART Driver"
> + select MFD_CORE
> + help
> +   Select this to get support for AT91 USART IP. This is a wrapper
> +   over at91-usart-serial driver and usart-spi-driver. Only one function
> +   can be used at a time. The choice is done at boot time by the probe
> +   function of this MFD driver according to a device tree property.
> +
>  config MFD_ATMEL_FLEXCOM
>   tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
>   select MFD_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index d9d2cf0d32ef..db1332aa96db 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC)   += qcom-spmi-pmic.o
>  obj-$(CONFIG_TPS65911_COMPARATOR)+= tps65911-comparator.o
>  obj-$(CONFIG_MFD_TPS65090)   += tps65090.o
>  obj-$(CONFIG_MFD_AAT2870_CORE)   += aat2870-core.o
> +obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o
>  obj-$(CONFIG_MFD_ATMEL_FLEXCOM)  += atmel-flexcom.o
>  obj-$(CONFIG_MFD_ATMEL_HLCDC)+= atmel-hlcdc.o
>  obj-$(CONFIG_MFD_ATMEL_SMC)  += atmel-smc.o
> diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c
> new file mode 100644
> index ..3014ce532644
> --- /dev/null
> +++ b/drivers/mfd/at91-usart.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for AT91 USART
> + *
> + * Copyright (C) 2018 Microchip Technology
> + *
> + * Author: Radu Pirea 
> + *
> + */
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +static struct mfd_cell at91_usart_spi_subdev = {
> + .name = "at91_usart_spi",
> + .of_compatible = "microchip,at91sam9g45-usart-spi",
> + };
> +
> +static struct mfd_cell at91_usart_serial_subdev = {
> + .name = "atmel_usart_serial",
> + .of_compatible = "atmel,at91rm9200-usart-serial",
> + };
> +
> +static int at91_usart_mode_probe(struct platform_device *pdev)
> +{
> + struct mfd_cell cell;
> + u32 opmode = AT91_USART_MODE_SERIAL;
> +
> + device_property_read_u32(>dev, "atmel,usart-mode", );
> +
> + switch (opmode) {
> + case AT91_USART_MODE_SPI:
> + cell = at91_usart_spi_subdev;
> + break;
> + case AT91_USART_MODE_SERIAL:
> + cell = at91_usart_serial_subdev;
> + break;
> + default:
> + break;

If there is an invalid opmode from the DT, you will pass a non initialized cell
to mfd_add_device().

Regards

Ludovic

> + }
> +
> + return devm_mfd_add_devices(>dev, PLATFORM_DEVID_AUTO, , 1,
> +   NULL, 0, NULL);
> +}
> +
> +static const struct of_device_id at91_usart_mode_of_match[] = {
> + { .compatible = "atmel,at91rm9200-usart" },
> + { .compatible = "atmel,at91sam9260-usart" },
> + { /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, at91_flexcom_of_match);
> +
> +static struct platform_driver at91_usart_mfd = {
> + .probe  = at91_usart_mode_probe,
> + .driver = {
> + .name   = "at91_usart_mode",
> + .of_match_table = at91_usart_mode_of_match,
> + },
> +};
> +
> +module_platform_driver(at91_usart_mfd);
> +
> +MODULE_AUTHOR("Radu Pirea ");
> +MODULE_DESCRIPTION("AT91 USART MFD driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.17.1
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH v7 3/6] mfd: at91-usart: added mfd driver for usart

2018-06-14 Thread Ludovic Desroches
On Wed, Jun 13, 2018 at 07:36:18PM +0300, Radu Pirea wrote:
> This mfd driver is just a wrapper over atmel_serial driver and
> spi-at91-usart driver. Selection of one of the drivers is based on a
> property from device tree. If the property is not specified, the default
> driver is atmel_serial.
> 
> Signed-off-by: Radu Pirea 
> Acked-by: Rob Herring 
> Reviewed-by: Andy Shevchenko 
> Acked-for-MFD-by: Lee Jones 
> ---
>  drivers/mfd/Kconfig  |  9 ++
>  drivers/mfd/Makefile |  1 +
>  drivers/mfd/at91-usart.c | 69 
>  3 files changed, 79 insertions(+)
>  create mode 100644 drivers/mfd/at91-usart.c
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index b860eb5aa194..a886672b960d 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -99,6 +99,15 @@ config MFD_AAT2870_CORE
> additional drivers must be enabled in order to use the
> functionality of the device.
>  
> +config MFD_AT91_USART
> + tristate "AT91 USART Driver"
> + select MFD_CORE
> + help
> +   Select this to get support for AT91 USART IP. This is a wrapper
> +   over at91-usart-serial driver and usart-spi-driver. Only one function
> +   can be used at a time. The choice is done at boot time by the probe
> +   function of this MFD driver according to a device tree property.
> +
>  config MFD_ATMEL_FLEXCOM
>   tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
>   select MFD_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index d9d2cf0d32ef..db1332aa96db 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC)   += qcom-spmi-pmic.o
>  obj-$(CONFIG_TPS65911_COMPARATOR)+= tps65911-comparator.o
>  obj-$(CONFIG_MFD_TPS65090)   += tps65090.o
>  obj-$(CONFIG_MFD_AAT2870_CORE)   += aat2870-core.o
> +obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o
>  obj-$(CONFIG_MFD_ATMEL_FLEXCOM)  += atmel-flexcom.o
>  obj-$(CONFIG_MFD_ATMEL_HLCDC)+= atmel-hlcdc.o
>  obj-$(CONFIG_MFD_ATMEL_SMC)  += atmel-smc.o
> diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c
> new file mode 100644
> index ..3014ce532644
> --- /dev/null
> +++ b/drivers/mfd/at91-usart.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for AT91 USART
> + *
> + * Copyright (C) 2018 Microchip Technology
> + *
> + * Author: Radu Pirea 
> + *
> + */
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +static struct mfd_cell at91_usart_spi_subdev = {
> + .name = "at91_usart_spi",
> + .of_compatible = "microchip,at91sam9g45-usart-spi",
> + };
> +
> +static struct mfd_cell at91_usart_serial_subdev = {
> + .name = "atmel_usart_serial",
> + .of_compatible = "atmel,at91rm9200-usart-serial",
> + };
> +
> +static int at91_usart_mode_probe(struct platform_device *pdev)
> +{
> + struct mfd_cell cell;
> + u32 opmode = AT91_USART_MODE_SERIAL;
> +
> + device_property_read_u32(>dev, "atmel,usart-mode", );
> +
> + switch (opmode) {
> + case AT91_USART_MODE_SPI:
> + cell = at91_usart_spi_subdev;
> + break;
> + case AT91_USART_MODE_SERIAL:
> + cell = at91_usart_serial_subdev;
> + break;
> + default:
> + break;

If there is an invalid opmode from the DT, you will pass a non initialized cell
to mfd_add_device().

Regards

Ludovic

> + }
> +
> + return devm_mfd_add_devices(>dev, PLATFORM_DEVID_AUTO, , 1,
> +   NULL, 0, NULL);
> +}
> +
> +static const struct of_device_id at91_usart_mode_of_match[] = {
> + { .compatible = "atmel,at91rm9200-usart" },
> + { .compatible = "atmel,at91sam9260-usart" },
> + { /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, at91_flexcom_of_match);
> +
> +static struct platform_driver at91_usart_mfd = {
> + .probe  = at91_usart_mode_probe,
> + .driver = {
> + .name   = "at91_usart_mode",
> + .of_match_table = at91_usart_mode_of_match,
> + },
> +};
> +
> +module_platform_driver(at91_usart_mfd);
> +
> +MODULE_AUTHOR("Radu Pirea ");
> +MODULE_DESCRIPTION("AT91 USART MFD driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.17.1
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH 1/5] pinctrl: at91-pio4: add missing of_node_put

2018-05-24 Thread Ludovic Desroches
On Wed, May 23, 2018 at 09:07:12PM +0200, Julia Lawall wrote:
> The device node iterators perform an of_node_get on each iteration, so a
> jump out of the loop requires an of_node_put.
> 
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
> 
> // 
> @@
> expression root,e;
> local idexpression child;
> iterator name for_each_child_of_node;
> @@
> 
>  for_each_child_of_node(root, child) {
>... when != of_node_put(child)
>when != e = child
> +  of_node_put(child);
> ?  break;
>...
> }
> ... when != child
> // 
> 
> Signed-off-by: Julia Lawall <julia.law...@lip6.fr>
Acked-by: Ludovic Desroches <ludovic.desroc...@microchip.com>

Thanks
> 
> ---
>  drivers/pinctrl/pinctrl-at91-pio4.c |4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c 
> b/drivers/pinctrl/pinctrl-at91-pio4.c
> index 4b57a13..bafb3d4 100644
> --- a/drivers/pinctrl/pinctrl-at91-pio4.c
> +++ b/drivers/pinctrl/pinctrl-at91-pio4.c
> @@ -576,8 +576,10 @@ static int atmel_pctl_dt_node_to_map(struct pinctrl_dev 
> *pctldev,
>   for_each_child_of_node(np_config, np) {
>   ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map,
>   _maps, num_maps);
> - if (ret < 0)
> + if (ret < 0) {
> + of_node_put(np);
>   break;
> + }
>   }
>   }
>  
> 


Re: [PATCH 1/5] pinctrl: at91-pio4: add missing of_node_put

2018-05-24 Thread Ludovic Desroches
On Wed, May 23, 2018 at 09:07:12PM +0200, Julia Lawall wrote:
> The device node iterators perform an of_node_get on each iteration, so a
> jump out of the loop requires an of_node_put.
> 
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
> 
> // 
> @@
> expression root,e;
> local idexpression child;
> iterator name for_each_child_of_node;
> @@
> 
>  for_each_child_of_node(root, child) {
>... when != of_node_put(child)
>when != e = child
> +  of_node_put(child);
> ?  break;
>...
> }
> ... when != child
> // 
> 
> Signed-off-by: Julia Lawall 
Acked-by: Ludovic Desroches 

Thanks
> 
> ---
>  drivers/pinctrl/pinctrl-at91-pio4.c |4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c 
> b/drivers/pinctrl/pinctrl-at91-pio4.c
> index 4b57a13..bafb3d4 100644
> --- a/drivers/pinctrl/pinctrl-at91-pio4.c
> +++ b/drivers/pinctrl/pinctrl-at91-pio4.c
> @@ -576,8 +576,10 @@ static int atmel_pctl_dt_node_to_map(struct pinctrl_dev 
> *pctldev,
>   for_each_child_of_node(np_config, np) {
>   ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map,
>   _maps, num_maps);
> - if (ret < 0)
> + if (ret < 0) {
> + of_node_put(np);
>   break;
> + }
>   }
>   }
>  
> 


Re: [PATCH v7 7/9] dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific consumer info

2018-05-22 Thread Ludovic Desroches
On Tue, May 22, 2018 at 10:52:37AM +0300, Eugen Hristev wrote:
> Added defines for channel consumer device-tree binding
> 
> Signed-off-by: Eugen Hristev <eugen.hris...@microchip.com>
> Reviewed-by: Rob Herring <r...@kernel.org>
Acked-by: Ludovic Desroches <ludovic.desroc...@microchip.com>

> ---
>  .../devicetree/bindings/iio/adc/at91-sama5d2_adc.txt |  9 +
>  include/dt-bindings/iio/adc/at91-sama5d2_adc.h   | 16 
> 
>  2 files changed, 25 insertions(+)
>  create mode 100644 include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt 
> b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> index 6469a4c..4a3c1d4 100644
> --- a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> +++ b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> @@ -21,6 +21,14 @@ Optional properties:
>- dmas: Phandle to dma channel for the ADC.
>- dma-names: Must be "rx" when dmas property is being used.
>See ../../dma/dma.txt for details.
> +  - #io-channel-cells: in case consumer drivers are attached, this must be 1.
> +  See  for details.
> +
> +Properties for consumer drivers:
> +  - Consumer drivers can be connected to this producer device, as specified
> +  in 
> +  - Channels exposed are specified in:
> +  
>  
>  Example:
>  
> @@ -38,4 +46,5 @@ adc: adc@fc03 {
>   atmel,trigger-edge-type = ;
>   dmas = < (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | 
> AT91_XDMAC_DT_PERID(25))>;
>   dma-names = "rx";
> + #io-channel-cells = <1>;
>  }
> diff --git a/include/dt-bindings/iio/adc/at91-sama5d2_adc.h 
> b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> new file mode 100644
> index 000..70f99db
> --- /dev/null
> +++ b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * This header provides constants for configuring the AT91 SAMA5D2 ADC
> + */
> +
> +#ifndef _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H
> +#define _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H
> +
> +/* X relative position channel index */
> +#define AT91_SAMA5D2_ADC_X_CHANNEL   24
> +/* Y relative position channel index */
> +#define AT91_SAMA5D2_ADC_Y_CHANNEL   25
> +/* pressure channel index */
> +#define AT91_SAMA5D2_ADC_P_CHANNEL   26
> +
> +#endif
> -- 
> 2.7.4
> 


Re: [PATCH v7 7/9] dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific consumer info

2018-05-22 Thread Ludovic Desroches
On Tue, May 22, 2018 at 10:52:37AM +0300, Eugen Hristev wrote:
> Added defines for channel consumer device-tree binding
> 
> Signed-off-by: Eugen Hristev 
> Reviewed-by: Rob Herring 
Acked-by: Ludovic Desroches 

> ---
>  .../devicetree/bindings/iio/adc/at91-sama5d2_adc.txt |  9 +
>  include/dt-bindings/iio/adc/at91-sama5d2_adc.h   | 16 
> 
>  2 files changed, 25 insertions(+)
>  create mode 100644 include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt 
> b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> index 6469a4c..4a3c1d4 100644
> --- a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> +++ b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
> @@ -21,6 +21,14 @@ Optional properties:
>- dmas: Phandle to dma channel for the ADC.
>- dma-names: Must be "rx" when dmas property is being used.
>See ../../dma/dma.txt for details.
> +  - #io-channel-cells: in case consumer drivers are attached, this must be 1.
> +  See  for details.
> +
> +Properties for consumer drivers:
> +  - Consumer drivers can be connected to this producer device, as specified
> +  in 
> +  - Channels exposed are specified in:
> +  
>  
>  Example:
>  
> @@ -38,4 +46,5 @@ adc: adc@fc03 {
>   atmel,trigger-edge-type = ;
>   dmas = < (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | 
> AT91_XDMAC_DT_PERID(25))>;
>   dma-names = "rx";
> + #io-channel-cells = <1>;
>  }
> diff --git a/include/dt-bindings/iio/adc/at91-sama5d2_adc.h 
> b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> new file mode 100644
> index 000..70f99db
> --- /dev/null
> +++ b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * This header provides constants for configuring the AT91 SAMA5D2 ADC
> + */
> +
> +#ifndef _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H
> +#define _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H
> +
> +/* X relative position channel index */
> +#define AT91_SAMA5D2_ADC_X_CHANNEL   24
> +/* Y relative position channel index */
> +#define AT91_SAMA5D2_ADC_Y_CHANNEL   25
> +/* pressure channel index */
> +#define AT91_SAMA5D2_ADC_P_CHANNEL   26
> +
> +#endif
> -- 
> 2.7.4
> 


Re: [PATCH v7 5/9] iio: adc: at91-sama5d2_adc: add support for position and pressure channels

2018-05-22 Thread Ludovic Desroches
On Tue, May 22, 2018 at 10:52:35AM +0300, Eugen Hristev wrote:
> This implements the support for position and pressure for the included
> touchscreen support in the SAMA5D2 SOC ADC block.
> Two position channels are added and one for pressure.
> They can be read in raw format, or through a buffer.
> A normal use case is for a consumer driver to register a callback buffer
> for these channels.
> When the touchscreen channels are in the active scan mask,
> the driver will start the touchscreen sampling and push the data to the
> buffer.
> 
> Some parts of this patch are based on initial original work by
> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
> 
> Signed-off-by: Eugen Hristev <eugen.hris...@microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroc...@microchip.com>

> ---
> Changes in v6:
>  - fixed a crash when issuing buffer enable from sysfs, if no trigger was
> previously configured. This is because now the driver can work in software
> buffer mode (to connect the callback buffer). So, when trying to enable the
> buffer, check if we are going indeed to a triggered mode or not. If not, do
> not allow buffer to be started (we do not have the right trigger).
> It's in buffer_postenable and predisable.
> 
> Changes in v4:
>  - use return value of at91_adc_configure_touch
>  - rewrote some part of the read_info_raw according to Jonathan's
> suggestion
> 
> Changes in v3:
>  - prefix macros with AT91_SAMA5D2
>  - reworked the x_pos and y_pos functions into a single one with two
> additional wrappers
>  - reworked pressure report to have it grow naturally and not top down
>  - fixed some checks regarding IIO_VOLTAGE as suggested
>  - added a comment explaining some code in trigger handling
>  - reworked the frequency get handler to use the saved value instead of
> reading it from the hardware.
>  - added comment on deffered work queueing
>  - pulled out INFO_RAW function into a separate utility function as suggested
>  - added iio_dev ops structure at all times . The functions are needed in
> case we do not have a hardware trigger attached, but we want to use the
> consumer touchscreen driver, thus a callback buffer is attached. Then we still
> need to have buffer preenable and postdisable to configure the touch IRQs 
> (etc.)
> 
> Changes in v2:
>  - the support is now based on callback buffer.
> 
>  drivers/iio/adc/at91-sama5d2_adc.c | 609 
> +
>  1 file changed, 551 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c 
> b/drivers/iio/adc/at91-sama5d2_adc.c
> index 8729d65..58c4c2b 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -102,14 +102,26 @@
>  #define AT91_SAMA5D2_LCDR0x20
>  /* Interrupt Enable Register */
>  #define AT91_SAMA5D2_IER 0x24
> +/* Interrupt Enable Register - TS X measurement ready */
> +#define AT91_SAMA5D2_IER_XRDY   BIT(20)
> +/* Interrupt Enable Register - TS Y measurement ready */
> +#define AT91_SAMA5D2_IER_YRDY   BIT(21)
> +/* Interrupt Enable Register - TS pressure measurement ready */
> +#define AT91_SAMA5D2_IER_PRDY   BIT(22)
>  /* Interrupt Enable Register - general overrun error */
>  #define AT91_SAMA5D2_IER_GOVRE BIT(25)
> +/* Interrupt Enable Register - Pen detect */
> +#define AT91_SAMA5D2_IER_PENBIT(29)
> +/* Interrupt Enable Register - No pen detect */
> +#define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>  /* Interrupt Disable Register */
>  #define AT91_SAMA5D2_IDR 0x28
>  /* Interrupt Mask Register */
>  #define AT91_SAMA5D2_IMR 0x2c
>  /* Interrupt Status Register */
>  #define AT91_SAMA5D2_ISR 0x30
> +/* Interrupt Status Register - Pen touching sense status */
> +#define AT91_SAMA5D2_ISR_PENS   BIT(31)
>  /* Last Channel Trigger Mode Register */
>  #define AT91_SAMA5D2_LCTMR   0x34
>  /* Last Channel Compare Window Register */
> @@ -131,8 +143,38 @@
>  #define AT91_SAMA5D2_CDR00x50
>  /* Analog Control Register */
>  #define AT91_SAMA5D2_ACR 0x94
> +/* Analog Control Register - Pen detect sensitivity mask */
> +#define AT91_SAMA5D2_ACR_PENDETSENS_MASKGENMASK(1, 0)
> +
>  /* Touchscreen Mode Register */
>  #define AT91_SAMA5D2_TSMR0xb0
> +/* Touchscreen Mode Register - No touch mode */
> +#define AT91_SAMA5D2_TSMR_TSMODE_NONE   0
> +/* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_NO_PRESS 1
> +/* Touchscreen Mode Register - 4 wire screen, pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_PRESS2
> +/* Touchscreen Mode Register - 5 wire screen */
> +#define AT91_SAMA5D2_TSMR_TSMODE_5WIRE   

Re: [PATCH v7 5/9] iio: adc: at91-sama5d2_adc: add support for position and pressure channels

2018-05-22 Thread Ludovic Desroches
On Tue, May 22, 2018 at 10:52:35AM +0300, Eugen Hristev wrote:
> This implements the support for position and pressure for the included
> touchscreen support in the SAMA5D2 SOC ADC block.
> Two position channels are added and one for pressure.
> They can be read in raw format, or through a buffer.
> A normal use case is for a consumer driver to register a callback buffer
> for these channels.
> When the touchscreen channels are in the active scan mask,
> the driver will start the touchscreen sampling and push the data to the
> buffer.
> 
> Some parts of this patch are based on initial original work by
> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
> 
> Signed-off-by: Eugen Hristev 
Acked-by: Ludovic Desroches 

> ---
> Changes in v6:
>  - fixed a crash when issuing buffer enable from sysfs, if no trigger was
> previously configured. This is because now the driver can work in software
> buffer mode (to connect the callback buffer). So, when trying to enable the
> buffer, check if we are going indeed to a triggered mode or not. If not, do
> not allow buffer to be started (we do not have the right trigger).
> It's in buffer_postenable and predisable.
> 
> Changes in v4:
>  - use return value of at91_adc_configure_touch
>  - rewrote some part of the read_info_raw according to Jonathan's
> suggestion
> 
> Changes in v3:
>  - prefix macros with AT91_SAMA5D2
>  - reworked the x_pos and y_pos functions into a single one with two
> additional wrappers
>  - reworked pressure report to have it grow naturally and not top down
>  - fixed some checks regarding IIO_VOLTAGE as suggested
>  - added a comment explaining some code in trigger handling
>  - reworked the frequency get handler to use the saved value instead of
> reading it from the hardware.
>  - added comment on deffered work queueing
>  - pulled out INFO_RAW function into a separate utility function as suggested
>  - added iio_dev ops structure at all times . The functions are needed in
> case we do not have a hardware trigger attached, but we want to use the
> consumer touchscreen driver, thus a callback buffer is attached. Then we still
> need to have buffer preenable and postdisable to configure the touch IRQs 
> (etc.)
> 
> Changes in v2:
>  - the support is now based on callback buffer.
> 
>  drivers/iio/adc/at91-sama5d2_adc.c | 609 
> +
>  1 file changed, 551 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c 
> b/drivers/iio/adc/at91-sama5d2_adc.c
> index 8729d65..58c4c2b 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -102,14 +102,26 @@
>  #define AT91_SAMA5D2_LCDR0x20
>  /* Interrupt Enable Register */
>  #define AT91_SAMA5D2_IER 0x24
> +/* Interrupt Enable Register - TS X measurement ready */
> +#define AT91_SAMA5D2_IER_XRDY   BIT(20)
> +/* Interrupt Enable Register - TS Y measurement ready */
> +#define AT91_SAMA5D2_IER_YRDY   BIT(21)
> +/* Interrupt Enable Register - TS pressure measurement ready */
> +#define AT91_SAMA5D2_IER_PRDY   BIT(22)
>  /* Interrupt Enable Register - general overrun error */
>  #define AT91_SAMA5D2_IER_GOVRE BIT(25)
> +/* Interrupt Enable Register - Pen detect */
> +#define AT91_SAMA5D2_IER_PENBIT(29)
> +/* Interrupt Enable Register - No pen detect */
> +#define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>  /* Interrupt Disable Register */
>  #define AT91_SAMA5D2_IDR 0x28
>  /* Interrupt Mask Register */
>  #define AT91_SAMA5D2_IMR 0x2c
>  /* Interrupt Status Register */
>  #define AT91_SAMA5D2_ISR 0x30
> +/* Interrupt Status Register - Pen touching sense status */
> +#define AT91_SAMA5D2_ISR_PENS   BIT(31)
>  /* Last Channel Trigger Mode Register */
>  #define AT91_SAMA5D2_LCTMR   0x34
>  /* Last Channel Compare Window Register */
> @@ -131,8 +143,38 @@
>  #define AT91_SAMA5D2_CDR00x50
>  /* Analog Control Register */
>  #define AT91_SAMA5D2_ACR 0x94
> +/* Analog Control Register - Pen detect sensitivity mask */
> +#define AT91_SAMA5D2_ACR_PENDETSENS_MASKGENMASK(1, 0)
> +
>  /* Touchscreen Mode Register */
>  #define AT91_SAMA5D2_TSMR0xb0
> +/* Touchscreen Mode Register - No touch mode */
> +#define AT91_SAMA5D2_TSMR_TSMODE_NONE   0
> +/* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_NO_PRESS 1
> +/* Touchscreen Mode Register - 4 wire screen, pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_PRESS2
> +/* Touchscreen Mode Register - 5 wire screen */
> +#define AT91_SAMA5D2_TSMR_TSMODE_5WIRE  3
> +/* Touchscreen Mode Register - Average samples mask */
>

Re: [PATCH v2] i2c: at91: Read all available bytes at once

2018-04-26 Thread Ludovic Desroches
On Thu, Apr 26, 2018 at 11:53:14AM +0200, David Engraf wrote:
> With FIFO enabled it is possible to read multiple bytes
> at once in the interrupt handler as long as RXRDY is
> set. This may also reduce the number of interrupts.
> 
> This patch polls RXRDY and reads all available bytes at
> once.
> 
> Signed-off-by: David Engraf <david.eng...@sysgo.com>
Acked-by: Ludovic Desroches <ludovic.desroc...@microchip.com>

Thanks a lot David.

Regards

Ludovic

> ---
>  drivers/i2c/busses/i2c-at91.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index bfd1fdff64a9..9caee5b79eac 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -518,8 +518,16 @@ static irqreturn_t atmel_twi_interrupt(int irq, void 
> *dev_id)
>* the RXRDY interrupt first in order to not keep garbage data in the
>* Receive Holding Register for the next transfer.
>*/
> - if (irqstatus & AT91_TWI_RXRDY)
> - at91_twi_read_next_byte(dev);
> + if (irqstatus & AT91_TWI_RXRDY) {
> + /*
> +  * Read all available bytes at once by polling RXRDY usable w/ 
> and w/o
> +  * FIFO. With FIFO enabled we could also read RXFL and avoid 
> polling
> +  * RXRDY.
> +  */
> + do {
> + at91_twi_read_next_byte(dev);
> + } while (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY);
> + }
>  
>   /*
>* When a NACK condition is detected, the I2C controller sets the NACK,
> -- 
> 2.14.1
> 


Re: [PATCH v2] i2c: at91: Read all available bytes at once

2018-04-26 Thread Ludovic Desroches
On Thu, Apr 26, 2018 at 11:53:14AM +0200, David Engraf wrote:
> With FIFO enabled it is possible to read multiple bytes
> at once in the interrupt handler as long as RXRDY is
> set. This may also reduce the number of interrupts.
> 
> This patch polls RXRDY and reads all available bytes at
> once.
> 
> Signed-off-by: David Engraf 
Acked-by: Ludovic Desroches 

Thanks a lot David.

Regards

Ludovic

> ---
>  drivers/i2c/busses/i2c-at91.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index bfd1fdff64a9..9caee5b79eac 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -518,8 +518,16 @@ static irqreturn_t atmel_twi_interrupt(int irq, void 
> *dev_id)
>* the RXRDY interrupt first in order to not keep garbage data in the
>* Receive Holding Register for the next transfer.
>*/
> - if (irqstatus & AT91_TWI_RXRDY)
> - at91_twi_read_next_byte(dev);
> + if (irqstatus & AT91_TWI_RXRDY) {
> + /*
> +  * Read all available bytes at once by polling RXRDY usable w/ 
> and w/o
> +  * FIFO. With FIFO enabled we could also read RXFL and avoid 
> polling
> +  * RXRDY.
> +  */
> + do {
> + at91_twi_read_next_byte(dev);
> + } while (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY);
> + }
>  
>   /*
>* When a NACK condition is detected, the I2C controller sets the NACK,
> -- 
> 2.14.1
> 


<    1   2   3   4   5   6   7   8   9   10   >