[PATCH v3 2/3] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-21 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers.

Use existing dspi_data_to_pushr function to restructure the transmit
code path and set or reset the CONT bit on same lines as code path
in EOQ mode does. This correctly implements continuous selection format
while also correcting and cleaning up the transmit code path.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 911aadb..8af3151 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -196,6 +196,8 @@ struct fsl_dspi {
struct fsl_dspi_dma *dma;
 };
 
+static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
+
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
 {
unsigned int val;
@@ -242,24 +244,15 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
int time_left;
int tx_word;
int i;
-   u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] =
-   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
-   dspi->tx += tx_word + 1;
+   for (i = 0; i < dma->curr_xfer_len; i++) {
+   dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
+   if ((dspi->cs_change) && (!dspi->len))
+   dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
-   SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0);
-   dspi->tx += tx_word + 1;
-
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
dma->curr_xfer_len *
@@ -351,7 +344,6 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
curr_remaining_bytes -= dma->curr_xfer_len * word;
if (curr_remaining_bytes < 0)
curr_remaining_bytes = 0;
-   dspi->len = curr_remaining_bytes;
}
}
 
-- 
2.10.2



[PATCH v3 2/3] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-21 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers.

Use existing dspi_data_to_pushr function to restructure the transmit
code path and set or reset the CONT bit on same lines as code path
in EOQ mode does. This correctly implements continuous selection format
while also correcting and cleaning up the transmit code path.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 911aadb..8af3151 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -196,6 +196,8 @@ struct fsl_dspi {
struct fsl_dspi_dma *dma;
 };
 
+static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
+
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
 {
unsigned int val;
@@ -242,24 +244,15 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
int time_left;
int tx_word;
int i;
-   u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] =
-   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
-   dspi->tx += tx_word + 1;
+   for (i = 0; i < dma->curr_xfer_len; i++) {
+   dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
+   if ((dspi->cs_change) && (!dspi->len))
+   dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
-   SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0);
-   dspi->tx += tx_word + 1;
-
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
dma->curr_xfer_len *
@@ -351,7 +344,6 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
curr_remaining_bytes -= dma->curr_xfer_len * word;
if (curr_remaining_bytes < 0)
curr_remaining_bytes = 0;
-   dspi->len = curr_remaining_bytes;
}
}
 
-- 
2.10.2



[PATCH v3 0/3] Fixes for Vybrid SPI DMA implementation

2016-11-21 Thread Sanchayan Maity
Hello,

This v3 set of patches have fixes for Vybrid SPI DMA
implementation and is rebased on top of latest topic/fsl-dspi. 

http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module
and now incoporate feedback from Stefan on version 2 of patchset.

Changes since v2:
1. Drop the patch "Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE"
since it's now applied and rebase the whole patchset
2. Second patch in this series "Fix continuous selection format" now
fixes the issue using an existing function and handling it similar to
existing EOQ mode and also cleaning up nicely the transmit code path.
3. Third patch now just fixes the incorrect freeing of DMA allocated buffers
and drops the minor clean up patch from earlier series completely due to
the clean up from 2 above.

Changes since v1:
1. Place the continuous selection format patch second in order and remove
code duplication
2. Improve the use of curr_xfer_len and instead of converting from bytes
to DMA transfers in every use, do it at a single place. Accordingly change
it's use at other places
3. Code cleanup patch has less to clean with change above

v2:
https://www.spinics.net/lists/arm-kernel/msg543941.html

v1:
http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1274632.html

Thanks & Regards,
Sanchayan.

Sanchayan Maity (3):
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Fix incorrect freeing of DMA allocated buffers

 drivers/spi/spi-fsl-dspi.c | 59 +-
 1 file changed, 27 insertions(+), 32 deletions(-)

-- 
2.10.2



[PATCH v3 3/3] spi: spi-fsl-dspi: Fix incorrect freeing of DMA allocated buffers

2016-11-21 Thread Sanchayan Maity
Buffers allocated with a call to dma_alloc_coherent should be
freed with dma_free_coherent instead of the currently used
devm_kfree.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 8af3151..7ada112 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -420,9 +420,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
-- 
2.10.2



[PATCH v3 1/3] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-21 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

