[PATCH] spi: qup: Fix runtime and system PM callbacks.

2017-01-26 Thread Pramod Gurav
The SPI clocks were being turned on every suspend/resume cycle.
This was increamenting the prepare/enable count after every resume.
Fix the same.

Signed-off-by: Pramod Gurav 
---
Tested on db410c

 drivers/spi/spi-qup.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 1bfa889..a9731e8 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -956,8 +956,10 @@ static int spi_qup_pm_resume_runtime(struct device *device)
return ret;
 
ret = clk_prepare_enable(controller->cclk);
-   if (ret)
+   if (ret) {
+   clk_disable_unprepare(controller->iclk);
return ret;
+   }
 
/* Disable clocks auto gaiting */
config = readl_relaxed(controller->base + QUP_CONFIG);
@@ -983,8 +985,7 @@ static int spi_qup_suspend(struct device *device)
return ret;
 
if (!pm_runtime_suspended(device)) {
-   clk_disable_unprepare(controller->cclk);
-   clk_disable_unprepare(controller->iclk);
+   pm_runtime_put(device);
}
return 0;
 }
@@ -995,18 +996,17 @@ static int spi_qup_resume(struct device *device)
struct spi_qup *controller = spi_master_get_devdata(master);
int ret;
 
-   ret = clk_prepare_enable(controller->iclk);
-   if (ret)
-   return ret;
-
-   ret = clk_prepare_enable(controller->cclk);
-   if (ret)
+   ret = pm_runtime_get_sync(device);
+   if (ret < 0) {
+   dev_err(device, "pm runtime failed in resume\n");
return ret;
+   }
 
ret = spi_qup_set_state(controller, QUP_STATE_RESET);
if (ret)
return ret;
 
+   pm_runtime_put(device);
return spi_master_resume(master);
 }
 #endif /* CONFIG_PM_SLEEP */
-- 
2.10.2



[PATCH v5] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-10-20 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Reviewed-by: Ritesh Harjani 
Reviewed-by: Georgi Djakov 
Tested-by: Ritesh Harjani 
Signed-off-by: Pramod Gurav 
---
Tested on DB410C.

Changes in v5:
- Added pm_runtime_mark_last_busy in probe before calling autosuspend
- included clock names in error logs
- Used micro instead of constant for autosuspend delay
- Removed platform_set_drvdata in probe as sdhci_pltfm_init does it.
- Aligned PM ops structure with the parenthesis

Changes in v4:
- Remove calls to sdhci_runtime_resume_host/sdhci_runtime_suspend_host
  from runtime callbacks as sdhc msm controller is capable of restoring
  it's register values after clocks are disabled and re-enabled.

Changes in v3:
- Added CONFIG_PM around runtime pm function.
- Replaced msm suspend/resume with generic function directly
- Use SET_SYSTEM_SLEEP_PM_OPS instead of late version

Changes in v2:
- Moved pm_rutime enabling before adding host
- Handled pm_rutime in remove
- Changed runtime handling with reference from sdhci-of-at91.c

 drivers/mmc/host/sdhci-msm.c | 68 +++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 8ef44a2a..795f16f 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -68,6 +69,7 @@
 #define CMUX_SHIFT_PHASE_SHIFT 24
 #define CMUX_SHIFT_PHASE_MASK  (7 << CMUX_SHIFT_PHASE_SHIFT)
 
+#define MSM_MMC_AUTOSUSPEND_DELAY_MS   50
 struct sdhci_msm_host {
struct platform_device *pdev;
void __iomem *core_mem; /* MSM SDCC mapped address */
@@ -658,12 +660,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto clk_disable;
}
 
+   pm_runtime_get_noresume(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev,
+MSM_MMC_AUTOSUSPEND_DELAY_MS);
+   pm_runtime_use_autosuspend(&pdev->dev);
+
ret = sdhci_add_host(host);
if (ret)
-   goto clk_disable;
+   goto pm_runtime_disable;
+
+   pm_runtime_mark_last_busy(&pdev->dev);
+   pm_runtime_put_autosuspend(&pdev->dev);
 
return 0;
 
+pm_runtime_disable:
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
 clk_disable:
clk_disable_unprepare(msm_host->clk);
 pclk_disable:
@@ -685,6 +701,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
0x);
 
sdhci_remove_host(host, dead);
+
+   pm_runtime_get_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+
clk_disable_unprepare(msm_host->clk);
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR(msm_host->bus_clk))
@@ -693,12 +714,57 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed for core_clk: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed for iface_clk: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return 0;
+}
+#endif
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+   pm_runtime_force_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend,
+  sdhci_msm_runtime_resume,
+  NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
2.9.3



Re: [PATCH v4] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-10-20 Thread Pramod Gurav
Hi Ritesh,

On 20 October 2016 at 20:20, Ritesh Harjani  wrote:
> Hi Pramod,
>
> Thanks for this patch. Few minor comments.
>
> I have tested your patch on db410c and 8996 based internal platform and it
> works fine.
Thanks for the review and testing.
>
>
>
> On 10/18/2016 3:46 PM, Pramod Gurav wrote:
>>
>> Provides runtime PM callbacks to enable and disable clock resources
>> when idle. Also support system PM callbacks to be called during system
>> suspend and resume.
>>
>> Signed-off-by: Pramod Gurav 
>> ---
>>
>> Tested on DB410C.
>>
>> Changes in v4:
>> - Remove calls to sdhci_runtime_resume_host/sdhci_runtime_suspend_host
>>   from runtime callbacks as sdhc msm controller is capable of restoring
>>   it's register values after clocks are disabled and re-enabled.
>>
>> Changes in v3:
>> - Added CONFIG_PM around runtime pm function.
>> - Replaced msm suspend/resume with generic function directly
>> - Use SET_SYSTEM_SLEEP_PM_OPS instead of late version
>>
>> Changes in v2:
>> - Moved pm_rutime enabling before adding host
>> - Handled pm_rutime in remove
>> - Changed runtime handling with reference from sdhci-of-at91.c
>>
>>  drivers/mmc/host/sdhci-msm.c | 66
>> +++-
>>  1 file changed, 65 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
>> index 8ef44a2a..33ec809 100644
>> --- a/drivers/mmc/host/sdhci-msm.c
>> +++ b/drivers/mmc/host/sdhci-msm.c
>> @@ -18,6 +18,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>
>>  #include "sdhci-pltfm.h"
>> @@ -658,12 +659,26 @@ static int sdhci_msm_probe(struct platform_device
>> *pdev)
>> goto clk_disable;
>> }
>>
>> +   pm_runtime_get_noresume(&pdev->dev);
>> +   pm_runtime_set_active(&pdev->dev);
>> +   pm_runtime_enable(&pdev->dev);
>> +   pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
>
> Use a macro MSM_MMC_AUTOSUSPEND_DELAY_MS instead of using 50 directly here.

Will add.
>
>> +   pm_runtime_use_autosuspend(&pdev->dev);
>> +
>> ret = sdhci_add_host(host);
>> if (ret)
>> -   goto clk_disable;
>> +   goto pm_runtime_disable;
>> +
>> +   platform_set_drvdata(pdev, host);
>
> No need to set platform_set_drvdata here. sdhci_pltfm_init will do it
> anyways.
Good to know this. Will do away with this.
>
>> +
>
> pm_runtime_mark_last_busy(&pdev->dev) can be added here.
Yeah. Agree.
>
>> +   pm_runtime_put_autosuspend(&pdev->dev);
>>
>> return 0;
>>
>> +pm_runtime_disable:
>> +   pm_runtime_disable(&pdev->dev);
>> +   pm_runtime_set_suspended(&pdev->dev);
>> +   pm_runtime_put_noidle(&pdev->dev);
>>  clk_disable:
>> clk_disable_unprepare(msm_host->clk);
>>  pclk_disable:
>> @@ -685,6 +700,11 @@ static int sdhci_msm_remove(struct platform_device
>> *pdev)
>> 0x);
>>
>> sdhci_remove_host(host, dead);
>> +
>> +   pm_runtime_get_sync(&pdev->dev);
>> +   pm_runtime_disable(&pdev->dev);
>> +   pm_runtime_put_noidle(&pdev->dev);
>> +
>> clk_disable_unprepare(msm_host->clk);
>> clk_disable_unprepare(msm_host->pclk);
>> if (!IS_ERR(msm_host->bus_clk))
>> @@ -693,12 +713,56 @@ static int sdhci_msm_remove(struct platform_device
>> *pdev)
>> return 0;
>>  }
>>
>> +#ifdef CONFIG_PM
>> +static int sdhci_msm_runtime_suspend(struct device *dev)
>> +{
>> +   struct sdhci_host *host = dev_get_drvdata(dev);
>> +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +   clk_disable_unprepare(msm_host->clk);
>> +   clk_disable_unprepare(msm_host->pclk);
>> +
>> +   return 0;
>> +}
>> +
>> +static int sdhci_msm_runtime_resume(struct device *dev)
>> +{
>> +   struct sdhci_host *host = dev_get_drvdata(dev);
>> +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>> +   int ret;
>> +
>> +   ret = clk_prepare_enable(msm_host->clk);
>

Re: [PATCH v4] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-10-20 Thread Pramod Gurav
Thanks Georgi for the review.

On 20 October 2016 at 18:38, Georgi Djakov  wrote:
> Hi Pramod,
>
> Thanks for the patch!
>
> On 10/18/2016 01:16 PM, Pramod Gurav wrote:
>>
>> Provides runtime PM callbacks to enable and disable clock resources
>> when idle. Also support system PM callbacks to be called during system
>> suspend and resume.
>>
>> Signed-off-by: Pramod Gurav 
>> ---
>>
>> Tested on DB410C.
>>
>
> [..]
>
>> +static int sdhci_msm_runtime_resume(struct device *dev)
>> +{
>> +   struct sdhci_host *host = dev_get_drvdata(dev);
>> +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>> +   int ret;
>> +
>> +   ret = clk_prepare_enable(msm_host->clk);
>> +   if (ret) {
>> +   dev_err(dev, "clk_enable failed: %d\n", ret);
>> +   return ret;
>> +   }
>> +   ret = clk_prepare_enable(msm_host->pclk);
>> +   if (ret) {
>> +   dev_err(dev, "clk_enable failed: %d\n", ret);
>
>
> Nit: Maybe mention in the prints which clock failed - core or peripheral.

Agree. Will add in v5.

>
>> +   clk_disable_unprepare(msm_host->clk);
>> +   return ret;
>> +   }
>> +
>> +   return 0;
>> +}
>> +#endif
>> +
>> +static const struct dev_pm_ops sdhci_msm_pm_ops = {
>> +   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>> +   pm_runtime_force_resume)
>
>
> Nit: Please align with the parenthesis.
>
>> +   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend,
>> sdhci_msm_runtime_resume,
>> +   NULL)
>
>
> Ditto.
Yes. Will take care of this as well.
>
> Reviewed-by: Georgi Djakov 

Thanks again. :)
>
> BR,
> Georgi


[PATCH v4] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-10-18 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Signed-off-by: Pramod Gurav 
---

Tested on DB410C.

Changes in v4:
- Remove calls to sdhci_runtime_resume_host/sdhci_runtime_suspend_host
  from runtime callbacks as sdhc msm controller is capable of restoring
  it's register values after clocks are disabled and re-enabled.

Changes in v3:
- Added CONFIG_PM around runtime pm function.
- Replaced msm suspend/resume with generic function directly
- Use SET_SYSTEM_SLEEP_PM_OPS instead of late version

Changes in v2:
- Moved pm_rutime enabling before adding host
- Handled pm_rutime in remove
- Changed runtime handling with reference from sdhci-of-at91.c

 drivers/mmc/host/sdhci-msm.c | 66 +++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 8ef44a2a..33ec809 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -658,12 +659,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto clk_disable;
}
 
+   pm_runtime_get_noresume(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+   pm_runtime_use_autosuspend(&pdev->dev);
+
ret = sdhci_add_host(host);
if (ret)
-   goto clk_disable;
+   goto pm_runtime_disable;
+
+   platform_set_drvdata(pdev, host);
+
+   pm_runtime_put_autosuspend(&pdev->dev);
 
return 0;
 
+pm_runtime_disable:
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
 clk_disable:
clk_disable_unprepare(msm_host->clk);
 pclk_disable:
@@ -685,6 +700,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
0x);
 
sdhci_remove_host(host, dead);
+
+   pm_runtime_get_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+
clk_disable_unprepare(msm_host->clk);
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR(msm_host->bus_clk))
@@ -693,12 +713,56 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return 0;
+}
+#endif
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+   pm_runtime_force_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume,
+   NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
2.9.3



Re: [PATCH v3] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-22 Thread Pramod Gurav
Hi Ritesh,

Thanks for the inputs.

On 22 September 2016 at 20:02, Ritesh Harjani  wrote:
> Hi Pramod,



>> Thanks Ulf for the comments. Will check this and see if there is
>> something of this sort we have to do to achieve auto tuning.
>> Adding Ritesh who has been posting some SDHCI MSM patches recently in
>> case he knows about this.
>
>
> Internally, we don't use this Auto re-tuning and rely on explicit re-tune by
> host driver.
>
> Question though -
> 1. why do we need to call sdhci_runtime_resume/suspend from
> sdhci_msm_runtime_suspend/resume?
> From what I see is, sdhci_runtime_susend/resume will do reset and re-program
> of host->pwr and host->clk because of which a retune will be required for
> the next command after runtime resume.

Honestly I took reference from existing SDHCI HC driver which
implement the runtime PM and each one uses this function.

>
> We can *only* disable and enable the clocks in
> sdhci_msm_runtime_suspend/resume?
> Thoughts? With this, I suppose you would not see any issue.
This should work as I did not have this funtion call in my V1 but
later included when I referred the other sdhci drivers.

>
>
> Though for this issue, since internally also auto retuning is never used, we
> can have this mode disabled. I can once again check with HW team to get more
> details about this mode for MSM controller.
This seems a read only register. And I could not find any other
reference of this mode in any of the docs.
>
>>
>> Regards,
>> Pramod
>>
>


Re: [PATCH v3] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-15 Thread Pramod Gurav
On 15 September 2016 at 15:49, Ulf Hansson  wrote:
> On 15 September 2016 at 09:59, Pramod Gurav  wrote:
>> On 9 September 2016 at 15:48, Georgi Djakov  wrote:
>>> On 09/08/2016 11:02 AM, Adrian Hunter wrote:
>>>>
>>>> On 01/09/16 17:23, Pramod Gurav wrote:
>>>>>
>>>>> Provides runtime PM callbacks to enable and disable clock resources
>>>>> when idle. Also support system PM callbacks to be called during system
>>>>> suspend and resume.
>>>>>
>>>>> Signed-off-by: Pramod Gurav 
>>>>
>>>>
>>>> Can we get some Tested/Reviewed/Acked-by from people using this driver?
>>>>
>>>
>>> Hi Pramod,
>>> Thanks for the patch. Unfortunately, my db410c board fails to
>>> boot when i apply it.
>>>
>>
>> Thanks Georgi for testing the patch. Its my wrong I did not update my
>> kernel and continued fixing comments on old kernel.
>> After spending some time I came to know that below change is causing the 
>> issue:
>>
>> Author: Dong Aisheng 
>> Date:   Tue Jul 12 15:46:17 2016 +0800
>>
>> mmc: sdhci: add standard hw auto retuning support
>>
>> If HW supports SDHCI_TUNING_MODE_3 which is auto retuning, we won't
>> retune during runtime suspend and resume, instead we use Re-tuning
>> Request signaled via SDHCI_INT_RETUNE interrupt to do retuning and
>> hw auto retuning during data transfer to guarantee the signal sample
>> window correction.
>>
>> This can avoid a mass of repeatedly retuning during small file system
>> data access and improve the performance.
>>
>> Specially these lines that was added to suspend path:
>>
>> +   if (host->tuning_mode != SDHCI_TUNING_MODE_3)
>> +   mmc_retune_needed(host->mmc);
>>
>> During sdhci setup in msm driver, the host returns the values to set
>> sdhci auto tuning as supported.
>> Hence host->tuning_mode is set to SDHCI_TUNING_MODE_3 during setup.
>> But some how the auto tuning is not happening.
>> Just to verify my case, I removed the 'if' part in above code and got
>> the FS mounted.
>>
>> Is there anything else needed in msm sdhci driver so that the auto
>> tuning is taken care of?
>
> I am not familiar with any other than sdhci-esdhc-imx which supports
> the SDHCI_TUNING_MODE_3. I may be wrong though.
>
> In the sdhci-esdhc-imx case, enabling of auto tuning seems to be done
> in esdhc_post_tuning(), where a vendor specific register
> (ESDHC_MIX_CTRL) is being written to. Perhaps something similar in
> your case?
>
Thanks Ulf for the comments. Will check this and see if there is
something of this sort we have to do to achieve auto tuning.
Adding Ritesh who has been posting some SDHCI MSM patches recently in
case he knows about this.

Regards,
Pramod


Re: [PATCH v3] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-15 Thread Pramod Gurav
On 9 September 2016 at 15:48, Georgi Djakov  wrote:
> On 09/08/2016 11:02 AM, Adrian Hunter wrote:
>>
>> On 01/09/16 17:23, Pramod Gurav wrote:
>>>
>>> Provides runtime PM callbacks to enable and disable clock resources
>>> when idle. Also support system PM callbacks to be called during system
>>> suspend and resume.
>>>
>>> Signed-off-by: Pramod Gurav 
>>
>>
>> Can we get some Tested/Reviewed/Acked-by from people using this driver?
>>
>
> Hi Pramod,
> Thanks for the patch. Unfortunately, my db410c board fails to
> boot when i apply it.
>

Thanks Georgi for testing the patch. Its my wrong I did not update my
kernel and continued fixing comments on old kernel.
After spending some time I came to know that below change is causing the issue:

Author: Dong Aisheng 
Date:   Tue Jul 12 15:46:17 2016 +0800

mmc: sdhci: add standard hw auto retuning support

If HW supports SDHCI_TUNING_MODE_3 which is auto retuning, we won't
retune during runtime suspend and resume, instead we use Re-tuning
Request signaled via SDHCI_INT_RETUNE interrupt to do retuning and
hw auto retuning during data transfer to guarantee the signal sample
window correction.

This can avoid a mass of repeatedly retuning during small file system
data access and improve the performance.

Specially these lines that was added to suspend path:

+   if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+   mmc_retune_needed(host->mmc);

During sdhci setup in msm driver, the host returns the values to set
sdhci auto tuning as supported.
Hence host->tuning_mode is set to SDHCI_TUNING_MODE_3 during setup.
But some how the auto tuning is not happening.
Just to verify my case, I removed the 'if' part in above code and got
the FS mounted.

Is there anything else needed in msm sdhci driver so that the auto
tuning is taken care of?

> [1.778433] mmc0: new HS200 MMC card at address 0001
> [1.783115] mmcblk0: mmc0:0001 DS2008 7.28 GiB
> [1.783337] mmcblk0boot0: mmc0:0001 DS2008 partition 1 4.00 MiB
> [1.787025] mmcblk0boot1: mmc0:0001 DS2008 partition 2 4.00 MiB
> [1.792893] mmcblk0rpmb: mmc0:0001 DS2008 partition 3 4.00 MiB
> [1.802603]  mmcblk0: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10
> [2.693631] blk_update_request: I/O error, dev mmcblk0, sector 462880
> [2.710381] blk_update_request: I/O error, dev mmcblk0, sector 462880
> [2.710443] Buffer I/O error on dev mmcblk0p10, logical block 0, async
> page read
> [2.724827] blk_update_request: I/O error, dev mmcblk0, sector 462881
> [2.724853] Buffer I/O error on dev mmcblk0p10, logical block 1, async
> page read
> ...
>
> More I/O errors are following and it is unable to mount the rootfs from
> the eMMC. When i retried booting, got also the following:
>
> [2.877149] mmcblk0: error -110 sending status command, retrying
> [2.879408] mmcblk0: error -110 sending status command, retrying
> [2.884436] mmcblk0: error -110 sending status command, aborting
> [2.896826] mmc0: cache flush error -110
>
> BR,
> Georgi


Re: [PATCH v3] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-12 Thread Pramod Gurav
On 9 September 2016 at 15:30, Tummala, Sahitya  wrote:
> Hi Pramod,

>> +   ret = clk_prepare_enable(msm_host->clk);
>> +   if (ret) {
>> +   dev_err(dev, "clk_enable failed: %d\n", ret);
>
> A minor comment - Both error prints related to clock enable are same. Better
> to print the clock name as well to know which clock enable got failed.
>

Thanks Sahitya for comments. Will take care of this in next version.
>> +   return ret;
>> +   }


[PATCH] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-01 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Signed-off-by: Pramod Gurav 
---
Changes in v1:
- Added CONFIG_PM around runtime pm function.
- Replaced msm suspend/resume with generic function directly

Changes in v2:
- Moved pm_rutime enabling before adding host
- Handled pm_rutime in remove
- Changed runtime handling with reference from sdhci-of-at91.c

 drivers/mmc/host/sdhci-msm.c | 71 +++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 8ef44a2a..881c564 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -658,12 +659,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto clk_disable;
}
 
+   pm_runtime_get_noresume(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+   pm_runtime_use_autosuspend(&pdev->dev);
+
ret = sdhci_add_host(host);
if (ret)
-   goto clk_disable;
+   goto pm_runtime_disable;
+
+   platform_set_drvdata(pdev, host);
+
+   pm_runtime_put_autosuspend(&pdev->dev);
 
return 0;
 
+pm_runtime_disable:
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
 clk_disable:
clk_disable_unprepare(msm_host->clk);
 pclk_disable:
@@ -685,6 +700,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
0x);
 
sdhci_remove_host(host, dead);
+
+   pm_runtime_get_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+
clk_disable_unprepare(msm_host->clk);
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR(msm_host->bus_clk))
@@ -693,12 +713,61 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = sdhci_runtime_suspend_host(host);
+   if (ret)
+   return ret;
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return sdhci_runtime_resume_host(host);
+}
+#endif
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+   pm_runtime_force_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume,
+   NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
2.9.3



[PATCH v3] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-01 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Signed-off-by: Pramod Gurav 
---
Changes in v3:
- Added CONFIG_PM around runtime pm function.
- Replaced msm suspend/resume with generic function directly
- Use SET_SYSTEM_SLEEP_PM_OPS instead of late version

Changes in v2:
- Moved pm_rutime enabling before adding host
- Handled pm_rutime in remove
- Changed runtime handling with reference from sdhci-of-at91.c

 drivers/mmc/host/sdhci-msm.c | 71 +++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 8ef44a2a..0ef4f29 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -658,12 +659,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto clk_disable;
}
 
+   pm_runtime_get_noresume(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+   pm_runtime_use_autosuspend(&pdev->dev);
+
ret = sdhci_add_host(host);
if (ret)
-   goto clk_disable;
+   goto pm_runtime_disable;
+
+   platform_set_drvdata(pdev, host);
+
+   pm_runtime_put_autosuspend(&pdev->dev);
 
return 0;
 
+pm_runtime_disable:
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
 clk_disable:
clk_disable_unprepare(msm_host->clk);
 pclk_disable:
@@ -685,6 +700,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
0x);
 
sdhci_remove_host(host, dead);
+
+   pm_runtime_get_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+
clk_disable_unprepare(msm_host->clk);
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR(msm_host->bus_clk))
@@ -693,12 +713,61 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = sdhci_runtime_suspend_host(host);
+   if (ret)
+   return ret;
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return sdhci_runtime_resume_host(host);
+}
+#endif
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+   pm_runtime_force_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume,
+   NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
2.9.3



