Re: [PATCH] dmaengine: edma: fix build without CONFIG_OF

2015-11-03 Thread Peter Ujfalusi
On 11/03/2015 04:00 PM, Arnd Bergmann wrote:
> During the edma rework, a build error was introduced for the
> case that CONFIG_OF is disabled:
> 
> drivers/built-in.o: In function `edma_tc_set_pm_state':
> :(.text+0x43bf0): undefined reference to `of_find_device_by_node'
> 
> As the edma_tc_set_pm_state() function does nothing in case
> we are running without OF, this adds an IS_ENABLED() check
> that turns the function into an empty stub then and avoids the
> link error.
> 
> Signed-off-by: Arnd Bergmann 
> Fixes: ca304fa9bb76 ("ARM/dmaengine: edma: Public API to use private struct 
> pointer")

The actual commit this patch is fixing is:
1be5336bc7ba dmaengine: edma: New device tree binding

> ---
> Found on ARM randconfig builds with today's linux-next

I have sanity built the kernel with omap2plus_defconfig and
davinci_all_defconfig since eDMA is used by these platforms and did not faced
with this issue, as obviously these defconfigs will result OF to be enabled.

> diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
> index 31722d436a42..16713a93da10 100644
> --- a/drivers/dma/edma.c
> +++ b/drivers/dma/edma.c
> @@ -1560,7 +1560,7 @@ static void edma_tc_set_pm_state(struct edma_tc *tc, 
> bool enable)
>   struct platform_device *tc_pdev;
>   int ret;
>  
> - if (!tc)
> + if (!IS_ENABLED(CONFIG_OF) || !tc)
>   return;

Should we instead put the function inside of:
#if IS_ENABLED(CONFIG_OF)
static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
{
...
}
#else
static inline void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
{
}
#endif /* IS_ENABLED(CONFIG_OF) */


>  
>   tc_pdev = of_find_device_by_node(tc->node);
> 

-- 
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-03 Thread Vignesh R
Hi,

On 11/03/2015 04:49 PM, Michal Suchanek wrote:
> On 3 November 2015 at 11:06, Vignesh R  wrote:
>> In addition to providing direct access to SPI bus, some spi controller
>> hardwares (like ti-qspi) provide special memory mapped port
>> to accesses SPI flash devices in order to increase read performance.
>> This means the controller can automatically send the SPI signals
>> required to read data from the SPI flash device.
>> For this, spi controller needs to know flash specific information like
>> read command to use, dummy bytes and address width. Once these settings
>> are populated in hardware registers, any read accesses to flash's memory
>> map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
>> handled by controller hardware. The hardware will automatically generate
>> SPI signals required to read data from flash and present it to CPU/DMA.
>>
>> Introduce spi_mtd_mmap_read() interface to support memory mapped read
>> over SPI flash devices. SPI master drivers can implement this callback to
>> support memory mapped read interfaces. m25p80 flash driver and other
>> flash drivers can call this to request memory mapped read. The interface
>> should only be used MTD flashes and cannot be used with other SPI devices.
>>
>> Signed-off-by: Vignesh R 
>> ---
>>  drivers/spi/spi.c   | 35 +++
>>  include/linux/spi/spi.h | 23 +++
>>  2 files changed, 58 insertions(+)
>>
>> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
>> index a5f53de813d3..5a5c7a7d47f2 100644
>> --- a/drivers/spi/spi.c
>> +++ b/drivers/spi/spi.c
>> @@ -1059,6 +1059,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> }
>> }
>>
>> +   mutex_lock(&master->mmap_lock_mutex);
>> trace_spi_message_start(master->cur_msg);
>>
>> if (master->prepare_message) {
>> @@ -1068,6 +1069,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> "failed to prepare message: %d\n", ret);
>> master->cur_msg->status = ret;
>> spi_finalize_current_message(master);
>> +   mutex_unlock(&master->mmap_lock_mutex);
>> return;
>> }
>> master->cur_msg_prepared = true;
>> @@ -1077,6 +1079,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> if (ret) {
>> master->cur_msg->status = ret;
>> spi_finalize_current_message(master);
>> +   mutex_unlock(&master->mmap_lock_mutex);
>> return;
>> }
>>
>> @@ -1084,8 +1087,10 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> if (ret) {
>> dev_err(&master->dev,
>> "failed to transfer one message from queue\n");
>> +   mutex_unlock(&master->mmap_lock_mutex);
>> return;
>> }
>> +   mutex_unlock(&master->mmap_lock_mutex);
>>  }
>>
>>  /**
>> @@ -1732,6 +1737,7 @@ int spi_register_master(struct spi_master *master)
>> spin_lock_init(&master->queue_lock);
>> spin_lock_init(&master->bus_lock_spinlock);
>> mutex_init(&master->bus_lock_mutex);
>> +   mutex_init(&master->mmap_lock_mutex);
>> master->bus_lock_flag = 0;
>> init_completion(&master->xfer_completion);
>> if (!master->max_dma_len)
>> @@ -2237,6 +2243,35 @@ int spi_async_locked(struct spi_device *spi, struct 
>> spi_message *message)
>>  EXPORT_SYMBOL_GPL(spi_async_locked);
>>
>>
>> +int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
>> + size_t *retlen, u_char *buf, u8 read_opcode,
>> + u8 addr_width, u8 dummy_bytes)
>> +
>> +{
>> +   struct spi_master *master = spi->master;
>> +   int ret;
>> +
>> +   if (master->auto_runtime_pm) {
>> +   ret = pm_runtime_get_sync(master->dev.parent);
>> +   if (ret < 0) {
>> +   dev_err(&master->dev, "Failed to power device: %d\n",
>> +   ret);
>> +   goto err;
>> +   }
>> +   }
>> +   mutex_lock(&master->mmap_lock_mutex);
>> +   ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
>> +   read_opcode, addr_width,
>> +   dummy_bytes);
>> +   mutex_unlock(&master->mmap_lock_mutex);
>> +   if (master->auto_runtime_pm)
>> +   pm_runtime_put(master->dev.parent);
>> +
>> +err:
>> +   return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(spi_mtd_mmap_read);
>> +
>>  
>> /*-*/
>>
>>  /* Utility methods for SPI master protocol drivers, layered on
>> diff --git a/include/linux/spi/spi.h b/includ

[PATCH] ti/fapll: fix wrong do_div() usage

2015-11-03 Thread Nicolas Pitre
do_div() is meant to be used with an unsigned dividend.

Signed-off-by: Nicolas Pitre 

diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c
index f4b2e9888b..66a0d0ed8b 100644
--- a/drivers/clk/ti/fapll.c
+++ b/drivers/clk/ti/fapll.c
@@ -168,7 +168,7 @@ static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,
 {
struct fapll_data *fd = to_fapll(hw);
u32 fapll_n, fapll_p, v;
-   long long rate;
+   u64 rate;
 
if (ti_fapll_clock_is_bypass(fd))
return parent_rate;
@@ -314,7 +314,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct 
clk_hw *hw,
 {
struct fapll_synth *synth = to_synth(hw);
u32 synth_div_m;
-   long long rate;
+   u64 rate;
 
/* The audio_pll_clk1 is hardwired to produce 32.768KiHz clock */
if (!synth->div)
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ti/clkt_dpll: fix wrong do_div() usage