While at it also clean up the use of curr_xfer_len which is central
to the DMA setup, from bytes to DMA transfers for every use.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
Reviewed-by: Stefan Agner <ste...@agner.ch>
---
 drivers/spi/spi-fsl-dspi.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..911aadb 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
 };
 
 struct fsl_dspi_dma {
+   /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len;
 
u32 *tx_dma_buf;
@@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg)
struct fsl_dspi *dspi = arg;
struct fsl_dspi_dma *dma = dspi->dma;
int rx_word;
-   int i, len;
+   int i;
u16 d;
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
-   for (i = 0; i < len; i++) {
+   for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
rx_word ? (*(u16 *)dspi->rx = d) :
(*(u8 *)dspi->rx = d);
@@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
struct device *dev = >pdev->dev;
int time_left;
int tx_word;
-   int i, len;
+   int i;
u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
-   for (i = 0; i < len - 1; i++) {
+   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
@@ -265,7 +262,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -281,7 +280,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -328,17 +329,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
struct device *dev = >pdev->dev;
int curr_remaining_bytes;
int bytes_per_buffer;
-   int tx_word;
+   int word = 1;
int ret = 0;
 
-   tx_word = is_double_byte_mode(dspi);
+   if (is_double_byte_mode(dspi))
+   word = 2;
curr_remaining_bytes = dspi->len;
+   bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
while (curr_remaining_bytes) {
/* Check if current transfer fits the DMA buffer */
-   dma->curr_xfer_len = curr_remaining_bytes;
-   bytes_per_buffer = DSPI_DMA_BUFSIZE /
-   (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
-   if (curr_remaining_bytes > bytes_per_buffer)
+   dma->curr_xfer_len = curr_remaining_bytes / word;
+   if (dma->curr_xfer_len > bytes_per_buffer)
dma->curr_xfer_len = bytes_per_buffer;
 
ret = dspi_next_xfer_dma_submit(dspi);
@@ -347,7 +348,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
goto exit;
 

[PATCH v3 0/3] Fixes for Vybrid SPI DMA implementation

2016-11-21 Thread Sanchayan Maity
Hello,

This v3 set of patches have fixes for Vybrid SPI DMA
implementation and is rebased on top of latest topic/fsl-dspi. 

http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module
and now incoporate feedback from Stefan on version 2 of patchset.

Changes since v2:
1. Drop the patch "Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE"
since it's now applied and rebase the whole patchset
2. Second patch in this series "Fix continuous selection format" now
fixes the issue using an existing function and handling it similar to
existing EOQ mode and also cleaning up nicely the transmit code path.
3. Third patch now just fixes the incorrect freeing of DMA allocated buffers
and drops the minor clean up patch from earlier series completely due to
the clean up from 2 above.

Changes since v1:
1. Place the continuous selection format patch second in order and remove
code duplication
2. Improve the use of curr_xfer_len and instead of converting from bytes
to DMA transfers in every use, do it at a single place. Accordingly change
it's use at other places
3. Code cleanup patch has less to clean with change above

v2:
https://www.spinics.net/lists/arm-kernel/msg543941.html

v1:
http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1274632.html

Thanks & Regards,
Sanchayan.

Sanchayan Maity (3):
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Fix incorrect freeing of DMA allocated buffers

 drivers/spi/spi-fsl-dspi.c | 59 +-
 1 file changed, 27 insertions(+), 32 deletions(-)

-- 
2.10.2



[PATCH v3 3/3] spi: spi-fsl-dspi: Fix incorrect freeing of DMA allocated buffers

2016-11-21 Thread Sanchayan Maity
Buffers allocated with a call to dma_alloc_coherent should be
freed with dma_free_coherent instead of the currently used
devm_kfree.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 8af3151..7ada112 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -420,9 +420,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
-- 
2.10.2



[PATCH v3 1/3] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-21 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

While at it also clean up the use of curr_xfer_len which is central
to the DMA setup, from bytes to DMA transfers for every use.

Signed-off-by: Sanchayan Maity 
Reviewed-by: Stefan Agner 
---
 drivers/spi/spi-fsl-dspi.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..911aadb 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
 };
 
 struct fsl_dspi_dma {
+   /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len;
 
u32 *tx_dma_buf;
@@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg)
struct fsl_dspi *dspi = arg;
struct fsl_dspi_dma *dma = dspi->dma;
int rx_word;
-   int i, len;
+   int i;
u16 d;
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
-   for (i = 0; i < len; i++) {
+   for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
rx_word ? (*(u16 *)dspi->rx = d) :
(*(u8 *)dspi->rx = d);
@@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
struct device *dev = >pdev->dev;
int time_left;
int tx_word;
-   int i, len;
+   int i;
u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
-   for (i = 0; i < len - 1; i++) {
+   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
@@ -265,7 +262,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -281,7 +280,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -328,17 +329,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
struct device *dev = >pdev->dev;
int curr_remaining_bytes;
int bytes_per_buffer;
-   int tx_word;
+   int word = 1;
int ret = 0;
 
-   tx_word = is_double_byte_mode(dspi);
+   if (is_double_byte_mode(dspi))
+   word = 2;
curr_remaining_bytes = dspi->len;
+   bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
while (curr_remaining_bytes) {
/* Check if current transfer fits the DMA buffer */
-   dma->curr_xfer_len = curr_remaining_bytes;
-   bytes_per_buffer = DSPI_DMA_BUFSIZE /
-   (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
-   if (curr_remaining_bytes > bytes_per_buffer)
+   dma->curr_xfer_len = curr_remaining_bytes / word;
+   if (dma->curr_xfer_len > bytes_per_buffer)
dma->curr_xfer_len = bytes_per_buffer;
 
ret = dspi_next_xfer_dma_submit(dspi);
@@ -347,7 +348,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
goto exit;
 
} else {
-   curr_remaining_bytes 

[PATCH v2 2/4] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-20 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers. Use the cs_change variable and correctly set or
reset the CONT bit accordingly for case where peripherals require
the chip select to be asserted between sequential transfers.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..41422cd 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -261,6 +261,8 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
+   if (!dspi->cs_change)
+   dspi->dma->tx_dma_buf[i] |= SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
-- 
2.10.2



[PATCH v2 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes

2016-11-20 Thread Sanchayan Maity
Code cleanup for improving code readability and error path fixes
and cleanup removing use of devm_kfree.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 08882f7..2987a16 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -226,8 +226,10 @@ static void dspi_rx_dma_callback(void *arg)
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
-   rx_word ? (*(u16 *)dspi->rx = d) :
-   (*(u8 *)dspi->rx = d);
+   if (rx_word)
+   *(u16 *)dspi->rx = d;
+   else
+   *(u8 *)dspi->rx = d;
dspi->rx += rx_word + 1;
}
}
@@ -247,14 +249,20 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
tx_word = is_double_byte_mode(dspi);
 
for (i = 0; i < dma->curr_xfer_len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
@@ -430,9 +438,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
-- 
2.10.2



[PATCH v2 0/4] Fixes for Vybrid SPI DMA implementation

2016-11-20 Thread Sanchayan Maity
Hello,

The following set of patches have fixes for Vybrid SPI DMA
implementation along with some minor clean ups requested
at time when v3 version of SPI DMA support patch was accepted.

This series of patches is based on top of branch topic/fsl-dspi.
http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module
and now incoporate feedback from Stefan on version 1 of patchset.

Changes since v1:
1. Place the continuous selection format patch second in order and remove
code duplication
2. Improve the use of curr_xfer_len and instead of converting from bytes
to DMA transfers in every use, do it at a single place. Accordingly change
it's use at other places
3. Code cleanup patch has less to clean with change above 

v1:
http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1274632.html

Thanks & Regards,
Sanchayan.

Sanchayan Maity (4):
  spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Minor code cleanup and error path fixes

 drivers/spi/spi-fsl-dspi.c | 71 --
 1 file changed, 44 insertions(+), 27 deletions(-)

-- 
2.10.2



[PATCH v2 3/4] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-20 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

While at it also clean up the use of curr_xfer_len which is central
to the DMA setup, from bytes to DMA transfers for every use.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 41422cd..08882f7 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
 };
 
 struct fsl_dspi_dma {
+   /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len;
 
u32 *tx_dma_buf;
@@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg)
struct fsl_dspi *dspi = arg;
struct fsl_dspi_dma *dma = dspi->dma;
int rx_word;
-   int i, len;
+   int i;
u16 d;
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
-   for (i = 0; i < len; i++) {
+   for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
rx_word ? (*(u16 *)dspi->rx = d) :
(*(u8 *)dspi->rx = d);
@@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
struct device *dev = >pdev->dev;
int time_left;
int tx_word;
-   int i, len;
+   int i;
u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
-   for (i = 0; i < len - 1; i++) {
+   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
@@ -267,7 +264,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -283,7 +282,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -330,17 +331,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
struct device *dev = >pdev->dev;
int curr_remaining_bytes;
int bytes_per_buffer;
-   int tx_word;
+   int word = 1;
int ret = 0;
 
-   tx_word = is_double_byte_mode(dspi);
+   if (is_double_byte_mode(dspi))
+   word = 2;
curr_remaining_bytes = dspi->len;
+   bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
while (curr_remaining_bytes) {
/* Check if current transfer fits the DMA buffer */
-   dma->curr_xfer_len = curr_remaining_bytes;
-   bytes_per_buffer = DSPI_DMA_BUFSIZE /
-   (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
-   if (curr_remaining_bytes > bytes_per_buffer)
+   dma->curr_xfer_len = curr_remaining_bytes / word;
+   if (dma->curr_xfer_len > bytes_per_buffer)
dma->curr_xfer_len = bytes_per_buffer;
 
ret = dspi_next_xfer_dma_submit(dspi);
@@ -349,7 +350,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
goto exit;
 
} else {
-   curr_remaining_

[PATCH v2 1/4] spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE

2016-11-20 Thread Sanchayan Maity
Current DMA implementation had a bug where the DMA transfer would
exit the loop in dspi_transfer_one_message after the completion of
a single transfer. This results in a multi message transfer submitted
with SPI_IOC_MESSAGE to terminate incorrectly without an error.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
Reviewed-by: Stefan Agner <ste...@agner.ch>
---
 drivers/spi/spi-fsl-dspi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index bc64700..b1ee1f5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -714,7 +714,7 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
SPI_RSER_TFFFE | SPI_RSER_TFFFD |
SPI_RSER_RFDFE | SPI_RSER_RFDFD);
status = dspi_dma_xfer(dspi);
-   goto out;
+   break;
default:
dev_err(>pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -722,9 +722,13 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
goto out;
}
 
-   if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
-   dev_err(>pdev->dev, "wait transfer complete 
fail!\n");
-   dspi->waitflags = 0;
+   if (trans_mode != DSPI_DMA_MODE) {
+   if (wait_event_interruptible(dspi->waitq,
+   dspi->waitflags))
+   dev_err(>pdev->dev,
+   "wait transfer complete fail!\n");
+   dspi->waitflags = 0;
+   }
 
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
-- 
2.10.2



[PATCH v2 2/4] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-20 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers. Use the cs_change variable and correctly set or
reset the CONT bit accordingly for case where peripherals require
the chip select to be asserted between sequential transfers.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..41422cd 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -261,6 +261,8 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
+   if (!dspi->cs_change)
+   dspi->dma->tx_dma_buf[i] |= SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
-- 
2.10.2



[PATCH v2 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes

2016-11-20 Thread Sanchayan Maity
Code cleanup for improving code readability and error path fixes
and cleanup removing use of devm_kfree.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 08882f7..2987a16 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -226,8 +226,10 @@ static void dspi_rx_dma_callback(void *arg)
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
-   rx_word ? (*(u16 *)dspi->rx = d) :
-   (*(u8 *)dspi->rx = d);
+   if (rx_word)
+   *(u16 *)dspi->rx = d;
+   else
+   *(u8 *)dspi->rx = d;
dspi->rx += rx_word + 1;
}
}
@@ -247,14 +249,20 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
tx_word = is_double_byte_mode(dspi);
 
for (i = 0; i < dma->curr_xfer_len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
@@ -430,9 +438,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
-- 
2.10.2



[PATCH v2 0/4] Fixes for Vybrid SPI DMA implementation

2016-11-20 Thread Sanchayan Maity
Hello,

The following set of patches have fixes for Vybrid SPI DMA
implementation along with some minor clean ups requested
at time when v3 version of SPI DMA support patch was accepted.

This series of patches is based on top of branch topic/fsl-dspi.
http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module
and now incoporate feedback from Stefan on version 1 of patchset.

Changes since v1:
1. Place the continuous selection format patch second in order and remove
code duplication
2. Improve the use of curr_xfer_len and instead of converting from bytes
to DMA transfers in every use, do it at a single place. Accordingly change
it's use at other places
3. Code cleanup patch has less to clean with change above 

v1:
http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1274632.html

Thanks & Regards,
Sanchayan.

Sanchayan Maity (4):
  spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Minor code cleanup and error path fixes

 drivers/spi/spi-fsl-dspi.c | 71 --
 1 file changed, 44 insertions(+), 27 deletions(-)

-- 
2.10.2



[PATCH v2 3/4] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-20 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

While at it also clean up the use of curr_xfer_len which is central
to the DMA setup, from bytes to DMA transfers for every use.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 41422cd..08882f7 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
 };
 
 struct fsl_dspi_dma {
+   /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len;
 
u32 *tx_dma_buf;
@@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg)
struct fsl_dspi *dspi = arg;
struct fsl_dspi_dma *dma = dspi->dma;
int rx_word;
-   int i, len;
+   int i;
u16 d;
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
-   for (i = 0; i < len; i++) {
+   for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
rx_word ? (*(u16 *)dspi->rx = d) :
(*(u8 *)dspi->rx = d);
@@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
struct device *dev = >pdev->dev;
int time_left;
int tx_word;
-   int i, len;
+   int i;
u16 val;
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
-   for (i = 0; i < len - 1; i++) {
+   for (i = 0; i < dma->curr_xfer_len - 1; i++) {
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
@@ -267,7 +264,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -283,7 +282,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES,
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -330,17 +331,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
struct device *dev = >pdev->dev;
int curr_remaining_bytes;
int bytes_per_buffer;
-   int tx_word;
+   int word = 1;
int ret = 0;
 
-   tx_word = is_double_byte_mode(dspi);
+   if (is_double_byte_mode(dspi))
+   word = 2;
curr_remaining_bytes = dspi->len;
+   bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
while (curr_remaining_bytes) {
/* Check if current transfer fits the DMA buffer */
-   dma->curr_xfer_len = curr_remaining_bytes;
-   bytes_per_buffer = DSPI_DMA_BUFSIZE /
-   (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
-   if (curr_remaining_bytes > bytes_per_buffer)
+   dma->curr_xfer_len = curr_remaining_bytes / word;
+   if (dma->curr_xfer_len > bytes_per_buffer)
dma->curr_xfer_len = bytes_per_buffer;
 
ret = dspi_next_xfer_dma_submit(dspi);
@@ -349,7 +350,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
goto exit;
 
} else {
-   curr_remaining_bytes 

[PATCH v2 1/4] spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE

2016-11-20 Thread Sanchayan Maity
Current DMA implementation had a bug where the DMA transfer would
exit the loop in dspi_transfer_one_message after the completion of
a single transfer. This results in a multi message transfer submitted
with SPI_IOC_MESSAGE to terminate incorrectly without an error.

Signed-off-by: Sanchayan Maity 
Reviewed-by: Stefan Agner 
---
 drivers/spi/spi-fsl-dspi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index bc64700..b1ee1f5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -714,7 +714,7 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
SPI_RSER_TFFFE | SPI_RSER_TFFFD |
SPI_RSER_RFDFE | SPI_RSER_RFDFD);
status = dspi_dma_xfer(dspi);
-   goto out;
+   break;
default:
dev_err(>pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -722,9 +722,13 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
goto out;
}
 
-   if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
-   dev_err(>pdev->dev, "wait transfer complete 
fail!\n");
-   dspi->waitflags = 0;
+   if (trans_mode != DSPI_DMA_MODE) {
+   if (wait_event_interruptible(dspi->waitq,
+   dspi->waitflags))
+   dev_err(>pdev->dev,
+   "wait transfer complete fail!\n");
+   dspi->waitflags = 0;
+   }
 
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
-- 
2.10.2



[PATCH 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes

2016-11-17 Thread Sanchayan Maity
Code cleanup for improving code readability and error path fixes
and cleanup removing use of devm_kfree.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 34 +-
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 164e2e1..382a7f9 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -222,13 +222,18 @@ static void dspi_rx_dma_callback(void *arg)
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+   if (rx_word)
+   len = dma->curr_xfer_len / 2;
+   else
+   len = dma->curr_xfer_len;
 
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
for (i = 0; i < len; i++) {
d = dspi->dma->rx_dma_buf[i];
-   rx_word ? (*(u16 *)dspi->rx = d) :
-   (*(u8 *)dspi->rx = d);
+   if (rx_word)
+   *(u16 *)dspi->rx = d;
+   else
+   *(u8 *)dspi->rx = d;
dspi->rx += rx_word + 1;
}
}
@@ -247,17 +252,27 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+   if (tx_word)
+   len = dma->curr_xfer_len / 2;
+   else
+   len = dma->curr_xfer_len;
 
for (i = 0; i < len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
+
if (dspi->cs_change) {
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
@@ -440,15 +455,16 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
dma_release_channel(dma->chan_rx);
 
-   devm_kfree(dev, dma);
dspi->dma = NULL;
 
return ret;
-- 
2.10.2



[PATCH 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes

2016-11-17 Thread Sanchayan Maity
Code cleanup for improving code readability and error path fixes
and cleanup removing use of devm_kfree.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 34 +-
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 164e2e1..382a7f9 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -222,13 +222,18 @@ static void dspi_rx_dma_callback(void *arg)
 
rx_word = is_double_byte_mode(dspi);
 
-   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+   if (rx_word)
+   len = dma->curr_xfer_len / 2;
+   else
+   len = dma->curr_xfer_len;
 
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
for (i = 0; i < len; i++) {
d = dspi->dma->rx_dma_buf[i];
-   rx_word ? (*(u16 *)dspi->rx = d) :
-   (*(u8 *)dspi->rx = d);
+   if (rx_word)
+   *(u16 *)dspi->rx = d;
+   else
+   *(u8 *)dspi->rx = d;
dspi->rx += rx_word + 1;
}
}
@@ -247,17 +252,27 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi 
*dspi)
 
tx_word = is_double_byte_mode(dspi);
 
-   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+   if (tx_word)
+   len = dma->curr_xfer_len / 2;
+   else
+   len = dma->curr_xfer_len;
 
for (i = 0; i < len - 1; i++) {
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
}
 
-   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   if (tx_word)
+   val = *(u16 *) dspi->tx;
+   else
+   val = *(u8 *) dspi->tx;
+
if (dspi->cs_change) {
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
@@ -440,15 +455,16 @@ static int dspi_request_dma(struct fsl_dspi *dspi, 
phys_addr_t phy_addr)
return 0;
 
 err_slave_config:
-   devm_kfree(dev, dma->rx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->rx_dma_buf, dma->rx_dma_phys);
 err_rx_dma_buf:
-   devm_kfree(dev, dma->tx_dma_buf);
+   dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+   dma->tx_dma_buf, dma->tx_dma_phys);
 err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
 err_tx_channel:
dma_release_channel(dma->chan_rx);
 
-   devm_kfree(dev, dma);
dspi->dma = NULL;
 
return ret;
-- 
2.10.2



[PATCH 2/4] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-17 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..aee8c88 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -265,7 +265,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES /
+   (tx_word ? 2 : 1),
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -281,7 +284,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES /
+   (tx_word ? 2 : 1),
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
-- 
2.10.2



[PATCH 2/4] spi: spi-fsl-dspi: Fix incorrect DMA setup

2016-11-17 Thread Sanchayan Maity
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..aee8c88 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -265,7 +265,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES /
+   (tx_word ? 2 : 1),
+   DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -281,7 +284,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
-   DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+   dma->curr_xfer_len *
+   DMA_SLAVE_BUSWIDTH_4_BYTES /
+   (tx_word ? 2 : 1),
+   DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
-- 
2.10.2



[PATCH 0/4] Fixes for Vybrid SPI DMA implementation

2016-11-17 Thread Sanchayan Maity
Hello,

The following set of patches have fixes for Vybrid SPI DMA
implementation along with some minor clean ups requested
at time when v3 version of SPI DMA support patch was accepted. 

This series of patches is based on top of branch topic/fsl-dspi.
http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module.

Thanks & Regards,
Sanchayan.

Sanchayan Maity (4):
  spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Minor code cleanup and error path fixes

 drivers/spi/spi-fsl-dspi.c | 69 ++
 1 file changed, 51 insertions(+), 18 deletions(-)

-- 
2.10.2



[PATCH 0/4] Fixes for Vybrid SPI DMA implementation

2016-11-17 Thread Sanchayan Maity
Hello,

The following set of patches have fixes for Vybrid SPI DMA
implementation along with some minor clean ups requested
at time when v3 version of SPI DMA support patch was accepted. 

This series of patches is based on top of branch topic/fsl-dspi.
http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi

The patches have been tested on a Toradex Colibri Vybrid VF61 module.

Thanks & Regards,
Sanchayan.

Sanchayan Maity (4):
  spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
  spi: spi-fsl-dspi: Fix incorrect DMA setup
  spi: spi-fsl-dspi: Fix continuous selection format
  spi: spi-fsl-dspi: Minor code cleanup and error path fixes

 drivers/spi/spi-fsl-dspi.c | 69 ++
 1 file changed, 51 insertions(+), 18 deletions(-)

-- 
2.10.2



[PATCH 3/4] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-17 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers. Use the cs_change variable and correctly set or
reset the CONT bit accordingly for case where peripherals require
the chip select to be asserted between sequential transfers.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index aee8c88..164e2e1 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -258,9 +258,16 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
}
 
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
-   SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0);
+   if (dspi->cs_change) {
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   } else {
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) |
+   SPI_PUSHR_CONT;
+   }
dspi->tx += tx_word + 1;
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
-- 
2.10.2



[PATCH 3/4] spi: spi-fsl-dspi: Fix continuous selection format

2016-11-17 Thread Sanchayan Maity
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers. Use the cs_change variable and correctly set or
reset the CONT bit accordingly for case where peripherals require
the chip select to be asserted between sequential transfers.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index aee8c88..164e2e1 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -258,9 +258,16 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
}
 
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
-   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
-   SPI_PUSHR_PCS(dspi->cs) |
-   SPI_PUSHR_CTAS(0);
+   if (dspi->cs_change) {
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   } else {
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) |
+   SPI_PUSHR_CONT;
+   }
dspi->tx += tx_word + 1;
 
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
-- 
2.10.2



[PATCH 1/4] spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE

2016-11-17 Thread Sanchayan Maity
Current DMA implementation had a bug where the DMA transfer would
exit the loop in dspi_transfer_one_message after the completion of
a single transfer. This results in a multi message transfer submitted
with SPI_IOC_MESSAGE to terminate incorrectly without an error.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index bc64700..b1ee1f5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -714,7 +714,7 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
SPI_RSER_TFFFE | SPI_RSER_TFFFD |
SPI_RSER_RFDFE | SPI_RSER_RFDFD);
status = dspi_dma_xfer(dspi);
-   goto out;
+   break;
default:
dev_err(>pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -722,9 +722,13 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
goto out;
}
 
-   if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
-   dev_err(>pdev->dev, "wait transfer complete 
fail!\n");
-   dspi->waitflags = 0;
+   if (trans_mode != DSPI_DMA_MODE) {
+   if (wait_event_interruptible(dspi->waitq,
+   dspi->waitflags))
+   dev_err(>pdev->dev,
+   "wait transfer complete fail!\n");
+   dspi->waitflags = 0;
+   }
 
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
-- 
2.10.2



[PATCH 1/4] spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE

2016-11-17 Thread Sanchayan Maity
Current DMA implementation had a bug where the DMA transfer would
exit the loop in dspi_transfer_one_message after the completion of
a single transfer. This results in a multi message transfer submitted
with SPI_IOC_MESSAGE to terminate incorrectly without an error.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index bc64700..b1ee1f5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -714,7 +714,7 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
SPI_RSER_TFFFE | SPI_RSER_TFFFD |
SPI_RSER_RFDFE | SPI_RSER_RFDFD);
status = dspi_dma_xfer(dspi);
-   goto out;
+   break;
default:
dev_err(>pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -722,9 +722,13 @@ static int dspi_transfer_one_message(struct spi_master 
*master,
goto out;
}
 
-   if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
-   dev_err(>pdev->dev, "wait transfer complete 
fail!\n");
-   dspi->waitflags = 0;
+   if (trans_mode != DSPI_DMA_MODE) {
+   if (wait_event_interruptible(dspi->waitq,
+   dspi->waitflags))
+   dev_err(>pdev->dev,
+   "wait transfer complete fail!\n");
+   dspi->waitflags = 0;
+   }
 
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
-- 
2.10.2



[PATCH v2] ARM: dts: vfxxx: Enable DMA for DSPI2 and DSPI3

2016-11-14 Thread Sanchayan Maity
Enable DMA for DSPI2 and DSPI3 on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Changes since v1:

Add signed-off-by missing in v1.
---
 arch/arm/boot/dts/vfxxx.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 000550f..e9d2847 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -573,6 +573,9 @@
clocks = < VF610_CLK_DSPI2>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 10>,
+   < 0 11>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -585,6 +588,9 @@
clocks = < VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 12>,
+   < 0 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.2



[PATCH v2] ARM: dts: vfxxx: Enable DMA for DSPI2 and DSPI3

2016-11-14 Thread Sanchayan Maity
Enable DMA for DSPI2 and DSPI3 on Vybrid.

Signed-off-by: Sanchayan Maity 
---
Changes since v1:

Add signed-off-by missing in v1.
---
 arch/arm/boot/dts/vfxxx.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 000550f..e9d2847 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -573,6 +573,9 @@
clocks = < VF610_CLK_DSPI2>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 10>,
+   < 0 11>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -585,6 +588,9 @@
clocks = < VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 12>,
+   < 0 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.2



[PATCH v3] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-11-10 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Changes since v2:
1. Rebase on top of Shawn's latest for-next branch
2. Make DMA mode the default for Vybrid. We no longer use the EOQ mode.
Since devtype_data has been constantified it's no longer makes sense to
change the trans_mode at run time.

Tested on Toradex Colibri Vybrid VF61 module using spidev and MCP CAN.

v1 Patch:
https://patchwork.kernel.org/patch/9360583/

v2 Patch:
https://patchwork.kernel.org/patch/9361601/

Regards,
Sanchayan.
---
 drivers/spi/spi-fsl-dspi.c | 301 -
 1 file changed, 300 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 35c0dd9..bc64700 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -125,7 +136,7 @@ struct fsl_dspi_devtype_data {
 };
 
 static const struct fsl_dspi_devtype_data vf610_data = {
-   .trans_mode = DSPI_EOQ_MODE,
+   .trans_mode = DSPI_DMA_MODE,
.max_clock_factor = 2,
 };
 
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -176,6 +204,263 @@ static inline int is_double_byte_mode(struct fsl_dspi 
*dspi)
return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma

[PATCH v3] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-11-10 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity 
---
Changes since v2:
1. Rebase on top of Shawn's latest for-next branch
2. Make DMA mode the default for Vybrid. We no longer use the EOQ mode.
Since devtype_data has been constantified it's no longer makes sense to
change the trans_mode at run time.

Tested on Toradex Colibri Vybrid VF61 module using spidev and MCP CAN.

v1 Patch:
https://patchwork.kernel.org/patch/9360583/

v2 Patch:
https://patchwork.kernel.org/patch/9361601/

Regards,
Sanchayan.
---
 drivers/spi/spi-fsl-dspi.c | 301 -
 1 file changed, 300 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 35c0dd9..bc64700 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -125,7 +136,7 @@ struct fsl_dspi_devtype_data {
 };
 
 static const struct fsl_dspi_devtype_data vf610_data = {
-   .trans_mode = DSPI_EOQ_MODE,
+   .trans_mode = DSPI_DMA_MODE,
.max_clock_factor = 2,
 };
 
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -176,6 +204,263 @@ static inline int is_double_byte_mode(struct fsl_dspi 
*dspi)
return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->t

[PATCH] ARM: dts: vfxxx: Enable DMA for DSPI2 and DSPI3

2016-11-10 Thread Sanchayan Maity
Enable DMA for DSPI2 and DSPI3 on Vybrid.
---
 arch/arm/boot/dts/vfxxx.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 000550f..e9d2847 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -573,6 +573,9 @@
clocks = < VF610_CLK_DSPI2>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 10>,
+   < 0 11>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -585,6 +588,9 @@
clocks = < VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 12>,
+   < 0 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.2



[PATCH] ARM: dts: vfxxx: Enable DMA for DSPI2 and DSPI3

2016-11-10 Thread Sanchayan Maity
Enable DMA for DSPI2 and DSPI3 on Vybrid.
---
 arch/arm/boot/dts/vfxxx.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 000550f..e9d2847 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -573,6 +573,9 @@
clocks = < VF610_CLK_DSPI2>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 10>,
+   < 0 11>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -585,6 +588,9 @@
clocks = < VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+   dmas = < 0 12>,
+   < 0 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.2



[PATCH v2] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-10-04 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Changes since v1:
- Change in the dspi_dma_xfer function. Use more apt DSPI_FIFO_SIZE
instead of sizeof(u32)
- Do not set RSER on every iteration of loop

Tested on Toradex Colibri Vybrid VF61 module with spi based MCP CAN 251x
and spidev using RX/TX loopback and based on shawn's for-next branch
currently at 4.8-rc1.

Regards,
Sanchayan.
---
 drivers/spi/spi-fsl-dspi.c | 291 +
 1 file changed, 291 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9e9dadb..0f81075 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -368,6 +396,259 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
dspi_data_from_popr(dspi, rx_word);
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   dspi->tx += tx_word + 1;
+
+   dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+   dma->tx_dma_phys,
+   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+ 

[PATCH v2] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-10-04 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity 
---
Changes since v1:
- Change in the dspi_dma_xfer function. Use more apt DSPI_FIFO_SIZE
instead of sizeof(u32)
- Do not set RSER on every iteration of loop

Tested on Toradex Colibri Vybrid VF61 module with spi based MCP CAN 251x
and spidev using RX/TX loopback and based on shawn's for-next branch
currently at 4.8-rc1.

Regards,
Sanchayan.
---
 drivers/spi/spi-fsl-dspi.c | 291 +
 1 file changed, 291 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9e9dadb..0f81075 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -368,6 +396,259 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
dspi_data_from_popr(dspi, rx_word);
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   dspi->tx += tx_word + 1;
+
+   dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+   dma->tx_dma_phys,
+   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   DMA

[PATCH v1 2/2] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-10-03 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/spi/spi-fsl-dspi.c | 293 +
 1 file changed, 293 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9e9dadb..ada50ee 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -368,6 +396,264 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
dspi_data_from_popr(dspi, rx_word);
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   dspi->tx += tx_word + 1;
+
+   dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+   dma->tx_dma_phys,
+   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!dma->tx_desc) {
+   dev_err(dev, "Not able to get desc for DMA xfer\n");
+   return -EIO;
+   }
+
+   dma->tx_desc->callback = dspi_tx_dma_callback;
+   dma->tx_desc->callback_param = dspi;
+   

[PATCH v1 2/2] spi: spi-fsl-dspi: Add DMA support for Vybrid

2016-10-03 Thread Sanchayan Maity
Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity 
---
 drivers/spi/spi-fsl-dspi.c | 293 +
 1 file changed, 293 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9e9dadb..ada50ee 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM0x04
 
 #define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE   (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR0x00
 #define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF0x1000
 #define SPI_SR_TCFQF   0x8000
 
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
 #define SPI_RSER   0x30
 #define SPI_RSER_EOQFE 0x1000
 #define SPI_RSER_TCFQE 0x8000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX   0x1
 
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
 struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+   DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+   u32 curr_xfer_len;
+
+   u32 *tx_dma_buf;
+   struct dma_chan *chan_tx;
+   dma_addr_t tx_dma_phys;
+   struct completion cmd_tx_complete;
+   struct dma_async_tx_descriptor *tx_desc;
+
+   u32 *rx_dma_buf;
+   struct dma_chan *chan_rx;
+   dma_addr_t rx_dma_phys;
+   struct completion cmd_rx_complete;
+   struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
struct spi_master   *master;
struct platform_device  *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
 
u32 spi_tcnt;
+   struct fsl_dspi_dma *dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -368,6 +396,264 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
dspi_data_from_popr(dspi, rx_word);
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+
+   complete(>cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+   struct fsl_dspi *dspi = arg;
+   struct fsl_dspi_dma *dma = dspi->dma;
+   int rx_word;
+   int i, len;
+   u16 d;
+
+   rx_word = is_double_byte_mode(dspi);
+
+   len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+   for (i = 0; i < len; i++) {
+   d = dspi->dma->rx_dma_buf[i];
+   rx_word ? (*(u16 *)dspi->rx = d) :
+   (*(u8 *)dspi->rx = d);
+   dspi->rx += rx_word + 1;
+   }
+   }
+
+   complete(>cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+   struct fsl_dspi_dma *dma = dspi->dma;
+   struct device *dev = >pdev->dev;
+   int time_left;
+   int tx_word;
+   int i, len;
+   u16 val;
+
+   tx_word = is_double_byte_mode(dspi);
+
+   len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+   for (i = 0; i < len - 1; i++) {
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] =
+   SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+   dspi->tx += tx_word + 1;
+   }
+
+   val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+   dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+   SPI_PUSHR_PCS(dspi->cs) |
+   SPI_PUSHR_CTAS(0);
+   dspi->tx += tx_word + 1;
+
+   dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+   dma->tx_dma_phys,
+   DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!dma->tx_desc) {
+   dev_err(dev, "Not able to get desc for DMA xfer\n");
+   return -EIO;
+   }
+
+   dma->tx_desc->callback = dspi_tx_dma_callback;
+   dma->tx_desc->callback_param = dspi;
+   if (dma_submit_error(dmaengine_submi

[PATCH v1 1/2] ARM: dts: vfxxx: Enable DMA for DSPI on Vybrid

2016-10-03 Thread Sanchayan Maity
Enable DMA for DSPI on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vf-colibri.dtsi | 4 
 arch/arm/boot/dts/vfxxx.dtsi  | 6 ++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index b741709..21bfef9 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -108,6 +108,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_esdhc1>;
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..eac4213 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -194,6 +194,9 @@
clocks = < VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <6>;
+   dmas = < 1 12>,
+   < 1 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -206,6 +209,9 @@
clocks = < VF610_CLK_DSPI1>;
clock-names = "dspi";
spi-num-chipselects = <4>;
+   dmas = < 1 14>,
+   < 1 15>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.0



[PATCH v1 1/2] ARM: dts: vfxxx: Enable DMA for DSPI on Vybrid

2016-10-03 Thread Sanchayan Maity
Enable DMA for DSPI on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vf-colibri.dtsi | 4 
 arch/arm/boot/dts/vfxxx.dtsi  | 6 ++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index b741709..21bfef9 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -108,6 +108,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_esdhc1>;
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..eac4213 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -194,6 +194,9 @@
clocks = < VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <6>;
+   dmas = < 1 12>,
+   < 1 13>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -206,6 +209,9 @@
clocks = < VF610_CLK_DSPI1>;
clock-names = "dspi";
spi-num-chipselects = <4>;
+   dmas = < 1 14>,
+   < 1 15>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.10.0



[PATCH] ARM: dts: imx6: Add support for Toradex Colibri iMX6 module

2016-09-21 Thread Sanchayan Maity
Add support for Toradex Colibri iMX6 module.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/Makefile   |   1 +
 arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 253 
 arch/arm/boot/dts/imx6qdl-colibri.dtsi   | 890 +++
 3 files changed, 1144 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-colibri.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f79cac2..44ff380 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -323,6 +323,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-aristainetos_7.dtb \
imx6dl-aristainetos2_4.dtb \
imx6dl-aristainetos2_7.dtb \
+   imx6dl-colibri-eval-v3.dtb \
imx6dl-cubox-i.dtb \
imx6dl-dfi-fs700-m60.dtb \
imx6dl-gw51xx.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts 
b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
new file mode 100644
index 000..e0c2172
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2014-2016 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include 
+#include 
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+   model = "Toradex Colibri iMX6DL/S on Colibri Evaluation Board V3";
+   compatible = "toradex,colibri_imx6dl-eval-v3", "toradex,colibri_imx6dl",
+"fsl,imx6dl";
+
+   aliases {
+   i2c0 = 
+   i2c1 = 
+   };
+
+   aliases {
+   rtc0 = _i2c;
+   rtc1 = _rtc;
+   };
+
+   clocks {
+   /* Fixed crystal dedicated to mcp251x */
+   clk16m: clk@1 {
+   compatible = "fixed-clock";
+   reg = <1>;
+   #clock-cells = <0>;
+   clock-frequency = <1600>;
+   clock-output-names = "clk16m";
+   };
+   };
+
+   gpio-keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_keys>;
+
+   wakeup {
+   label = "Wake-Up";
+   gpios = < 22 GPIO_ACTIVE_HIGH>; /* SODIMM 45 */
+   linux,code = ;
+   debounce-interval = <10>;
+   wakeup-source;
+   };
+   };
+
+   lcd_display: display@di0 {
+   compatible = "fsl,imx-parallel-display";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   interface-pix-fmt = "bgr666";
+   pinctrl-names = "default";
+   pinctrl-0 = <_ipu1_lcdif>;

[PATCH] ARM: dts: imx6: Add support for Toradex Colibri iMX6 module

2016-09-21 Thread Sanchayan Maity
Add support for Toradex Colibri iMX6 module.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/Makefile   |   1 +
 arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 253 
 arch/arm/boot/dts/imx6qdl-colibri.dtsi   | 890 +++
 3 files changed, 1144 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-colibri.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f79cac2..44ff380 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -323,6 +323,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-aristainetos_7.dtb \
imx6dl-aristainetos2_4.dtb \
imx6dl-aristainetos2_7.dtb \
+   imx6dl-colibri-eval-v3.dtb \
imx6dl-cubox-i.dtb \
imx6dl-dfi-fs700-m60.dtb \
imx6dl-gw51xx.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts 
b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
new file mode 100644
index 000..e0c2172
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2014-2016 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include 
+#include 
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+   model = "Toradex Colibri iMX6DL/S on Colibri Evaluation Board V3";
+   compatible = "toradex,colibri_imx6dl-eval-v3", "toradex,colibri_imx6dl",
+"fsl,imx6dl";
+
+   aliases {
+   i2c0 = 
+   i2c1 = 
+   };
+
+   aliases {
+   rtc0 = _i2c;
+   rtc1 = _rtc;
+   };
+
+   clocks {
+   /* Fixed crystal dedicated to mcp251x */
+   clk16m: clk@1 {
+   compatible = "fixed-clock";
+   reg = <1>;
+   #clock-cells = <0>;
+   clock-frequency = <1600>;
+   clock-output-names = "clk16m";
+   };
+   };
+
+   gpio-keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_keys>;
+
+   wakeup {
+   label = "Wake-Up";
+   gpios = < 22 GPIO_ACTIVE_HIGH>; /* SODIMM 45 */
+   linux,code = ;
+   debounce-interval = <10>;
+   wakeup-source;
+   };
+   };
+
+   lcd_display: display@di0 {
+   compatible = "fsl,imx-parallel-display";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   interface-pix-fmt = "bgr666";
+   pinctrl-names = "default";
+   pinctrl-0 = <_ipu1_lcdif>;
+

[PATCH v2 3/3] ARM: dts: imx6qdl-apalis: Use enable-gpios property for backlight

2016-09-18 Thread Sanchayan Maity
Use enable-gpios property of PWM backlight driver for backlight
control.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Changes since v1:

Fix commit message

v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6qdl-apalis.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 8c67dd8..9100bde 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -49,7 +49,10 @@
 
backlight: backlight {
compatible = "pwm-backlight";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_bl_on>;
pwms = < 0 500>;
+   enable-gpios = < 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
 
@@ -614,6 +617,12 @@
>;
};
 
+   pinctrl_gpio_bl_on: gpioblon {
+   fsl,pins = <
+   MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0
+   >;
+   };
+
pinctrl_gpio_keys: gpio1io04grp {
fsl,pins = <
/* Power button */
-- 
2.9.3



[PATCH v2 3/3] ARM: dts: imx6qdl-apalis: Use enable-gpios property for backlight

2016-09-18 Thread Sanchayan Maity
Use enable-gpios property of PWM backlight driver for backlight
control.

Signed-off-by: Sanchayan Maity 
---
Changes since v1:

Fix commit message

v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6qdl-apalis.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 8c67dd8..9100bde 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -49,7 +49,10 @@
 
backlight: backlight {
compatible = "pwm-backlight";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_bl_on>;
pwms = < 0 500>;
+   enable-gpios = < 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
 
@@ -614,6 +617,12 @@
>;
};
 
+   pinctrl_gpio_bl_on: gpioblon {
+   fsl,pins = <
+   MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0
+   >;
+   };
+
pinctrl_gpio_keys: gpio1io04grp {
fsl,pins = <
/* Power button */
-- 
2.9.3



[PATCH v2 1/3] ARM: dts: imx6qdl-apalis: Do not rely on DDC I2C bus bitbang for HDMI

2016-09-18 Thread Sanchayan Maity
Remove the use of DDC I2C bus bitbang to support reading of EDID
and rely on support from internal HDMI I2C master controller instead.
As a result remove the device tree property ddc-i2c-bus.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Changes since v1:

Change the ranking in i2c aliases

v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 12 +++-
 arch/arm/boot/dts/imx6qdl-apalis.dtsi| 25 +
 2 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 207b85b..82b81e0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -55,10 +55,9 @@
 "fsl,imx6q";
 
aliases {
-   i2c0 = 
-   i2c1 = 
-   i2c2 = 
-   i2c3 = 
+   i2c0 = 
+   i2c1 = 
+   i2c2 = 
};
 
aliases {
@@ -186,11 +185,6 @@
 };
 
  {
-   ddc-i2c-bus = <>;
-   status = "okay";
-};
-
- {
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 99e323b..8c67dd8 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -53,18 +53,6 @@
status = "disabled";
};
 
-   /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */
-   i2cddc: i2c@0 {
-   compatible = "i2c-gpio";
-   pinctrl-names = "default";
-   pinctrl-0 = <_i2c_ddc>;
-   gpios = < 16 GPIO_ACTIVE_HIGH /* sda */
- 30 GPIO_ACTIVE_HIGH /* scl */
-   >;
-   i2c-gpio,delay-us = <2>;/* ~100 kHz */
-   status = "disabled";
-   };
-
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
@@ -209,6 +197,12 @@
};
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_hdmi_ddc>;
+   status = "disabled";
+};
+
 /*
  * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier
  * board)
@@ -633,11 +627,10 @@
>;
};
 
-   pinctrl_i2c_ddc: gpioi2cddcgrp {
+   pinctrl_hdmi_ddc: hdmiddcgrp {
fsl,pins = <
-   /* DDC bitbang */
-   MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
-   MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+   MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
+   MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
>;
};
 
-- 
2.9.3



[PATCH v2 2/3] ARM: dts: imx6q-apalis-ixora: Remove use of pwm-leds

2016-09-18 Thread Sanchayan Maity
Remove use of pwm-leds and use the standard /sys/class/pwm
interface from PWM subsystem.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
Acked-by: Marcel Ziswiler <marcel.ziswi...@toradex.com>
---
v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 22 --
 1 file changed, 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 82b81e0..383192c 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -146,28 +146,6 @@
gpios = < 2 GPIO_ACTIVE_HIGH>;
};
};
-
-   pwmleds {
-   compatible = "pwm-leds";
-
-   ledpwm1 {
-   label = "PWM1";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm2 {
-   label = "PWM2";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm3 {
-   label = "PWM3";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-   };
 };
 
  {
-- 
2.9.3



[PATCH v2 1/3] ARM: dts: imx6qdl-apalis: Do not rely on DDC I2C bus bitbang for HDMI

2016-09-18 Thread Sanchayan Maity
Remove the use of DDC I2C bus bitbang to support reading of EDID
and rely on support from internal HDMI I2C master controller instead.
As a result remove the device tree property ddc-i2c-bus.

Signed-off-by: Sanchayan Maity 
---
Changes since v1:

Change the ranking in i2c aliases

v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 12 +++-
 arch/arm/boot/dts/imx6qdl-apalis.dtsi| 25 +
 2 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 207b85b..82b81e0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -55,10 +55,9 @@
 "fsl,imx6q";
 
aliases {
-   i2c0 = 
-   i2c1 = 
-   i2c2 = 
-   i2c3 = 
+   i2c0 = 
+   i2c1 = 
+   i2c2 = 
};
 
aliases {
@@ -186,11 +185,6 @@
 };
 
  {
-   ddc-i2c-bus = <>;
-   status = "okay";
-};
-
- {
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 99e323b..8c67dd8 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -53,18 +53,6 @@
status = "disabled";
};
 
-   /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */
-   i2cddc: i2c@0 {
-   compatible = "i2c-gpio";
-   pinctrl-names = "default";
-   pinctrl-0 = <_i2c_ddc>;
-   gpios = < 16 GPIO_ACTIVE_HIGH /* sda */
- 30 GPIO_ACTIVE_HIGH /* scl */
-   >;
-   i2c-gpio,delay-us = <2>;/* ~100 kHz */
-   status = "disabled";
-   };
-
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
@@ -209,6 +197,12 @@
};
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_hdmi_ddc>;
+   status = "disabled";
+};
+
 /*
  * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier
  * board)
@@ -633,11 +627,10 @@
>;
};
 
-   pinctrl_i2c_ddc: gpioi2cddcgrp {
+   pinctrl_hdmi_ddc: hdmiddcgrp {
fsl,pins = <
-   /* DDC bitbang */
-   MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
-   MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+   MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
+   MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
>;
};
 
-- 
2.9.3



[PATCH v2 2/3] ARM: dts: imx6q-apalis-ixora: Remove use of pwm-leds

2016-09-18 Thread Sanchayan Maity
Remove use of pwm-leds and use the standard /sys/class/pwm
interface from PWM subsystem.

Signed-off-by: Sanchayan Maity 
Acked-by: Marcel Ziswiler 
---
v1: https://lkml.org/lkml/2016/9/14/55
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 22 --
 1 file changed, 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 82b81e0..383192c 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -146,28 +146,6 @@
gpios = < 2 GPIO_ACTIVE_HIGH>;
};
};
-
-   pwmleds {
-   compatible = "pwm-leds";
-
-   ledpwm1 {
-   label = "PWM1";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm2 {
-   label = "PWM2";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm3 {
-   label = "PWM3";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-   };
 };
 
  {
-- 
2.9.3



[PATCH v1 3/3] ARM: dts: imx6qdl-apalis: Use enable-gpios property for backlight

2016-09-14 Thread Sanchayan Maity
Use enable-gpios property of PWM backlight driver for backlight
control. While at it also fix the use of brightness levels required
by EDT displays which require inverted PWM's.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/imx6qdl-apalis.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 8c67dd8..9100bde 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -49,7 +49,10 @@
 
backlight: backlight {
compatible = "pwm-backlight";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_bl_on>;
pwms = < 0 500>;
+   enable-gpios = < 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
 
@@ -614,6 +617,12 @@
>;
};
 
+   pinctrl_gpio_bl_on: gpioblon {
+   fsl,pins = <
+   MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0
+   >;
+   };
+
pinctrl_gpio_keys: gpio1io04grp {
fsl,pins = <
/* Power button */
-- 
2.9.3



[PATCH v1 3/3] ARM: dts: imx6qdl-apalis: Use enable-gpios property for backlight

2016-09-14 Thread Sanchayan Maity
Use enable-gpios property of PWM backlight driver for backlight
control. While at it also fix the use of brightness levels required
by EDT displays which require inverted PWM's.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/imx6qdl-apalis.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 8c67dd8..9100bde 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -49,7 +49,10 @@
 
backlight: backlight {
compatible = "pwm-backlight";
+   pinctrl-names = "default";
+   pinctrl-0 = <_gpio_bl_on>;
pwms = < 0 500>;
+   enable-gpios = < 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
 
@@ -614,6 +617,12 @@
>;
};
 
+   pinctrl_gpio_bl_on: gpioblon {
+   fsl,pins = <
+   MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0
+   >;
+   };
+
pinctrl_gpio_keys: gpio1io04grp {
fsl,pins = <
/* Power button */
-- 
2.9.3



[PATCH v1 2/3] ARM: dts: imx6q-apalis-ixora: Remove use of pwm-leds

2016-09-14 Thread Sanchayan Maity
Remove use of pwm-leds and use the standard /sys/class/pwm
interface from PWM subsystem.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 22 --
 1 file changed, 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index d99979e..70a3da0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -146,28 +146,6 @@
gpios = < 2 GPIO_ACTIVE_HIGH>;
};
};
-
-   pwmleds {
-   compatible = "pwm-leds";
-
-   ledpwm1 {
-   label = "PWM1";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm2 {
-   label = "PWM2";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm3 {
-   label = "PWM3";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-   };
 };
 
  {
-- 
2.9.3



[PATCH v1 2/3] ARM: dts: imx6q-apalis-ixora: Remove use of pwm-leds

2016-09-14 Thread Sanchayan Maity
Remove use of pwm-leds and use the standard /sys/class/pwm
interface from PWM subsystem.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts | 22 --
 1 file changed, 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index d99979e..70a3da0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -146,28 +146,6 @@
gpios = < 2 GPIO_ACTIVE_HIGH>;
};
};
-
-   pwmleds {
-   compatible = "pwm-leds";
-
-   ledpwm1 {
-   label = "PWM1";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm2 {
-   label = "PWM2";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-
-   ledpwm3 {
-   label = "PWM3";
-   pwms = < 0 5>;
-   max-brightness = <255>;
-   };
-   };
 };
 
  {
-- 
2.9.3



[PATCH v1 1/3] ARM: dts: imx6qdl-apalis: Do not rely on DDC I2C bus bitbang for HDMI

2016-09-14 Thread Sanchayan Maity
Remove the use of DDC I2C bus bitbang to support reading of EDID
and rely on support from internal HDMI I2C master controller instead.
As a result remove the device tree property ddc-i2c-bus.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
Hello,

This patch is tested with the following patch applied
https://patchwork.kernel.org/patch/9296883/

and is based on the suggestions from Vladimir
https://lkml.org/lkml/2016/8/29/322

This and following two patches are based on top of shawn's
for-next branch.

Regards,
Sanchayan.
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts |  6 --
 arch/arm/boot/dts/imx6qdl-apalis.dtsi| 25 +
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 207b85b..d99979e 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -55,7 +55,6 @@
 "fsl,imx6q";
 
aliases {
-   i2c0 = 
i2c1 = 
i2c2 = 
i2c3 = 
@@ -186,11 +185,6 @@
 };
 
  {
-   ddc-i2c-bus = <>;
-   status = "okay";
-};
-
- {
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 99e323b..8c67dd8 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -53,18 +53,6 @@
status = "disabled";
};
 
-   /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */
-   i2cddc: i2c@0 {
-   compatible = "i2c-gpio";
-   pinctrl-names = "default";
-   pinctrl-0 = <_i2c_ddc>;
-   gpios = < 16 GPIO_ACTIVE_HIGH /* sda */
- 30 GPIO_ACTIVE_HIGH /* scl */
-   >;
-   i2c-gpio,delay-us = <2>;/* ~100 kHz */
-   status = "disabled";
-   };
-
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
@@ -209,6 +197,12 @@
};
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_hdmi_ddc>;
+   status = "disabled";
+};
+
 /*
  * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier
  * board)
@@ -633,11 +627,10 @@
>;
};
 
-   pinctrl_i2c_ddc: gpioi2cddcgrp {
+   pinctrl_hdmi_ddc: hdmiddcgrp {
fsl,pins = <
-   /* DDC bitbang */
-   MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
-   MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+   MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
+   MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
>;
};
 
-- 
2.9.3



[PATCH v1 1/3] ARM: dts: imx6qdl-apalis: Do not rely on DDC I2C bus bitbang for HDMI

2016-09-14 Thread Sanchayan Maity
Remove the use of DDC I2C bus bitbang to support reading of EDID
and rely on support from internal HDMI I2C master controller instead.
As a result remove the device tree property ddc-i2c-bus.

Signed-off-by: Sanchayan Maity 
---
Hello,

This patch is tested with the following patch applied
https://patchwork.kernel.org/patch/9296883/

and is based on the suggestions from Vladimir
https://lkml.org/lkml/2016/8/29/322

This and following two patches are based on top of shawn's
for-next branch.

Regards,
Sanchayan.
---
 arch/arm/boot/dts/imx6q-apalis-ixora.dts |  6 --
 arch/arm/boot/dts/imx6qdl-apalis.dtsi| 25 +
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts 
b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 207b85b..d99979e 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -55,7 +55,6 @@
 "fsl,imx6q";
 
aliases {
-   i2c0 = 
i2c1 = 
i2c2 = 
i2c3 = 
@@ -186,11 +185,6 @@
 };
 
  {
-   ddc-i2c-bus = <>;
-   status = "okay";
-};
-
- {
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 99e323b..8c67dd8 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -53,18 +53,6 @@
status = "disabled";
};
 
-   /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */
-   i2cddc: i2c@0 {
-   compatible = "i2c-gpio";
-   pinctrl-names = "default";
-   pinctrl-0 = <_i2c_ddc>;
-   gpios = < 16 GPIO_ACTIVE_HIGH /* sda */
- 30 GPIO_ACTIVE_HIGH /* scl */
-   >;
-   i2c-gpio,delay-us = <2>;/* ~100 kHz */
-   status = "disabled";
-   };
-
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
@@ -209,6 +197,12 @@
};
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_hdmi_ddc>;
+   status = "disabled";
+};
+
 /*
  * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier
  * board)
@@ -633,11 +627,10 @@
>;
};
 
-   pinctrl_i2c_ddc: gpioi2cddcgrp {
+   pinctrl_hdmi_ddc: hdmiddcgrp {
fsl,pins = <
-   /* DDC bitbang */
-   MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
-   MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+   MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
+   MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
>;
};
 
-- 
2.9.3



[PATCH v4 2/5] ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid

2016-07-07 Thread Sanchayan Maity
Add a device tree node for the On-Chip ROM on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..6c5222e 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -91,6 +91,11 @@
interrupt-parent = <_ir>;
ranges;
 
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
+
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
-- 
2.9.0



[PATCH v4 4/5] soc: Add SoC driver for Freescale Vybrid platform

2016-07-07 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and expose the SoC specific
properties via sysfs.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/soc/Kconfig |   1 +
 drivers/soc/fsl/Kconfig |  10 +++
 drivers/soc/fsl/Makefile|   1 +
 drivers/soc/fsl/soc-vf610.c | 212 
 4 files changed, 224 insertions(+)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..746b5e3
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP && OF
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..23900ea
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.ma...@toradex.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSCM_CPxCOUNT_OFFSET   0x2C
+#define MSCM_CPxCFG1_OFFSET0x14
+#define ROM_REVISION_OFFSET0x80
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   struct vf610_soc *info;
+   struct device *dev = >dev;
+   struct device_node *soc_node;
+   struct device_node *cfg0_node, *cfg1_node;
+   struct regmap *rom_regmap, *mscm_regmap;
+   char soc_type[] = "xx0";
+   size_t id1_len, id2_len;
+   u32 cpucount, l2size, rom_rev;
+   u8 *socid1, *socid2;
+   int ret;
+
+   info = devm_kzalloc(dev, sizeof(struct vf610_soc), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->dev = dev;
+
+   soc_node = of_find_node_by_path("/soc");
+   if (!soc_node)
+   return -ENODEV;
+
+   cfg0_node = of_find_node_by_name(soc_node, "cfg0");
+   if (!cfg0_node) {
+   ret = -ENODEV;
+   goto out_cfg0_node;
+   }
+
+   cfg1_node = of_find_node_by_name(soc_node, "cfg1");
+   if (!cfg1_node) {
+   ret = -ENODEV;
+   goto out_cfg1_node;
+   }
+
+   info->ocotp_cfg0 = of_nvmem_cell_get_direct(cfg0_node);
+   if (IS_ERR(info->ocotp_cfg0)) {
+   ret = PTR_ERR(info->ocotp_cfg0);
+   goto out_ocotp_cfg0;
+   }
+
+   in

[PATCH v4 5/5] ARM: dts: vfxxx: Add a compatible binding for Vybrid SoC bus driver

2016-07-07 Thread Sanchayan Maity
Add a compatible binding to the main soc node required by the
Vybrid SoC bus driver to bind on.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 6c5222e..c68bc72 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -87,7 +87,7 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
-   compatible = "simple-bus";
+   compatible = "fsl,vf610-soc", "simple-bus";
interrupt-parent = <_ir>;
ranges;
 
-- 
2.9.0



[PATCH v4 2/5] ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid

2016-07-07 Thread Sanchayan Maity
Add a device tree node for the On-Chip ROM on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..6c5222e 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -91,6 +91,11 @@
interrupt-parent = <_ir>;
ranges;
 
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
+
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
-- 
2.9.0



[PATCH v4 4/5] soc: Add SoC driver for Freescale Vybrid platform

2016-07-07 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and expose the SoC specific
properties via sysfs.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity 
---
 drivers/soc/Kconfig |   1 +
 drivers/soc/fsl/Kconfig |  10 +++
 drivers/soc/fsl/Makefile|   1 +
 drivers/soc/fsl/soc-vf610.c | 212 
 4 files changed, 224 insertions(+)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..746b5e3
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP && OF
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..23900ea
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSCM_CPxCOUNT_OFFSET   0x2C
+#define MSCM_CPxCFG1_OFFSET0x14
+#define ROM_REVISION_OFFSET0x80
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   struct vf610_soc *info;
+   struct device *dev = >dev;
+   struct device_node *soc_node;
+   struct device_node *cfg0_node, *cfg1_node;
+   struct regmap *rom_regmap, *mscm_regmap;
+   char soc_type[] = "xx0";
+   size_t id1_len, id2_len;
+   u32 cpucount, l2size, rom_rev;
+   u8 *socid1, *socid2;
+   int ret;
+
+   info = devm_kzalloc(dev, sizeof(struct vf610_soc), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->dev = dev;
+
+   soc_node = of_find_node_by_path("/soc");
+   if (!soc_node)
+   return -ENODEV;
+
+   cfg0_node = of_find_node_by_name(soc_node, "cfg0");
+   if (!cfg0_node) {
+   ret = -ENODEV;
+   goto out_cfg0_node;
+   }
+
+   cfg1_node = of_find_node_by_name(soc_node, "cfg1");
+   if (!cfg1_node) {
+   ret = -ENODEV;
+   goto out_cfg1_node;
+   }
+
+   info->ocotp_cfg0 = of_nvmem_cell_get_direct(cfg0_node);
+   if (IS_ERR(info->ocotp_cfg0)) {
+   ret = PTR_ERR(info->ocotp_cfg0);
+   goto out_ocotp_cfg0;
+   }
+
+   info->ocotp_cfg1 = of_nvmem_cell_get_direct(cfg1_node)

[PATCH v4 5/5] ARM: dts: vfxxx: Add a compatible binding for Vybrid SoC bus driver

2016-07-07 Thread Sanchayan Maity
Add a compatible binding to the main soc node required by the
Vybrid SoC bus driver to bind on.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 6c5222e..c68bc72 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -87,7 +87,7 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
-   compatible = "simple-bus";
+   compatible = "fsl,vf610-soc", "simple-bus";
interrupt-parent = <_ir>;
ranges;
 
-- 
2.9.0



[PATCH v4 3/5] nvmem: core: Add consumer API to get nvmem cell from node

2016-07-07 Thread Sanchayan Maity
From: Stefan Agner <ste...@agner.ch>

The existing NVMEM consumer API's do not allow to get a
NVMEM cell directly given a device tree node. This patch
adds a function to provide this functionality.

Assuming the nvmem cell id name is known, this can be used
as follows

struct device_node *cell_np;
struct nvmem_cell *foo_cell;

cell_np = of_find_node_by_name(parent, "foo");
foo_cell = of_nvmem_cell_get_direct(cell_np);

Parent node can also be the of_node of the main SoC device
node.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/nvmem/core.c   | 44 +-
 include/linux/nvmem-consumer.h |  1 +
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 965911d..470abee 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -743,29 +743,21 @@ static struct nvmem_cell *nvmem_cell_get_from_list(const 
char *cell_id)
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
 /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ * of_nvmem_cell_get_direct() - Get a nvmem cell from given device node
  *
- * @dev node: Device tree node that uses the nvmem cell
- * @id: nvmem cell name from nvmem-cell-names property.
+ * @dev node: Device tree node that uses nvmem cell
  *
  * Return: Will be an ERR_PTR() on error or a valid pointer
  * to a struct nvmem_cell.  The nvmem_cell will be freed by the
  * nvmem_cell_put().
  */
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-   const char *name)
+struct nvmem_cell *of_nvmem_cell_get_direct(struct device_node *cell_np)
 {
-   struct device_node *cell_np, *nvmem_np;
+   struct device_node *nvmem_np;
struct nvmem_cell *cell;
struct nvmem_device *nvmem;
const __be32 *addr;
-   int rval, len, index;
-
-   index = of_property_match_string(np, "nvmem-cell-names", name);
-
-   cell_np = of_parse_phandle(np, "nvmem-cells", index);
-   if (!cell_np)
-   return ERR_PTR(-EINVAL);
+   int rval, len;
 
nvmem_np = of_get_next_parent(cell_np);
if (!nvmem_np)
@@ -824,6 +816,32 @@ err_mem:
 
return ERR_PTR(rval);
 }
+EXPORT_SYMBOL_GPL(of_nvmem_cell_get_direct);
+
+/**
+ * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ *
+ * @dev node: Device tree node that uses the nvmem cell
+ * @id: nvmem cell name from nvmem-cell-names property.
+ *
+ * Return: Will be an ERR_PTR() on error or a valid pointer
+ * to a struct nvmem_cell.  The nvmem_cell will be freed by the
+ * nvmem_cell_put().
+ */
+struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
+   const char *name)
+{
+   struct device_node *cell_np;
+   int index;
+
+   index = of_property_match_string(np, "nvmem-cell-names", name);
+
+   cell_np = of_parse_phandle(np, "nvmem-cells", index);
+   if (!cell_np)
+   return ERR_PTR(-EINVAL);
+
+   return of_nvmem_cell_get_direct(cell_np);
+}
 EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 #endif
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 9bb77d3..bf879fc 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -136,6 +136,7 @@ static inline int nvmem_device_write(struct nvmem_device 
*nvmem,
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
+struct nvmem_cell *of_nvmem_cell_get_direct(struct device_node *cell_np);
 struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 const char *name);
 struct nvmem_device *of_nvmem_device_get(struct device_node *np,
-- 
2.9.0



[PATCH v4 0/5] Implement SoC driver for Vybrid

2016-07-07 Thread Sanchayan Maity
Hello,

This fourth patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

@Rob Herring
Does this patchset address the concerns you had? The only change
to the device tree is now for the compatible property.

@Srinivas
Is this new NVMEM consumer API acceptable? Would you recommend a
different approach?

Changes since v3:
1. Use just a compatible node at the SoC node and do not
use a separate node for the binding
2. Use syscon regmap lookup for getting information from
MSCM and OCROM nodes.
3. Introduce a NVMEM consumer API for getting a NVMEM cell
given a device node containing that cell.
4. Do not introduce any node at the SoC level.

Changes since v2:
1. Remove syscon_regmap_read_from_offset function and use the
available syscon functions
2. Remove fsl,vf610-soc-bus and related bindings at SoC node
level and introduce a fsl,vf610-soc node which is used by the
driver to bind and has all the required phandles plus the NVMEM
consumer handles.
3. Fix memory leak. of_node_put was not called for returned node
of of_parse_phandle and memory allocated by nvmem_cell_read was
not freed explicitly in return error paths.

Changes since v1:
Add device tree binding documentation.

2016: v3 patchset
https://lkml.org/lkml/2016/5/20/200

2016: v2 patchset
https://lkml.org/lkml/2016/5/2/69

2016: v1 patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid
  soc: Add SoC driver for Freescale Vybrid platform
  ARM: dts: vfxxx: Add a compatible binding for Vybrid SoC bus driver

Stefan Agner (1):
  nvmem: core: Add consumer API to get nvmem cell from node

 arch/arm/boot/dts/vfxxx.dtsi   |  23 -
 drivers/nvmem/core.c   |  44 ++---
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 212 +
 include/linux/nvmem-consumer.h |   1 +
 7 files changed, 278 insertions(+), 14 deletions(-)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.9.0



[PATCH v4 3/5] nvmem: core: Add consumer API to get nvmem cell from node

2016-07-07 Thread Sanchayan Maity
From: Stefan Agner 

The existing NVMEM consumer API's do not allow to get a
NVMEM cell directly given a device tree node. This patch
adds a function to provide this functionality.

Assuming the nvmem cell id name is known, this can be used
as follows

struct device_node *cell_np;
struct nvmem_cell *foo_cell;

cell_np = of_find_node_by_name(parent, "foo");
foo_cell = of_nvmem_cell_get_direct(cell_np);

Parent node can also be the of_node of the main SoC device
node.

Signed-off-by: Sanchayan Maity 
---
 drivers/nvmem/core.c   | 44 +-
 include/linux/nvmem-consumer.h |  1 +
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 965911d..470abee 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -743,29 +743,21 @@ static struct nvmem_cell *nvmem_cell_get_from_list(const 
char *cell_id)
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
 /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ * of_nvmem_cell_get_direct() - Get a nvmem cell from given device node
  *
- * @dev node: Device tree node that uses the nvmem cell
- * @id: nvmem cell name from nvmem-cell-names property.
+ * @dev node: Device tree node that uses nvmem cell
  *
  * Return: Will be an ERR_PTR() on error or a valid pointer
  * to a struct nvmem_cell.  The nvmem_cell will be freed by the
  * nvmem_cell_put().
  */
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-   const char *name)
+struct nvmem_cell *of_nvmem_cell_get_direct(struct device_node *cell_np)
 {
-   struct device_node *cell_np, *nvmem_np;
+   struct device_node *nvmem_np;
struct nvmem_cell *cell;
struct nvmem_device *nvmem;
const __be32 *addr;
-   int rval, len, index;
-
-   index = of_property_match_string(np, "nvmem-cell-names", name);
-
-   cell_np = of_parse_phandle(np, "nvmem-cells", index);
-   if (!cell_np)
-   return ERR_PTR(-EINVAL);
+   int rval, len;
 
nvmem_np = of_get_next_parent(cell_np);
if (!nvmem_np)
@@ -824,6 +816,32 @@ err_mem:
 
return ERR_PTR(rval);
 }
+EXPORT_SYMBOL_GPL(of_nvmem_cell_get_direct);
+
+/**
+ * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ *
+ * @dev node: Device tree node that uses the nvmem cell
+ * @id: nvmem cell name from nvmem-cell-names property.
+ *
+ * Return: Will be an ERR_PTR() on error or a valid pointer
+ * to a struct nvmem_cell.  The nvmem_cell will be freed by the
+ * nvmem_cell_put().
+ */
+struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
+   const char *name)
+{
+   struct device_node *cell_np;
+   int index;
+
+   index = of_property_match_string(np, "nvmem-cell-names", name);
+
+   cell_np = of_parse_phandle(np, "nvmem-cells", index);
+   if (!cell_np)
+   return ERR_PTR(-EINVAL);
+
+   return of_nvmem_cell_get_direct(cell_np);
+}
 EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 #endif
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 9bb77d3..bf879fc 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -136,6 +136,7 @@ static inline int nvmem_device_write(struct nvmem_device 
*nvmem,
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
+struct nvmem_cell *of_nvmem_cell_get_direct(struct device_node *cell_np);
 struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 const char *name);
 struct nvmem_device *of_nvmem_device_get(struct device_node *np,
-- 
2.9.0



[PATCH v4 0/5] Implement SoC driver for Vybrid

2016-07-07 Thread Sanchayan Maity
Hello,

This fourth patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

@Rob Herring
Does this patchset address the concerns you had? The only change
to the device tree is now for the compatible property.

@Srinivas
Is this new NVMEM consumer API acceptable? Would you recommend a
different approach?

Changes since v3:
1. Use just a compatible node at the SoC node and do not
use a separate node for the binding
2. Use syscon regmap lookup for getting information from
MSCM and OCROM nodes.
3. Introduce a NVMEM consumer API for getting a NVMEM cell
given a device node containing that cell.
4. Do not introduce any node at the SoC level.

Changes since v2:
1. Remove syscon_regmap_read_from_offset function and use the
available syscon functions
2. Remove fsl,vf610-soc-bus and related bindings at SoC node
level and introduce a fsl,vf610-soc node which is used by the
driver to bind and has all the required phandles plus the NVMEM
consumer handles.
3. Fix memory leak. of_node_put was not called for returned node
of of_parse_phandle and memory allocated by nvmem_cell_read was
not freed explicitly in return error paths.

Changes since v1:
Add device tree binding documentation.

2016: v3 patchset
https://lkml.org/lkml/2016/5/20/200

2016: v2 patchset
https://lkml.org/lkml/2016/5/2/69

2016: v1 patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid
  soc: Add SoC driver for Freescale Vybrid platform
  ARM: dts: vfxxx: Add a compatible binding for Vybrid SoC bus driver

Stefan Agner (1):
  nvmem: core: Add consumer API to get nvmem cell from node

 arch/arm/boot/dts/vfxxx.dtsi   |  23 -
 drivers/nvmem/core.c   |  44 ++---
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 212 +
 include/linux/nvmem-consumer.h |   1 +
 7 files changed, 278 insertions(+), 14 deletions(-)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.9.0



[PATCH v4 1/5] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-07-07 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.9.0



[PATCH v4 1/5] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-07-07 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.9.0



[PATCH v3 0/4] Implement SoC driver for Vybrid

2016-05-20 Thread Sanchayan Maity
Hello,

This third patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

@Rob Herring
Does this patchset address the concerns you had?

Changes since v2:
1. Remove syscon_regmap_read_from_offset function and use the
available syscon functions
2. Remove fsl,vf610-soc-bus and related bindings at SoC node
level and introduce a fsl,vf610-soc node which is used by the
driver to bind and has all the required phandles plus the NVMEM
consumer handles.
3. Fix memory leak. of_node_put was not called for returned node
of of_parse_phandle and memory allocated by nvmem_cell_read was
not freed explicitly in return error paths.

Changes since v1:
Add device tree binding documentation.

2016: v2 patchset
https://lkml.org/lkml/2016/5/2/69

2016: v1 patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid
  ARM: dts: vfxxx: Add device tree node required by Vybrid SoC driver
  soc: Add SoC driver for Freescale Vybrid platform

 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  20 +++
 arch/arm/boot/dts/vfxxx.dtsi   |  29 +++
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 198 +
 6 files changed, 259 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.8.2



[PATCH v3 0/4] Implement SoC driver for Vybrid

2016-05-20 Thread Sanchayan Maity
Hello,

This third patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

@Rob Herring
Does this patchset address the concerns you had?

Changes since v2:
1. Remove syscon_regmap_read_from_offset function and use the
available syscon functions
2. Remove fsl,vf610-soc-bus and related bindings at SoC node
level and introduce a fsl,vf610-soc node which is used by the
driver to bind and has all the required phandles plus the NVMEM
consumer handles.
3. Fix memory leak. of_node_put was not called for returned node
of of_parse_phandle and memory allocated by nvmem_cell_read was
not freed explicitly in return error paths.

Changes since v1:
Add device tree binding documentation.

2016: v2 patchset
https://lkml.org/lkml/2016/5/2/69

2016: v1 patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid
  ARM: dts: vfxxx: Add device tree node required by Vybrid SoC driver
  soc: Add SoC driver for Freescale Vybrid platform

 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  20 +++
 arch/arm/boot/dts/vfxxx.dtsi   |  29 +++
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 198 +
 6 files changed, 259 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.8.2



[PATCH v3 3/4] ARM: dts: vfxxx: Add device tree node required by Vybrid SoC driver

2016-05-20 Thread Sanchayan Maity
Add a device tree node which will be used to bind the Vybrid
SoC driver and provide information adhering to the following:
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 6c5222e..24979d6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -770,5 +770,13 @@
compatible = "iio-hwmon";
io-channels = < 16>, < 16>;
};
+
+   vf610-soc {
+   compatible = "fsl,vf610-soc";
+   rom-revision = <>;
+   mscm = <_cpucfg>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+   };
};
 };
-- 
2.8.2



[PATCH v3 1/4] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-05-20 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.8.2



[PATCH v3 2/4] ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid

2016-05-20 Thread Sanchayan Maity
Add a device tree node for the On-Chip ROM on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..6c5222e 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -91,6 +91,11 @@
interrupt-parent = <_ir>;
ranges;
 
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
+
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
-- 
2.8.2



[PATCH v3 4/4] soc: Add SoC driver for Freescale Vybrid platform

2016-05-20 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and expose the SoC specific
properties via sysfs.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  20 +++
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 198 +
 5 files changed, 230 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt 
b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
new file mode 100644
index 000..338905d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
@@ -0,0 +1,20 @@
+Vybrid System-on-Chip
+-
+
+Required properties:
+
+- compatible: "fsl,vf610-soc"
+- rom-revision: phandle to the on-chip ROM node
+- mscm: phandle to the MSCM CPU configuration node
+- nvmem-cells: phandles to two OCOTP child nodes ocotp_cfg0 and ocotp_cfg1
+- nvmem-cell-names: should contain string names "cfg0" and "cfg1"
+
+Example:
+
+   vf610-soc {
+   compatible = "fsl,vf610-soc";
+   rom-revision = <>;
+   mscm = <_cpucfg>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+   };
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..029ea17
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..571ba69
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.ma...@toradex.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSCM_CPxCOUNT_OFFSET   0x2C
+#define MSCM_CPxCFG1_OFFSET0x14
+#define ROM_REVISION_OFFSET0x80
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   stru

[PATCH v3 3/4] ARM: dts: vfxxx: Add device tree node required by Vybrid SoC driver

2016-05-20 Thread Sanchayan Maity
Add a device tree node which will be used to bind the Vybrid
SoC driver and provide information adhering to the following:
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 6c5222e..24979d6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -770,5 +770,13 @@
compatible = "iio-hwmon";
io-channels = < 16>, < 16>;
};
+
+   vf610-soc {
+   compatible = "fsl,vf610-soc";
+   rom-revision = <>;
+   mscm = <_cpucfg>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+   };
};
 };