Re: [PATCH v2] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-01 Thread Pramod Gurav
On 1 September 2016 at 19:38, Ulf Hansson  wrote:
> [...]
>
>>> +
>>> +static const struct dev_pm_ops sdhci_msm_pm_ops = {
>>> +   SET_LATE_SYSTEM_SLEEP_PM_OPS(sdhci_msm_suspend, sdhci_msm_resume)
>
> One more thing. Why do you need the late versions of the system PM callbacks?
>
> I think it's fine to use the regular:
> SET_SYSTEM_SLEEP_PM_OPS(sdhci_msm_suspend, sdhci_msm_resume)
>
Should have waited for this review as well. :)
Anyway I forgot to add v3 tag in my new patch.
Will resend v3 with this change as well.

> [...]
>
> Kind regards
> Uffe


[PATCH v2] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-09-01 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Signed-off-by: Pramod Gurav 
---
Changes in v2:
- Moved pm_rutime enabling before adding host
- Handled pm_rutime in remove
- Changed runtime handling with reference from sdhci-of-at91.c
 
 drivers/mmc/host/sdhci-msm.c | 82 +++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 8ef44a2a..8273a71 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -658,12 +659,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto clk_disable;
}
 
+   pm_runtime_get_noresume(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+   pm_runtime_use_autosuspend(&pdev->dev);
+
ret = sdhci_add_host(host);
if (ret)
-   goto clk_disable;
+   goto pm_runtime_disable;
+
+   platform_set_drvdata(pdev, host);
+
+   pm_runtime_put_autosuspend(&pdev->dev);
 
return 0;
 
+pm_runtime_disable:
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
 clk_disable:
clk_disable_unprepare(msm_host->clk);
 pclk_disable:
@@ -685,6 +700,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
0x);
 
sdhci_remove_host(host, dead);
+
+   pm_runtime_get_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+
clk_disable_unprepare(msm_host->clk);
clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR(msm_host->bus_clk))
@@ -693,12 +713,72 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = sdhci_runtime_suspend_host(host);
+   if (ret)
+   return ret;
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return sdhci_runtime_resume_host(host);
+}
+
+static int sdhci_msm_suspend(struct device *dev)
+{
+   pm_runtime_force_suspend(dev);
+
+   return 0;
+}
+
+static int sdhci_msm_resume(struct device *dev)
+{
+   pm_runtime_force_resume(dev);
+
+   return 0;
+}
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(sdhci_msm_suspend, sdhci_msm_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume,
+   NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
2.9.3



Re: [PATCH] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-08-30 Thread Pramod Gurav
Thanks Ulf for the review.

On 29 August 2016 at 19:50, Ulf Hansson  wrote:
> On 16 June 2016 at 14:35, Pramod Gurav  wrote:



>> +   platform_set_drvdata(pdev, msm_host);
>> +
>> +   pm_runtime_set_active(&pdev->dev);
>> +   pm_runtime_enable(&pdev->dev);
>
> I think you need to move these a bit earlier, before calling sdhci_add_host().
>
> Maybe it's just easier if you look at the sdhci-of-at91.c driver,
> which behaves nicely around runtime PM deployment. You can probably
> use the very similar code, except the ->runtime_suspend|resume()
> callbacks.
>
> And don't forget to deploy runtime PM support in the ->remove()
> callback as well, again sdhci-of-at91 is a good reference.
>

Will take a look at the said driver and do necessary changes and repost.
Thanks again.

Regards,
Pramod


Re: [PATCH] tty: serial: msm: Add runtime PM and system sleep support

2016-08-29 Thread Pramod Gurav
Hi Stephen,

Thanks for having a look.

On 26 August 2016 at 04:20, Stephen Boyd  wrote:
> On 06/17, Pramod Gurav wrote:
>> @@ -1220,12 +1293,26 @@ static void msm_power(struct uart_port *port, 
>> unsigned int state,
>>
>>   switch (state) {
>>   case 0:
>> - clk_prepare_enable(msm_port->clk);
>> - clk_prepare_enable(msm_port->pclk);
>> + /*
>> +  * UART clk must be kept enabled to
>> +  * avoid losing received character
>> +  */
>
> Don't we have a wakeup irq? Two wire interfaces probably don't
> work though (like the debug uart).
I am not aware of wakeup irq for UART.

>
>> + if (clk_prepare_enable(msm_port->clk))
>> + return;
>> + if (clk_prepare(msm_port->pclk)) {
>> + clk_disable_unprepare(msm_port->clk);
>> + return;
>> + }
>> + if (pm_runtime_get_sync(port->dev) < 0) {
>> + clk_unprepare(msm_port->pclk);
>> + clk_disable_unprepare(msm_port->clk);
>
> I guess that's why we gate the interface clk and not the core clk
> during runtime PM? core clk goes off and then device is basically
> suspended unless it can wakeup with an irq.
Yes. With core clock disabled we cant get RX working as we dont have
any wakeup mechanism after which we could carry out RX.

>
>> + return;
>> + }
>>   break;
>>   case 3:
>> + pm_runtime_put(port->dev);
>> + clk_unprepare(msm_port->pclk);
>>   clk_disable_unprepare(msm_port->clk);
>> - clk_disable_unprepare(msm_port->pclk);
>>   break;
>>   default:
>>   pr_err("msm_serial: Unknown PM state %d\n", state);
>> @@ -1465,7 +1552,11 @@ static void msm_console_write(struct console *co, 
>> const char *s,
>>   port = msm_get_port_from_line(co->index);
>>   msm_port = UART_TO_MSM(port);
>>
>> + if (pm_runtime_get_sync(port->dev) < 0)
>> + return;
>>   __msm_console_write(port, s, count, msm_port->is_uartdm);
>> + pm_runtime_mark_last_busy(port->dev);
>> + pm_runtime_put_autosuspend(port->dev);
>
> Hmm ok, perhaps we should differentiate runtime PM for devices
> that use the console and ones that are being used for other
> things? I would guess that console can only turn off the
> interface clk while idle, but the non-console devices could turn
> off everything at runtime and rely on some out of band signaling
> to wakeup when something comes over the rx wire?
I will see if there is any way to wakeup the UART like you are saying.

>
>>  }
>>
>>  static int __init msm_console_setup(struct console *co, char *options)
>> @@ -1484,7 +1575,7 @@ static int __init msm_console_setup(struct console 
>> *co, char *options)
>>   if (unlikely(!port->membase))
>>   return -ENXIO;
>>
>> - msm_init_clock(port);
>> + msm_serial_set_mnd_regs(port);
>>
>>   if (options)
>>   uart_parse_options(options, &baud, &parity, &bits, &flow);
>
> Doesn't uart_set_options() go and touch hardware registers during
> termios settings? The clks are no longer enabled here though so I
> hope this isn't relying on the fact that the clks are enabled in
> the bootloader?
The clocks are enabled in serial_core with call to uart_change_pm()
just before console_setup and hence this should be okay.

>
>> @@ -1627,6 +1718,12 @@ static int msm_serial_probe(struct platform_device 
>> *pdev)
>>
>>   platform_set_drvdata(pdev, port);
>>
>> + pm_runtime_use_autosuspend(&pdev->dev);
>> + pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
>> + pm_runtime_irq_safe(&pdev->dev);
>
> So this means irqs are always disabled while runtime PM
> callbacks are run
Because we are accessing UART registers in IRQ handler.
>
>> + pm_runtime_enable(&pdev->dev);
>> + pm_runtime_set_suspended(&pdev->dev);
>> +
>>   return uart_add_one_port(&msm_uart_driver, port);
>>  }
>>
>> @@ -1645,12 +1743,67 @@ static const struct of_device_id msm_match_table[] = 
>> {
>>   {}
>>  };
>>
>> +#ifdef CONFIG_PM
>> +static int msm_serial_runtime_suspend(struct device *dev)
>> +{
>> + struct uart_port *port = dev_get_drvdata(dev);
>> + struct msm_port *msm_port = UART_TO_MSM(port);
>> +
>> + if (msm_port->is_uartdm)
>> + clk_disable(msm_port->pclk);
>
> ... so we can't unprepare clks here. That's unfortunate because
> clks that are ancestors of these clks will be kept prepared and
> that could lead to things like PLLs being kept enabled, etc.
Yes. clk_prepare/unprepare may sleep and we want to avoid that in runtime PM.
This is all we can do in runtime PM. suspend will achieve full
resource release though.

>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


Re: [PATCH] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-08-29 Thread Pramod Gurav
Hi Ulf,


On 16 June 2016 at 18:05, Pramod Gurav  wrote:
> Provides runtime PM callbacks to enable and disable clock resources
> when idle. Also support system PM callbacks to be called during system
> suspend and resume.
>
> Signed-off-by: Pramod Gurav 

Any comments on this patch?

> ---
>  drivers/mmc/host/sdhci-msm.c | 57 
> 
>  1 file changed, 57 insertions(+)
>


Re: [PATCH] tty: serial: msm: Add runtime PM and system sleep support

2016-08-24 Thread Pramod Gurav
Hi,

On 17 June 2016 at 15:46, Pramod Gurav  wrote:
> Add runtime pm and suspend/resume callback support to serial msm
> driver so that clock resources are managed runtime to save power.
>

Any comments on this patch?

> Signed-off-by: Pramod Gurav 
> ---
>  drivers/tty/serial/msm_serial.c | 183 
> 
>  1 file changed, 168 insertions(+), 15 deletions(-)
>

>


Re: [PATCH] tty: serial: msm: Add runtime PM and system sleep support

2016-08-24 Thread Pramod Gurav
On 25 August 2016 at 10:05, Andy Gross  wrote:
> On 17 June 2016 at 05:16, Pramod Gurav  wrote:
>



>> +   if (msm_port->is_uartdm) {
>> +   ret = clk_enable(msm_port->pclk);
>
> Ditto here.

Thanks Andy, will include these two changes in v2.
>
>> +   if (ret)


[PATCH v4] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-06-17 Thread Pramod Gurav
Adds pm_runtime support for BAM DMA so that clock is enabled only
when there is a transaction going on to help save power.

Signed-off-by: Pramod Gurav 
---
Changes in v3:
- pm_runtime_get_sync returns < 0 on error hence chech for return < 0
- Move pm_runtime_get_sync/put in bam_start_dma
- Tested large size file than tested with previous patch

Changes in v2:
- Handled return values of pm_runtime_get_sync to return error
- Rework remove function

 drivers/dma/qcom/bam_dma.c | 110 -
 1 file changed, 109 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 969b481..4754891 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../dmaengine.h"
 #include "../virt-dma.h"
@@ -58,6 +59,8 @@ struct bam_desc_hw {
__le16 flags;
 };
 
+#define BAM_DMA_AUTOSUSPEND_DELAY 100
+
 #define DESC_FLAG_INT BIT(15)
 #define DESC_FLAG_EOT BIT(14)
 #define DESC_FLAG_EOB BIT(13)
@@ -527,12 +530,17 @@ static void bam_free_chan(struct dma_chan *chan)
struct bam_device *bdev = bchan->bdev;
u32 val;
unsigned long flags;
+   int ret;
+
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret < 0)
+   return;
 
vchan_free_chan_resources(to_virt_chan(chan));
 
if (bchan->curr_txd) {
dev_err(bchan->bdev->dev, "Cannot free busy channel\n");
-   return;
+   goto err;
}
 
spin_lock_irqsave(&bchan->vc.lock, flags);
@@ -550,6 +558,10 @@ static void bam_free_chan(struct dma_chan *chan)
 
/* disable irq */
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN));
+
+err:
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -696,11 +708,18 @@ static int bam_pause(struct dma_chan *chan)
struct bam_chan *bchan = to_bam_chan(chan);
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
+   int ret;
+
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret < 0)
+   return ret;
 
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 1;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -715,11 +734,18 @@ static int bam_resume(struct dma_chan *chan)
struct bam_chan *bchan = to_bam_chan(chan);
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
+   int ret;
+
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret < 0)
+   return ret;
 
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 0;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -795,6 +821,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
 {
struct bam_device *bdev = data;
u32 clr_mask = 0, srcs = 0;
+   int ret;
 
srcs |= process_channel_irqs(bdev);
 
@@ -802,6 +829,10 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
if (srcs & P_IRQ)
tasklet_schedule(&bdev->task);
 
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret < 0)
+   return ret;
+
if (srcs & BAM_IRQ) {
clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
 
@@ -814,6 +845,9 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
}
 
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
+
return IRQ_HANDLED;
 }
 
@@ -893,6 +927,7 @@ static void bam_start_dma(struct bam_chan *bchan)
struct bam_desc_hw *desc;
struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
sizeof(struct bam_desc_hw));
+   int ret;
 
lockdep_assert_held(&bchan->vc.lock);
 
@@ -904,6 +939,10 @@ static void bam_start_dma(struct bam_chan *bchan)
async_desc = container_of(vd, struct bam_async_desc, vd);
bchan->curr_txd = async_desc;
 
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret < 0)
+   return;
+
/* on first use, initialize the channel hardware */
if (!bchan->initialized)
bam_chan_init_hw(bchan, async_desc->dir);
@@ -946,6 +985,9 @@ static void bam_start_dma(struct bam_chan *bchan)
 

[PATCH] tty: serial: msm: Add runtime PM and system sleep support

2016-06-17 Thread Pramod Gurav
Add runtime pm and suspend/resume callback support to serial msm
driver so that clock resources are managed runtime to save power.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c | 183 
 1 file changed, 168 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index b7d80bd..6b5776a 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -234,8 +235,12 @@ static void msm_stop_tx(struct uart_port *port)
 {
struct msm_port *msm_port = UART_TO_MSM(port);
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
msm_port->imr &= ~UART_IMR_TXLEV;
msm_write(port, msm_port->imr, UART_IMR);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static void msm_start_tx(struct uart_port *port)
@@ -247,8 +252,12 @@ static void msm_start_tx(struct uart_port *port)
if (dma->count)
return;
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
msm_port->imr |= UART_IMR_TXLEV;
msm_write(port, msm_port->imr, UART_IMR);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static void msm_reset_dm_count(struct uart_port *port, int count)
@@ -270,6 +279,8 @@ static void msm_complete_tx_dma(void *args)
unsigned int count;
u32 val;
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
spin_lock_irqsave(&port->lock, flags);
 
/* Already stopped */
@@ -306,6 +317,8 @@ static void msm_complete_tx_dma(void *args)
msm_handle_tx(port);
 done:
spin_unlock_irqrestore(&port->lock, flags);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static int msm_handle_tx_dma(struct msm_port *msm_port, unsigned int count)
@@ -378,6 +391,8 @@ static void msm_complete_rx_dma(void *args)
unsigned long flags;
u32 val;
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
spin_lock_irqsave(&port->lock, flags);
 
/* Already stopped */
@@ -433,6 +448,8 @@ done:
 
if (count)
tty_flip_buffer_push(tport);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static void msm_start_rx_dma(struct msm_port *msm_port)
@@ -507,19 +524,28 @@ static void msm_stop_rx(struct uart_port *port)
struct msm_port *msm_port = UART_TO_MSM(port);
struct msm_dma *dma = &msm_port->rx_dma;
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
msm_write(port, msm_port->imr, UART_IMR);
 
if (dma->chan)
msm_stop_dma(port, dma);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static void msm_enable_ms(struct uart_port *port)
 {
struct msm_port *msm_port = UART_TO_MSM(port);
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return;
+
msm_port->imr |= UART_IMR_DELTA_CTS;
msm_write(port, msm_port->imr, UART_IMR);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 }
 
 static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
@@ -766,6 +792,8 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
unsigned int misr;
u32 val;
 
+   if (pm_runtime_get_sync(port->dev) < 0)
+   return IRQ_NONE;
spin_lock_irqsave(&port->lock, flags);
misr = msm_read(port, UART_MISR);
msm_write(port, 0, UART_IMR); /* disable interrupt */
@@ -799,13 +827,25 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
 
msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
spin_unlock_irqrestore(&port->lock, flags);
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
 
return IRQ_HANDLED;
 }
 
 static unsigned int msm_tx_empty(struct uart_port *port)
 {
-   return (msm_read(port, UART_SR) & UART_SR_TX_EMPTY) ? TIOCSER_TEMT : 0;
+   int ret;
+
+   ret = pm_runtime_get_sync(port->dev);
+   if (ret < 0)
+   return ret;
+
+   ret = msm_read(port, UART_SR) & UART_SR_TX_EMPTY ? TIOCSER_TEMT : 0;
+   pm_runtime_mark_last_busy(port->dev);
+   pm_runtime_put_autosuspend(port->dev);
+
+   return ret;
 }
 
 static unsigned int msm_get_mctrl(struct uart_port *port)
@@ -834,6 +874,8 @@ static void msm_set_mctrl(struct uart_port *po

[PATCH] mmc: sdhci-msm: Add pm_runtime and system PM support

2016-06-16 Thread Pramod Gurav
Provides runtime PM callbacks to enable and disable clock resources
when idle. Also support system PM callbacks to be called during system
suspend and resume.

Signed-off-by: Pramod Gurav 
---
 drivers/mmc/host/sdhci-msm.c | 57 
 1 file changed, 57 insertions(+)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 0653fe7..f4394c8 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sdhci-pltfm.h"
@@ -549,6 +550,11 @@ static int sdhci_msm_probe(struct platform_device *pdev)
if (ret)
goto clk_disable;
 
+   platform_set_drvdata(pdev, msm_host);
+
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+
return 0;
 
 clk_disable:
@@ -580,12 +586,63 @@ static int sdhci_msm_remove(struct platform_device *pdev)
return 0;
 }
 
+static int sdhci_msm_runtime_suspend(struct device *dev)
+{
+   struct sdhci_msm_host *msm_host = dev_get_drvdata(dev);
+
+   clk_disable_unprepare(msm_host->clk);
+   clk_disable_unprepare(msm_host->pclk);
+
+   return 0;
+}
+
+static int sdhci_msm_runtime_resume(struct device *dev)
+{
+   struct sdhci_msm_host *msm_host = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_prepare_enable(msm_host->clk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(msm_host->pclk);
+   if (ret) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   clk_disable_unprepare(msm_host->clk);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int sdhci_msm_suspend(struct device *dev)
+{
+   pm_runtime_force_suspend(dev);
+
+   return 0;
+}
+
+static int sdhci_msm_resume(struct device *dev)
+{
+   pm_runtime_force_resume(dev);
+
+   return 0;
+}
+
+static const struct dev_pm_ops sdhci_msm_pm_ops = {
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(sdhci_msm_suspend, sdhci_msm_resume)
+   SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume,
+   NULL)
+};
+
 static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
.remove = sdhci_msm_remove,
.driver = {
   .name = "sdhci_msm",
   .of_match_table = sdhci_msm_dt_match,
+  .pm = &sdhci_msm_pm_ops,
},
 };
 
-- 
1.8.2.1



Re: [RFC PATCH] tty: serial: msm_serial: Don't reset uart on set_termios

2016-06-15 Thread Pramod Gurav
On 14 June 2016 at 00:32, Bjorn Andersson  wrote:
> Upon opening the tty, uart_open() ends up calling msm_set_baud_rate()
> which resets the uart block. If this happens as we're coming out of
> msm_console_write() a full fifo worth of console output will be
> discarded.
>
> Cc: Stephen Boyd 
> Signed-off-by: Bjorn Andersson 
> ---
>
> As reported here:
> https://bugs.96boards.org/show_bug.cgi?id=378
>
>  drivers/tty/serial/msm_serial.c | 18 --
>  1 file changed, 18 deletions(-)

Thanks for the patch.

I no longer see these corruptions with this patch. This is what I used
to see on my DB410C with debain FS:
http://paste.ubuntu.com/17319106/

Tested-by: Pramod Gurav 

Regards,
Pramod


Re: [PATCH] serial_core: Change UART PM state to OFF on failure

2016-06-09 Thread Pramod Gurav
Hi Peter,

