[PATCH] spi: qup: Fix runtime and system PM callbacks.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
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
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
+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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
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
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
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
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_
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
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/