-- 
2.8.2



[PATCH v3 1/4] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-05-20 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.8.2



[PATCH v3 2/4] ARM: dts: vfxxx: Add On-Chip ROM node for Vybrid

2016-05-20 Thread Sanchayan Maity
Add a device tree node for the On-Chip ROM on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..6c5222e 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -91,6 +91,11 @@
interrupt-parent = <_ir>;
ranges;
 
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
+
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
-- 
2.8.2



[PATCH v3 4/4] soc: Add SoC driver for Freescale Vybrid platform

2016-05-20 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and expose the SoC specific
properties via sysfs.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity 
---
 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  20 +++
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 198 +
 5 files changed, 230 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt 
b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
new file mode 100644
index 000..338905d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
@@ -0,0 +1,20 @@
+Vybrid System-on-Chip
+-
+
+Required properties:
+
+- compatible: "fsl,vf610-soc"
+- rom-revision: phandle to the on-chip ROM node
+- mscm: phandle to the MSCM CPU configuration node
+- nvmem-cells: phandles to two OCOTP child nodes ocotp_cfg0 and ocotp_cfg1
+- nvmem-cell-names: should contain string names "cfg0" and "cfg1"
+
+Example:
+
+   vf610-soc {
+   compatible = "fsl,vf610-soc";
+   rom-revision = <>;
+   mscm = <_cpucfg>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+   };
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..029ea17
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..571ba69
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MSCM_CPxCOUNT_OFFSET   0x2C
+#define MSCM_CPxCFG1_OFFSET0x14
+#define ROM_REVISION_OFFSET0x80
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   struct vf610_soc *info;
+   struct device *dev = >dev;
+   struct dev