On 8 June 2016 at 22:17, Peter Hurley  wrote:
> Hi Pramod,
>
> On 05/06/2016 02:46 AM, Pramod Gurav wrote:
>> uart_change_pm is used to turn on the UART controller resources and
>> change UART's PM status. On failure to allocate pages the controller
>> be left in ON state. This will change the state to OFF on failure.
>>
>> Signed-off-by: Pramod Gurav 
>> ---
>>  drivers/tty/serial/serial_core.c | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/tty/serial/serial_core.c 
>> b/drivers/tty/serial/serial_core.c
>> index 62fe368..58af2e9 100644
>> --- a/drivers/tty/serial/serial_core.c
>> +++ b/drivers/tty/serial/serial_core.c
>> @@ -156,9 +156,10 @@ static int uart_port_startup(struct tty_struct *tty, 
>> struct uart_state *state,
>>   if (!state->xmit.buf) {
>>   /* This is protected by the per port mutex */
>>   page = get_zeroed_page(GFP_KERNEL);
>> - if (!page)
>> + if (!page) {
>
> if (!uart_console(uport))
>
> Otherwise, you'll be powering off the console.
>

Agree. Should take care console is not disabled.
> Just out of curiosity, did you actually hit this error?
No, I did not. I thought we should not be leaving port power enabled
in error case.

Thanks for review and comments.

Regards,
Pramod


Re: [PATCH] serial_core: Change UART PM state to OFF on failure

2016-06-06 Thread Pramod Gurav
On 6 May 2016 at 15:16, Pramod Gurav  wrote:
> uart_change_pm is used to turn on the UART controller resources and
> change UART's PM status. On failure to allocate pages the controller
> be left in ON state. This will change the state to OFF on failure.
>
> Signed-off-by: Pramod Gurav 
> ---
>  drivers/tty/serial/serial_core.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/serial_core.c 
> b/drivers/tty/serial/serial_core.c
> index 62fe368..58af2e9 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -156,9 +156,10 @@ static int uart_port_startup(struct tty_struct *tty, 
> struct uart_state *state,
> if (!state->xmit.buf) {
> /* This is protected by the per port mutex */
> page = get_zeroed_page(GFP_KERNEL);
> -   if (!page)
> +   if (!page) {
> +   uart_change_pm(state, UART_PM_STATE_OFF);
> return -ENOMEM;
> -
> +   }
> state->xmit.buf = (unsigned char *) page;
> uart_circ_clear(&state->xmit);
> }

Greg,
Any comments on this change?

> --
> 1.8.2.1
>


Re: [PATCH] usb: echi-hcd: Add ehci_setup check before echi_shutdown

2016-05-30 Thread Pramod Gurav
On 19 May 2016 at 15:42, Srinivas Kandagatla
 wrote:



> Fixes 4bb3cad7125b ("usb: host: ehci-msm: Register usb shutdown function")
> Signed-off-by: Srinivas Kandagatla 

Was seeing this crash while doing a reboot on db410c which is fixed
with this patch:

Tested-by: Pramod Gurav 


Re: [PATCH] usb: host: ehci-msm: Conditionally call ehci suspend/resume

2016-05-25 Thread Pramod Gurav
On 21 May 2016 at 03:05, Andy Gross  wrote:
> This patch fixes a suspend/resume issue where the driver is blindly
> calling ehci_suspend/resume functions when the ehci hasn't been setup.
> This results in a crash during suspend/resume operations.
>
> Signed-off-by: Andy Gross 

Fixes below crash while doing a system suspend:

root@linaro-alip:~# echo freeze > /sys/power/state
[   22.348960] PM: Syncing filesystems ... done.
[   22.387778] Freezing user space processes ... (elapsed 0.001 seconds) done.
[   22.393614] Freezing remaining freezable tasks ... (elapsed 0.001
seconds) done.
[   22.512736] mmc0: Reset 0x1 never completed.
[   22.514296] Unable to handle kernel NULL pointer dereference at
virtual address 04e8
[   22.516068] pgd = 80003817d000
[   22.524161] [04e8] *pgd=b817e003,
*pud=b817f003, *pmd=
[   22.535414] Internal error: Oops: 9606 [#1] PREEMPT SMP
[   22.535680] Modules linked in:
[   22.544183] CPU: 3 PID: 1499 Comm: bash Not tainted 4.6.0+ #65
[   22.544275] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
[   22.550006] task: 800039abd780 ti: 80003928c000 task.ti:
80003928c000
[   22.556870] PC is at ehci_suspend+0x34/0xe4
[   22.564240] LR is at ehci_msm_pm_suspend+0x2c/0x34
[   22.568232] pc : [] lr : []
pstate: a0000145

Tested-by: Pramod Gurav 

> ---
>  drivers/usb/host/ehci-msm.c | 14 --
>  1 file changed, 12 insertions(+), 2 deletions(-)
>
Regards,
Pramod


Re: [PATCH] tty: serial: msm: Remove duplicate handling of clocks

2016-05-16 Thread Pramod Gurav
On 11 May 2016 at 14:30, Pramod Gurav  wrote:
> msm_serial driver provides a .pm callback to the serial core to enable
> and disable clock resource in suspend/resume path. This function is
> also called before msm_startup. msm_startup also enables the clocks which
> is not needed. Hence remove the duplcate clock operation from msm_startup
> and msm_shutdown. Same is done in console setup to get rid of duplicate
> clock operation.
>
> Tested on DB410C console.
>
> Signed-off-by: Pramod Gurav 
> ---
>  drivers/tty/serial/msm_serial.c | 15 ++-
>  1 file changed, 2 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
> index dcde955..73c3217 100644
> --- a/drivers/tty/serial/msm_serial.c
> +++ b/drivers/tty/serial/msm_serial.c
> @@ -959,15 +959,6 @@ static int msm_set_baud_rate(struct uart_port *port, 
> unsigned int baud,
> return baud;
>  }
>
> -static void msm_init_clock(struct uart_port *port)
> -{
> -   struct msm_port *msm_port = UART_TO_MSM(port);
> -
> -   clk_prepare_enable(msm_port->clk);
> -   clk_prepare_enable(msm_port->pclk);
> -   msm_serial_set_mnd_regs(port);
> -}
> -
>  static int msm_startup(struct uart_port *port)
>  {
> struct msm_port *msm_port = UART_TO_MSM(port);
> @@ -982,7 +973,7 @@ static int msm_startup(struct uart_port *port)
> if (unlikely(ret))
> return ret;
>
> -   msm_init_clock(port);
> +   msm_serial_set_mnd_regs(port);

Further testing with another UART port made me realize that serial
port does not work after disabling msm_port->clk clock. The RX data
part will be affected.
Confirmed from manual that this clock should never be turned of to
avoid loss of incoming data. Sorry for the noise.

>
> if (likely(port->fifosize > 12))
> rfr_level = port->fifosize - 12;
> @@ -1021,8 +1012,6 @@ static void msm_shutdown(struct uart_port *port)
> if (msm_port->is_uartdm)
> msm_release_dma(msm_port);
>
> -   clk_disable_unprepare(msm_port->clk);
> -
> free_irq(port->irq, port);
>  }
>
> @@ -1451,7 +1440,7 @@ static int __init msm_console_setup(struct console *co, 
> char *options)
> if (unlikely(!port->membase))
> return -ENXIO;
>
> -   msm_init_clock(port);
> +   msm_serial_set_mnd_regs(port);
>
> if (options)
> uart_parse_options(options, &baud, &parity, &bits, &flow);
> --
> 1.8.2.1
>


Re: [PATCH] tty: serial: msm: Remove duplicate handling of clocks

2016-05-11 Thread Pramod Gurav
On 12 May 2016 at 05:48, Stephen Boyd  wrote:
> On 05/11, Pramod Gurav wrote:
>> msm_serial driver provides a .pm callback to the serial core to enable
>> and disable clock resource in suspend/resume path. This function is
>> also called before msm_startup. msm_startup also enables the clocks which
>> is not needed. Hence remove the duplcate clock operation from msm_startup
>> and msm_shutdown. Same is done in console setup to get rid of duplicate
>> clock operation.
>
> I had to check and I see that for the console case we call the
> .pm callback and don't turn it off until suspend/resume paths
> (would be nice to add suspend/resume to this driver too). I
> guess that's what you meant by this last sentence?
>
Yes the clocks would be kept ON if its console.
I am working to add suspend/resume and runtime pm as it will not
happen by default through core.
>>
>> Tested on DB410C console.
>>
>> Signed-off-by: Pramod Gurav 
>
> Reviewed-by: Stephen Boyd 
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


[PATCH] tty: serial: msm: Remove duplicate handling of clocks

2016-05-11 Thread Pramod Gurav
msm_serial driver provides a .pm callback to the serial core to enable
and disable clock resource in suspend/resume path. This function is
also called before msm_startup. msm_startup also enables the clocks which
is not needed. Hence remove the duplcate clock operation from msm_startup
and msm_shutdown. Same is done in console setup to get rid of duplicate
clock operation.

Tested on DB410C console.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index dcde955..73c3217 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -959,15 +959,6 @@ static int msm_set_baud_rate(struct uart_port *port, 
unsigned int baud,
return baud;
 }
 
-static void msm_init_clock(struct uart_port *port)
-{
-   struct msm_port *msm_port = UART_TO_MSM(port);
-
-   clk_prepare_enable(msm_port->clk);
-   clk_prepare_enable(msm_port->pclk);
-   msm_serial_set_mnd_regs(port);
-}
-
 static int msm_startup(struct uart_port *port)
 {
struct msm_port *msm_port = UART_TO_MSM(port);
@@ -982,7 +973,7 @@ static int msm_startup(struct uart_port *port)
if (unlikely(ret))
return ret;
 
-   msm_init_clock(port);
+   msm_serial_set_mnd_regs(port);
 
if (likely(port->fifosize > 12))
rfr_level = port->fifosize - 12;
@@ -1021,8 +1012,6 @@ static void msm_shutdown(struct uart_port *port)
if (msm_port->is_uartdm)
msm_release_dma(msm_port);
 
-   clk_disable_unprepare(msm_port->clk);
-
free_irq(port->irq, port);
 }
 
@@ -1451,7 +1440,7 @@ static int __init msm_console_setup(struct console *co, 
char *options)
if (unlikely(!port->membase))
return -ENXIO;
 
-   msm_init_clock(port);
+   msm_serial_set_mnd_regs(port);
 
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
-- 
1.8.2.1



[PATCH] serial_core: Change UART PM state to OFF on failure

2016-05-06 Thread Pramod Gurav
uart_change_pm is used to turn on the UART controller resources and
change UART's PM status. On failure to allocate pages the controller
be left in ON state. This will change the state to OFF on failure.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/serial_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 62fe368..58af2e9 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -156,9 +156,10 @@ static int uart_port_startup(struct tty_struct *tty, 
struct uart_state *state,
if (!state->xmit.buf) {
/* This is protected by the per port mutex */
page = get_zeroed_page(GFP_KERNEL);
-   if (!page)
+   if (!page) {
+   uart_change_pm(state, UART_PM_STATE_OFF);
return -ENOMEM;
-
+   }
state->xmit.buf = (unsigned char *) page;
uart_circ_clear(&state->xmit);
}
-- 
1.8.2.1



[PATCH v3 2/2] MAINTAINERS: Update the files to include the Qualcomm DMA folder

2016-05-04 Thread Pramod Gurav
Recently all qcom dma drivers were moved a separate directory. Update
the files to include the same

Signed-off-by: Pramod Gurav 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d826f1b..2327f92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1407,6 +1407,7 @@ L:linux-arm-...@vger.kernel.org
 L: linux-...@vger.kernel.org
 S: Maintained
 F: arch/arm/mach-qcom/
+F: drivers/dma/qcom/
 F: drivers/soc/qcom/
 F: drivers/tty/serial/msm_serial.h
 F: drivers/tty/serial/msm_serial.c
-- 
1.8.2.1



[PATCH v3 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-05-04 Thread Pramod Gurav
Adds pm_runtime support for BAM DMA so that clock
is enabled only when there is a transaction going on to help
save power.

Signed-off-by: Pramod Gurav 
---
Changes in v2:
- Handled return values of pm_runtime_get_sync to return error
- Rework remove function

 drivers/dma/qcom/bam_dma.c | 98 +-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 5b427c4..da64511 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../dmaengine.h"
 #include "../virt-dma.h"
@@ -58,6 +59,8 @@ struct bam_desc_hw {
u16 flags;
 };
 
+#define BAM_DMA_AUTOSUSPEND_DELAY 100
+
 #define DESC_FLAG_INT BIT(15)
 #define DESC_FLAG_EOT BIT(14)
 #define DESC_FLAG_EOB BIT(13)
@@ -528,11 +531,14 @@ static void bam_free_chan(struct dma_chan *chan)
u32 val;
unsigned long flags;
 
+   if (pm_runtime_get_sync(bdev->dev))
+   return;
+
vchan_free_chan_resources(to_virt_chan(chan));
 
if (bchan->curr_txd) {
dev_err(bchan->bdev->dev, "Cannot free busy channel\n");
-   return;
+   goto err;
}
 
spin_lock_irqsave(&bchan->vc.lock, flags);
@@ -550,6 +556,10 @@ static void bam_free_chan(struct dma_chan *chan)
 
/* disable irq */
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN));
+
+err:
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -695,11 +705,18 @@ static int bam_pause(struct dma_chan *chan)
struct bam_chan *bchan = to_bam_chan(chan);
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
+   int ret;
+
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret)
+   return ret;
 
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 1;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -714,11 +731,17 @@ static int bam_resume(struct dma_chan *chan)
struct bam_chan *bchan = to_bam_chan(chan);
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
+   int ret;
 
+   ret = pm_runtime_get_sync(bdev->dev);
+   if (ret)
+   return ret;
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 0;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -967,6 +990,9 @@ static void dma_tasklet(unsigned long data)
bam_start_dma(bchan);
spin_unlock_irqrestore(&bchan->vc.lock, flags);
}
+
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -978,8 +1004,13 @@ static void dma_tasklet(unsigned long data)
 static void bam_issue_pending(struct dma_chan *chan)
 {
struct bam_chan *bchan = to_bam_chan(chan);
+   struct bam_device *bdev = bchan->bdev;
unsigned long flags;
 
+   if (pm_runtime_status_suspended(bdev->dev))
+   if (pm_runtime_get_sync(bdev->dev))
+   return;
+
spin_lock_irqsave(&bchan->vc.lock, flags);
 
/* if work pending and idle, start a transaction */
@@ -1210,6 +1241,13 @@ static int bam_dma_probe(struct platform_device *pdev)
if (ret)
goto err_unregister_dma;
 
+   pm_runtime_irq_safe(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
+   pm_runtime_use_autosuspend(&pdev->dev);
+   pm_runtime_mark_last_busy(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+
return 0;
 
 err_unregister_dma:
@@ -1230,6 +1268,8 @@ static int bam_dma_remove(struct platform_device *pdev)
struct bam_device *bdev = platform_get_drvdata(pdev);
u32 i;
 
+   pm_runtime_force_suspend(&pdev->dev);
+
of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(&bdev->common);
 
@@ -1257,11 +1297,67 @@ static int bam_dma_remove(struct platform_device *pdev)
return 0;
 }
 
+static int bam_dma_runtime_suspend(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+
+   clk_disable(bdev->bamclk);
+
+   return 0;
+}
+
+static int bam_dma_runtime_resume(struct device *dev)
+{
+   struc

Re: [PATCH v2 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-05-03 Thread Pramod Gurav
Hi Manish,

Thanks for review.

On 3 May 2016 at 15:21, Manish Badarkhe  wrote:
> Hi Pramod
>
>> @@ -715,10 +724,13 @@ static int bam_resume(struct dma_chan *chan)
>> struct bam_device *bdev = bchan->bdev;
>> unsigned long flag;
>>
>> +   pm_runtime_get_sync(bdev->dev);
>> spin_lock_irqsave(&bchan->vc.lock, flag);
>> writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
>> bchan->paused = 0;
>> spin_unlock_irqrestore(&bchan->vc.lock, flag);
>> +   pm_runtime_mark_last_busy(bdev->dev);
>> +   pm_runtime_put_autosuspend(bdev->dev);
>>
>> return 0;
>>  }
>
> Why this function simply return 'success' without any error capture?
>
I should check return of pm_runtime_get_sync.

>> @@ -1252,16 +1278,76 @@ static int bam_dma_remove(struct platform_device 
>> *pdev)
>>
>> tasklet_kill(&bdev->task);
>>
>> +   pm_runtime_get_sync(&pdev->dev);
>> clk_disable_unprepare(bdev->bamclk);
>> +   pm_runtime_disable(&pdev->dev);
>> +   pm_runtime_put_noidle(&pdev->dev);
>> +   pm_runtime_set_suspended(&pdev->dev);
>> +
>> +   return 0;
>> +}
>
> Why this function simply return 'success' without any error capture?
Need to handle it better.

>
>> +static int bam_dma_runtime_suspend(struct device *dev)
>> +{
>> +   struct bam_device *bdev = dev_get_drvdata(dev);
>> +
>> +   clk_disable(bdev->bamclk);
>> +
>> +   return 0;
>> +}
>
> Why this function simply return 'success' without any error capture?
If probe has succeeded means bdev->bamclk is not NULL and error hence
clk_disable wont return anything.

>
>
>> +#ifdef CONFIG_PM_SLEEP
>> +static int bam_dma_suspend(struct device *dev)
>> +{
>> +   struct bam_device *bdev = dev_get_drvdata(dev);
>> +
>> +   pm_runtime_force_suspend(dev);
>> +
>> +   clk_unprepare(bdev->bamclk);
>>
>> return 0;
>>  }
>
> Why this function simply return 'success' without any error capture?
Same logic applies here as well, as pm_runtime_force_suspend and
clk_unprepare may not return error in our case once probe is through.

>
> Regards
> Manish Badarkhe


[PATCH v2 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-05-03 Thread Pramod Gurav
Adds pm_runtime support for BAM DMA so that clock
is enabled only when there is a transaction going on to help
save power.

Signed-off-by: Pramod Gurav 
---
Changes since v1:
- Removed unnecessary extra line additions and remavals

 drivers/dma/qcom/bam_dma.c | 86 ++
 1 file changed, 86 insertions(+)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 5b427c4..f2a8b17 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../dmaengine.h"
 #include "../virt-dma.h"
@@ -58,6 +59,8 @@ struct bam_desc_hw {
u16 flags;
 };
 
+#define BAM_DMA_AUTOSUSPEND_DELAY 100
+
 #define DESC_FLAG_INT BIT(15)
 #define DESC_FLAG_EOT BIT(14)
 #define DESC_FLAG_EOB BIT(13)
@@ -535,6 +538,7 @@ static void bam_free_chan(struct dma_chan *chan)
return;
}
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flags);
bam_reset_channel(bchan);
spin_unlock_irqrestore(&bchan->vc.lock, flags);
@@ -550,6 +554,8 @@ static void bam_free_chan(struct dma_chan *chan)
 
/* disable irq */
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN));
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -696,10 +702,13 @@ static int bam_pause(struct dma_chan *chan)
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 1;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -715,10 +724,13 @@ static int bam_resume(struct dma_chan *chan)
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 0;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -967,6 +979,9 @@ static void dma_tasklet(unsigned long data)
bam_start_dma(bchan);
spin_unlock_irqrestore(&bchan->vc.lock, flags);
}
+
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -978,8 +993,12 @@ static void dma_tasklet(unsigned long data)
 static void bam_issue_pending(struct dma_chan *chan)
 {
struct bam_chan *bchan = to_bam_chan(chan);
+   struct bam_device *bdev = bchan->bdev;
unsigned long flags;
 
+   if (pm_runtime_status_suspended(bdev->dev))
+   pm_runtime_get_sync(bdev->dev);
+
spin_lock_irqsave(&bchan->vc.lock, flags);
 
/* if work pending and idle, start a transaction */
@@ -1210,6 +1229,13 @@ static int bam_dma_probe(struct platform_device *pdev)
if (ret)
goto err_unregister_dma;
 
+   pm_runtime_irq_safe(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
+   pm_runtime_use_autosuspend(&pdev->dev);
+   pm_runtime_mark_last_busy(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+
return 0;
 
 err_unregister_dma:
@@ -1252,16 +1278,76 @@ static int bam_dma_remove(struct platform_device *pdev)
 
tasklet_kill(&bdev->task);
 
+   pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(bdev->bamclk);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+
+   return 0;
+}
+
+static int bam_dma_runtime_suspend(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+
+   clk_disable(bdev->bamclk);
+
+   return 0;
+}
+
+static int bam_dma_runtime_resume(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_enable(bdev->bamclk);
+   if (ret < 0) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#ifdef CONFIG_PM_SLEEP
+static int bam_dma_suspend(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+
+   pm_runtime_force_suspend(dev);
+
+   clk_unprepare(bdev->bamclk);
 
return 0;
 }
 
+static int bam_dma_resume(struct device *dev)
+{

[PATCH v2 2/2] MAINTAINERS: Update the files to include the Qualcomm DMA folder

2016-05-03 Thread Pramod Gurav
Recently all qcom dma drivers were moved a separate directory. Update
the files to include the same

Signed-off-by: Pramod Gurav 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d826f1b..2327f92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1407,6 +1407,7 @@ L:linux-arm-...@vger.kernel.org
 L: linux-...@vger.kernel.org
 S: Maintained
 F: arch/arm/mach-qcom/
+F: drivers/dma/qcom/
 F: drivers/soc/qcom/
 F: drivers/tty/serial/msm_serial.h
 F: drivers/tty/serial/msm_serial.c
-- 
1.8.2.1



Re: [PATCH 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-05-02 Thread Pramod Gurav
Hi Kedar,
Thanks for having a look and comments.

On 2 May 2016 at 17:58, Appana Durga Kedareswara Rao
 wrote:
>
> Hi,
>
> > -Original Message-
> > From: dmaengine-ow...@vger.kernel.org [mailto:dmaengine-
> > ow...@vger.kernel.org] On Behalf Of Pramod Gurav
> > Sent: Monday, May 02, 2016 5:48 PM
> > To: vinod.k...@intel.com; andy.gr...@linaro.org; ulf.hans...@linaro.org;
> > r...@rjwysocki.net; linux-arm-...@vger.kernel.org
> > Cc: linux...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > dmaeng...@vger.kernel.org; stanimir.varba...@linaro.org;
> > ok...@codeaurora.org; Pramod Gurav 
> > Subject: [PATCH 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support
> >
> > Adds pm_runtime support for BAM DMA so that clock
> > is enabled only when there is a transaction going on to help
> > save power.
> >
> > Signed-off-by: Pramod Gurav 
> > ---
> >  drivers/dma/qcom/bam_dma.c | 88
> > +-
> >  1 file changed, 87 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
> > index 5b427c4..577f323 100644
> > --- a/drivers/dma/qcom/bam_dma.c
> > +++ b/drivers/dma/qcom/bam_dma.c
> > @@ -48,6 +48,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include "../dmaengine.h"
> >  #include "../virt-dma.h"
> > @@ -58,6 +59,8 @@ struct bam_desc_hw {
> >   u16 flags;
> >  };
> >
> > +#define BAM_DMA_AUTOSUSPEND_DELAY 100
> > +
> >  #define DESC_FLAG_INT BIT(15)
> >  #define DESC_FLAG_EOT BIT(14)
> >  #define DESC_FLAG_EOB BIT(13)
> > @@ -535,6 +538,7 @@ static void bam_free_chan(struct dma_chan *chan)
> >   return;
> >   }
> >
> > + pm_runtime_get_sync(bdev->dev);
> >   spin_lock_irqsave(&bchan->vc.lock, flags);
> >   bam_reset_channel(bchan);
> >   spin_unlock_irqrestore(&bchan->vc.lock, flags);
> > @@ -550,6 +554,8 @@ static void bam_free_chan(struct dma_chan *chan)
> >
> >   /* disable irq */
> >   writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN));
> > + pm_runtime_mark_last_busy(bdev->dev);
> > + pm_runtime_put_autosuspend(bdev->dev);
> >  }
> >
> >  /**
> > @@ -696,10 +702,13 @@ static int bam_pause(struct dma_chan *chan)
> >   struct bam_device *bdev = bchan->bdev;
> >   unsigned long flag;
> >
> > + pm_runtime_get_sync(bdev->dev);
> >   spin_lock_irqsave(&bchan->vc.lock, flag);
> >   writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
> >   bchan->paused = 1;
> >   spin_unlock_irqrestore(&bchan->vc.lock, flag);
> > + pm_runtime_mark_last_busy(bdev->dev);
> > + pm_runtime_put_autosuspend(bdev->dev);
> >
> >   return 0;
> >  }
> > @@ -715,10 +724,13 @@ static int bam_resume(struct dma_chan *chan)
> >   struct bam_device *bdev = bchan->bdev;
> >   unsigned long flag;
> >
> > + pm_runtime_get_sync(bdev->dev);
> >   spin_lock_irqsave(&bchan->vc.lock, flag);
> >   writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
> >   bchan->paused = 0;
> >   spin_unlock_irqrestore(&bchan->vc.lock, flag);
> > + pm_runtime_mark_last_busy(bdev->dev);
> > + pm_runtime_put_autosuspend(bdev->dev);
> >
> >   return 0;
> >  }
> > @@ -943,6 +955,7 @@ static void bam_start_dma(struct bam_chan *bchan)
> >   wmb();
> >   writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
> >   bam_addr(bdev, bchan->id, BAM_P_EVNT_REG));
> > +
>
> Unrelated change...
>
> >  }
> >
> >  /**
> > @@ -967,6 +980,9 @@ static void dma_tasklet(unsigned long data)
> >   bam_start_dma(bchan);
> >   spin_unlock_irqrestore(&bchan->vc.lock, flags);
> >   }
> > +
> > + pm_runtime_mark_last_busy(bdev->dev);
> > + pm_runtime_put_autosuspend(bdev->dev);
> >  }
> >
> >  /**
> > @@ -978,8 +994,12 @@ static void dma_tasklet(unsigned long data)
> >  static void bam_issue_pending(struct dma_chan *chan)
> >  {
> >   struct bam_chan *bchan = to_bam_chan(chan);
> > + struct bam_device *bdev = bchan->bdev;
> >   unsigned long flags;
> >
> > + if (pm_runtime_status_suspended(bdev->dev))
> > +  

[PATCH 2/2] MAINTAINERS: Update the files to include the Qualcomm DMA folder

2016-05-02 Thread Pramod Gurav
Recently all qcom dma drivers were moved a separate directory. Update
the files to include the same

Signed-off-by: Pramod Gurav 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d826f1b..2327f92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1407,6 +1407,7 @@ L:linux-arm-...@vger.kernel.org
 L: linux-...@vger.kernel.org
 S: Maintained
 F: arch/arm/mach-qcom/
+F: drivers/dma/qcom/
 F: drivers/soc/qcom/
 F: drivers/tty/serial/msm_serial.h
 F: drivers/tty/serial/msm_serial.c
-- 
1.8.2.1



[PATCH 1/2] dmaengine: qcom-bam-dma: Add pm_runtime support

2016-05-02 Thread Pramod Gurav
Adds pm_runtime support for BAM DMA so that clock
is enabled only when there is a transaction going on to help
save power.

Signed-off-by: Pramod Gurav 
---
 drivers/dma/qcom/bam_dma.c | 88 +-
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 5b427c4..577f323 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../dmaengine.h"
 #include "../virt-dma.h"
@@ -58,6 +59,8 @@ struct bam_desc_hw {
u16 flags;
 };
 
+#define BAM_DMA_AUTOSUSPEND_DELAY 100
+
 #define DESC_FLAG_INT BIT(15)
 #define DESC_FLAG_EOT BIT(14)
 #define DESC_FLAG_EOB BIT(13)
@@ -535,6 +538,7 @@ static void bam_free_chan(struct dma_chan *chan)
return;
}
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flags);
bam_reset_channel(bchan);
spin_unlock_irqrestore(&bchan->vc.lock, flags);
@@ -550,6 +554,8 @@ static void bam_free_chan(struct dma_chan *chan)
 
/* disable irq */
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN));
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -696,10 +702,13 @@ static int bam_pause(struct dma_chan *chan)
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 1;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -715,10 +724,13 @@ static int bam_resume(struct dma_chan *chan)
struct bam_device *bdev = bchan->bdev;
unsigned long flag;
 
+   pm_runtime_get_sync(bdev->dev);
spin_lock_irqsave(&bchan->vc.lock, flag);
writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
bchan->paused = 0;
spin_unlock_irqrestore(&bchan->vc.lock, flag);
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 
return 0;
 }