2015-11-03 Thread Nicolas Pitre
do_div() is meant to be used with an unsigned dividend.

Signed-off-by: Nicolas Pitre 

diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c
index 9023ca9caf..b5cc6f66ae 100644
--- a/drivers/clk/ti/clkt_dpll.c
+++ b/drivers/clk/ti/clkt_dpll.c
@@ -240,7 +240,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw)
  */
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
 {
-   long long dpll_clk;
+   u64 dpll_clk;
u32 dpll_mult, dpll_div, v;
struct dpll_data *dd;
 
@@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
dpll_div = v & dd->div1_mask;
dpll_div >>= __ffs(dd->div1_mask);
 
-   dpll_clk = (long long)clk_get_rate(dd->clk_ref) * dpll_mult;
+   dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult;
do_div(dpll_clk, dpll_div + 1);
 
return dpll_clk;
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drivers: net: cpsw: Add support for fixed-link PHY

2015-11-03 Thread Markus Brunner
Add support for a fixed-link devicetree sub-node in case the the 
cpsw MAC is directly connected to a non-mdio PHY/device. 

Signed-off-by: Markus Brunner 

---
 Documentation/devicetree/bindings/net/cpsw.txt |5 +
 drivers/net/ethernet/ti/cpsw.c |   13 +
 2 files changed, 18 insertions(+)

diff -upNr linux-4.3.orig/Documentation/devicetree/bindings/net/cpsw.txt 
linux-4.3/Documentation/devicetree/bindings/net/cpsw.txt
--- linux-4.3.orig/Documentation/devicetree/bindings/net/cpsw.txt   
2015-11-03 17:21:40.0 +0100
+++ linux-4.3/Documentation/devicetree/bindings/net/cpsw.txt2015-11-02 
16:53:43.0 +0100
@@ -41,6 +41,11 @@ Optional properties:
 - mac-address  : See ethernet.txt file in the same directory
 - phy-handle   : See ethernet.txt file in the same directory
 
+Slave sub-nodes:
+- fixed-link   : See fixed-link.txt file in the same directory
+ Either the properties phy_id and phy-mode,
+ or the sub-node fixed-link can be specified
+
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
 Future plan is to migrate hwmod data base contents into device tree
diff -upNr linux-4.3.orig/drivers/net/ethernet/ti/cpsw.c 
linux-4.3/drivers/net/ethernet/ti/cpsw.c
--- linux-4.3.orig/drivers/net/ethernet/ti/cpsw.c   2015-11-03 
17:18:00.0 +0100
+++ linux-4.3/drivers/net/ethernet/ti/cpsw.c2015-11-03 17:04:08.0 
+0100
@@ -2037,6 +2037,19 @@ static int cpsw_probe_dt(struct cpsw_pri
continue;
 
priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
+   if (of_phy_is_fixed_link(slave_node)) {
+   struct phy_device *pd;
+
+   ret = of_phy_register_fixed_link(slave_node);
+   if (ret)
+   return ret;
+   pd = of_phy_find_device(slave_node);
+   if (!pd)
+   return -ENODEV;
+   snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
+PHY_ID_FMT, pd->bus->id, pd->phy_id);
+   goto no_phy_slave;
+   }
parp = of_get_property(slave_node, "phy_id", &lenp);
if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
dev_err(&pdev->dev, "Missing slave[%d] phy_id 
property\n", i);

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] dmaengine: edma: fix build without CONFIG_OF

2015-11-03 Thread Arnd Bergmann
During the edma rework, a build error was introduced for the
case that CONFIG_OF is disabled:

drivers/built-in.o: In function `edma_tc_set_pm_state':
:(.text+0x43bf0): undefined reference to `of_find_device_by_node'

As the edma_tc_set_pm_state() function does nothing in case
we are running without OF, this adds an IS_ENABLED() check
that turns the function into an empty stub then and avoids the
link error.

Signed-off-by: Arnd Bergmann 
Fixes: ca304fa9bb76 ("ARM/dmaengine: edma: Public API to use private struct 
pointer")
---
Found on ARM randconfig builds with today's linux-next

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 31722d436a42..16713a93da10 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -1560,7 +1560,7 @@ static void edma_tc_set_pm_state(struct edma_tc *tc, bool 
enable)
struct platform_device *tc_pdev;
int ret;
 
-   if (!tc)
+   if (!IS_ENABLED(CONFIG_OF) || !tc)
return;
 
tc_pdev = of_find_device_by_node(tc->node);

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mmc: omap_hsmmc: No need to check DMA channel validity at module remove

2015-11-03 Thread Peter Ujfalusi
The driver will not probe without valid DMA channels so no need to check
if they are valid when the module is removed.

Signed-off-by: Peter Ujfalusi 
CC: Ulf Hansson 
---
 drivers/mmc/host/omap_hsmmc.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f70e52b05648..712c74fd0401 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2262,10 +2262,8 @@ static int omap_hsmmc_remove(struct platform_device 
*pdev)
pm_runtime_get_sync(host->dev);
mmc_remove_host(host->mmc);
 
-   if (host->tx_chan)
-   dma_release_channel(host->tx_chan);
-   if (host->rx_chan)
-   dma_release_channel(host->rx_chan);
+   dma_release_channel(host->tx_chan);
+   dma_release_channel(host->rx_chan);
 
pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-03 Thread Michal Suchanek
On 3 November 2015 at 11:06, Vignesh R  wrote:
> In addition to providing direct access to SPI bus, some spi controller
> hardwares (like ti-qspi) provide special memory mapped port
> to accesses SPI flash devices in order to increase read performance.
> This means the controller can automatically send the SPI signals
> required to read data from the SPI flash device.
> For this, spi controller needs to know flash specific information like
> read command to use, dummy bytes and address width. Once these settings
> are populated in hardware registers, any read accesses to flash's memory
> map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
> handled by controller hardware. The hardware will automatically generate
> SPI signals required to read data from flash and present it to CPU/DMA.
>
> Introduce spi_mtd_mmap_read() interface to support memory mapped read
> over SPI flash devices. SPI master drivers can implement this callback to
> support memory mapped read interfaces. m25p80 flash driver and other
> flash drivers can call this to request memory mapped read. The interface
> should only be used MTD flashes and cannot be used with other SPI devices.
>
> Signed-off-by: Vignesh R 
> ---
>  drivers/spi/spi.c   | 35 +++
>  include/linux/spi/spi.h | 23 +++
>  2 files changed, 58 insertions(+)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index a5f53de813d3..5a5c7a7d47f2 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1059,6 +1059,7 @@ static void __spi_pump_messages(struct spi_master 
> *master, bool in_kthread)
> }
> }
>
> +   mutex_lock(&master->mmap_lock_mutex);
> trace_spi_message_start(master->cur_msg);
>
> if (master->prepare_message) {
> @@ -1068,6 +1069,7 @@ static void __spi_pump_messages(struct spi_master 
> *master, bool in_kthread)
> "failed to prepare message: %d\n", ret);
> master->cur_msg->status = ret;
> spi_finalize_current_message(master);
> +   mutex_unlock(&master->mmap_lock_mutex);
> return;
> }
> master->cur_msg_prepared = true;
> @@ -1077,6 +1079,7 @@ static void __spi_pump_messages(struct spi_master 
> *master, bool in_kthread)
> if (ret) {
> master->cur_msg->status = ret;
> spi_finalize_current_message(master);
> +   mutex_unlock(&master->mmap_lock_mutex);
> return;
> }
>
> @@ -1084,8 +1087,10 @@ static void __spi_pump_messages(struct spi_master 
> *master, bool in_kthread)
> if (ret) {
> dev_err(&master->dev,
> "failed to transfer one message from queue\n");
> +   mutex_unlock(&master->mmap_lock_mutex);
> return;
> }
> +   mutex_unlock(&master->mmap_lock_mutex);
>  }
>
>  /**
> @@ -1732,6 +1737,7 @@ int spi_register_master(struct spi_master *master)
> spin_lock_init(&master->queue_lock);
> spin_lock_init(&master->bus_lock_spinlock);
> mutex_init(&master->bus_lock_mutex);
> +   mutex_init(&master->mmap_lock_mutex);
> master->bus_lock_flag = 0;
> init_completion(&master->xfer_completion);
> if (!master->max_dma_len)
> @@ -2237,6 +2243,35 @@ int spi_async_locked(struct spi_device *spi, struct 
> spi_message *message)
>  EXPORT_SYMBOL_GPL(spi_async_locked);
>
>
> +int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
> + size_t *retlen, u_char *buf, u8 read_opcode,
> + u8 addr_width, u8 dummy_bytes)
> +
> +{
> +   struct spi_master *master = spi->master;
> +   int ret;
> +
> +   if (master->auto_runtime_pm) {
> +   ret = pm_runtime_get_sync(master->dev.parent);
> +   if (ret < 0) {
> +   dev_err(&master->dev, "Failed to power device: %d\n",
> +   ret);
> +   goto err;
> +   }
> +   }
> +   mutex_lock(&master->mmap_lock_mutex);
> +   ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
> +   read_opcode, addr_width,
> +   dummy_bytes);
> +   mutex_unlock(&master->mmap_lock_mutex);
> +   if (master->auto_runtime_pm)
> +   pm_runtime_put(master->dev.parent);
> +
> +err:
> +   return ret;
> +}
> +EXPORT_SYMBOL_GPL(spi_mtd_mmap_read);
> +
>  /*-*/
>
>  /* Utility methods for SPI master protocol drivers, layered on
> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> index 6b00f18f5e6b..0a6d8ad57357 100644
> --- a/include/linux/spi/spi.h
> +++ b/include/linux/spi/spi.h
> @@ -297,6 +297,7 @@ static inline void spi_un

[PATCH v2 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-11-03 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R 
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index f05dd631bef1..05488970060b 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -17,9 +17,10 @@ Recommended properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 0447c04a40cc..1b2c545f3f2c 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -962,7 +962,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/5] Add memory mapped read support for ti-qspi

2015-11-03 Thread Vignesh R

Changes since v1:
Introduce API in SPI core that MTD flash driver can call for mmap read
instead of directly calling spi-master driver callback. This API makes
sure that SPI core msg queue is locked during mmap transfers.
v1: https://lkml.org/lkml/2015/9/4/103


Cover letter:

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.


Vignesh R (5):
  spi: introduce mmap read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 18 -
 arch/arm/boot/dts/am4372.dtsi |  4 +-
 arch/arm/boot/dts/dra7.dtsi   |  6 +-
 drivers/mtd/devices/m25p80.c  |  5 ++
 drivers/spi/spi-ti-qspi.c | 92 ++-
 drivers/spi/spi.c | 35 +
 include/linux/spi/spi.h   | 23 ++
 7 files changed, 174 insertions(+), 9 deletions(-)

-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-03 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special memory mapped port
to accesses SPI flash devices in order to increase read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, spi controller needs to know flash specific information like
read command to use, dummy bytes and address width. Once these settings
are populated in hardware registers, any read accesses to flash's memory
map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
handled by controller hardware. The hardware will automatically generate
SPI signals required to read data from flash and present it to CPU/DMA.

Introduce spi_mtd_mmap_read() interface to support memory mapped read
over SPI flash devices. SPI master drivers can implement this callback to
support memory mapped read interfaces. m25p80 flash driver and other
flash drivers can call this to request memory mapped read. The interface
should only be used MTD flashes and cannot be used with other SPI devices.

Signed-off-by: Vignesh R 
---
 drivers/spi/spi.c   | 35 +++
 include/linux/spi/spi.h | 23 +++
 2 files changed, 58 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a5f53de813d3..5a5c7a7d47f2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1059,6 +1059,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
}
}
 
+   mutex_lock(&master->mmap_lock_mutex);
trace_spi_message_start(master->cur_msg);
 
if (master->prepare_message) {
@@ -1068,6 +1069,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
"failed to prepare message: %d\n", ret);
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(&master->mmap_lock_mutex);
return;
}
master->cur_msg_prepared = true;
@@ -1077,6 +1079,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(&master->mmap_lock_mutex);
return;
}
 
@@ -1084,8 +1087,10 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
dev_err(&master->dev,
"failed to transfer one message from queue\n");
+   mutex_unlock(&master->mmap_lock_mutex);
return;
}
+   mutex_unlock(&master->mmap_lock_mutex);
 }
 
 /**
@@ -1732,6 +1737,7 @@ int spi_register_master(struct spi_master *master)
spin_lock_init(&master->queue_lock);
spin_lock_init(&master->bus_lock_spinlock);
mutex_init(&master->bus_lock_mutex);
+   mutex_init(&master->mmap_lock_mutex);
master->bus_lock_flag = 0;
init_completion(&master->xfer_completion);
if (!master->max_dma_len)
@@ -2237,6 +2243,35 @@ int spi_async_locked(struct spi_device *spi, struct 
spi_message *message)
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
+ size_t *retlen, u_char *buf, u8 read_opcode,
+ u8 addr_width, u8 dummy_bytes)
+
+{
+   struct spi_master *master = spi->master;
+   int ret;
+
+   if (master->auto_runtime_pm) {
+   ret = pm_runtime_get_sync(master->dev.parent);
+   if (ret < 0) {
+   dev_err(&master->dev, "Failed to power device: %d\n",
+   ret);
+   goto err;
+   }
+   }
+   mutex_lock(&master->mmap_lock_mutex);
+   ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
+   read_opcode, addr_width,
+   dummy_bytes);
+   mutex_unlock(&master->mmap_lock_mutex);
+   if (master->auto_runtime_pm)
+   pm_runtime_put(master->dev.parent);
+
+err:
+   return ret;
+}
+EXPORT_SYMBOL_GPL(spi_mtd_mmap_read);
+
 /*-*/
 
 /* Utility methods for SPI master protocol drivers, layered on
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 6b00f18f5e6b..0a6d8ad57357 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -297,6 +297,7 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @flags: other constraints relevant to this driver
  * @bus_lock_spinlock: spinlock for SPI bus locking
  * @bus_lock_mutex: mutex for SPI bus locking
+ * @mmap_lock_mutex: mutex for locking SPI bus when mmap transfer i

[PATCH v2 3/5] mtd: devices: m25p80: add support for mmap read request

2015-11-03 Thread Vignesh R
Certain spi controllers may support memory mapped interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_mtd_mmap_read() interface, if supported, to make use of
memory-mapped interface.

Signed-off-by: Vignesh R 
---
 drivers/mtd/devices/m25p80.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 9cd3631170ef..3978bcb513b9 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -133,6 +133,11 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi_mmap_read_supported(spi))
+   return spi_mtd_mmap_read(spi, from, len, retlen, buf,
+nor->read_opcode,
+nor->addr_width, dummy);
+
spi_message_init(&m);
memset(t, 0, (sizeof t));
 
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-03 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_mtd_mmap_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R 
---
 drivers/spi/spi-ti-qspi.c | 92 ---
 1 file changed, 88 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 69c1a95b0615..2f58fb7eb410 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -65,11 +65,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -109,6 +106,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -366,6 +373,82 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val |= MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   /* dummy readl to ensure bus sync */
+   readl(qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val &= ~MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   u8 read_opcode, u8 addr_width,
+   u8 dummy_bytes)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 mode = spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD);
+   u32 memval = read_opcode;
+
+   switch (mode) {
+   case SPI_RX_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_RX_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_mtd_mmap_read(struct  spi_device *spi,
+loff_t from, size_t len,
+size_t *retlen, u_char *buf,
+u8 read_opcode, u8 addr_width,
+u8 dummy_bytes)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
+   int ret = 0;
+
+   mutex_lock(&qspi->list_lock);
+
+   ti_qspi_enable_memory_map(spi);
+   ti_qspi_setup_mmap_read(spi, read_opcode, addr_width,
+   dummy_bytes);
+   memcpy_fromio(buf, qspi->mmap_base + from, len);
+   *retlen = len;
+   ti_qspi_disable_memory_map(spi);
+
+   mutex_unlock(&qspi->list_lock);
+
+   return ret;
+}
+
 static int ti_qspi_start_transfer_one(

[PATCH v2 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-11-03 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R 
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 13 +
 arch/arm/boot/dts/dra7.dtsi   |  6 --
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..f05dd631bef1 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -26,3 +26,16 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index e289c706d27d..13c2f10ec217 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1108,8 +1108,10 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html