[PATCH v2 4/5] soc: Add SoC bus driver for Freescale Vybrid Platform

2016-05-02 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and sysfs exposes the SoC specific
properties.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/soc/Kconfig |   1 +
 drivers/soc/fsl/Kconfig |  10 +++
 drivers/soc/fsl/Makefile|   1 +
 drivers/soc/fsl/soc-vf610.c | 160 
 4 files changed, 172 insertions(+)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..029ea17
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..99bf641
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.ma...@toradex.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   struct vf610_soc *info;
+   struct device *dev = >dev;
+   struct device_node *soc_node;
+   char soc_type[] = "xx0";
+   size_t id1_len;
+   size_t id2_len;
+   u32 cpucount;
+   u32 l2size;
+   u32 rom_rev;
+   u8 *socid1;
+   u8 *socid2;
+   int ret;
+
+   info = devm_kzalloc(dev, sizeof(struct vf610_soc), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->dev = dev;
+
+   info->ocotp_cfg0 = devm_nvmem_cell_get(dev, "cfg0");
+   if (IS_ERR(info->ocotp_cfg0))
+   return -EPROBE_DEFER;
+
+   info->ocotp_cfg1 = devm_nvmem_cell_get(dev, "cfg1");
+   if (IS_ERR(info->ocotp_cfg1))
+   return -EPROBE_DEFER;
+
+   socid1 = nvmem_cell_read(info->ocotp_cfg0, _len);
+   if (IS_ERR(socid1)) {
+   dev_err(dev, "Could not read nvmem cell %ld\n",
+   PTR_ERR(socid1));
+   return PTR_ERR(socid1);
+   }
+
+   socid2 = nvmem_cell_read(info->ocotp_cfg1, _len);
+   if (IS_ERR(socid2)) {
+   dev_err(dev, "Could not read nvmem cell %ld\n",
+   PTR_ERR(socid2));
+   return PTR_ERR(socid2);
+   }
+   add_device_randomness(soc

[PATCH v2 5/5] vf610-soc: Add Vybrid SoC device tree binding documentation

2016-05-02 Thread Sanchayan Maity
Add device tree binding documentation for Vybrid SoC.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 .../bindings/arm/freescale/fsl,vf610-soc.txt   | 35 ++
 1 file changed, 35 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt 
b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
new file mode 100644
index 000..bdd95e8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
@@ -0,0 +1,35 @@
+Vybrid System-on-Chip
+-
+
+Required properties:
+
+- #address-cells: must be 1
+- #size-cells: must be 1
+- compatible: "fsl,vf610-soc-bus", "simple-bus"
+- interrupt-parent: phandle to the MSCM interrupt router node
+- ranges
+- fsl,rom-revision: phandle to the on-chip ROM node and address of rom
+  revision register
+- fsl,cpu-count: phandle to the MSCM CPU configuration node and address of
+  CPU count register
+- fsl,l2-size: phandle to the MSCM CPU configuration node and address of
+  L2 cache size register
+- nvmem-cells: phandles to two OCOTP child nodes ocotp_cfg0 and ocotp_cfg1
+- nvmem-cell-names: should contain string names "cfg0" and "cfg1"
+
+Example:
+
+   soc {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "fsl,vf610-soc-bus", "simple-bus";
+   interrupt-parent = <_ir>;
+   ranges;
+   fsl,rom-revision = < 0x80>;
+   fsl,cpu-count = <_cpucfg 0x2C>;
+   fsl,l2-size = <_cpucfg 0x14>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+
+   ...
+   };
-- 
2.8.2



[PATCH v2 4/5] soc: Add SoC bus driver for Freescale Vybrid Platform

2016-05-02 Thread Sanchayan Maity
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and sysfs exposes the SoC specific
properties.

A sample output from Colibri Vybrid VF61 is below:

root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machinepower  revision   soc_id subsystem  uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
0013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4

Signed-off-by: Sanchayan Maity 
---
 drivers/soc/Kconfig |   1 +
 drivers/soc/fsl/Kconfig |  10 +++
 drivers/soc/fsl/Makefile|   1 +
 drivers/soc/fsl/soc-vf610.c | 160 
 4 files changed, 172 insertions(+)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index cb58ef0..4410eb7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 000..029ea17
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+   bool "SoC bus device for the Freescale Vybrid platform"
+   depends on NVMEM && NVMEM_VF610_OCOTP
+   select SOC_BUS
+   help
+Include support for the SoC bus on the Freescale Vybrid platform
+providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
 # Makefile for the Linux Kernel SOC fsl specific device drivers
 #
 
+obj-$(CONFIG_SOC_VF610)+= soc-vf610.o
 obj-$(CONFIG_QUICC_ENGINE) += qe/
 obj-$(CONFIG_CPM)  += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 000..99bf641
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct vf610_soc {
+   struct device *dev;
+   struct soc_device_attribute *soc_dev_attr;
+   struct soc_device *soc_dev;
+   struct nvmem_cell *ocotp_cfg0;
+   struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+   struct vf610_soc *info;
+   struct device *dev = >dev;
+   struct device_node *soc_node;
+   char soc_type[] = "xx0";
+   size_t id1_len;
+   size_t id2_len;
+   u32 cpucount;
+   u32 l2size;
+   u32 rom_rev;
+   u8 *socid1;
+   u8 *socid2;
+   int ret;
+
+   info = devm_kzalloc(dev, sizeof(struct vf610_soc), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->dev = dev;
+
+   info->ocotp_cfg0 = devm_nvmem_cell_get(dev, "cfg0");
+   if (IS_ERR(info->ocotp_cfg0))
+   return -EPROBE_DEFER;
+
+   info->ocotp_cfg1 = devm_nvmem_cell_get(dev, "cfg1");
+   if (IS_ERR(info->ocotp_cfg1))
+   return -EPROBE_DEFER;
+
+   socid1 = nvmem_cell_read(info->ocotp_cfg0, _len);
+   if (IS_ERR(socid1)) {
+   dev_err(dev, "Could not read nvmem cell %ld\n",
+   PTR_ERR(socid1));
+   return PTR_ERR(socid1);
+   }
+
+   socid2 = nvmem_cell_read(info->ocotp_cfg1, _len);
+   if (IS_ERR(socid2)) {
+   dev_err(dev, "Could not read nvmem cell %ld\n",
+   PTR_ERR(socid2));
+   return PTR_ERR(socid2);
+   }
+   add_device_randomness(socid1, id1_len);
+   add_device_randomness(socid2, id2_len);
+
+   

[PATCH v2 5/5] vf610-soc: Add Vybrid SoC device tree binding documentation

2016-05-02 Thread Sanchayan Maity
Add device tree binding documentation for Vybrid SoC.

Signed-off-by: Sanchayan Maity 
---
 .../bindings/arm/freescale/fsl,vf610-soc.txt   | 35 ++
 1 file changed, 35 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt 
b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
new file mode 100644
index 000..bdd95e8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
@@ -0,0 +1,35 @@
+Vybrid System-on-Chip
+-
+
+Required properties:
+
+- #address-cells: must be 1
+- #size-cells: must be 1
+- compatible: "fsl,vf610-soc-bus", "simple-bus"
+- interrupt-parent: phandle to the MSCM interrupt router node
+- ranges
+- fsl,rom-revision: phandle to the on-chip ROM node and address of rom
+  revision register
+- fsl,cpu-count: phandle to the MSCM CPU configuration node and address of
+  CPU count register
+- fsl,l2-size: phandle to the MSCM CPU configuration node and address of
+  L2 cache size register
+- nvmem-cells: phandles to two OCOTP child nodes ocotp_cfg0 and ocotp_cfg1
+- nvmem-cell-names: should contain string names "cfg0" and "cfg1"
+
+Example:
+
+   soc {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "fsl,vf610-soc-bus", "simple-bus";
+   interrupt-parent = <_ir>;
+   ranges;
+   fsl,rom-revision = < 0x80>;
+   fsl,cpu-count = <_cpucfg 0x2C>;
+   fsl,l2-size = <_cpucfg 0x14>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+
+   ...
+   };
-- 
2.8.2



[PATCH v2 1/5] mfd: syscon: Introduce syscon_regmap_read_from_offset

2016-05-02 Thread Sanchayan Maity
Currently syscon does not provide an abstraction to access a
register from syscon reference like below

ocotp-cfg1 = < 0x20>

syscon_regmap_read_from_offset provides a generic abstraction to
access a register from syscon reference as above. It allows to
specify the node and node name of phandle reference, reading the
offset from the node entry and providing the value from the offset
in the register map.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/mfd/syscon.c   | 30 ++
 include/linux/mfd/syscon.h | 10 ++
 2 files changed, 40 insertions(+)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 2f2225e..74724c3 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -136,6 +136,36 @@ struct regmap *syscon_node_to_regmap(struct device_node 
*np)
 }
 EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
 
+int syscon_regmap_read_from_offset(struct device_node *np,
+   const char *s, unsigned int *val)
+{
+   struct of_phandle_args pargs;
+   struct regmap *regmap;
+   int offset;
+   int ret;
+
+   if (!np)
+   return -ENODEV;
+
+   ret = of_parse_phandle_with_fixed_args(np, s, 1, 0, );
+   if (ret)
+   return ret;
+
+   regmap = syscon_node_to_regmap(pargs.np);
+   if (IS_ERR(regmap)) {
+   of_node_put(pargs.np);
+   return PTR_ERR(regmap);
+   }
+
+   offset = pargs.args[0];
+   of_node_put(pargs.np);
+
+   ret = regmap_read(regmap, offset, val);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_read_from_offset);
+
 struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
 {
struct device_node *syscon_np;
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index 1088149..42b0759 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -26,6 +26,9 @@ extern struct regmap *syscon_regmap_lookup_by_pdevname(const 
char *s);
 extern struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np,
const char *property);
+extern int syscon_regmap_read_from_offset(struct device_node *np,
+ const char *s,
+ unsigned int *val);
 #else
 static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
 {
@@ -48,6 +51,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle(
 {
return ERR_PTR(-ENOTSUPP);
 }
+
+static inline int syscon_regmap_read_from_offset(struct device_node *np,
+const char *s,
+unsigned int *val)
+{
+   return ERR_PTR(-ENOSYS);
+}
 #endif
 
 #endif /* __LINUX_MFD_SYSCON_H__ */
-- 
2.8.2



[PATCH v2 2/5] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-05-02 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.8.2



[PATCH v2 3/5] ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver

2016-05-02 Thread Sanchayan Maity
Add OCROM node and introduce phandles to OCROM, MSCM and NVMEM
OCOTP for use by the Vybrid SoC bus driver.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..e58f4c6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -87,9 +87,19 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
-   compatible = "simple-bus";
+   compatible = "fsl,vf610-soc-bus", "simple-bus";
interrupt-parent = <_ir>;
ranges;
+   fsl,rom-revision = < 0x80>;
+   fsl,cpu-count = <_cpucfg 0x2C>;
+   fsl,l2-size = <_cpucfg 0x14>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
 
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
-- 
2.8.2



[PATCH v2 0/5] Implement SoC bus driver for Vybrid

2016-05-02 Thread Sanchayan Maity
Hello,

This second patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now. Also now a new syscon
abstraction "syscon_regmap_read_from_offset" is implemented and
exported from syscon allowing accessing a register from a syscon
reference like this

ocotp-cfg1 = < 0x20>;

avoiding code repetition in the driver.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

Changes since v1:
Add device tree binding documentation.

v1 new patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (5):
  mfd: syscon: Introduce syscon_regmap_read_from_offset
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
  soc: Add SoC bus driver for Freescale Vybrid Platform
  vf610-soc: Add Vybrid SoC device tree binding documentation

 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  35 +
 arch/arm/boot/dts/vfxxx.dtsi   |  28 +++-
 drivers/mfd/syscon.c   |  30 
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 160 +
 include/linux/mfd/syscon.h |  10 ++
 8 files changed, 274 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.8.2



[PATCH v2 1/5] mfd: syscon: Introduce syscon_regmap_read_from_offset

2016-05-02 Thread Sanchayan Maity
Currently syscon does not provide an abstraction to access a
register from syscon reference like below

ocotp-cfg1 = < 0x20>

syscon_regmap_read_from_offset provides a generic abstraction to
access a register from syscon reference as above. It allows to
specify the node and node name of phandle reference, reading the
offset from the node entry and providing the value from the offset
in the register map.

Signed-off-by: Sanchayan Maity 
---
 drivers/mfd/syscon.c   | 30 ++
 include/linux/mfd/syscon.h | 10 ++
 2 files changed, 40 insertions(+)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 2f2225e..74724c3 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -136,6 +136,36 @@ struct regmap *syscon_node_to_regmap(struct device_node 
*np)
 }
 EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
 
+int syscon_regmap_read_from_offset(struct device_node *np,
+   const char *s, unsigned int *val)
+{
+   struct of_phandle_args pargs;
+   struct regmap *regmap;
+   int offset;
+   int ret;
+
+   if (!np)
+   return -ENODEV;
+
+   ret = of_parse_phandle_with_fixed_args(np, s, 1, 0, );
+   if (ret)
+   return ret;
+
+   regmap = syscon_node_to_regmap(pargs.np);
+   if (IS_ERR(regmap)) {
+   of_node_put(pargs.np);
+   return PTR_ERR(regmap);
+   }
+
+   offset = pargs.args[0];
+   of_node_put(pargs.np);
+
+   ret = regmap_read(regmap, offset, val);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_read_from_offset);
+
 struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
 {
struct device_node *syscon_np;
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index 1088149..42b0759 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -26,6 +26,9 @@ extern struct regmap *syscon_regmap_lookup_by_pdevname(const 
char *s);
 extern struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np,
const char *property);
+extern int syscon_regmap_read_from_offset(struct device_node *np,
+ const char *s,
+ unsigned int *val);
 #else
 static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
 {
@@ -48,6 +51,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle(
 {
return ERR_PTR(-ENOTSUPP);
 }
+
+static inline int syscon_regmap_read_from_offset(struct device_node *np,
+const char *s,
+unsigned int *val)
+{
+   return ERR_PTR(-ENOSYS);
+}
 #endif
 
 #endif /* __LINUX_MFD_SYSCON_H__ */
-- 
2.8.2



[PATCH v2 2/5] ARM: dts: vfxxx: Add device tree node for OCOTP

2016-05-02 Thread Sanchayan Maity
Add device tree node for the OCOTP peripheral on Vybrid.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec6..0e34d44 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,22 @@
status = "disabled";
};
 
+   ocotp@400a5000 {
+   compatible = "fsl,vf610-ocotp";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x400a5000 0xCF0>;
+   clocks = < VF610_CLK_OCOTP>;
+
+   ocotp_cfg0: cfg0@410 {
+   reg = <0x410 0x4>;
+   };
+
+   ocotp_cfg1: cfg1@420 {
+   reg = <0x420 0x4>;
+   };
+   };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", 
"simple-mfd";
reg = <0x400a7000 0x2000>;
-- 
2.8.2



[PATCH v2 3/5] ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver

2016-05-02 Thread Sanchayan Maity
Add OCROM node and introduce phandles to OCROM, MSCM and NVMEM
OCOTP for use by the Vybrid SoC bus driver.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 0e34d44..e58f4c6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -87,9 +87,19 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
-   compatible = "simple-bus";
+   compatible = "fsl,vf610-soc-bus", "simple-bus";
interrupt-parent = <_ir>;
ranges;
+   fsl,rom-revision = < 0x80>;
+   fsl,cpu-count = <_cpucfg 0x2C>;
+   fsl,l2-size = <_cpucfg 0x14>;
+   nvmem-cells = <_cfg0>, <_cfg1>;
+   nvmem-cell-names = "cfg0", "cfg1";
+
+   ocrom: ocrom@ {
+   compatible = "fsl,vf610-ocrom", "syscon";
+   reg = <0x 0x18000>;
+   };
 
aips0: aips-bus@4000 {
compatible = "fsl,aips-bus", "simple-bus";
-- 
2.8.2



[PATCH v2 0/5] Implement SoC bus driver for Vybrid

2016-05-02 Thread Sanchayan Maity
Hello,

This second patch series is rebased on top of shawn's for-next branch
and tested on Colibri Vybrid VF50 and VF61 modules.

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now. Also now a new syscon
abstraction "syscon_regmap_read_from_offset" is implemented and
exported from syscon allowing accessing a register from a syscon
reference like this

ocotp-cfg1 = < 0x20>;

avoiding code repetition in the driver.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

Feedback is most welcome.

Changes since v1:
Add device tree binding documentation.

v1 new patchset
https://lkml.org/lkml/2016/3/11/132

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (5):
  mfd: syscon: Introduce syscon_regmap_read_from_offset
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
  soc: Add SoC bus driver for Freescale Vybrid Platform
  vf610-soc: Add Vybrid SoC device tree binding documentation

 .../bindings/arm/freescale/fsl,vf610-soc.txt   |  35 +
 arch/arm/boot/dts/vfxxx.dtsi   |  28 +++-
 drivers/mfd/syscon.c   |  30 
 drivers/soc/Kconfig|   1 +
 drivers/soc/fsl/Kconfig|  10 ++
 drivers/soc/fsl/Makefile   |   1 +
 drivers/soc/fsl/soc-vf610.c| 160 +
 include/linux/mfd/syscon.h |  10 ++
 8 files changed, 274 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-soc.txt
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.8.2



[RFC PATCH 1/4] usb: chipidea: Do not rely on OTG while using extcon

2016-03-15 Thread Sanchayan Maity
The existing usage of extcon in Chipidea driver relies on OTG
registers. In case of SoC with dual role device but not a true
OTG controller, this does not work. Such SoC's should specify
the existing CI_HDRC_DUAL_ROLE_NOT_OTG flag and do the role
switch without checking any of the OTG registers.

This patch almost reverts most of commit "usb: chipidea: Use
extcon framework for VBUS and ID detect". We do not rely
anymore on emulating an OTG capable controller by faking OTG
controller reads.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/usb/chipidea/core.c  | 64 
 drivers/usb/chipidea/otg.c   | 39 +--
 include/linux/usb/chipidea.h |  2 --
 3 files changed, 36 insertions(+), 69 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 7404064..d29118d 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -607,14 +607,15 @@ static int ci_vbus_notifier(struct notifier_block *nb, 
unsigned long event,
struct ci_hdrc_cable *vbus = container_of(nb, struct ci_hdrc_cable, nb);
struct ci_hdrc *ci = vbus->ci;
 
+   pm_runtime_get_sync(ci->dev);
+
if (event)
-   vbus->state = true;
+   usb_gadget_vbus_connect(>gadget);
else
-   vbus->state = false;
+   usb_gadget_vbus_disconnect(>gadget);
 
-   vbus->changed = true;
+   pm_runtime_put_sync(ci->dev);
 
-   ci_irq(ci->irq, ci);
return NOTIFY_DONE;
 }
 
@@ -624,14 +625,19 @@ static int ci_id_notifier(struct notifier_block *nb, 
unsigned long event,
struct ci_hdrc_cable *id = container_of(nb, struct ci_hdrc_cable, nb);
struct ci_hdrc *ci = id->ci;
 
-   if (event)
-   id->state = false;
-   else
-   id->state = true;
+   pm_runtime_get_sync(ci->dev);
+
+   ci_role_stop(ci);
+
+   hw_wait_phy_stable();
+
+   if (ci_role_start(ci, event ? CI_ROLE_HOST : CI_ROLE_GADGET))
+   dev_err(ci->dev,
+   "Can't start %s role\n",
+   event ? "host" : "gadget");
 
-   id->changed = true;
+   pm_runtime_put_sync(ci->dev);
 
-   ci_irq(ci->irq, ci);
return NOTIFY_DONE;
 }
 
@@ -738,25 +744,10 @@ static int ci_get_platdata(struct device *dev,
cable->nb.notifier_call = ci_vbus_notifier;
cable->edev = ext_vbus;
 
-   if (!IS_ERR(ext_vbus)) {
-   ret = extcon_get_cable_state_(cable->edev, EXTCON_USB);
-   if (ret)
-   cable->state = true;
-   else
-   cable->state = false;
-   }
-
cable = >id_extcon;
cable->nb.notifier_call = ci_id_notifier;
cable->edev = ext_id;
 
-   if (!IS_ERR(ext_id)) {
-   ret = extcon_get_cable_state_(cable->edev, EXTCON_USB_HOST);
-   if (ret)
-   cable->state = false;
-   else
-   cable->state = true;
-   }
return 0;
 }
 
@@ -896,6 +887,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
void __iomem*base;
int ret;
enum usb_dr_mode dr_mode;
+   struct ci_hdrc_cable *cable;
 
if (!dev_get_platdata(dev)) {
dev_err(dev, "platform data missing\n");
@@ -963,6 +955,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
ci_get_otg_capable(ci);
 
+   ret = ci_extcon_register(ci);
+   if (ret) {
+   dev_err(dev, "extcon registration failed\n");
+   goto deinit_phy;
+   }
+
dr_mode = ci->platdata->dr_mode;
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
@@ -1003,6 +1001,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 * user can switch it through debugfs.
 */
ci->role = CI_ROLE_GADGET;
+   cable = >platdata->id_extcon;
+   if (!IS_ERR(cable->edev)) {
+   if (extcon_get_cable_state(cable->edev,
+   "USB-HOST") == true)
+   ci->role = CI_ROLE_HOST;
+   }
}
} else {
ci->role = ci->roles[CI_ROLE_HOST]
@@ -1021,6 +1025,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ci_role(ci)->name);
goto stop;
}
+   cable = >platda

[RFC PATCH 4/4] ARM: dts: vf-colibri: USB device/host switch using extcon gpio

2016-03-15 Thread Sanchayan Maity
Use USBC_DET feature of standard Colibri SODIMM pin 137 for USB
device/host switching using the generic extcon USB gpio implementation.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 
 arch/arm/boot/dts/vf-colibri.dtsi |  7 +++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi 
b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index 4d8b7f6..794c02e 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -50,6 +50,14 @@
clock-frequency = <1600>;
};
 
+   extcon_usbc_det: usbc_det {
+   compatible = "linux,extcon-usb-gpio";
+   debounce = <25>;
+   id-gpio = < 6 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_usbc_det>;
+   };
+
reg_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "3.3V";
@@ -146,6 +154,10 @@
status = "okay";
 };
 
+ {
+   extcon = <_usbc_det>, <_usbc_det>;
+};
+
  {
vbus-supply = <_usbh_vbus>;
 };
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index fda7f28..551b6a1 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -171,6 +171,7 @@
 
  {
disable-over-current;
+   dr_mode = "otg";
status = "okay";
 };
 
@@ -326,6 +327,12 @@
>;
};
 
+   pinctrl_usbc_det: gpio_usbc_det {
+   fsl,pins = <
+   VF610_PAD_PTC29__GPIO_102   0x22ed
+   >;
+   };
+
pinctrl_usbh1_reg: gpio_usb_vbus {
fsl,pins = <
VF610_PAD_PTD4__GPIO_83 0x22ed
-- 
2.7.3



[RFC PATCH 1/4] usb: chipidea: Do not rely on OTG while using extcon

2016-03-15 Thread Sanchayan Maity
The existing usage of extcon in Chipidea driver relies on OTG
registers. In case of SoC with dual role device but not a true
OTG controller, this does not work. Such SoC's should specify
the existing CI_HDRC_DUAL_ROLE_NOT_OTG flag and do the role
switch without checking any of the OTG registers.

This patch almost reverts most of commit "usb: chipidea: Use
extcon framework for VBUS and ID detect". We do not rely
anymore on emulating an OTG capable controller by faking OTG
controller reads.

Signed-off-by: Sanchayan Maity 
---
 drivers/usb/chipidea/core.c  | 64 
 drivers/usb/chipidea/otg.c   | 39 +--
 include/linux/usb/chipidea.h |  2 --
 3 files changed, 36 insertions(+), 69 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 7404064..d29118d 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -607,14 +607,15 @@ static int ci_vbus_notifier(struct notifier_block *nb, 
unsigned long event,
struct ci_hdrc_cable *vbus = container_of(nb, struct ci_hdrc_cable, nb);
struct ci_hdrc *ci = vbus->ci;
 
+   pm_runtime_get_sync(ci->dev);
+
if (event)
-   vbus->state = true;
+   usb_gadget_vbus_connect(>gadget);
else
-   vbus->state = false;
+   usb_gadget_vbus_disconnect(>gadget);
 
-   vbus->changed = true;
+   pm_runtime_put_sync(ci->dev);
 
-   ci_irq(ci->irq, ci);
return NOTIFY_DONE;
 }
 
@@ -624,14 +625,19 @@ static int ci_id_notifier(struct notifier_block *nb, 
unsigned long event,
struct ci_hdrc_cable *id = container_of(nb, struct ci_hdrc_cable, nb);
struct ci_hdrc *ci = id->ci;
 
-   if (event)
-   id->state = false;
-   else
-   id->state = true;
+   pm_runtime_get_sync(ci->dev);
+
+   ci_role_stop(ci);
+
+   hw_wait_phy_stable();
+
+   if (ci_role_start(ci, event ? CI_ROLE_HOST : CI_ROLE_GADGET))
+   dev_err(ci->dev,
+   "Can't start %s role\n",
+   event ? "host" : "gadget");
 
-   id->changed = true;
+   pm_runtime_put_sync(ci->dev);
 
-   ci_irq(ci->irq, ci);
return NOTIFY_DONE;
 }
 
@@ -738,25 +744,10 @@ static int ci_get_platdata(struct device *dev,
cable->nb.notifier_call = ci_vbus_notifier;
cable->edev = ext_vbus;
 
-   if (!IS_ERR(ext_vbus)) {
-   ret = extcon_get_cable_state_(cable->edev, EXTCON_USB);
-   if (ret)
-   cable->state = true;
-   else
-   cable->state = false;
-   }
-
cable = >id_extcon;
cable->nb.notifier_call = ci_id_notifier;
cable->edev = ext_id;
 
-   if (!IS_ERR(ext_id)) {
-   ret = extcon_get_cable_state_(cable->edev, EXTCON_USB_HOST);
-   if (ret)
-   cable->state = false;
-   else
-   cable->state = true;
-   }
return 0;
 }
 
@@ -896,6 +887,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
void __iomem*base;
int ret;
enum usb_dr_mode dr_mode;
+   struct ci_hdrc_cable *cable;
 
if (!dev_get_platdata(dev)) {
dev_err(dev, "platform data missing\n");
@@ -963,6 +955,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
ci_get_otg_capable(ci);
 
+   ret = ci_extcon_register(ci);
+   if (ret) {
+   dev_err(dev, "extcon registration failed\n");
+   goto deinit_phy;
+   }
+
dr_mode = ci->platdata->dr_mode;
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
@@ -1003,6 +1001,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 * user can switch it through debugfs.
 */
ci->role = CI_ROLE_GADGET;
+   cable = >platdata->id_extcon;
+   if (!IS_ERR(cable->edev)) {
+   if (extcon_get_cable_state(cable->edev,
+   "USB-HOST") == true)
+   ci->role = CI_ROLE_HOST;
+   }
}
} else {
ci->role = ci->roles[CI_ROLE_HOST]
@@ -1021,6 +1025,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ci_role(ci)->name);
goto stop;
}
+   cable = >platdata->vbus_extcon;
+   if (!IS_ERR(cable->edev)) {
+

[RFC PATCH 4/4] ARM: dts: vf-colibri: USB device/host switch using extcon gpio

2016-03-15 Thread Sanchayan Maity
Use USBC_DET feature of standard Colibri SODIMM pin 137 for USB
device/host switching using the generic extcon USB gpio implementation.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 
 arch/arm/boot/dts/vf-colibri.dtsi |  7 +++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi 
b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index 4d8b7f6..794c02e 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -50,6 +50,14 @@
clock-frequency = <1600>;
};
 