@@ -943,6 +955,7 @@ static void bam_start_dma(struct bam_chan *bchan)
wmb();
writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
bam_addr(bdev, bchan->id, BAM_P_EVNT_REG));
+
 }
 
 /**
@@ -967,6 +980,9 @@ static void dma_tasklet(unsigned long data)
bam_start_dma(bchan);
spin_unlock_irqrestore(&bchan->vc.lock, flags);
}
+
+   pm_runtime_mark_last_busy(bdev->dev);
+   pm_runtime_put_autosuspend(bdev->dev);
 }
 
 /**
@@ -978,8 +994,12 @@ static void dma_tasklet(unsigned long data)
 static void bam_issue_pending(struct dma_chan *chan)
 {
struct bam_chan *bchan = to_bam_chan(chan);
+   struct bam_device *bdev = bchan->bdev;
unsigned long flags;
 
+   if (pm_runtime_status_suspended(bdev->dev))
+   pm_runtime_get_sync(bdev->dev);
+
spin_lock_irqsave(&bchan->vc.lock, flags);
 
/* if work pending and idle, start a transaction */
@@ -1210,6 +1230,13 @@ static int bam_dma_probe(struct platform_device *pdev)
if (ret)
goto err_unregister_dma;
 
+   pm_runtime_irq_safe(&pdev->dev);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
+   pm_runtime_use_autosuspend(&pdev->dev);
+   pm_runtime_mark_last_busy(&pdev->dev);
+   pm_runtime_set_active(&pdev->dev);
+   pm_runtime_enable(&pdev->dev);
+
return 0;
 
 err_unregister_dma:
@@ -1221,7 +1248,6 @@ err_tasklet_kill:
tasklet_kill(&bdev->task);
 err_disable_clk:
clk_disable_unprepare(bdev->bamclk);
-
return ret;
 }
 
@@ -1252,16 +1278,76 @@ static int bam_dma_remove(struct platform_device *pdev)
 
tasklet_kill(&bdev->task);
 
+   pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(bdev->bamclk);
+   pm_runtime_disable(&pdev->dev);
+   pm_runtime_put_noidle(&pdev->dev);
+   pm_runtime_set_suspended(&pdev->dev);
+
+   return 0;
+}
+
+static int bam_dma_runtime_suspend(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+
+   clk_disable(bdev->bamclk);
+
+   return 0;
+}
+
+static int bam_dma_runtime_resume(struct device *dev)
+{
+   struct bam_device *bdev = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_enable(bdev->bamclk);
+   if (ret < 0) {
+   dev_err(dev, "clk_enable failed: %d\n", ret);
+ 

[PATCH 1/2] spi: qup: Handle clocks in pm_runtime suspend and resume

2016-05-02 Thread Pramod Gurav
Clocks must ne disabled in pm_runtime to achieve some power saving.
Enable the clocks when the device is runtime resumed during a transfer.

Signed-off-by: Pramod Gurav 
---
 drivers/spi/spi-qup.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 810a7fa..e42ff61 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -937,6 +937,10 @@ static int spi_qup_pm_suspend_runtime(struct device 
*device)
config = readl(controller->base + QUP_CONFIG);
config |= QUP_CONFIG_CLOCK_AUTO_GATE;
writel_relaxed(config, controller->base + QUP_CONFIG);
+
+   clk_disable_unprepare(controller->cclk);
+   clk_disable_unprepare(controller->iclk);
+
return 0;
 }
 
@@ -945,6 +949,15 @@ static int spi_qup_pm_resume_runtime(struct device *device)
struct spi_master *master = dev_get_drvdata(device);
struct spi_qup *controller = spi_master_get_devdata(master);
u32 config;
+   int ret;
+
+   ret = clk_prepare_enable(controller->iclk);
+   if (ret)
+   return ret;
+
+   ret = clk_prepare_enable(controller->cclk);
+   if (ret)
+   return ret;
 
/* Disable clocks auto gaiting */
config = readl_relaxed(controller->base + QUP_CONFIG);
-- 
1.8.2.1



[PATCH 2/2] spi: qup: Add spi_master_put in remove function

2016-05-02 Thread Pramod Gurav
Release memory allocated for spi master by calling spi_master_put in
.remove function.

Signed-off-by: Pramod Gurav 
---
 drivers/spi/spi-qup.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index e42ff61..c338ef1 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -1030,6 +1030,8 @@ static int spi_qup_remove(struct platform_device *pdev)
 
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+   spi_master_put(master);
+
return 0;
 }
 
-- 
1.8.2.1



[PATCH 2/2] dmaengine: qcom_bam_dma: Bypass BAM init if not managed locally

2016-03-22 Thread Pramod Gurav
On some QOCM platforms BAM control registers are managed remotely
hence can not be accessed by application processor for writes. Pass
a DT property qcom,bam_ctrl_remote to declare the same to skip bam_init.

Move the pipe number initialisation from bam_init to probe functiom
as it should be done for all platforms.

Signed-off-by: Pramod Gurav 
---
 Documentation/devicetree/bindings/dma/qcom_bam_dma.txt |  3 +++
 drivers/dma/qcom/bam_dma.c | 18 +++---
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt 
b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
index 1c9d48e..46e33ae 100644
--- a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
@@ -13,6 +13,8 @@ Required properties:
 - clock-names: must contain "bam_clk" entry
 - qcom,ee : indicates the active Execution Environment identifier (0-7) used in
   the secure world.
+- qcom,bam_ctrl_remote: Use when BAM global device control is managed remotely
+  and not locally by the application processor.
 
 Example:
 
@@ -24,6 +26,7 @@ Example:
clock-names = "bam_clk";
#dma-cells = <1>;
qcom,ee = <0>;
+   qcom,bam_ctrl_remote;
};
 
 DMA clients must use the format described in the dma.txt file, using a two cell
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 0880345..04dd446 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -384,6 +384,7 @@ struct bam_device {
struct device_dma_parameters dma_parms;
struct bam_chan *channels;
u32 num_channels;
+   bool bam_ctrl_remote;
 
/* execution environment ID, from DT */
u32 ee;
@@ -1036,9 +1037,6 @@ static int bam_init(struct bam_device *bdev)
if (bdev->ee >= val)
return -EINVAL;
 
-   val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES));
-   bdev->num_channels = val & BAM_NUM_PIPES_MASK;
-
/* s/w reset bam */
/* after reset all pipes are disabled and idle */
val = readl_relaxed(bam_addr(bdev, 0, BAM_CTRL));
@@ -1095,7 +1093,7 @@ static int bam_dma_probe(struct platform_device *pdev)
struct bam_device *bdev;
const struct of_device_id *match;
struct resource *iores;
-   int ret, i;
+   int ret, i, val;
 
bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
if (!bdev)
@@ -1136,9 +1134,15 @@ static int bam_dma_probe(struct platform_device *pdev)
return ret;
}
 
-   ret = bam_init(bdev);
-   if (ret)
-   goto err_disable_clk;
+   val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES));
+   bdev->num_channels = val & BAM_NUM_PIPES_MASK;
+
+   bdev->bam_ctrl_remote = of_property_read_bool(pdev->dev.of_node,
+   "qcom,bam_ctrl_remote");
+   if (bdev->bam_ctrl_remote != true)
+   ret = bam_init(bdev);
+   if (ret)
+   goto err_disable_clk;
 
tasklet_init(&bdev->task, dma_tasklet, (unsigned long)bdev);
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH 1/2] dmaengine: qcom_bam_dma: Clear IRQ only if its set

2016-03-22 Thread Pramod Gurav
Clear the BAM IRQ bit only if there is a BAM interrupt.

Signed-off-by: Pramod Gurav 
---
 drivers/dma/qcom/bam_dma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index d5e0a9c..0880345 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -807,7 +807,8 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
/* don't allow reorder of the various accesses to the BAM registers */
mb();
 
-   writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
+   if (srcs & BAM_IRQ)
+   writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
 
return IRQ_HANDLED;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



[PATCH 0/2] Bypass BAM init if Remotely controlled

2016-03-22 Thread Pramod Gurav
On some QOCM platforms(eg 8996) BAM control registers are managed remotely
hence can not be accessed by application processor for writes. So skip the 
bam_init
for any such platform if DT property is set.

Tested on 8996 (BAM Global control is through remote) and DB410C boards.
Tested with i2c DMA on these targets which uses BAM as DMA controller.

Pramod Gurav (2):
  dmaengine: qcom_bam_dma: Clear IRQ only if its set
  dmaengine: qcom_bam_dma: Bypass BAM init if not managed locally

 .../devicetree/bindings/dma/qcom_bam_dma.txt|  3 +++
 drivers/dma/qcom/bam_dma.c  | 21 +
 2 files changed, 16 insertions(+), 8 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



Re: [PATCH] drivers: i2c: Fix qup fifo handling

2016-02-29 Thread Pramod Gurav

On Fri, February 26, 2016 9:28 pm, Sricharan R wrote:
> After the addition of V2 support, there was a regression observed
> when testing it on MSM8996. The reason is driver puts the controller
> in to RUN state and writes the data to be 'tx' ed in fifo. But controller
> has to be put in to 'PAUSE' state and data has to written to fifo. Then
> should be put in to 'RUN' state separately.
>
> Signed-off-by: Sricharan R 

Tested-by: Pramod Gurav 

Regards,
Pramod
> ---
>  drivers/i2c/busses/i2c-qup.c | 46
> +---
>  1 file changed, 39 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
> index 30f3a2b..23eaabb 100644
> --- a/drivers/i2c/busses/i2c-qup.c
> +++ b/drivers/i2c/busses/i2c-qup.c
> @@ -372,6 +372,38 @@ static void qup_i2c_set_write_mode(struct qup_i2c_dev
> *qup, struct i2c_msg *msg)
>   }
>  }
>
> +static int check_for_fifo_space(struct qup_i2c_dev *qup)
> +{
> + int ret;
> +
> + ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
> + if (ret)
> + goto out;
> +
> + ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL,
> +  RESET_BIT, 4 * ONE_BYTE);
> + if (ret) {
> + /* Fifo is full. Drain out the fifo */
> + ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
> + if (ret)
> + goto out;
> +
> + ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY,
> +  RESET_BIT, 256 * ONE_BYTE);
> + if (ret) {
> + dev_err(qup->dev, "timeout for fifo out full");
> + goto out;
> + }
> +
> + ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
> + if (ret)
> + goto out;
> + }
> +
> +out:
> + return ret;
> +}
> +
>  static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg
> *msg)
>  {
>   u32 addr = msg->addr << 1;
> @@ -390,8 +422,7 @@ static int qup_i2c_issue_write(struct qup_i2c_dev
> *qup, struct i2c_msg *msg)
>
>   while (qup->pos < msg->len) {
>   /* Check that there's space in the FIFO for our pair */
> - ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL, RESET_BIT,
> -  4 * ONE_BYTE);
> + ret = check_for_fifo_space(qup);
>   if (ret)
>   return ret;
>
> @@ -413,6 +444,8 @@ static int qup_i2c_issue_write(struct qup_i2c_dev
> *qup, struct i2c_msg *msg)
>   idx++;
>   }
>
> + ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
> +
>   return ret;
>  }
>
> @@ -441,12 +474,9 @@ static int qup_i2c_send_data(struct qup_i2c_dev *qup,
> int tlen, u8 *tbuf,
>   int ret = 0;
>
>   while (len > 0) {
> - ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL,
> -  RESET_BIT, 4 * ONE_BYTE);
> - if (ret) {
> - dev_err(qup->dev, "timeout for fifo out full");
> + ret = check_for_fifo_space(qup);
> + if (ret)
>   return ret;
> - }
>
>   t = (len >= 4) ? 4 : len;
>
> @@ -465,6 +495,8 @@ static int qup_i2c_send_data(struct qup_i2c_dev *qup,
> int tlen, u8 *tbuf,
>   len -= 4;
>   }
>
> + ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
> +
>   return ret;
>  }
>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>


Pramod
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 2/3] tty: serial: msm: Remove duplicate operations on clocks in startup/shutdown

2015-04-29 Thread Pramod Gurav
Thanks Stephen for review.

On Fri, April 10, 2015 11:33 pm, Stephen Boyd wrote:
> On 04/10/15 05:19, Pramod Gurav wrote:
>> @@ -683,8 +679,7 @@ static void msm_power(struct uart_port *port,
>> unsigned int state,
>>
>>  switch (state) {
>>  case 0:
>> -clk_prepare_enable(msm_port->clk);
>> -clk_prepare_enable(msm_port->pclk);
>> +msm_init_clock(port);
>
> Hm... now we would call msm_serial_set_mnd_regs() whenever we power on
> the port? Presumably we only need to do that once when we probe (or when
> we resume from a sleep state that resets the registers, i.e.
> hibernation) but I guess we're getting saved by the fact that the
> if/else if pair in msm_serial_set_mnd_regs_from_uartclk would never be
> true after the first time we call it?

I tried replacing msm_init_clock() call with msm_serial_set_mnd_regs() in
msm_startup() as msm_startup gets called just after msm_power() so that
clk_prepare_enable() is followed by mnd settings. But it does not get the
kernel booted for some reason.

So, can I get a acked-by for this patch or you still think it can be done
in a better way?
>
>>  break;
>>  case 3:
>>  clk_disable_unprepare(msm_port->clk);
>
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
> in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


Re: [PATCH v2 2/2] tty: serial: msm: Disable pclk when port is closed

2015-04-08 Thread Pramod Gurav

On Thu, April 9, 2015 5:21 am, Stephen Boyd wrote:
> On 04/08/15 06:28, Pramod Gurav wrote:
>> Disable the pclk when tty port is closed by user space.
>>
>> Signed-off-by: Pramod Gurav 
>> ---
>>  drivers/tty/serial/msm_serial.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/tty/serial/msm_serial.c
>> b/drivers/tty/serial/msm_serial.c
>> index 4c1e9ea..f38565c 100644
>> --- a/drivers/tty/serial/msm_serial.c
>> +++ b/drivers/tty/serial/msm_serial.c
>> @@ -523,6 +523,7 @@ static void msm_shutdown(struct uart_port *port)
>>  msm_write(port, 0, UART_IMR); /* disable interrupts */
>>
>>  clk_disable_unprepare(msm_port->clk);
>> +clk_disable_unprepare(msm_port->pclk);
>>
>>  free_irq(port->irq, port);
>>  }
>
> It's not clear to me at all when this clock is enabled and when it's
> disabled during the lifetime of this driver. For example, why do we have
> a .pm op to turn clocks on and off? Shouldn't they already be on? Can
> you please explain when the clocks are turned on and off and what
> userspace actions cause that to happen? Looking at drivers like
> amba-pl010.c I don't see any .pm op, just a
> clk_prepare_enable/clk_disable_unprepare pair in the startup and
> shutdown ops.


When a userspce opens a serial port the uart_startup (in serial_core)
function is executed which changes the uart_pm state to UART_PM_STATE_ON.
So when this port is release/closed by the application
uart_close(serial_core) changes the uart_pm state to UART_PM_STATE_OFF if
its not console. But it is not done in uart_shutdown function.

So ideally clk_prepare_enable/clk_disable_unprepare must be called in .pm
only. So, we can get rid of these operations from msm_startup function as
these will be called anyway using .pm ops.

About .pm in uart_ops, there are few drivers which have it for an example,
atmel_serial, sh-sci etc. That is where they do
clk_prepare_enable/clk_disable_unprepare. And moreover when there is
suspend across system these function will handled through .pm.


>
> Minus my confusion of why our clocking is complicated, it looks correct
> to me to do this, so
>
> Reviewed-by: Stephen Boyd 

>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
>

Pramod

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


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


[PATCH v2 2/2] tty: serial: msm: Disable pclk when port is closed

2015-04-08 Thread Pramod Gurav
Disable the pclk when tty port is closed by user space.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 4c1e9ea..f38565c 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -523,6 +523,7 @@ static void msm_shutdown(struct uart_port *port)
msm_write(port, 0, UART_IMR); /* disable interrupts */
 
clk_disable_unprepare(msm_port->clk);
+   clk_disable_unprepare(msm_port->pclk);
 
free_irq(port->irq, port);
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


[PATCH v2 1/2] tty: serial: msm: Add mask value for UART_DM registers

2015-04-08 Thread Pramod Gurav
The bit masks for RFR_LEVEL1 and STALE_TIMEOUT_MSB values in MR1 and
IPR registers respectively are different for UART and UART_DM hardware
cores. We have been using UART core mask values for these. Add the same
for UART_DM core.

There is no bit setting as UART_IPR_RXSTALE_LAST for UART_DM core so do
it only for UART core.

Signed-off-by: Pramod Gurav 

---
Changes since last version:
 - Added new macro fo UART_DM_MR1_AUTO_RFR_LEVEL1 instead of modifying existing.
 - Added a new macro for IPR register as it is also different in UART_DM
 - Changed subject line
 - Removed change log from message 

 drivers/tty/serial/msm_serial.c | 19 +++
 drivers/tty/serial/msm_serial.h |  2 ++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index b73889c..4c1e9ea 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -432,8 +432,13 @@ static int msm_set_baud_rate(struct uart_port *port, 
unsigned int baud)
/* RX stale watermark */
rxstale = entry->rxstale;
watermark = UART_IPR_STALE_LSB & rxstale;
-   watermark |= UART_IPR_RXSTALE_LAST;
-   watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   if (msm_port->is_uartdm)
+   watermark |= UART_DM_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   else {
+   watermark |= UART_IPR_RXSTALE_LAST;
+   watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   }
+
msm_write(port, watermark, UART_IPR);
 
/* set RX watermark */
@@ -496,9 +501,15 @@ static int msm_startup(struct uart_port *port)
 
/* set automatic RFR level */
data = msm_read(port, UART_MR1);
-   data &= ~UART_MR1_AUTO_RFR_LEVEL1;
+   if (msm_port->is_uartdm) {
+   data &= ~UART_DM_MR1_AUTO_RFR_LEVEL1;
+   data |= UART_DM_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
+   } else {
+   data &= ~UART_MR1_AUTO_RFR_LEVEL1;
+   data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
+   }
+
data &= ~UART_MR1_AUTO_RFR_LEVEL0;
-   data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
msm_write(port, data, UART_MR1);
return 0;
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 3e1c713..caf5363 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -20,6 +20,7 @@
 
 #define UART_MR1_AUTO_RFR_LEVEL0   0x3F
 #define UART_MR1_AUTO_RFR_LEVEL1   0x3FF00
+#define UART_DM_MR1_AUTO_RFR_LEVEL10xFF00
 #define UART_MR1_RX_RDY_CTL(1 << 7)
 #define UART_MR1_CTS_CTL   (1 << 6)
 
@@ -78,6 +79,7 @@
 #define UART_IPR_RXSTALE_LAST  0x20
 #define UART_IPR_STALE_LSB 0x1F
 #define UART_IPR_STALE_TIMEOUT_MSB 0x3FF80
+#define UART_DM_IPR_STALE_TIMEOUT_MSB  0xFF80
 
 #define UART_IPR   0x0018
 #define UART_TFWR  0x001C
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


[PATCH 2/2] tty: serial: msm: Disable pclk when port is closed

2015-04-08 Thread Pramod Gurav
Disable the pclk when tty port is closed by user space.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 4c1e9ea..f38565c 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -523,6 +523,7 @@ static void msm_shutdown(struct uart_port *port)
msm_write(port, 0, UART_IMR); /* disable interrupts */
 
clk_disable_unprepare(msm_port->clk);
+   clk_disable_unprepare(msm_port->pclk);
 
free_irq(port->irq, port);
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


[PATCH 1/2] tty: serial: msm: Add mask value for UART_DM registers

2015-04-08 Thread Pramod Gurav
The bit masks for RFR_LEVEL1 and STALE_TIMEOUT_MSB values in MR1 and
IPR registers respectively are different for UART and UART_DM hardware
cores. We have been using UART core mask values for these. Add the same
for UART_DM core.

There is no bit setting as UART_IPR_RXSTALE_LAST for UART_DM core so do
it only for UART core.

Signed-off-by: Pramod Gurav 
--

Changes since last version:
 - Added new macro fo UART_DM_MR1_AUTO_RFR_LEVEL1 instead of modifying existing.
 - Added a new macro for IPR register as it is also different in UART_DM
 - Changed subject line

---
 drivers/tty/serial/msm_serial.c | 19 +++
 drivers/tty/serial/msm_serial.h |  2 ++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index b73889c..4c1e9ea 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -432,8 +432,13 @@ static int msm_set_baud_rate(struct uart_port *port, 
unsigned int baud)
/* RX stale watermark */
rxstale = entry->rxstale;
watermark = UART_IPR_STALE_LSB & rxstale;
-   watermark |= UART_IPR_RXSTALE_LAST;
-   watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   if (msm_port->is_uartdm)
+   watermark |= UART_DM_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   else {
+   watermark |= UART_IPR_RXSTALE_LAST;
+   watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+   }
+
msm_write(port, watermark, UART_IPR);
 
/* set RX watermark */
@@ -496,9 +501,15 @@ static int msm_startup(struct uart_port *port)
 
/* set automatic RFR level */
data = msm_read(port, UART_MR1);
-   data &= ~UART_MR1_AUTO_RFR_LEVEL1;
+   if (msm_port->is_uartdm) {
+   data &= ~UART_DM_MR1_AUTO_RFR_LEVEL1;
+   data |= UART_DM_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
+   } else {
+   data &= ~UART_MR1_AUTO_RFR_LEVEL1;
+   data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
+   }
+
data &= ~UART_MR1_AUTO_RFR_LEVEL0;
-   data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
msm_write(port, data, UART_MR1);
return 0;
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 3e1c713..caf5363 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -20,6 +20,7 @@
 
 #define UART_MR1_AUTO_RFR_LEVEL0   0x3F
 #define UART_MR1_AUTO_RFR_LEVEL1   0x3FF00
+#define UART_DM_MR1_AUTO_RFR_LEVEL10xFF00
 #define UART_MR1_RX_RDY_CTL(1 << 7)
 #define UART_MR1_CTS_CTL   (1 << 6)
 
@@ -78,6 +79,7 @@
 #define UART_IPR_RXSTALE_LAST  0x20
 #define UART_IPR_STALE_LSB 0x1F
 #define UART_IPR_STALE_TIMEOUT_MSB 0x3FF80
+#define UART_DM_IPR_STALE_TIMEOUT_MSB  0xFF80
 
 #define UART_IPR   0x0018
 #define UART_TFWR  0x001C
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


[PATCH] tty: serial: msm: Fix mask value of RFR level

2015-04-07 Thread Pramod Gurav
According to documents The RFR_LEVEL1 in UART_DM_MR1 can be
programmed in bits 31:8 but the masks only bits 17:8.
Correct the same.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 8f7806d..5ff9ebf 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -19,7 +19,7 @@
 #define UART_MR1   0x
 
 #define UART_MR1_AUTO_RFR_LEVEL0   0x3F
-#define UART_MR1_AUTO_RFR_LEVEL1   0x3FF00
+#define UART_MR1_AUTO_RFR_LEVEL1   0xFF00
 #define UART_MR1_RX_RDY_CTL(1 << 7)
 #define UART_MR1_CTS_CTL   (1 << 6)
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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


[PATCH RESEND] dmaengine: qcom_bam_dma: Fix error path in probe function

2015-02-11 Thread Pramod Gurav
Calls tasklet_kill() in error path of the probe function were missing.
Add the same in error path.

Signed-off-by: Pramod Gurav 
---

Resending it with linux-arm-msm in cc.

 drivers/dma/qcom_bam_dma.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index 3122a99..a1ff4a6 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -1115,7 +1115,7 @@ static int bam_dma_probe(struct platform_device *pdev)
 
if (!bdev->channels) {
ret = -ENOMEM;
-   goto err_disable_clk;
+   goto err_tasklet_kill;
}
 
/* allocate and initialize channels */
@@ -1127,7 +1127,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
IRQF_TRIGGER_HIGH, "bam_dma", bdev);
if (ret)
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
 