+   extcon_usbc_det: usbc_det {
+   compatible = "linux,extcon-usb-gpio";
+   debounce = <25>;
+   id-gpio = < 6 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_usbc_det>;
+   };
+
reg_3v3: regulator-3v3 {
compatible = "regulator-fixed";
regulator-name = "3.3V";
@@ -146,6 +154,10 @@
status = "okay";
 };
 
+ {
+   extcon = <_usbc_det>, <_usbc_det>;
+};
+
  {
vbus-supply = <_usbh_vbus>;
 };
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index fda7f28..551b6a1 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -171,6 +171,7 @@
 
  {
disable-over-current;
+   dr_mode = "otg";
status = "okay";
 };
 
@@ -326,6 +327,12 @@
>;
};
 
+   pinctrl_usbc_det: gpio_usbc_det {
+   fsl,pins = <
+   VF610_PAD_PTC29__GPIO_102   0x22ed
+   >;
+   };
+
pinctrl_usbh1_reg: gpio_usb_vbus {
fsl,pins = <
VF610_PAD_PTD4__GPIO_83 0x22ed
-- 
2.7.3



[RFC PATCH 3/4] ARM: dts: vfxxx: Make Vybrid match only on it's own compatible string

2016-03-15 Thread Sanchayan Maity
Remove the compatible string "fsl,imx27-usb" from being used to
match on usb device nodes for Vybrid. This is required for specifying
that Vybrid USB controller is a dual role but not a true OTG controller
using the CI_HDRC_DUAL_ROLE_NOT_OTG flag in the corresponding ci_hdrc_imx
driver.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 5e49fbd..c2d1b5d 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -452,7 +452,7 @@
};
 
usbdev0: usb@40034000 {
-   compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+   compatible = "fsl,vf610-usb";
reg = <0x40034000 0x800>;
interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
clocks = < VF610_CLK_USBC0>;
-- 
2.7.3



[RFC PATCH 3/4] ARM: dts: vfxxx: Make Vybrid match only on it's own compatible string

2016-03-15 Thread Sanchayan Maity
Remove the compatible string "fsl,imx27-usb" from being used to
match on usb device nodes for Vybrid. This is required for specifying
that Vybrid USB controller is a dual role but not a true OTG controller
using the CI_HDRC_DUAL_ROLE_NOT_OTG flag in the corresponding ci_hdrc_imx
driver.

Signed-off-by: Sanchayan Maity 
---
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 5e49fbd..c2d1b5d 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -452,7 +452,7 @@
};
 
usbdev0: usb@40034000 {
-   compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+   compatible = "fsl,vf610-usb";
reg = <0x40034000 0x800>;
interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
clocks = < VF610_CLK_USBC0>;
-- 
2.7.3



[RFC PATCH 0/4] Implement USB device/host switch for Vybrid

2016-03-15 Thread Sanchayan Maity
Hello Peter,

The existing usage of extcon in Chipidea driver relies on OTG
registers. In case of SoC with dual role device but not a true
OTG controller, this does not work. Such SoC's should specify
the existing CI_HDRC_DUAL_ROLE_NOT_OTG flag and do the role
switch without checking any of the OTG registers in my opinion.
This is the case for Vybrid which uses a Chipidea IP but does
not have a true 5 pin OTG implemented.

This patch almost reverts most of commit 
3ecb3e09b042e70799ff3a1ff464a5ecaa7547d9
"usb: chipidea: Use extcon framework for VBUS and ID detect".
We do not rely anymore on emulating an OTG capable controller
by faking OTG controller reads.

Observations without the following patchset with the current
implementation.

CONFIG_USB_OTG was kept selected. Just the device tree changes
done in the fourth patch of this patch were done.

1. Booting with the USB device connected and then disconnecting
on boot results in "irq 38: nobody cared (try booting with the
"irqpoll" option)" stack trace.