/* set max dma segment size */
bdev->common.dev = bdev->dev;
@@ -1135,7 +1135,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
if (ret) {
dev_err(bdev->dev, "cannot set maximum segment size\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
platform_set_drvdata(pdev, bdev);
@@ -1156,7 +1156,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&bdev->common);
if (ret) {
dev_err(bdev->dev, "failed to register dma async device\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
@@ -1168,8 +1168,14 @@ static int bam_dma_probe(struct platform_device *pdev)
 
 err_unregister_dma:
dma_async_device_unregister(&bdev->common);
+err_bam_channel_exit:
+   for (i = 0; i < bdev->num_channels; i++)
+   tasklet_kill(&bdev->channels[i].vc.task);
+err_tasklet_kill:
+   tasklet_kill(&bdev->task);
 err_disable_clk:
clk_disable_unprepare(bdev->bamclk);
+
return ret;
 }
 
-- 
1.7.9.5

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


[PATCH RESEND] dmaengine: qcom_bam_dma: Fix error path in probe function

2015-02-11 Thread Pramod Gurav
Calls tasklet_kill() in error path of the probe function were missing.
Add the same in error path.

Signed-off-by: Pramod Gurav 
---

Resending it with linux-arm-msm in cc.

 drivers/dma/qcom_bam_dma.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index 3122a99..a1ff4a6 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -1115,7 +1115,7 @@ static int bam_dma_probe(struct platform_device *pdev)
 
if (!bdev->channels) {
ret = -ENOMEM;
-   goto err_disable_clk;
+   goto err_tasklet_kill;
}
 
/* allocate and initialize channels */
@@ -1127,7 +1127,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
IRQF_TRIGGER_HIGH, "bam_dma", bdev);
if (ret)
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
 
/* set max dma segment size */
bdev->common.dev = bdev->dev;
@@ -1135,7 +1135,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
if (ret) {
dev_err(bdev->dev, "cannot set maximum segment size\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
platform_set_drvdata(pdev, bdev);
@@ -1156,7 +1156,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&bdev->common);
if (ret) {
dev_err(bdev->dev, "failed to register dma async device\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
@@ -1168,8 +1168,14 @@ static int bam_dma_probe(struct platform_device *pdev)
 
 err_unregister_dma:
dma_async_device_unregister(&bdev->common);
+err_bam_channel_exit:
+   for (i = 0; i < bdev->num_channels; i++)
+   tasklet_kill(&bdev->channels[i].vc.task);
+err_tasklet_kill:
+   tasklet_kill(&bdev->task);
 err_disable_clk:
clk_disable_unprepare(bdev->bamclk);
+
return ret;
 }
 
-- 
1.7.9.5

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


[PATCH] dmaengine: qcom_bam_dma: Fix error path in probe function

2015-02-06 Thread Pramod Gurav
Calls tasklet_kill() in error path of the probe function were missing.
Add the same in error path.

Signed-off-by: Pramod Gurav 
---
 drivers/dma/qcom_bam_dma.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index 3122a99..a1ff4a6 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -1115,7 +1115,7 @@ static int bam_dma_probe(struct platform_device *pdev)
 
if (!bdev->channels) {
ret = -ENOMEM;
-   goto err_disable_clk;
+   goto err_tasklet_kill;
}
 
/* allocate and initialize channels */
@@ -1127,7 +1127,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
IRQF_TRIGGER_HIGH, "bam_dma", bdev);
if (ret)
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
 
/* set max dma segment size */
bdev->common.dev = bdev->dev;
@@ -1135,7 +1135,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
if (ret) {
dev_err(bdev->dev, "cannot set maximum segment size\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
platform_set_drvdata(pdev, bdev);
@@ -1156,7 +1156,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&bdev->common);
if (ret) {
dev_err(bdev->dev, "failed to register dma async device\n");
-   goto err_disable_clk;
+   goto err_bam_channel_exit;
}
 
ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
@@ -1168,8 +1168,14 @@ static int bam_dma_probe(struct platform_device *pdev)
 
 err_unregister_dma:
dma_async_device_unregister(&bdev->common);
+err_bam_channel_exit:
+   for (i = 0; i < bdev->num_channels; i++)
+   tasklet_kill(&bdev->channels[i].vc.task);
+err_tasklet_kill:
+   tasklet_kill(&bdev->task);
 err_disable_clk:
clk_disable_unprepare(bdev->bamclk);
+
return ret;
 }
 
-- 
1.7.9.5

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


Re: [Patch v2 1/2] dmaengine: Add ADM driver

2015-01-30 Thread Pramod Gurav
Hi Andy,
A minor doubt.

On Thursday 08 January 2015 08:56 AM, Andy Gross wrote:
> Signed-off-by: Andy Gross 
> ---
>  drivers/dma/Kconfig|   10 +
>  drivers/dma/Makefile   |1 +
>  drivers/dma/qcom_adm.c |  899 
> 



> +
> + return ret;
> +}
> +
> +static struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec,
> + struct of_dma *of)
> +{
> + struct adm_device *adev = container_of(of->of_dma_data,
> + struct adm_device, common);
> + struct adm_chan *achan;
I don't see achan being used anywhere in this function? apart from below.
> + struct dma_chan *chan;
> + unsigned int request;
> +
> + if (dma_spec->args_count != 1) {
> + dev_err(adev->dev, "incorrect number of dma arguments\n");
> + return NULL;
> + }
> +
> + request = dma_spec->args[0];
> + if (request >= adev->num_channels)
> + return NULL;
> +
> + chan = dma_get_slave_channel(&(adev->channels[request].vc.chan));
> +
> + if (!chan)
> + return NULL;
> +
> + achan = to_adm_chan(chan);
Could not understand the use of achan here. unused code?

> +
> + return chan;
> +}
> +
> +/**
> + * adm_issue_pending - starts pending transactions
> + * @chan: dma channel



> +module_platform_driver(adm_dma_driver);
> +
> +MODULE_AUTHOR("Andy Gross ");
> +MODULE_DESCRIPTION("QCOM ADM DMA engine driver");
> +MODULE_LICENSE("GPL v2");
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND] ssb: Fix Sparse error in main

2015-01-27 Thread Pramod Gurav
This change fixes below sparse error:
drivers/ssb/main.c:94:16: warning: symbol 'ssb_sdio_func_to_bus'
was not declared. Should it be static?

Acked-by: Michael Buesch 
Signed-off-by: Pramod Gurav 
---
 drivers/ssb/main.c |   19 ---
 1 file changed, 19 deletions(-)

diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 2fead38..1e180c4 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -90,25 +90,6 @@ found:
 }
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
-#ifdef CONFIG_SSB_SDIOHOST
-struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
-{
-   struct ssb_bus *bus;
-
-   ssb_buses_lock();
-   list_for_each_entry(bus, &buses, list) {
-   if (bus->bustype == SSB_BUSTYPE_SDIO &&
-   bus->host_sdio == func)
-   goto found;
-   }
-   bus = NULL;
-found:
-   ssb_buses_unlock();
-
-   return bus;
-}
-#endif /* CONFIG_SSB_SDIOHOST */
-
 int ssb_for_each_bus_call(unsigned long data,
  int (*func)(struct ssb_bus *bus, unsigned long data))
 {
-- 
1.7.9.5

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


[PATCH RESEND] ssb: Fix Sparse error in main

2015-01-27 Thread Pramod Gurav
This change fixes below sparse error:
drivers/ssb/main.c:94:16: warning: symbol 'ssb_sdio_func_to_bus'
was not declared. Should it be static?

Acked-by: Michael Buesch 
Signed-off-by: Pramod Gurav 
---
 drivers/ssb/main.c |   19 ---
 1 file changed, 19 deletions(-)

diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 2fead38..1e180c4 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -90,25 +90,6 @@ found:
 }
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
-#ifdef CONFIG_SSB_SDIOHOST
-struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
-{
-   struct ssb_bus *bus;
-
-   ssb_buses_lock();
-   list_for_each_entry(bus, &buses, list) {
-   if (bus->bustype == SSB_BUSTYPE_SDIO &&
-   bus->host_sdio == func)
-   goto found;
-   }
-   bus = NULL;
-found:
-   ssb_buses_unlock();
-
-   return bus;
-}
-#endif /* CONFIG_SSB_SDIOHOST */
-
 int ssb_for_each_bus_call(unsigned long data,
  int (*func)(struct ssb_bus *bus, unsigned long data))
 {
-- 
1.7.9.5

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


[PATCH RESEND] mmc: mmci: Get rid of dead code in mmci_dma_setup

2015-01-21 Thread Pramod Gurav
DMA configuration has been removed from function mmci_dma_setup but the
local mask variable was not removed. This remains unused hence remove
it from the function and operations on it

Signed-off-by: Pramod Gurav 
---
 drivers/mmc/host/mmci.c |5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 47dcece..122a751 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -435,7 +435,6 @@ static void mmci_init_sg(struct mmci_host *host, struct 
mmc_data *data)
 static void mmci_dma_setup(struct mmci_host *host)
 {
const char *rxname, *txname;
-   dma_cap_mask_t mask;
struct variant_data *variant = host->variant;
 
host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 
"rx");
@@ -444,10 +443,6 @@ static void mmci_dma_setup(struct mmci_host *host)
/* initialize pre request cookie */
host->next_data.cookie = 1;
 
-   /* Try to acquire a generic DMA engine slave channel */
-   dma_cap_zero(mask);
-   dma_cap_set(DMA_SLAVE, mask);
-
/*
 * If only an RX channel is specified, the driver will
 * attempt to use it bidirectionally, however if it is
-- 
1.7.9.5

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


[PATCH] tty: serial: msm_serial: Remove console unregistration from driver exit.

2015-01-12 Thread Pramod Gurav
unregister_console() will be called from uart_remove_one_port() while
removing the platform driver. So not necessary to call it in driver
exit path.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c |3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 8a7af98..58ba602 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -1298,9 +1298,6 @@ static int __init msm_serial_init(void)
 
 static void __exit msm_serial_exit(void)
 {
-#ifdef CONFIG_SERIAL_MSM_CONSOLE
-   unregister_console(&msm_console);
-#endif
platform_driver_unregister(&msm_platform_driver);
uart_unregister_driver(&msm_uart_driver);
 }
-- 
1.7.9.5

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


[PATCH v3] tty: serial: msm_serial: code cleanup in msm_console_setup

2015-01-12 Thread Pramod Gurav
The change does following:
 - baud, flow, bits, parity were being overwritten as they were
   being reinitialized after parsing.  Initialize them when they are
   declared so that user provided setting are not overwritten.
 - msm_set_baud_rate() is anyway called in uart_set_options when it calls
   msm_set_termios(). msm_reset() is called when we change the baud rate.
   Hence doing away with both of these calls.
 - CR_CMD_PROTECTION_EN and CR_TX_ENABLE settings are done in msm_set_baud_rate.
   So do away with this here.

Signed-off-by: Pramod Gurav 
---

Changes since v2:
 - initialize baud, flow, bits, parity when they are declared.
 - undo msm_init_clock removal as suggested by Stephen.
 - Remove unused variable msm_port

Tested on IFC6410.

 drivers/tty/serial/msm_serial.c |   24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index c88b522..a0cc6e0 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -920,14 +920,15 @@ static void msm_console_write(struct console *co, const 
char *s,
 static int __init msm_console_setup(struct console *co, char *options)
 {
struct uart_port *port;
-   struct msm_port *msm_port;
-   int baud = 0, flow, bits, parity;
+   int baud = 115200;
+   int bits = 8;
+   int parity = 'n';
+   int flow = 'n';
 
if (unlikely(co->index >= UART_NR || co->index < 0))
return -ENXIO;
 
port = get_port_from_line(co->index);
-   msm_port = UART_TO_MSM(port);
 
if (unlikely(!port->membase))
return -ENXIO;
@@ -937,23 +938,6 @@ static int __init msm_console_setup(struct console *co, 
char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
 
-   bits = 8;
-   parity = 'n';
-   flow = 'n';
-   msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE,
- UART_MR2);/* 8N1 */
-
-   if (baud < 300 || baud > 115200)
-   baud = 115200;
-   msm_set_baud_rate(port, baud);
-
-   msm_reset(port);
-
-   if (msm_port->is_uartdm) {
-   msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
-   msm_write(port, UART_CR_TX_ENABLE, UART_CR);
-   }
-
pr_info("msm_serial: console setup on port #%d\n", port->line);
 
return uart_set_options(port, co, baud, parity, bits, flow);
-- 
1.7.9.5

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


Re: [PATCH v2] tty: serial: msm_serial: Remove duplicate code in msm_console_setup

2015-01-12 Thread Pramod Gurav
Hi Stephen,

On Friday 09 January 2015 03:16 AM, Stephen Boyd wrote:
> On 01/08/2015 01:15 AM, Pramod Gurav wrote:
>>  drivers/tty/serial/msm_serial.c |   15 ---
>>  1 file changed, 15 deletions(-)
>>
>> diff --git a/drivers/tty/serial/msm_serial.c 
>> b/drivers/tty/serial/msm_serial.c
>> index c88b522..057008d 100644
>> --- a/drivers/tty/serial/msm_serial.c
>> +++ b/drivers/tty/serial/msm_serial.c
>> @@ -932,27 +932,12 @@ static int __init msm_console_setup(struct console 
>> *co, char *options)
>>  if (unlikely(!port->membase))
>>  return -ENXIO;
>>  
>> -msm_init_clock(port);
>> -
> 
> Hm.. doesn't the console setup happen before the port is opened though?
> I would think that we need to keep this around so that the clock is
> actually enabled before we go and write to hardware registers.
> 
>>  if (options)
>>  uart_parse_options(options, &baud, &parity, &bits, &flow);
>>  
>>  bits = 8;
>>  parity = 'n';
>>  flow = 'n';

Checked some of the driver registering console and they mostly have this
but this initialization is done when these variables are declared so
that user provided setting won't be overwritten. I think we too should
follow the same. With these variables initialized when they are declared
user's values will be retained.

> 
> I wonder if we should leave this here? Maybe we can rely on the user
> specifying the right values on the command line?
> 
>> -msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE,
>> -  UART_MR2);/* 8N1 */
>> -
>> -if (baud < 300 || baud > 115200)
>> -baud = 115200;
>> -msm_set_baud_rate(port, baud);
>> -
>> -msm_reset(port);
>> -
>> -if (msm_port->is_uartdm) {
> 
> msm_port is unused now. Please remove it in the same patch.
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] tty: serial: msm_serial: Remove duplicate code in msm_console_setup

2015-01-08 Thread Pramod Gurav
Hi Stephen,

On Friday 09 January 2015 03:16 AM, Stephen Boyd wrote:
> On 01/08/2015 01:15 AM, Pramod Gurav wrote:
>>  drivers/tty/serial/msm_serial.c |   15 ---
>>  1 file changed, 15 deletions(-)
>>
>> diff --git a/drivers/tty/serial/msm_serial.c 
>> b/drivers/tty/serial/msm_serial.c
>> index c88b522..057008d 100644
>> --- a/drivers/tty/serial/msm_serial.c
>> +++ b/drivers/tty/serial/msm_serial.c
>> @@ -932,27 +932,12 @@ static int __init msm_console_setup(struct console 
>> *co, char *options)
>>  if (unlikely(!port->membase))
>>  return -ENXIO;
>>  
>> -msm_init_clock(port);
>> -
> 
> Hm.. doesn't the console setup happen before the port is opened though?
> I would think that we need to keep this around so that the clock is
> actually enabled before we go and write to hardware registers.
Thanks. Verified this. Will undo this change.

> 
>>  if (options)
>>  uart_parse_options(options, &baud, &parity, &bits, &flow);
>>  
>>  bits = 8;
>>  parity = 'n';
>>  flow = 'n';
> 
> I wonder if we should leave this here? Maybe we can rely on the user
> specifying the right values on the command line?

Ok. Will do.
> 
>> -msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE,
>> -  UART_MR2);/* 8N1 */
>> -
>> -if (baud < 300 || baud > 115200)
>> -baud = 115200;
>> -msm_set_baud_rate(port, baud);
>> -
>> -msm_reset(port);
>> -
>> -if (msm_port->is_uartdm) {
> 
> msm_port is unused now. Please remove it in the same patch.
Sure. Thanks.
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] tty: serial: msm_serial: Remove duplicate code in msm_console_setup

2015-01-08 Thread Pramod Gurav
The changes done here are already being done somewhere else in code.
 - The function msm_init_clock() is also called while doing msm_startup
   hence removing.
 - msm_set_baud_rate() is anyway called in uart_set_options when it calls
   msm_set_termios(). msm_reset() is called when we change the baud rate.
   Hence doing away with both of these calls.
 - CR_CMD_PROTECTION_EN and CR_TX_ENABLE settings are done in msm_set_baud_rate.
   So do away with this here.

Signed-off-by: Pramod Gurav 
---

Changes since v1:
 - v1 was just removing call to msm_set_baud_rate(). Other code is removed on 
review
   comments from Stephen Boyd here [1].
 - Removed call to msm_init_clock() as it is called while doing msm_startup

Tested on ifc6410 console.

[1]: https://patchwork.kernel.org/patch/5527551/

 drivers/tty/serial/msm_serial.c |   15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index c88b522..057008d 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -932,27 +932,12 @@ static int __init msm_console_setup(struct console *co, 
char *options)
if (unlikely(!port->membase))
return -ENXIO;
 
-   msm_init_clock(port);
-
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
 
bits = 8;
parity = 'n';
flow = 'n';
-   msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE,
- UART_MR2);/* 8N1 */
-
-   if (baud < 300 || baud > 115200)
-   baud = 115200;
-   msm_set_baud_rate(port, baud);
-
-   msm_reset(port);
-
-   if (msm_port->is_uartdm) {
-   msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
-   msm_write(port, UART_CR_TX_ENABLE, UART_CR);
-   }
 
pr_info("msm_serial: console setup on port #%d\n", port->line);
 
-- 
1.7.9.5

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


Re: [PATCH] mmc: mmci: Get rid of unused variable and operations on it

2015-01-08 Thread Pramod Gurav
Hi Ulf,

Any comment on this change?

Thanks
Pramod
On Tuesday 16 December 2014 07:21 PM, Pramod Gurav wrote:
> DMA configuration has been removed from function mmci_dma_setup but the
> local mask variable was not removed. This remains unused hence remove
> it from the function and operations on it
> 
> Signed-off-by: Pramod Gurav 
> ---
>  drivers/mmc/host/mmci.c |5 -
>  1 file changed, 5 deletions(-)
> 
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index f31d702..08bbeb0 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -435,7 +435,6 @@ static void mmci_init_sg(struct mmci_host *host, struct 
> mmc_data *data)
>  static void mmci_dma_setup(struct mmci_host *host)
>  {
>   const char *rxname, *txname;
> - dma_cap_mask_t mask;
>   struct variant_data *variant = host->variant;
>  
>   host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 
> "rx");
> @@ -444,10 +443,6 @@ static void mmci_dma_setup(struct mmci_host *host)
>   /* initialize pre request cookie */
>   host->next_data.cookie = 1;
>  
> - /* Try to acquire a generic DMA engine slave channel */
> - dma_cap_zero(mask);
> - dma_cap_set(DMA_SLAVE, mask);
> -
>   /*
>* If only an RX channel is specified, the driver will
>* attempt to use it bidirectionally, however if it is
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] tty: serial: msm_serial: Remove duplicate call to msm_set_baud_rate

2014-12-22 Thread Pramod Gurav
The function 'msm_set_baud_rate' is called twice while setting up
msm console. Once in msm_console_setup and next when uart_set_options
calls port->ops->set_termios ie. msm_set_termios().

Remove the duplicate call in msm_console_setup. Tested on IFC6410
console.

Signed-off-by: Pramod Gurav 
---
 drivers/tty/serial/msm_serial.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index dbc278d..4c4a250 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -945,7 +945,6 @@ static int __init msm_console_setup(struct console *co, 
char *options)
 
if (baud < 300 || baud > 115200)
baud = 115200;
-   msm_set_baud_rate(port, baud);
 
msm_reset(port);
 
-- 
1.7.9.5

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


[PATCH] mmc: mmci: Get rid of unused variable and operations on it

2014-12-16 Thread Pramod Gurav
DMA configuration has been removed from function mmci_dma_setup but the
local mask variable was not removed. This remains unused hence remove
it from the function and operations on it

Signed-off-by: Pramod Gurav 
---
 drivers/mmc/host/mmci.c |5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index f31d702..08bbeb0 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -435,7 +435,6 @@ static void mmci_init_sg(struct mmci_host *host, struct 
mmc_data *data)
 static void mmci_dma_setup(struct mmci_host *host)
 {
const char *rxname, *txname;
-   dma_cap_mask_t mask;
struct variant_data *variant = host->variant;
 
host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 
"rx");
@@ -444,10 +443,6 @@ static void mmci_dma_setup(struct mmci_host *host)
/* initialize pre request cookie */
host->next_data.cookie = 1;
 
-   /* Try to acquire a generic DMA engine slave channel */
-   dma_cap_zero(mask);
-   dma_cap_set(DMA_SLAVE, mask);
-
/*
 * If only an RX channel is specified, the driver will
 * attempt to use it bidirectionally, however if it is
-- 
1.7.9.5

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


Re: [PATCH] drivers: Kconfig: Remove duplicate sourcing of soc folder

2014-12-08 Thread Pramod Gurav
Thanks. :-)

On Mon, Dec 8, 2014 at 7:08 PM, Tobias Klauser  wrote:
> On 2014-12-08 at 14:36:24 +0100, Pramod Gurav  
> wrote:
>> Folder soc/ was sourced twice somehow. Remove duplicate entry.
>
> I already sent a patch for this a while ago [1], though it wasn't
> applied yet.
>
> [1] http://thread.gmane.org/gmane.linux.kernel/1831623
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] drivers: Kconfig: Remove duplicate sourcing of soc folder

2014-12-08 Thread Pramod Gurav
Folder soc/ was sourced twice somehow. Remove duplicate entry.

Signed-off-by: Pramod Gurav 
---
 drivers/Kconfig |2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 1a693d3..5add358 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -132,8 +132,6 @@ source "drivers/staging/Kconfig"
 
 source "drivers/platform/Kconfig"
 
-source "drivers/soc/Kconfig"
-
 source "drivers/clk/Kconfig"
 
 source "drivers/hwspinlock/Kconfig"
-- 
1.7.9.5

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


Re: [RFC PATCH] regulator: core: do not disable regulator if boot_on is set

2014-11-25 Thread Pramod Gurav
On Tuesday 25 November 2014 04:27 PM, Lucas Stach wrote:
> Am Dienstag, den 25.11.2014, 16:23 +0530 schrieb Pramod Gurav:
>> Currently the regulator core disables the regulators which are unused
>> or whose reference count is zero or if they are configured always_on.
>> This change adds a check in this logic to see if a regulator is
>> configured as boot_on and does not disable it if found true.
>>
>> Signed-off-by: Pramod Gurav 
>>
>> ---
>>
>> The issue was found on apq8064 based IFC6410 on which a fixed regulator
>> configured as regulator-boot-on in DT and was being disabled when not in
>> use. Tested this change on this board and found working.
>>
> Um, why would this be the correct fix? regulator-boot-on just tells the
> regulator core that the bootloader might have left this regulator
> enabled. If you want it to stay on after the kernel finished init you
> need to mark it as always-on.

Thanks Lucas. Shall mark it as alway_on.
> 
>>  drivers/regulator/core.c |2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>> index cd87c0c..9f7a13f 100644
>> --- a/drivers/regulator/core.c
>> +++ b/drivers/regulator/core.c
>> @@ -4019,7 +4019,7 @@ static int __init regulator_init_complete(void)
>>  ops = rdev->desc->ops;
>>  c = rdev->constraints;
>>  
>> -if (c && c->always_on)
>> +if (c && (c->always_on || c->boot_on))
>>  continue;
>>  
>>  if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] regulator: core: do not disable regulator if boot_on is set

2014-11-25 Thread Pramod Gurav
Hi Mark,

On Tuesday 25 November 2014 04:35 PM, Mark Brown wrote:
> On Tue, Nov 25, 2014 at 04:23:23PM +0530, Pramod Gurav wrote:
>> Currently the regulator core disables the regulators which are unused
>> or whose reference count is zero or if they are configured always_on.
> 
> No, it does *not* disable them if they are configured always_on (as the
> code you're modifying shows).

Yes, thats a typo.
> 
>> This change adds a check in this logic to see if a regulator is
>> configured as boot_on and does not disable it if found true.
> 
>> -if (c && c->always_on)
>> +if (c && (c->always_on || c->boot_on))
>>  continue;
> 
> This isn't what boot_on means.  It just means that the regulator is
> expected to be enabled at initial power on, it doesn't mean it needs to
> be enabled all the time.  Otherwise there'd be no point in having a
> separate always_on flag.

Thanks for the comment. :-)
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH] regulator: core: do not disable regulator if boot_on is set

2014-11-25 Thread Pramod Gurav
Currently the regulator core disables the regulators which are unused
or whose reference count is zero or if they are configured always_on.
This change adds a check in this logic to see if a regulator is
configured as boot_on and does not disable it if found true.

Signed-off-by: Pramod Gurav 

---

The issue was found on apq8064 based IFC6410 on which a fixed regulator
configured as regulator-boot-on in DT and was being disabled when not in
use. Tested this change on this board and found working.

 drivers/regulator/core.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index cd87c0c..9f7a13f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4019,7 +4019,7 @@ static int __init regulator_init_complete(void)
ops = rdev->desc->ops;
c = rdev->constraints;
 
-   if (c && c->always_on)
+   if (c && (c->always_on || c->boot_on))
continue;
 
if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
-- 
1.7.9.5

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


Re: [PATCH v2] mmc: davinci: Fix and simplify probe failure path

2014-10-30 Thread Pramod Gurav
Thanks Ulf,

On Thu, Oct 30, 2014 at 4:38 PM, Ulf Hansson  wrote:
> On 30 October 2014 08:46, Pramod Gurav  wrote:
>> The sequence of resource release in probe failure path in this
>> driver was wrong and needed fixes to cleanly unload the driver.
>> This changes does the same by switching to managed resources and
>> fixes return path to release resource in proper sequence.
>>
>> Cc: Chris Ball 
>> Cc: Ulf Hansson 
>> Cc: linux-...@vger.kernel.org
>
> Please remove these Ccs above from the commit message. It's not needed
> when you anyway need to send the patches directly to these addresses.
Will remove Cc.

>
>> Signed-off-by: Pramod Gurav 
>> ---
..

>>
>> host = mmc_priv(mmc);
>> host->mmc = mmc;/* Important */
>> @@ -1275,15 +1273,16 @@ static int __init davinci_mmcsd_probe(struct 
>> platform_device *pdev)
>> host->txdma = r->start;
>>
>> host->mem_res = mem;
>> -   host->base = ioremap(mem->start, mem_size);
>> -   if (!host->base)
>> -   goto out;
>> +   host->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
>
> I realized that you should use devm_ioremap_resource() instead. That
> would simplify the code even more.
>
Yes, we could have used devm_ioremap_resource() but this driver stores
the return from devm_request_mem_region() in host->mem_res and uses
the same in the other part of drivers. Is there a way to work this
around?

> [...]
>
> Kind regards
> Uffe
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mfd: db8500-prcmu: check return of devm_ioremap for error

2014-10-30 Thread Pramod Gurav
Error check around return value of devm_ioremap is missing. Add the same
to avoid NULL pointer dereference.

Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Lee Jones 
Signed-off-by: Pramod Gurav 
---
 drivers/mfd/db8500-prcmu.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 193cf16..89ae8bf 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -3167,6 +3167,11 @@ static int db8500_prcmu_probe(struct platform_device 
*pdev)
}
tcdm_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
+   if (!tcdm_base) {
+   dev_err(&pdev->dev,
+   "failed to ioremap prcmu-tcdm register memory\n");
+   return -ENOENT;
+   }
 
/* Clean up the mailbox interrupts after pre-kernel code. */
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
-- 
1.7.9.5

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


[PATCH v2] mmc: davinci: Fix and simplify probe failure path

2014-10-30 Thread Pramod Gurav
The sequence of resource release in probe failure path in this
driver was wrong and needed fixes to cleanly unload the driver.
This changes does the same by switching to managed resources and
fixes return path to release resource in proper sequence.

Cc: Chris Ball 
Cc: Ulf Hansson 
Cc: linux-...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
Changes since v1:
- Dropped IS_ERR check on devm_ioremap() return.
- Fixed sequence on mmc_remove_host in fail as well as in remove function

 drivers/mmc/host/davinci_mmc.c |   91 +++-
 1 file changed, 33 insertions(+), 58 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 5d4c5e0..dc49b22 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -1242,22 +1242,20 @@ static int __init davinci_mmcsd_probe(struct 
platform_device *pdev)
return -ENOENT;
}
 
-   ret = -ENODEV;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (!r || irq == NO_IRQ)
-   goto out;
+   return -ENODEV;
 
-   ret = -EBUSY;
mem_size = resource_size(r);
-   mem = request_mem_region(r->start, mem_size, pdev->name);
+   mem = devm_request_mem_region(&pdev->dev, r->start, mem_size,
+ pdev->name);
if (!mem)
-   goto out;
+   return -EBUSY;
 
-   ret = -ENOMEM;
mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev);
if (!mmc)
-   goto out;
+   return -ENOMEM;
 
host = mmc_priv(mmc);
host->mmc = mmc;/* Important */
@@ -1275,15 +1273,16 @@ static int __init davinci_mmcsd_probe(struct 
platform_device *pdev)
host->txdma = r->start;
 
host->mem_res = mem;
-   host->base = ioremap(mem->start, mem_size);
-   if (!host->base)
-   goto out;
+   host->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
+   if (!host->base) {
+   ret = -ENOMEM;
+   goto err_ioremap;
+   }
 
-   ret = -ENXIO;
-   host->clk = clk_get(&pdev->dev, "MMCSDCLK");
+   host->clk = devm_clk_get(&pdev->dev, "MMCSDCLK");
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
-   goto out;
+   goto err_ioremap;
}
clk_enable(host->clk);
host->mmc_input_clk = clk_get_rate(host->clk);
@@ -1350,20 +1349,22 @@ static int __init davinci_mmcsd_probe(struct 
platform_device *pdev)
ret = mmc_davinci_cpufreq_register(host);
if (ret) {
dev_err(&pdev->dev, "failed to register cpufreq\n");
-   goto cpu_freq_fail;
+   goto err_cpu_freq;
}
 
ret = mmc_add_host(mmc);
if (ret < 0)
-   goto out;
+   goto err_mmc_add;
 
-   ret = request_irq(irq, mmc_davinci_irq, 0, mmc_hostname(mmc), host);
+   ret = devm_request_irq(&pdev->dev, irq, mmc_davinci_irq, 0,
+  mmc_hostname(mmc), host);
if (ret)
-   goto out;
+   goto err_request_irq;
 
if (host->sdio_irq >= 0) {
-   ret = request_irq(host->sdio_irq, mmc_davinci_sdio_irq, 0,
- mmc_hostname(mmc), host);
+   ret = devm_request_irq(&pdev->dev, host->sdio_irq,
+  mmc_davinci_sdio_irq, 0,
+  mmc_hostname(mmc), host);
if (!ret)
mmc->caps |= MMC_CAP_SDIO_IRQ;
}
@@ -1376,27 +1377,15 @@ static int __init davinci_mmcsd_probe(struct 
platform_device *pdev)
 
return 0;
 
-out:
+err_request_irq:
+   mmc_remove_host(mmc);
+err_mmc_add:
mmc_davinci_cpufreq_deregister(host);
-cpu_freq_fail:
-   if (host) {
-   davinci_release_dma_channels(host);
-
-   if (host->clk) {
-   clk_disable(host->clk);
-   clk_put(host->clk);
-   }
-
-   if (host->base)
-   iounmap(host->base);
-   }
-
-   if (mmc)
-   mmc_free_host(mmc);
-
-   if (mem)
-   release_resource(mem);
-
+err_cpu_freq:
+   davinci_release_dma_channels(host);
+   clk_disable(host->clk);
+err_ioremap:
+   mmc_free_host(mmc);
dev_dbg(&pdev->dev, "probe err %d\n", ret);
 
return ret;
@@ -1406,25 +1395,11 @@ static int __exit davinci_mmcsd_remove(struct 
platform_device *pdev)
 {
struct mmc_davinci_host *host = platform_get_drvdata(pdev);
 
-   if (host) {

Re: [PATCH] Input: nomadik-ske-keypad: Switch to using managed resources

2014-10-28 Thread Pramod Gurav
Hi Dmitry,
Is this change okey?

On Wed, Oct 8, 2014 at 4:20 PM, Pramod Gurav
 wrote:
> This change switches to using devm_* APIs to allocate  resources.
> This helps to simplify failure path in probe function as well as
> remove function.
>
> Cc: Dmitry Torokhov 
> Cc: linux-in...@vger.kernel.org
> Signed-off-by: Pramod Gurav 
> ---
>  drivers/input/keyboard/nomadik-ske-keypad.c |   63 
> +--
>  1 file changed, 20 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c 
> b/drivers/input/keyboard/nomadik-ske-keypad.c
> index 63332e2..95ac317 100644
> --- a/drivers/input/keyboard/nomadik-ske-keypad.c
> +++ b/drivers/input/keyboard/nomadik-ske-keypad.c
> @@ -247,12 +247,11 @@ static int __init ske_keypad_probe(struct 
> platform_device *pdev)
> return -EINVAL;
> }
>
> -   keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
> +   keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> input = input_allocate_device();
> if (!keypad || !input) {
> dev_err(&pdev->dev, "failed to allocate keypad memory\n");
> -   error = -ENOMEM;
> -   goto err_free_mem;
> +   return -ENOMEM;
> }
>
> keypad->irq = irq;
> @@ -260,31 +259,29 @@ static int __init ske_keypad_probe(struct 
> platform_device *pdev)
> keypad->input = input;
> spin_lock_init(&keypad->ske_keypad_lock);
>
> -   if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
> +   if (!devm_request_mem_region(&pdev->dev, res->start,
> +resource_size(res), pdev->name)) {
> dev_err(&pdev->dev, "failed to request I/O memory\n");
> -   error = -EBUSY;
> -   goto err_free_mem;
> +   return -EBUSY;
> }
>
> -   keypad->reg_base = ioremap(res->start, resource_size(res));
> +   keypad->reg_base = devm_ioremap(&pdev->dev, res->start,
> +   resource_size(res));
> if (!keypad->reg_base) {
> dev_err(&pdev->dev, "failed to remap I/O memory\n");
> -   error = -ENXIO;
> -   goto err_free_mem_region;
> +   return -ENXIO;
> }
>
> -   keypad->pclk = clk_get(&pdev->dev, "apb_pclk");
> +   keypad->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
> if (IS_ERR(keypad->pclk)) {
> dev_err(&pdev->dev, "failed to get pclk\n");
> -   error = PTR_ERR(keypad->pclk);
> -   goto err_iounmap;
> +   return PTR_ERR(keypad->pclk);
> }
>
> -   keypad->clk = clk_get(&pdev->dev, NULL);
> +   keypad->clk = devm_clk_get(&pdev->dev, NULL);
> if (IS_ERR(keypad->clk)) {
> dev_err(&pdev->dev, "failed to get clk\n");
> -   error = PTR_ERR(keypad->clk);
> -   goto err_pclk;
> +   return PTR_ERR(keypad->clk);
> }
>
> input->id.bustype = BUS_HOST;
> @@ -296,7 +293,7 @@ static int __init ske_keypad_probe(struct platform_device 
> *pdev)
>keypad->keymap, input);
> if (error) {
> dev_err(&pdev->dev, "Failed to build keymap\n");
> -   goto err_clk;
> +   return error;
> }
>
> input_set_capability(input, EV_MSC, MSC_SCAN);
> @@ -306,7 +303,7 @@ static int __init ske_keypad_probe(struct platform_device 
> *pdev)
> error = clk_prepare_enable(keypad->pclk);
> if (error) {
> dev_err(&pdev->dev, "Failed to prepare/enable pclk\n");
> -   goto err_clk;
> +   return error;
> }
>
> error = clk_prepare_enable(keypad->clk);
> @@ -326,8 +323,9 @@ static int __init ske_keypad_probe(struct platform_device 
> *pdev)
> goto err_clk_disable;
> }
>
> -   error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
> -IRQF_ONESHOT, "ske-keypad", keypad);
> +   error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL,
> + ske_keypad_irq, IRQF_ONESHOT,
> + "ske-keypad", keypad);
> if 

Re: [PATCH] mmc: sdhci-pxav3: Fix Sparse warning of duplicate set_uhs_signaling entry

2014-10-28 Thread Pramod Gurav
Hi Ulf,

Is this good to go?

On Mon, Sep 29, 2014 at 6:55 PM, Pramod Gurav
 wrote:
> This fixes below sparse warning:
> drivers/mmc/host/sdhci-pxav3.c:227:10: warning: Initializer entry defined 
> twice
> drivers/mmc/host/sdhci-pxav3.c:232:10:   also defined here
>
> by removing duplicate initialization of .set_uhs_signaling in
> struct sdhci_ops. Also does away with duplcated function.
>
> Cc: Russell King 
> Cc: Ulf Hansson 
> Cc: Chris Ball 
> Cc: linux-...@vger.kernel.org
> Signed-off-by: Pramod Gurav 
> ---
>  drivers/mmc/host/sdhci-pxav3.c |   37 -
>  1 file changed, 37 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index 6f842fb..fd93e60 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -186,45 +186,8 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
> *host, u8 power_mode)
> pxa->power_mode = power_mode;
>  }
>
> -static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int 
> uhs)
> -{
> -   u16 ctrl_2;
> -
> -   /*
> -* Set V18_EN -- UHS modes do not work without this.
> -* does not change signaling voltage
> -*/
> -   ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
> -
> -   /* Select Bus Speed Mode for host */
> -   ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
> -   switch (uhs) {
> -   case MMC_TIMING_UHS_SDR12:
> -   ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
> -   break;
> -   case MMC_TIMING_UHS_SDR25:
> -   ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
> -   break;
> -   case MMC_TIMING_UHS_SDR50:
> -   ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
> -   break;
> -   case MMC_TIMING_UHS_SDR104:
> -   ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
> -   break;
> -   case MMC_TIMING_UHS_DDR50:
> -   ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
> -   break;
> -   }
> -
> -   sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
> -   dev_dbg(mmc_dev(host->mmc),
> -   "%s uhs = %d, ctrl_2 = %04X\n",
> -   __func__, uhs, ctrl_2);
> -}
> -
>  static const struct sdhci_ops pxav3_sdhci_ops = {
> .set_clock = sdhci_set_clock,
> -   .set_uhs_signaling = pxav3_set_uhs_signaling,
> .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
> .get_max_clock = sdhci_pltfm_clk_get_max_clock,
> .set_bus_width = sdhci_set_bus_width,
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] ssb: Fix Sparse error in main

2014-10-28 Thread Pramod Gurav
Michael had suggested to do away with this function if not being used.
Good to go?

Michale can you provide acked-by?

On Wed, Oct 1, 2014 at 10:58 PM, Pramod Gurav
 wrote:
> This change fixes below sparse error:
> drivers/ssb/main.c:94:16: warning: symbol 'ssb_sdio_func_to_bus'
> was not declared. Should it be static?
>
> Cc: Michael Buesch 
> Cc: net...@vger.kernel.org
> Signed-off-by: Pramod Gurav 
> ---
> Changes since v1:
> Removed the function as it is not called anywhere in the kernel
> as per suggestion from Michael Buesch.
>
>  drivers/ssb/main.c | 19 ---
>  1 file changed, 19 deletions(-)
>
> diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
> index 2fead38..1e180c4 100644
> --- a/drivers/ssb/main.c
> +++ b/drivers/ssb/main.c
> @@ -90,25 +90,6 @@ found:
>  }
>  #endif /* CONFIG_SSB_PCMCIAHOST */
>
> -#ifdef CONFIG_SSB_SDIOHOST
> -struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
> -{
> -   struct ssb_bus *bus;
> -
> -   ssb_buses_lock();
> -   list_for_each_entry(bus, &buses, list) {
> -   if (bus->bustype == SSB_BUSTYPE_SDIO &&
> -   bus->host_sdio == func)
> -   goto found;
> -   }
> -   bus = NULL;
> -found:
> -   ssb_buses_unlock();
> -
> -   return bus;
> -}
> -#endif /* CONFIG_SSB_SDIOHOST */
> -
>  int ssb_for_each_bus_call(unsigned long data,
>   int (*func)(struct ssb_bus *bus, unsigned long 
> data))
>  {
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] gpio: Switch to using managed resources with devm_

2014-10-21 Thread Pramod Gurav
On Tue, Oct 21, 2014 at 2:22 PM, Linus Walleij  wrote:
> On Wed, Oct 1, 2014 at 12:46 PM, Pramod Gurav
>  wrote:
>
>> This change switches to devm_request_region to request region
>> and hence simplifies the module unload and does away with
>> release_region in remove function.
>>
>> Cc: Linus Walleij 
>> Cc: Alexandre Courbot 
>> Cc: linux-g...@vger.kernel.org
>> Signed-off-by: Pramod Gurav 
>
> Patch applied with augmented subject.

Had sent v2 of this with change in subject. But thanks for the manual
change and applying.
>
> Yours,
> Linus Walleij
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] ARM: DT: apq8064: Add Support for SD Card Detect for ifc6410 board

2014-10-20 Thread Pramod Gurav
This changes muxes in gpio26 pin to function as gpio and adds support
for sd card detect for apq8064 based IFC6410 board.

Cc: Rob Herring 
Cc: Pawel Moll 
Cc: Mark Rutland 
Cc: Ian Campbell 
Cc: Kumar Gala 
Cc: Russell King 
Cc: Srinivas Kandagatla 

Signed-off-by: Pramod Gurav 
---

Changes since v2:
 - Replaced hardcode value with GPIO_ACTIVE_LOW

 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts |   12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts 
b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index b396c83..e641001 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -1,4 +1,5 @@
 #include "qcom-apq8064-v2.0.dtsi"
+#include 
 
 / {
model = "Qualcomm APQ8064/IFC6410";
@@ -12,6 +13,14 @@
function = "gsbi1";
};
};
+
+   card_detect: card_detect {
+   mux {
+   pins = "gpio26";
+   function = "gpio";
+   bias-disable;
+   };
+   };
};
 
gsbi@1244 {
@@ -49,6 +58,9 @@
/* External micro SD card */
sdcc3: sdcc@1218 {
status = "okay";
+   pinctrl-names   = "default";
+   pinctrl-0   = <&card_detect>;
+   cd-gpios= <&tlmm_pinmux 26 
GPIO_ACTIVE_LOW>;
};
/* WLAN */
sdcc4: sdcc@121c {
-- 
1.7.9.5

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


Re: [PATCH] ARM: DT: apq8064: Add Support for SD Card Detect for ifc6410 board

2014-10-20 Thread Pramod Gurav
+linux-arm-msm

On Monday 20 October 2014 05:09 PM, Pramod Gurav wrote:
> This changes muxes in gpio26 pin to function as gpio and adds support
> for sd card detect for apq8064 based IFC6410 board.
> 
> Cc: Rob Herring 
> Cc: Pawel Moll 
> Cc: Mark Rutland 
> Cc: Ian Campbell 
> Cc: Kumar Gala 
> Cc: Russell King 
> Cc: Srinivas Kandagatla 
> 
> Signed-off-by: Pramod Gurav 
> 
> ---
>  arch/arm/boot/dts/qcom-apq8064-ifc6410.dts |   11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts 
> b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> index b396c83..bf6262f 100644
> --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> @@ -12,6 +12,14 @@
>   function = "gsbi1";
>   };
>   };
> +
> + card_detect: card_detect {
> + mux {
> + pins = "gpio26";
> + function = "gpio";
> + bias-disable;
> + };
> + };
>   };
>  
>   gsbi@1244 {
> @@ -49,6 +57,9 @@
>   /* External micro SD card */
>   sdcc3: sdcc@1218 {
>   status = "okay";
> + pinctrl-names   = "default";
> + pinctrl-0   = <&card_detect>;
> + cd-gpios= <&tlmm_pinmux 26 1>;
>   };
>   /* WLAN */
>   sdcc4: sdcc@121c {
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ARM: DT: apq8064: Add Support for SD Card Detect for ifc6410 board

2014-10-20 Thread Pramod Gurav
This changes muxes in gpio26 pin to function as gpio and adds support
for sd card detect for apq8064 based IFC6410 board.

Cc: Rob Herring 
Cc: Pawel Moll 
Cc: Mark Rutland 
Cc: Ian Campbell 
Cc: Kumar Gala 
Cc: Russell King 
Cc: Srinivas Kandagatla 

Signed-off-by: Pramod Gurav 

---
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts 
b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index b396c83..bf6262f 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -12,6 +12,14 @@
function = "gsbi1";
};
};
+
+   card_detect: card_detect {
+   mux {
+   pins = "gpio26";
+   function = "gpio";
+   bias-disable;
+   };
+   };
};
 