2. Disconnecting the USB device and reconnecting results in a
timeout error message coming ci_handle_id_switch --> hw_wait_reg
while waiting for OTGSC_BSV register field. Why rely on a read
from OTG register while using extcon?

Also, usb_gadget_vbus_connect seems not to be called, render device
mode useless (usb_gadget_vbus_connect according to my understanding
should be called through ci_vbus_notifier -> ci_irq -> ci_otg_work ->
ci_handle_vbus_change).

3. Once in a while doing the switch from host to device would
result "ci_hdrc.0 Freeing queued request" but the switch won't
be successful as expected and I wont get the following message

[  167.298040] ci_hdrc ci_hdrc.0: USB bus 2 deregistered
[  167.772520] configfs-gadget gadget: high-speed config #1: c

and further our RNDIS client configuration on said USB connection
won't work. Once in a while I also experience a complete freeze
if I try to ping the interface after this.

4. With the current "OTG" implementation, should the ci->lock not
be acquired before calling ci_role_stop or ci_role_start in the
code path ci_id_notifier -> ci_irq -> otg_workqueue?

Looking at the commit message this extcon was introduced for Qualcomm's
410 Dragonboard and while I did not look at Dragonboard's or 410's DS,
requirement seems similar to Vybrid.?

What are your thoughts on this? Or considering the requirement of Qualcomm
would keeping direct role switch in case of DUAL_ROLE_NOT_OTG flag
and keeping existing OTG reads would be acceptable? Currently in our tree
we keep both implementations. The 410 is a 64bit SoC but grepping arch/
arm64/boot/dts/qcom for an extcon entry I didn't find any.