gsbi@1244 {
@@ -49,6 +57,9 @@
/* External micro SD card */
sdcc3: sdcc@1218 {
status = "okay";
+   pinctrl-names   = "default";
+   pinctrl-0   = <&card_detect>;
+   cd-gpios= <&tlmm_pinmux 26 1>;
};
/* WLAN */
sdcc4: sdcc@121c {
-- 
1.7.9.5

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


[PATCH v3] thermal: ti-soc-thermal: Switch to using managed resources

2014-10-09 Thread Pramod Gurav
This change switches to managed resource APIs to allocated resources
such as irq, clock. Hence does away with release statements of the
same resorces in error lables and remove function.

Cc: Eduardo Valentin 
Cc: Zhang Rui 
Cc: linux...@vger.kernel.org
Signed-off-by: Pramod Gurav 

---
Changes since v2:
- fix failure path of clk_get_rate by returning error.
Change since v1:
- Passing struct device to devm_clk_get was missing. Fix the same in v2.

 drivers/thermal/ti-soc-thermal/ti-bandgap.c |   58 ---
 1 file changed, 16 insertions(+), 42 deletions(-)

diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c 
b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 634b6ce..22ad68e 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -1060,7 +1060,7 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
int status;
 
/* Request for gpio_86 line */
-   status = gpio_request(gpio_nr, "tshut");
+   status = devm_gpio_request(&pdev->dev, gpio_nr, "tshut");
if (status < 0) {
dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
return status;
@@ -1071,14 +1071,13 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
return status;
}
 
-   status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
-IRQF_TRIGGER_RISING, "tshut", NULL);
-   if (status) {
-   gpio_free(gpio_nr);
+   status = devm_request_irq(&pdev->dev, gpio_to_irq(gpio_nr),
+ ti_bandgap_tshut_irq_handler,
+ IRQF_TRIGGER_RISING, "tshut", NULL);
+   if (status)
dev_err(bgp->dev, "request irq failed for TSHUT");
-   }
 
-   return 0;
+   return status;
 }
 
 /**
@@ -1104,16 +1103,14 @@ static int ti_bandgap_talert_init(struct ti_bandgap 
*bgp,
dev_err(&pdev->dev, "get_irq failed\n");
return bgp->irq;
}
-   ret = request_threaded_irq(bgp->irq, NULL,
+   ret = devm_request_threaded_irq(&pdev->dev, bgp->irq, NULL,
   ti_bandgap_talert_irq_handler,
   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
   "talert", bgp);
-   if (ret) {
+   if (ret)
dev_err(&pdev->dev, "Request threaded irq failed.\n");
-   return ret;
-   }
 
-   return 0;
+   return ret;
 }
 
 static const struct of_device_id of_ti_bandgap_match[];
@@ -1212,21 +1209,17 @@ int ti_bandgap_probe(struct platform_device *pdev)
}
}
 
-   bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
-   ret = IS_ERR(bgp->fclock);
-   if (ret) {
+   bgp->fclock = devm_clk_get(&pdev->dev, bgp->conf->fclock_name);
+   if (IS_ERR(bgp->fclock)) {
dev_err(&pdev->dev, "failed to request fclock reference\n");
-   ret = PTR_ERR(bgp->fclock);
-   goto free_irqs;
+   return PTR_ERR(bgp->fclock);
}
 
-   bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
-   ret = IS_ERR(bgp->div_clk);
-   if (ret) {
+   bgp->div_clk = devm_clk_get(&pdev->dev, bgp->conf->div_ck_name);
+   if (IS_ERR(bgp->div_clk)) {
dev_err(&pdev->dev,
"failed to request div_ts_ck clock ref\n");
-   ret = PTR_ERR(bgp->div_clk);
-   goto free_irqs;
+   return PTR_ERR(bgp->div_clk);
}
 
for (i = 0; i < bgp->conf->sensor_count; i++) {
@@ -1249,9 +1242,8 @@ int ti_bandgap_probe(struct platform_device *pdev)
  bgp->conf->sensors[0].ts_data->max_freq);
if (clk_rate < bgp->conf->sensors[0].ts_data->min_freq ||
clk_rate <= 0) {
-   ret = -ENODEV;
dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
-   goto put_clks;
+   return -ENODEV;
}
 
ret = clk_set_rate(bgp->div_clk, clk_rate);
@@ -1357,14 +1349,6 @@ remove_sensors:
 disable_clk:
if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
clk_disable_unprepare(bgp->fclock);
-put_clks:
-   clk_put(bgp->fclock);
-   clk_put(bgp->div_clk);
-free_irqs:
-   if (TI_BANDGAP_HAS(bgp, TSHUT)) {
-   free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
-   gpio_free(bgp->tshut_gpio);
-   }
 
return ret;
 }
@@ -1388,16 +1372,6 @@ int ti_bandgap_remove(struct platform_device *pdev)
 
if (TI_BANDGAP_H

[PATCH] thermal: ti-soc-thermal: Switch to using managed resources

2014-10-09 Thread Pramod Gurav
This change switches to managed resource APIs to allocated resources
such as irq, clock. Hence does away with release statements of the
same resorces in error lables and remove function.

Cc: Eduardo Valentin 
Cc: Zhang Rui 
Cc: linux...@vger.kernel.org
Signed-off-by: Pramod Gurav 

---
Changes since v2:
- fix failure path of clk_get_rate by returning error.
Change since v1:
- Passing struct device to devm_clk_get was missing. Fix the same in v2.

 drivers/thermal/ti-soc-thermal/ti-bandgap.c |   58 ---
 1 file changed, 16 insertions(+), 42 deletions(-)

diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c 
b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 634b6ce..22ad68e 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -1060,7 +1060,7 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
int status;
 
/* Request for gpio_86 line */
-   status = gpio_request(gpio_nr, "tshut");
+   status = devm_gpio_request(&pdev->dev, gpio_nr, "tshut");
if (status < 0) {
dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
return status;
@@ -1071,14 +1071,13 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
return status;
}
 
-   status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
-IRQF_TRIGGER_RISING, "tshut", NULL);
-   if (status) {
-   gpio_free(gpio_nr);
+   status = devm_request_irq(&pdev->dev, gpio_to_irq(gpio_nr),
+ ti_bandgap_tshut_irq_handler,
+ IRQF_TRIGGER_RISING, "tshut", NULL);
+   if (status)
dev_err(bgp->dev, "request irq failed for TSHUT");
-   }
 
-   return 0;
+   return status;
 }
 
 /**
@@ -1104,16 +1103,14 @@ static int ti_bandgap_talert_init(struct ti_bandgap 
*bgp,
dev_err(&pdev->dev, "get_irq failed\n");
return bgp->irq;
}
-   ret = request_threaded_irq(bgp->irq, NULL,
+   ret = devm_request_threaded_irq(&pdev->dev, bgp->irq, NULL,
   ti_bandgap_talert_irq_handler,
   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
   "talert", bgp);
-   if (ret) {
+   if (ret)
dev_err(&pdev->dev, "Request threaded irq failed.\n");
-   return ret;
-   }
 
-   return 0;
+   return ret;
 }
 
 static const struct of_device_id of_ti_bandgap_match[];
@@ -1212,21 +1209,17 @@ int ti_bandgap_probe(struct platform_device *pdev)
}
}
 
-   bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
-   ret = IS_ERR(bgp->fclock);
-   if (ret) {
+   bgp->fclock = devm_clk_get(&pdev->dev, bgp->conf->fclock_name);
+   if (IS_ERR(bgp->fclock)) {
dev_err(&pdev->dev, "failed to request fclock reference\n");
-   ret = PTR_ERR(bgp->fclock);
-   goto free_irqs;
+   return PTR_ERR(bgp->fclock);
}
 
-   bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
-   ret = IS_ERR(bgp->div_clk);
-   if (ret) {
+   bgp->div_clk = devm_clk_get(&pdev->dev, bgp->conf->div_ck_name);
+   if (IS_ERR(bgp->div_clk)) {
dev_err(&pdev->dev,
"failed to request div_ts_ck clock ref\n");
-   ret = PTR_ERR(bgp->div_clk);
-   goto free_irqs;
+   return PTR_ERR(bgp->div_clk);
}
 
for (i = 0; i < bgp->conf->sensor_count; i++) {
@@ -1249,9 +1242,8 @@ int ti_bandgap_probe(struct platform_device *pdev)
  bgp->conf->sensors[0].ts_data->max_freq);
if (clk_rate < bgp->conf->sensors[0].ts_data->min_freq ||
clk_rate <= 0) {
-   ret = -ENODEV;
dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
-   goto put_clks;
+   return -ENODEV;
}
 
ret = clk_set_rate(bgp->div_clk, clk_rate);
@@ -1357,14 +1349,6 @@ remove_sensors:
 disable_clk:
if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
clk_disable_unprepare(bgp->fclock);
-put_clks:
-   clk_put(bgp->fclock);
-   clk_put(bgp->div_clk);
-free_irqs:
-   if (TI_BANDGAP_HAS(bgp, TSHUT)) {
-   free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
-   gpio_free(bgp->tshut_gpio);
-   }
 
return ret;
 }
@@ -1388,16 +1372,6 @@ int ti_bandgap_remove(struct platform_device *pdev)
 
if (TI_BANDGAP_H

Re: [PATCH v2] thermal: ti-soc-thermal: Switch to using managed resources

2014-10-09 Thread Pramod Gurav
On Thu, Oct 9, 2014 at 2:50 AM, Vladimir Zapolskiy  wrote:
> On 07.10.2014 10:11, Pramod Gurav wrote:
>>
>> This change switches to managed resource APIs to allocated resources
>> such as irq, clock. Hence does away with release statements of the
>> same resorces in error lables and remove function.
>>
>> Cc: Eduardo Valentin
>> Cc: Zhang Rui
>> Cc: linux...@vger.kernel.org
>> Signed-off-by: Pramod Gurav
>> ---
>> Change since v1:
>>
>> Passing struct device to devm_clk_get was missing. Fix the same in v2.
>>
>>   drivers/thermal/ti-soc-thermal/ti-bandgap.c |   46
>> +++
>>   1 file changed, 12 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
>> b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
>> index 634b6ce..22013ef 100644
>> --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
>> +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
>> @@ -1060,7 +1060,7 @@ static int ti_bandgap_tshut_init(struct ti_bandgap
>> *bgp,
>> int status;
>>
>> /* Request for gpio_86 line */
>> -   status = gpio_request(gpio_nr, "tshut");
>> +   status = devm_gpio_request(&pdev->dev, gpio_nr, "tshut");
>> if (status<  0) {
>> dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n",
>> 86);
>> return status;
>> @@ -1071,11 +1071,12 @@ static int ti_bandgap_tshut_init(struct ti_bandgap
>> *bgp,
>> return status;
>> }
>>
>> -   status = request_irq(gpio_to_irq(gpio_nr),
>> ti_bandgap_tshut_irq_handler,
>> -IRQF_TRIGGER_RISING, "tshut", NULL);
>> +   status = devm_request_irq(&pdev->dev, gpio_to_irq(gpio_nr),
>> + ti_bandgap_tshut_irq_handler,
>> + IRQF_TRIGGER_RISING, "tshut", NULL);
>> if (status) {
>> -   gpio_free(gpio_nr);
>> dev_err(bgp->dev, "request irq failed for TSHUT");
>> +   return status;
>> }
>>
>> return 0;
>
>
> Remove two more lines:
>
> if (status)
> dev_err(bgp->dev, "request irq failed for TSHUT");
>
> return status;
Thanks fore comment. Will do this here. Same can be done in another
function which requests one more irq.

>
>
>> @@ -1104,7 +1105,7 @@ static int ti_bandgap_talert_init(struct ti_bandgap
>> *bgp,
>> dev_err(&pdev->dev, "get_irq failed\n");
>> return bgp->irq;
>> }
>> -   ret = request_threaded_irq(bgp->irq, NULL,
>> +   ret = devm_request_threaded_irq(&pdev->dev, bgp->irq, NULL,
>>ti_bandgap_talert_irq_handler,
>>IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
>>"talert", bgp);
>> @@ -1212,21 +1213,17 @@ int ti_bandgap_probe(struct platform_device *pdev)
>> }
>> }
>>
>> -   bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
>> -   ret = IS_ERR(bgp->fclock);
>> -   if (ret) {
>> +   bgp->fclock = devm_clk_get(&pdev->dev, NULL,
>> bgp->conf->fclock_name);
>> +   if (IS_ERR(bgp->fclock)) {
>> dev_err(&pdev->dev, "failed to request fclock
>> reference\n");
>> -   ret = PTR_ERR(bgp->fclock);
>> -   goto free_irqs;
>> +   return PTR_ERR(bgp->fclock);
>> }
>>
>> -   bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
>> -   ret = IS_ERR(bgp->div_clk);
>> -   if (ret) {
>> +   bgp->div_clk = devm_clk_get(&pdev->dev, NULL,
>> bgp->conf->div_ck_name);
>> +   if (IS_ERR(bgp->div_clk)) {
>> dev_err(&pdev->dev,
>> "failed to request div_ts_ck clock ref\n");
>> -   ret = PTR_ERR(bgp->div_clk);
>> -   goto free_irqs;
>> +   return PTR_ERR(bgp->div_clk);
>> }
>>
>> for (i = 0; i<  bgp->conf->sensor_count; i++) {
>> @@ -1251,7 +1248,6 @@ int ti_bandgap_probe(struct platform_device *pdev)
>> clk_rate<= 0) {
>> ret = -ENODEV;
>>  

[PATCH] Input: nomadik-ske-keypad: Switch to using managed resources

2014-10-08 Thread Pramod Gurav
This change switches to using devm_* APIs to allocate  resources.
This helps to simplify failure path in probe function as well as
remove function.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/nomadik-ske-keypad.c |   63 +--
 1 file changed, 20 insertions(+), 43 deletions(-)

diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c 
b/drivers/input/keyboard/nomadik-ske-keypad.c
index 63332e2..95ac317 100644
--- a/drivers/input/keyboard/nomadik-ske-keypad.c
+++ b/drivers/input/keyboard/nomadik-ske-keypad.c
@@ -247,12 +247,11 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
-   keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
+   keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
input = input_allocate_device();
if (!keypad || !input) {
dev_err(&pdev->dev, "failed to allocate keypad memory\n");
-   error = -ENOMEM;
-   goto err_free_mem;
+   return -ENOMEM;
}
 
keypad->irq = irq;
@@ -260,31 +259,29 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
keypad->input = input;
spin_lock_init(&keypad->ske_keypad_lock);
 
-   if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+   if (!devm_request_mem_region(&pdev->dev, res->start,
+resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
-   error = -EBUSY;
-   goto err_free_mem;
+   return -EBUSY;
}
 
-   keypad->reg_base = ioremap(res->start, resource_size(res));
+   keypad->reg_base = devm_ioremap(&pdev->dev, res->start,
+   resource_size(res));
if (!keypad->reg_base) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
-   error = -ENXIO;
-   goto err_free_mem_region;
+   return -ENXIO;
}
 
-   keypad->pclk = clk_get(&pdev->dev, "apb_pclk");
+   keypad->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
if (IS_ERR(keypad->pclk)) {
dev_err(&pdev->dev, "failed to get pclk\n");
-   error = PTR_ERR(keypad->pclk);
-   goto err_iounmap;
+   return PTR_ERR(keypad->pclk);
}
 
-   keypad->clk = clk_get(&pdev->dev, NULL);
+   keypad->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get clk\n");
-   error = PTR_ERR(keypad->clk);
-   goto err_pclk;
+   return PTR_ERR(keypad->clk);
}
 
input->id.bustype = BUS_HOST;
@@ -296,7 +293,7 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
   keypad->keymap, input);
if (error) {
dev_err(&pdev->dev, "Failed to build keymap\n");
-   goto err_clk;
+   return error;
}
 
input_set_capability(input, EV_MSC, MSC_SCAN);
@@ -306,7 +303,7 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
error = clk_prepare_enable(keypad->pclk);
if (error) {
dev_err(&pdev->dev, "Failed to prepare/enable pclk\n");
-   goto err_clk;
+   return error;
}
 
error = clk_prepare_enable(keypad->clk);
@@ -326,8 +323,9 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
goto err_clk_disable;
}
 
-   error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
-IRQF_ONESHOT, "ske-keypad", keypad);
+   error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL,
+ ske_keypad_irq, IRQF_ONESHOT,
+ "ske-keypad", keypad);
if (error) {
dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
goto err_clk_disable;
@@ -337,7 +335,7 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
if (error) {
dev_err(&pdev->dev,
"unable to register input device: %d\n", error);
-   goto err_free_irq;
+   goto err_clk_disable;
}
 
if (plat->wakeup_enable)
@@ -347,45 +345,24 @@ static int __init ske_keypad_probe(struct platform_device 
*pdev)
 

[PATCH] Input: pxa27x_keypad: Switch to using managed resources

2014-10-08 Thread Pramod Gurav
This change switches to using devm_* APIs to allocate  resources.
This helps to simplify failure path in probe function and module
unloading and does away with remove function.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/pxa27x_keypad.c |   69 +---
 1 file changed, 18 insertions(+), 51 deletions(-)

diff --git a/drivers/input/keyboard/pxa27x_keypad.c 
b/drivers/input/keyboard/pxa27x_keypad.c
index a15063b..719e44e 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -741,37 +742,36 @@ static int pxa27x_keypad_probe(struct platform_device 
*pdev)
return -ENXIO;
}
 
-   keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
-   input_dev = input_allocate_device();
+   keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad),
+ GFP_KERNEL);
+   input_dev = devm_input_allocate_device(&pdev->dev);
if (!keypad || !input_dev) {
dev_err(&pdev->dev, "failed to allocate memory\n");
-   error = -ENOMEM;
-   goto failed_free;
+   return -ENOMEM;
}
 
keypad->pdata = pdata;
keypad->input_dev = input_dev;
keypad->irq = irq;
 
-   res = request_mem_region(res->start, resource_size(res), pdev->name);
+   res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name);
if (res == NULL) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
-   error = -EBUSY;
-   goto failed_free;
+   return -EBUSY;
}
 
-   keypad->mmio_base = ioremap(res->start, resource_size(res));
+   keypad->mmio_base = devm_ioremap(&pdev->dev, res->start,
+resource_size(res));
if (keypad->mmio_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
-   error = -ENXIO;
-   goto failed_free_mem;
+   return -ENXIO;
}
 
-   keypad->clk = clk_get(&pdev->dev, NULL);
+   keypad->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get keypad clock\n");
-   error = PTR_ERR(keypad->clk);
-   goto failed_free_io;
+   return PTR_ERR(keypad->clk);
}
 
input_dev->name = pdev->name;
@@ -802,7 +802,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
}
if (error) {
dev_err(&pdev->dev, "failed to build keycode\n");
-   goto failed_put_clk;
+   return error;
}
 
keypad->row_shift = get_count_order(pdata->matrix_key_cols);
@@ -812,56 +812,24 @@ static int pxa27x_keypad_probe(struct platform_device 
*pdev)
input_dev->evbit[0] |= BIT_MASK(EV_REL);
}
 
-   error = request_irq(irq, pxa27x_keypad_irq_handler, 0,
-   pdev->name, keypad);
+   error = devm_request_irq(&pdev->dev, irq, pxa27x_keypad_irq_handler,
+0, pdev->name, keypad);
if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n");
-   goto failed_put_clk;
+   return error;
}
 
/* Register the input device */
error = input_register_device(input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
-   goto failed_free_irq;
+   return error;
}
 
platform_set_drvdata(pdev, keypad);
device_init_wakeup(&pdev->dev, 1);
 
return 0;
-
-failed_free_irq:
-   free_irq(irq, keypad);
-failed_put_clk:
-   clk_put(keypad->clk);
-failed_free_io:
-   iounmap(keypad->mmio_base);
-failed_free_mem:
-   release_mem_region(res->start, resource_size(res));
-failed_free:
-   input_free_device(input_dev);
-   kfree(keypad);
-   return error;
-}
-
-static int pxa27x_keypad_remove(struct platform_device *pdev)
-{
-   struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
-   struct resource *res;
-
-   free_irq(keypad->irq, keypad);
-   clk_put(keypad->clk);
-
-   input_unregister_device(keypad->input_dev);
-   iounmap(keypad->mmio_base);
-
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   release_mem_region(res->start, resource_size(res));
-
-   kfree(keypad);
-
-   re

Re: [PATCH] Input: adp5588-keys: cancel workqueue in failure path

2014-10-08 Thread Pramod Gurav
On Wed, Oct 8, 2014 at 3:48 PM, Pramod Gurav  wrote:
> Hi Dmitry,
>
> On Tue, Oct 7, 2014 at 10:08 PM, Dmitry Torokhov
>

..

> Thanks. I saw the change in your tree. Shouldn't
> cancel_delayed_work_sync(&kpad->work) be called under label
> err_free_mem so that it will executed in case adp5588_read,
> input_register_device, request_irq etc.
> Or else we will still have workqueue instance hanging around.
>

Sorry, Should have read Michael's reply more carefully. I get the
reason behind cancelling workquequq after freeing irq.


-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Input: adp5588-keys: cancel workqueue in failure path

2014-10-08 Thread Pramod Gurav
Hi Dmitry,

On Tue, Oct 7, 2014 at 10:08 PM, Dmitry Torokhov
 wrote:
> On Tue, Oct 07, 2014 at 01:00:49PM +0530, Pramod Gurav wrote:
>> This change introduces a label to call cancel_delayed_work_sync in
>> failure path.
>>
>> Cc: Michael Hennerich 
>> Cc: Dmitry Torokhov 
>> Cc: linux-in...@vger.kernel.org
>> Signed-off-by: Pramod Gurav 
>> ---
>>  drivers/input/keyboard/adp5588-keys.c |4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/input/keyboard/adp5588-keys.c 
>> b/drivers/input/keyboard/adp5588-keys.c
>> index 5ef7fcf..b494062 100644
>> --- a/drivers/input/keyboard/adp5588-keys.c
>> +++ b/drivers/input/keyboard/adp5588-keys.c
>> @@ -559,7 +559,7 @@ static int adp5588_probe(struct i2c_client *client,
>>   error = input_register_device(input);
>>   if (error) {
>>   dev_err(&client->dev, "unable to register input device\n");
>> - goto err_free_mem;
>> + goto err_delayed_work;
>>   }
>>
>>   error = request_irq(client->irq, adp5588_irq,
>> @@ -592,6 +592,8 @@ static int adp5588_probe(struct i2c_client *client,
>>   err_unreg_dev:
>>   input_unregister_device(input);
>>   input = NULL;
>> + err_delayed_work:
>> + cancel_delayed_work_sync(&kpad->work);
>
> We do not need to have a separate label, just need to cancel workqueue
> after freeing interrupt. I adjusted the patch and applied.
>
Thanks. I saw the change in your tree. Shouldn't
cancel_delayed_work_sync(&kpad->work) be called under label
err_free_mem so that it will executed in case adp5588_read,
input_register_device, request_irq etc.
Or else we will still have workqueue instance hanging around.

> Thanks.
>
> --
> Dmitry
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks and Regards
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Input: mpr121: Switch to using managed resources

2014-10-07 Thread Pramod Gurav
This change switches to using devm_* managed resources APIs to
request the resources in probe to simplify probe error path and
module unloading and does away with remove function.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/mpr121_touchkey.c |   35 +++---
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/drivers/input/keyboard/mpr121_touchkey.c 
b/drivers/input/keyboard/mpr121_touchkey.c
index 009c822..49c578e 100644
--- a/drivers/input/keyboard/mpr121_touchkey.c
+++ b/drivers/input/keyboard/mpr121_touchkey.c
@@ -214,12 +214,12 @@ static int mpr_touchkey_probe(struct i2c_client *client,
return -EINVAL;
}
 
-   mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL);
-   input_dev = input_allocate_device();
+   mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121),
+ GFP_KERNEL);
+   input_dev = devm_input_allocate_device(&client->dev);
if (!mpr121 || !input_dev) {
dev_err(&client->dev, "Failed to allocate memory\n");
-   error = -ENOMEM;
-   goto err_free_mem;
+   return -ENOMEM;
}
 
mpr121->client = client;
@@ -243,44 +243,26 @@ static int mpr_touchkey_probe(struct i2c_client *client,
error = mpr121_phys_init(pdata, mpr121, client);
if (error) {
dev_err(&client->dev, "Failed to init register\n");
-   goto err_free_mem;
+   return error;
}
 
-   error = request_threaded_irq(client->irq, NULL,
+   error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 mpr_touchkey_interrupt,
 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 client->dev.driver->name, mpr121);
if (error) {
dev_err(&client->dev, "Failed to register interrupt\n");
-   goto err_free_mem;
+   return error;
}
 
error = input_register_device(input_dev);
if (error)
-   goto err_free_irq;
+   return error;
 
i2c_set_clientdata(client, mpr121);
device_init_wakeup(&client->dev, pdata->wakeup);
 
return 0;
-
-err_free_irq:
-   free_irq(client->irq, mpr121);
-err_free_mem:
-   input_free_device(input_dev);
-   kfree(mpr121);
-   return error;
-}
-
-static int mpr_touchkey_remove(struct i2c_client *client)
-{
-   struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
-
-   free_irq(client->irq, mpr121);
-   input_unregister_device(mpr121->input_dev);
-   kfree(mpr121);
-
-   return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -327,7 +309,6 @@ static struct i2c_driver mpr_touchkey_driver = {
},
.id_table   = mpr121_id,
.probe  = mpr_touchkey_probe,
-   .remove = mpr_touchkey_remove,
 };
 
 module_i2c_driver(mpr_touchkey_driver);
-- 
1.7.9.5

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


[PATCH] Input: lpc32xx-keys: Switch to using managed resources

2014-10-07 Thread Pramod Gurav
This change switches to using devm_* managed resources APIs to
request the resources in probe to simplify probe error path and
module unloading.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/lpc32xx-keys.c |   86 +
 1 file changed, 23 insertions(+), 63 deletions(-)

diff --git a/drivers/input/keyboard/lpc32xx-keys.c 
b/drivers/input/keyboard/lpc32xx-keys.c
index 8b1b013..6e244df 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -188,32 +188,27 @@ static int lpc32xx_kscan_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
-   kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL);
-   if (!kscandat) {
-   dev_err(&pdev->dev, "failed to allocate memory\n");
+   kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat),
+   GFP_KERNEL);
+   if (!kscandat)
return -ENOMEM;
-   }
 