Regards,
Sanchayan.

Sanchayan Maity (4):
  usb: chipidea: Do not rely on OTG while using extcon
  usb: chipidea: ci_hdrc_imx: Introduce CI_HDRC_DUAL_ROLE_NOT_OTG for Vybrid
  ARM: dts: vfxxx: Make Vybrid match only on it's own compatible string
  ARM: dts: vf-colibri: USB device/host switch using extcon gpio

 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 ++
 arch/arm/boot/dts/vf-colibri.dtsi |  7 
 arch/arm/boot/dts/vfxxx.dtsi  |  2 +-
 drivers/usb/chipidea/ci_hdrc_imx.c|  5 +++
 drivers/usb/chipidea/core.c   | 64 +--
 drivers/usb/chipidea/otg.c| 39 +--
 include/linux/usb/chipidea.h  |  2 -
 7 files changed, 61 insertions(+), 70 deletions(-)

-- 
2.7.3



[RFC PATCH 0/4] Implement USB device/host switch for Vybrid

2016-03-15 Thread Sanchayan Maity
Hello Peter,

The existing usage of extcon in Chipidea driver relies on OTG
registers. In case of SoC with dual role device but not a true
OTG controller, this does not work. Such SoC's should specify
the existing CI_HDRC_DUAL_ROLE_NOT_OTG flag and do the role
switch without checking any of the OTG registers in my opinion.
This is the case for Vybrid which uses a Chipidea IP but does
not have a true 5 pin OTG implemented.

This patch almost reverts most of commit 
3ecb3e09b042e70799ff3a1ff464a5ecaa7547d9
"usb: chipidea: Use extcon framework for VBUS and ID detect".
We do not rely anymore on emulating an OTG capable controller
by faking OTG controller reads.

Observations without the following patchset with the current
implementation.

CONFIG_USB_OTG was kept selected. Just the device tree changes
done in the fourth patch of this patch were done.

1. Booting with the USB device connected and then disconnecting
on boot results in "irq 38: nobody cared (try booting with the
"irqpoll" option)" stack trace.

2. Disconnecting the USB device and reconnecting results in a
timeout error message coming ci_handle_id_switch --> hw_wait_reg
while waiting for OTGSC_BSV register field. Why rely on a read
from OTG register while using extcon?

Also, usb_gadget_vbus_connect seems not to be called, render device
mode useless (usb_gadget_vbus_connect according to my understanding
should be called through ci_vbus_notifier -> ci_irq -> ci_otg_work ->
ci_handle_vbus_change).

3. Once in a while doing the switch from host to device would
result "ci_hdrc.0 Freeing queued request" but the switch won't
be successful as expected and I wont get the following message

[  167.298040] ci_hdrc ci_hdrc.0: USB bus 2 deregistered
[  167.772520] configfs-gadget gadget: high-speed config #1: c

and further our RNDIS client configuration on said USB connection
won't work. Once in a while I also experience a complete freeze
if I try to ping the interface after this.

4. With the current "OTG" implementation, should the ci->lock not
be acquired before calling ci_role_stop or ci_role_start in the
code path ci_id_notifier -> ci_irq -> otg_workqueue?

Looking at the commit message this extcon was introduced for Qualcomm's
410 Dragonboard and while I did not look at Dragonboard's or 410's DS,
requirement seems similar to Vybrid.?

What are your thoughts on this? Or considering the requirement of Qualcomm
would keeping direct role switch in case of DUAL_ROLE_NOT_OTG flag
and keeping existing OTG reads would be acceptable? Currently in our tree
we keep both implementations. The 410 is a 64bit SoC but grepping arch/
arm64/boot/dts/qcom for an extcon entry I didn't find any.

Regards,
Sanchayan.

Sanchayan Maity (4):
  usb: chipidea: Do not rely on OTG while using extcon
  usb: chipidea: ci_hdrc_imx: Introduce CI_HDRC_DUAL_ROLE_NOT_OTG for Vybrid
  ARM: dts: vfxxx: Make Vybrid match only on it's own compatible string
  ARM: dts: vf-colibri: USB device/host switch using extcon gpio

 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 ++
 arch/arm/boot/dts/vf-colibri.dtsi |  7 
 arch/arm/boot/dts/vfxxx.dtsi  |  2 +-
 drivers/usb/chipidea/ci_hdrc_imx.c|  5 +++
 drivers/usb/chipidea/core.c   | 64 +--
 drivers/usb/chipidea/otg.c| 39 +--
 include/linux/usb/chipidea.h  |  2 -
 7 files changed, 61 insertions(+), 70 deletions(-)

-- 
2.7.3



[RFC PATCH 2/4] usb: chipidea: ci_hdrc_imx: Introduce CI_HDRC_DUAL_ROLE_NOT_OTG for Vybrid

2016-03-15 Thread Sanchayan Maity
The Vybrid SoC has a dual role device which can be configured to
act as a host or device through firmware interface, but, it is
not a true OTG controller.

Use the CI_HDRC_DUAL_ROLE_NOT_OTG in the platform flag, introduce
a new platform data structure for Vybrid and match on the compatible
string fsl,vf610-usb instead of the earlier fsl,imx27-usb.

Signed-off-by: Sanchayan Maity <maitysancha...@gmail.com>
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index f14f4ab..d9b8a53 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -65,6 +65,10 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data 
= {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
 };
 
+static const struct ci_hdrc_imx_platform_flag vf610_usb_data = {
+   .flags = CI_HDRC_DUAL_ROLE_NOT_OTG,
+};
+
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx28-usb", .data = _usb_data},
{ .compatible = "fsl,imx27-usb", .data = _usb_data},
@@ -73,6 +77,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usb", .data = _usb_data},
{ .compatible = "fsl,imx6ul-usb", .data = _usb_data},
{ .compatible = "fsl,imx7d-usb", .data = _usb_data},
+   { .compatible = "fsl,vf610-usb", .data = _usb_data},
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
-- 
2.7.3



[RFC PATCH 2/4] usb: chipidea: ci_hdrc_imx: Introduce CI_HDRC_DUAL_ROLE_NOT_OTG for Vybrid

2016-03-15 Thread Sanchayan Maity
The Vybrid SoC has a dual role device which can be configured to
act as a host or device through firmware interface, but, it is
not a true OTG controller.

Use the CI_HDRC_DUAL_ROLE_NOT_OTG in the platform flag, introduce
a new platform data structure for Vybrid and match on the compatible
string fsl,vf610-usb instead of the earlier fsl,imx27-usb.

Signed-off-by: Sanchayan Maity 
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c 
b/drivers/usb/chipidea/ci_hdrc_imx.c
index f14f4ab..d9b8a53 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -65,6 +65,10 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data 
= {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
 };
 
+static const struct ci_hdrc_imx_platform_flag vf610_usb_data = {
+   .flags = CI_HDRC_DUAL_ROLE_NOT_OTG,
+};
+
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx28-usb", .data = _usb_data},
{ .compatible = "fsl,imx27-usb", .data = _usb_data},
@@ -73,6 +77,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usb", .data = _usb_data},
{ .compatible = "fsl,imx6ul-usb", .data = _usb_data},
{ .compatible = "fsl,imx7d-usb", .data = _usb_data},
+   { .compatible = "fsl,vf610-usb", .data = _usb_data},
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
-- 
2.7.3



[PATCH v1 0/4] Implement SoC bus driver for Vybrid

2016-03-11 Thread Sanchayan Maity
Hello,

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now. Also now a new syscon
abstraction "syscon_regmap_read_from_offset" is implemented and
exported from syscon allowing accessing a register from a syscon
reference like this

ocotp-cfg1 = < 0x20>;

avoiding code repetition in the driver.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

This patch series is based on top of shawn's for-next branch and
tested on Colibri Vybrid VF50 and VF61 modules.

Feedback is most welcome.

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  mfd: syscon: Introduce syscon_regmap_read_from_offset
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
  soc: Add SoC bus driver for Freescale Vybrid Platform

 arch/arm/boot/dts/vfxxx.dtsi |  28 +++-
 drivers/mfd/syscon.c |  30 
 drivers/soc/Kconfig  |   1 +
 drivers/soc/fsl/Kconfig  |  10 +++
 drivers/soc/fsl/Makefile |   1 +
 drivers/soc/fsl/soc-vf610.c  | 160 +++
 include/linux/mfd/syscon.h   |  10 +++
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.7.2



[PATCH v1 0/4] Implement SoC bus driver for Vybrid

2016-03-11 Thread Sanchayan Maity
Hello,

This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc

This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.

Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now. Also now a new syscon
abstraction "syscon_regmap_read_from_offset" is implemented and
exported from syscon allowing accessing a register from a syscon
reference like this

ocotp-cfg1 = < 0x20>;

avoiding code repetition in the driver.

One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.

This patch series is based on top of shawn's for-next branch and
tested on Colibri Vybrid VF50 and VF61 modules.

Feedback is most welcome.

[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Regards,
Sanchayan.

Sanchayan Maity (4):
  mfd: syscon: Introduce syscon_regmap_read_from_offset
  ARM: dts: vfxxx: Add device tree node for OCOTP
  ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
  soc: Add SoC bus driver for Freescale Vybrid Platform

 arch/arm/boot/dts/vfxxx.dtsi |  28 +++-
 drivers/mfd/syscon.c |  30 
 drivers/soc/Kconfig  |   1 +
 drivers/soc/fsl/Kconfig  |  10 +++
 drivers/soc/fsl/Makefile |   1 +
 drivers/soc/fsl/soc-vf610.c  | 160 +++
 include/linux/mfd/syscon.h   |  10 +++
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/fsl/Kconfig
 create mode 100644 drivers/soc/fsl/soc-vf610.c

-- 
2.7.2



  1   2   3   4   >