error = lpc32xx_parse_dt(&pdev->dev, kscandat);
if (error) {
dev_err(&pdev->dev, "failed to parse device tree\n");
-   goto err_free_mem;
+   return error;
}
 
keymap_size = sizeof(kscandat->keymap[0]) *
(kscandat->matrix_sz << kscandat->row_shift);
-   kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL);
-   if (!kscandat->keymap) {
-   dev_err(&pdev->dev, "could not allocate memory for keymap\n");
-   error = -ENOMEM;
-   goto err_free_mem;
-   }
+   kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL);
+   if (!kscandat->keymap)
+   return -ENOMEM;
 
-   kscandat->input = input = input_allocate_device();
+   kscandat->input = input = devm_input_allocate_device(&pdev->dev);
if (!input) {
dev_err(&pdev->dev, "failed to allocate input device\n");
-   error = -ENOMEM;
-   goto err_free_keymap;
+   return -ENOMEM;
}
 
/* Setup key input */
@@ -234,39 +229,37 @@ static int lpc32xx_kscan_probe(struct platform_device 
*pdev)
   kscandat->keymap, kscandat->input);
if (error) {
dev_err(&pdev->dev, "failed to build keymap\n");
-   goto err_free_input;
+   return error;
}
 
input_set_drvdata(kscandat->input, kscandat);
 
-   kscandat->iores = request_mem_region(res->start, resource_size(res),
-pdev->name);
+   kscandat->iores = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res),
+ pdev->name);
if (!kscandat->iores) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
-   error = -EBUSY;
-   goto err_free_input;
+   return -EBUSY;
}
 
-   kscandat->kscan_base = ioremap(kscandat->iores->start,
+   kscandat->kscan_base = devm_ioremap(&pdev->dev, kscandat->iores->start,
   resource_size(kscandat->iores));
if (!kscandat->kscan_base) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
-   error = -EBUSY;
-   goto err_release_memregion;
+   return -EBUSY;
}
 
/* Get the key scanner clock */
-   kscandat->clk = clk_get(&pdev->dev, NULL);
+   kscandat->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(kscandat->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
-   error = PTR_ERR(kscandat->clk);
-   goto err_unmap;
+   return PTR_ERR(kscandat->clk);
}
 
/* Configure the key scanner */
error = clk_prepare_enable(kscandat->clk);
if (error)
-   goto err_clk_put;
+   return error;
 
writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base));
writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base));
@@ -277,52 +270,20 @@ static int lpc32xx_kscan_probe(struct platform_device 
*pdev)
writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
clk_disable_unprepare(kscandat->clk);
 
-   error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat);
+   error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0,
+pdev->name, kscandat);

[PATCH] Input: opencores-kbd: Switch to using managed resources

2014-10-07 Thread Pramod Gurav
This change switch to managed resources to simplifies error handling
and module unloading and does away with platform_driver remove function.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/opencores-kbd.c |   54 
 1 file changed, 13 insertions(+), 41 deletions(-)

diff --git a/drivers/input/keyboard/opencores-kbd.c 
b/drivers/input/keyboard/opencores-kbd.c
index 7b9b441..ecacb87 100644
--- a/drivers/input/keyboard/opencores-kbd.c
+++ b/drivers/input/keyboard/opencores-kbd.c
@@ -56,27 +56,27 @@ static int opencores_kbd_probe(struct platform_device *pdev)
return -EINVAL;
}
 
-   opencores_kbd = kzalloc(sizeof(*opencores_kbd), GFP_KERNEL);
-   input = input_allocate_device();
+   opencores_kbd = devm_kzalloc(&pdev->dev, sizeof(*opencores_kbd),
+GFP_KERNEL);
+   input = devm_input_allocate_device(&pdev->dev);
if (!opencores_kbd || !input) {
dev_err(&pdev->dev, "failed to allocate device structures\n");
-   error = -ENOMEM;
-   goto err_free_mem;
+   return -ENOMEM;
}
 
opencores_kbd->addr_res = res;
-   res = request_mem_region(res->start, resource_size(res), pdev->name);
+   res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name);
if (!res) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
-   error = -EBUSY;
-   goto err_free_mem;
+   return -EBUSY;
}
 
-   opencores_kbd->addr = ioremap(res->start, resource_size(res));
+   opencores_kbd->addr = devm_ioremap(&pdev->dev, res->start,
+  resource_size(res));
if (!opencores_kbd->addr) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
-   error = -ENXIO;
-   goto err_rel_mem;
+   return -ENXIO;
}
 
opencores_kbd->input = input;
@@ -109,54 +109,26 @@ static int opencores_kbd_probe(struct platform_device 
*pdev)
}
__clear_bit(KEY_RESERVED, input->keybit);
 
-   error = request_irq(irq, &opencores_kbd_isr,
+   error = devm_request_irq(&pdev->dev, irq, &opencores_kbd_isr,
IRQF_TRIGGER_RISING, pdev->name, opencores_kbd);
if (error) {
dev_err(&pdev->dev, "unable to claim irq %d\n", irq);
-   goto err_unmap_mem;
+   return error;
}
 
error = input_register_device(input);
if (error) {
dev_err(&pdev->dev, "unable to register input device\n");
-   goto err_free_irq;
+   return error;
}
 
platform_set_drvdata(pdev, opencores_kbd);
 
return 0;
-
- err_free_irq:
-   free_irq(irq, opencores_kbd);
- err_unmap_mem:
-   iounmap(opencores_kbd->addr);
- err_rel_mem:
-   release_mem_region(res->start, resource_size(res));
- err_free_mem:
-   input_free_device(input);
-   kfree(opencores_kbd);
-
-   return error;
-}
-
-static int opencores_kbd_remove(struct platform_device *pdev)
-{
-   struct opencores_kbd *opencores_kbd = platform_get_drvdata(pdev);
-
-   free_irq(opencores_kbd->irq, opencores_kbd);
-
-   iounmap(opencores_kbd->addr);
-   release_mem_region(opencores_kbd->addr_res->start,
-   resource_size(opencores_kbd->addr_res));
-   input_unregister_device(opencores_kbd->input);
-   kfree(opencores_kbd);
-
-   return 0;
 }
 
 static struct platform_driver opencores_kbd_device_driver = {
.probe= opencores_kbd_probe,
-   .remove   = opencores_kbd_remove,
.driver   = {
.name = "opencores-kbd",
},
-- 
1.7.9.5

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


[PATCH] input: lm8323: Switch to using managed resources

2014-10-07 Thread Pramod Gurav
This change switches to using devm_* APIs to allocate  resources.
This helps to simplify failure path in probe function as well as
remove function.

Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/lm8323.c |   39 ---
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index cb32e2b..c4325a1 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -653,12 +653,10 @@ static int lm8323_probe(struct i2c_client *client,
return -EINVAL;
}
 
-   lm = kzalloc(sizeof *lm, GFP_KERNEL);
-   idev = input_allocate_device();
-   if (!lm || !idev) {
-   err = -ENOMEM;
-   goto fail1;
-   }
+   lm = devm_kzalloc(&client->dev, sizeof(*lm), GFP_KERNEL);
+   idev = devm_input_allocate_device(&client->dev);
+   if (!lm || !idev)
+   return -ENOMEM;
 
lm->client = client;
lm->idev = idev;
@@ -695,21 +693,20 @@ static int lm8323_probe(struct i2c_client *client,
/* If a true probe check the device */
if (lm8323_read_id(lm, data) != 0) {
dev_err(&client->dev, "device not found\n");
-   err = -ENODEV;
-   goto fail1;
+   return -ENODEV;
}
 
for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) {
err = init_pwm(lm, pwm + 1, &client->dev,
   pdata->pwm_names[pwm]);
if (err < 0)
-   goto fail2;
+   goto fail1;
}
 
lm->kp_enabled = true;
err = device_create_file(&client->dev, &dev_attr_disable_kp);
if (err < 0)
-   goto fail2;
+   goto fail1;
 
idev->name = pdata->name ? : "LM8323 keypad";
snprintf(lm->phys, sizeof(lm->phys),
@@ -730,14 +727,16 @@ static int lm8323_probe(struct i2c_client *client,
err = input_register_device(idev);
if (err) {
dev_dbg(&client->dev, "error registering input device\n");
-   goto fail3;
+   goto fail2;
}
 
-   err = request_threaded_irq(client->irq, NULL, lm8323_irq,
- IRQF_TRIGGER_LOW|IRQF_ONESHOT, "lm8323", lm);
+   err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+   lm8323_irq,
+   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+   "lm8323", lm);
if (err) {
dev_err(&client->dev, "could not get IRQ %d\n", client->irq);
-   goto fail4;
+   goto fail3;
}
 
i2c_set_clientdata(client, lm);
@@ -747,18 +746,15 @@ static int lm8323_probe(struct i2c_client *client,
 
return 0;
 
-fail4:
+fail3:
input_unregister_device(idev);
idev = NULL;
-fail3:
-   device_remove_file(&client->dev, &dev_attr_disable_kp);
 fail2:
+   device_remove_file(&client->dev, &dev_attr_disable_kp);
+fail1:
while (--pwm >= 0)
if (lm->pwm[pwm].enabled)
led_classdev_unregister(&lm->pwm[pwm].cdev);
-fail1:
-   input_free_device(idev);
-   kfree(lm);
return err;
 }
 
@@ -768,7 +764,6 @@ static int lm8323_remove(struct i2c_client *client)
int i;
 
disable_irq_wake(client->irq);
-   free_irq(client->irq, lm);
 
input_unregister_device(lm->idev);
 
@@ -778,8 +773,6 @@ static int lm8323_remove(struct i2c_client *client)
if (lm->pwm[i].enabled)
led_classdev_unregister(&lm->pwm[i].cdev);
 
-   kfree(lm);
-
return 0;
 }
 
-- 
1.7.9.5

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


[PATCH] Input: adp5588-keys: cancel workqueue in failure path

2014-10-07 Thread Pramod Gurav
This change introduces a label to call cancel_delayed_work_sync in
failure path.

Cc: Michael Hennerich 
Cc: Dmitry Torokhov 
Cc: linux-in...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/input/keyboard/adp5588-keys.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/input/keyboard/adp5588-keys.c 
b/drivers/input/keyboard/adp5588-keys.c
index 5ef7fcf..b494062 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -559,7 +559,7 @@ static int adp5588_probe(struct i2c_client *client,
error = input_register_device(input);
if (error) {
dev_err(&client->dev, "unable to register input device\n");
-   goto err_free_mem;
+   goto err_delayed_work;
}
 
error = request_irq(client->irq, adp5588_irq,
@@ -592,6 +592,8 @@ static int adp5588_probe(struct i2c_client *client,
  err_unreg_dev:
input_unregister_device(input);
input = NULL;
+ err_delayed_work:
+   cancel_delayed_work_sync(&kpad->work);
  err_free_mem:
input_free_device(input);
kfree(kpad);
-- 
1.7.9.5

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


[PATCH v2] thermal: ti-soc-thermal: Switch to using managed resources

2014-10-07 Thread Pramod Gurav
This change switches to managed resource APIs to allocated resources
such as irq, clock. Hence does away with release statements of the
same resorces in error lables and remove function.

Cc: Eduardo Valentin 
Cc: Zhang Rui 
Cc: linux...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
Change since v1:

Passing struct device to devm_clk_get was missing. Fix the same in v2.

 drivers/thermal/ti-soc-thermal/ti-bandgap.c |   46 +++
 1 file changed, 12 insertions(+), 34 deletions(-)

diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c 
b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 634b6ce..22013ef 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -1060,7 +1060,7 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
int status;
 
/* Request for gpio_86 line */
-   status = gpio_request(gpio_nr, "tshut");
+   status = devm_gpio_request(&pdev->dev, gpio_nr, "tshut");
if (status < 0) {
dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
return status;
@@ -1071,11 +1071,12 @@ static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
return status;
}
 
-   status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
-IRQF_TRIGGER_RISING, "tshut", NULL);
+   status = devm_request_irq(&pdev->dev, gpio_to_irq(gpio_nr),
+ ti_bandgap_tshut_irq_handler,
+ IRQF_TRIGGER_RISING, "tshut", NULL);
if (status) {
-   gpio_free(gpio_nr);
dev_err(bgp->dev, "request irq failed for TSHUT");
+   return status;
}
 
return 0;
@@ -1104,7 +1105,7 @@ static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
dev_err(&pdev->dev, "get_irq failed\n");
return bgp->irq;
}
-   ret = request_threaded_irq(bgp->irq, NULL,
+   ret = devm_request_threaded_irq(&pdev->dev, bgp->irq, NULL,
   ti_bandgap_talert_irq_handler,
   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
   "talert", bgp);
@@ -1212,21 +1213,17 @@ int ti_bandgap_probe(struct platform_device *pdev)
}
}
 
-   bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
-   ret = IS_ERR(bgp->fclock);
-   if (ret) {
+   bgp->fclock = devm_clk_get(&pdev->dev, NULL, bgp->conf->fclock_name);
+   if (IS_ERR(bgp->fclock)) {
dev_err(&pdev->dev, "failed to request fclock reference\n");
-   ret = PTR_ERR(bgp->fclock);
-   goto free_irqs;
+   return PTR_ERR(bgp->fclock);
}
 
-   bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
-   ret = IS_ERR(bgp->div_clk);
-   if (ret) {
+   bgp->div_clk = devm_clk_get(&pdev->dev, NULL,  bgp->conf->div_ck_name);
+   if (IS_ERR(bgp->div_clk)) {
dev_err(&pdev->dev,
"failed to request div_ts_ck clock ref\n");
-   ret = PTR_ERR(bgp->div_clk);
-   goto free_irqs;
+   return PTR_ERR(bgp->div_clk);
}
 
for (i = 0; i < bgp->conf->sensor_count; i++) {
@@ -1251,7 +1248,6 @@ int ti_bandgap_probe(struct platform_device *pdev)
clk_rate <= 0) {
ret = -ENODEV;
dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
-   goto put_clks;
}
 
ret = clk_set_rate(bgp->div_clk, clk_rate);
@@ -1357,14 +1353,6 @@ remove_sensors:
 disable_clk:
if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
clk_disable_unprepare(bgp->fclock);
-put_clks:
-   clk_put(bgp->fclock);
-   clk_put(bgp->div_clk);
-free_irqs:
-   if (TI_BANDGAP_HAS(bgp, TSHUT)) {
-   free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
-   gpio_free(bgp->tshut_gpio);
-   }
 
return ret;
 }
@@ -1388,16 +1376,6 @@ int ti_bandgap_remove(struct platform_device *pdev)
 
if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
clk_disable_unprepare(bgp->fclock);
-   clk_put(bgp->fclock);
-   clk_put(bgp->div_clk);
-
-   if (TI_BANDGAP_HAS(bgp, TALERT))
-   free_irq(bgp->irq, bgp);
-
-   if (TI_BANDGAP_HAS(bgp, TSHUT)) {
-   free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
-   gpio_free(bgp->tshut_gpio);
-   }
 
return 0;
 }
-- 
1.7.9.5

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


[PATCH v2] gpio: cs5535: Switch to using managed resources with devm_

2014-10-07 Thread Pramod Gurav
This change switches to devm_request_region to request region
and hence simplifies the module unload and does away with
release_region in remove function.

Cc: Linus Walleij 
Cc: Alexandre Courbot 
Cc: linux-g...@vger.kernel.org
Signed-off-by: Pramod Gurav 
Reviewed-by: Alexandre Courbot 
---

Changes since v1:

Change commit subject to reflect cs5535.

 drivers/gpio/gpio-cs5535.c |   11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c
index 668127f..71484ee 100644
--- a/drivers/gpio/gpio-cs5535.c
+++ b/drivers/gpio/gpio-cs5535.c
@@ -322,7 +322,8 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
goto done;
}
 
-   if (!request_region(res->start, resource_size(res), pdev->name)) {
+   if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
+pdev->name)) {
dev_err(&pdev->dev, "can't request region\n");
goto done;
}
@@ -348,24 +349,18 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
/* finally, register with the generic GPIO API */
err = gpiochip_add(&cs5535_gpio_chip.chip);
if (err)
-   goto release_region;
+   goto done;
 
return 0;
 
-release_region:
-   release_region(res->start, resource_size(res));
 done:
return err;
 }
 
 static int cs5535_gpio_remove(struct platform_device *pdev)
 {
-   struct resource *r;
-
gpiochip_remove(&cs5535_gpio_chip.chip);
 
-   r = platform_get_resource(pdev, IORESOURCE_IO, 0);
-   release_region(r->start, resource_size(r));
return 0;
 }
 
-- 
1.7.9.5

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


[PATCH] gpio: grgpio: remove irq_domain resources on failure

2014-10-01 Thread Pramod Gurav
Call irq_domain_remove when gpiochip_add fails to release irq_domain
resources.

Cc: Linus Walleij 
Cc: Alexandre Courbot 
Cc: linux-g...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/gpio/gpio-grgpio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
index 66ad3df..38acdce 100644
--- a/drivers/gpio/gpio-grgpio.c
+++ b/drivers/gpio/gpio-grgpio.c
@@ -441,6 +441,7 @@ static int grgpio_probe(struct platform_device *ofdev)
err = gpiochip_add(gc);
if (err) {
dev_err(&ofdev->dev, "Could not add gpiochip\n");
+   irq_domain_remove(priv->domain);
return err;
}
 
-- 
1.8.3.2

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


[PATCH v2] ssb: Fix Sparse error in main

2014-10-01 Thread Pramod Gurav
This change fixes below sparse error:
drivers/ssb/main.c:94:16: warning: symbol 'ssb_sdio_func_to_bus'
was not declared. Should it be static?

Cc: Michael Buesch 
Cc: net...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
Changes since v1:
Removed the function as it is not called anywhere in the kernel
as per suggestion from Michael Buesch.

 drivers/ssb/main.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 2fead38..1e180c4 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -90,25 +90,6 @@ found:
 }
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
-#ifdef CONFIG_SSB_SDIOHOST
-struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
-{
-   struct ssb_bus *bus;
-
-   ssb_buses_lock();
-   list_for_each_entry(bus, &buses, list) {
-   if (bus->bustype == SSB_BUSTYPE_SDIO &&
-   bus->host_sdio == func)
-   goto found;
-   }
-   bus = NULL;
-found:
-   ssb_buses_unlock();
-
-   return bus;
-}
-#endif /* CONFIG_SSB_SDIOHOST */
-
 int ssb_for_each_bus_call(unsigned long data,
  int (*func)(struct ssb_bus *bus, unsigned long data))
 {
-- 
1.8.3.2

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


Re: [PATCH] ASoC: remove use of gpiochip_remove() retval

2014-10-01 Thread Pramod Gurav
On Wednesday 01 October 2014 05:08 PM, Mark Brown wrote:
> On Wed, Oct 01, 2014 at 11:17:46AM +0530, Pramod Gurav wrote:
>> Get rid of using return value from gpiochip_remove() as it returns
>> void with a new change in kernel.
> 
> Applied, I'm assuming that the API change is going to be introduced in a
> future kernel version since obviously it'll break the build otherwise.
> 
Mark please revert the changes as these are already present in
linux-next master. I realized it late. Sorry for trouble.

Thanks
Pramod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] gpio: Switch to using managed resources with devm_

2014-10-01 Thread Pramod Gurav
This change switches to devm_request_region to request region
and hence simplifies the module unload and does away with
release_region in remove function.

Cc: Linus Walleij 
Cc: Alexandre Courbot 
Cc: linux-g...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/gpio/gpio-cs5535.c |   11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c
index 92ec58f..802d518 100644
--- a/drivers/gpio/gpio-cs5535.c
+++ b/drivers/gpio/gpio-cs5535.c
@@ -319,7 +319,8 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
goto done;
}
 
-   if (!request_region(res->start, resource_size(res), pdev->name)) {
+   if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
+pdev->name)) {
dev_err(&pdev->dev, "can't request region\n");
goto done;
}
@@ -345,24 +346,18 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
/* finally, register with the generic GPIO API */
err = gpiochip_add(&cs5535_gpio_chip.chip);
if (err)
-   goto release_region;
+   goto done;
 
return 0;
 
-release_region:
-   release_region(res->start, resource_size(res));
 done:
return err;
 }
 
 static int cs5535_gpio_remove(struct platform_device *pdev)
 {
-   struct resource *r;
-
gpiochip_remove(&cs5535_gpio_chip.chip);
 
-   r = platform_get_resource(pdev, IORESOURCE_IO, 0);
-   release_region(r->start, resource_size(r));
return 0;
 }
 
-- 
1.7.9.5

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


[PATCH] gpio: amd8111: unmap ioport on failure case

2014-10-01 Thread Pramod Gurav
This change unmaps ioport when gpiochip_add fails

Cc: Linus Walleij 
Cc: Alexandre Courbot 
Cc: linux-g...@vger.kernel.org
Signed-off-by: Pramod Gurav 
---
 drivers/gpio/gpio-amd8111.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c
index 3c09f1a6..d3d2d10 100644
--- a/drivers/gpio/gpio-amd8111.c
+++ b/drivers/gpio/gpio-amd8111.c
@@ -223,6 +223,7 @@ found:
if (err) {
printk(KERN_ERR "GPIO registering failed (%d)\n",
   err);
+   ioport_unmap(gp.pm);
release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
goto out;
}
-- 
1.7.9.5

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


  1   2   3   >