Re: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes

2015-08-03 Thread Andreas Fenkart
Hi Kishon,

Thanks for taking a look at the regulator code. Do you have a public
git repository so I can pull your patches instead of cherry picking
1-by-1?

/Andi

2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I :
> This patch series does the following
> *) Uses devm_regulator_get_optional() for vmmc and then removes the
>CONFIG_REGULATOR check altogether.
> *) return on -EPROBE_DEFER
> *) enable/disable vmmc_aux regulator based on prior state
>
> This series is in preparation for implementing the voltage switch
> sequence so that UHS cards can be supported.
>
> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>
> Kishon Vijay Abraham I (16):
>   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
>   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
> -EPROBE_DEFER
>   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
>   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
>   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
>   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
>   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
>   mmc: host: omap_hsmmc: add separate functions for enable/disable
> supply
>   mmc: host: omap_hsmmc: add separate function to set pbias
>   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
>   mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator
> state
>   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
>   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
> prior state
>   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
>   mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage
>   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check
>
> Roger Quadros (1):
>   mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail
>
>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
>  arch/arm/boot/dts/am57xx-beagle-x15.dts|1 -
>  drivers/mmc/host/omap_hsmmc.c  |  333 
> +---
>  3 files changed, 216 insertions(+), 120 deletions(-)
>
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes

2015-08-03 Thread Kishon Vijay Abraham I
Hi,

On Monday 03 August 2015 12:58 PM, Andreas Fenkart wrote:
> Hi Kishon,
> 
> Thanks for taking a look at the regulator code. Do you have a public
> git repository so I can pull your patches instead of cherry picking
> 1-by-1?

I'll post v2 shortly. With that I'll have the patches in a git tree.

Thanks
Kishon

> 
> /Andi
> 
> 2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I :
>> This patch series does the following
>> *) Uses devm_regulator_get_optional() for vmmc and then removes the
>>CONFIG_REGULATOR check altogether.
>> *) return on -EPROBE_DEFER
>> *) enable/disable vmmc_aux regulator based on prior state
>>
>> This series is in preparation for implementing the voltage switch
>> sequence so that UHS cards can be supported.
>>
>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>>
>> Kishon Vijay Abraham I (16):
>>   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
>>   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
>> -EPROBE_DEFER
>>   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
>>   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
>>   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
>>   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
>>   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
>>   mmc: host: omap_hsmmc: add separate functions for enable/disable
>> supply
>>   mmc: host: omap_hsmmc: add separate function to set pbias
>>   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
>>   mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator
>> state
>>   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
>>   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
>> prior state
>>   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
>>   mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage
>>   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check
>>
>> Roger Quadros (1):
>>   mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail
>>
>>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
>>  arch/arm/boot/dts/am57xx-beagle-x15.dts|1 -
>>  drivers/mmc/host/omap_hsmmc.c  |  333 
>> +---
>>  3 files changed, 216 insertions(+), 120 deletions(-)
>>
>> --
>> 1.7.9.5
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 14/16] mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage

2015-08-03 Thread Kishon Vijay Abraham I
vdd voltage is set in mmc core to ios->vdd and vmmc should actually
be set to this voltage. Modify omap_hsmmc_enable_supply
to not take vdd as argument since now it's directly set to
the voltage in ios->vdd.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e04060b..9a28719 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -247,13 +247,14 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 
 #ifdef CONFIG_REGULATOR
 
-static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd)
+static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
 {
int ret;
struct omap_hsmmc_host *host = mmc_priv(mmc);
+   struct mmc_ios *ios = &mmc->ios;
 
if (mmc->supply.vmmc) {
-   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
if (ret)
return ret;
}
@@ -385,7 +386,7 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   ret = omap_hsmmc_enable_supply(mmc, vdd);
+   ret = omap_hsmmc_enable_supply(mmc);
if (ret)
return ret;
 
-- 
1.7.9.5

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


[PATCH v2 05/16] mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc

2015-08-03 Thread Kishon Vijay Abraham I
No functional change. Instead of using omap_hsmmc_host's vcc and vcc_aux
members, use vmmc and vqmmc present in mmc_host which is present
for the same purpose.

Signed-off-by: Kishon Vijay Abraham I 
Reviewed-by: Roger Quadros 
---
 drivers/mmc/host/omap_hsmmc.c |   63 ++---
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8cf040f..f6b056f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -181,15 +181,6 @@ struct omap_hsmmc_host {
struct  mmc_data*data;
struct  clk *fclk;
struct  clk *dbclk;
-   /*
-* vcc == configured supply
-* vcc_aux == optional
-*   -  MMC1, supply for DAT4..DAT7
-*   -  MMC2/MMC2, external level shifter voltage supply, for
-*  chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
-*/
-   struct  regulator   *vcc;
-   struct  regulator   *vcc_aux;
struct  regulator   *pbias;
boolpbias_enabled;
void__iomem *base;
@@ -260,13 +251,14 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 {
struct omap_hsmmc_host *host =
platform_get_drvdata(to_platform_device(dev));
+   struct mmc_host *mmc = host->mmc;
int ret = 0;
 
/*
 * If we don't see a Vcc regulator, assume it's a fixed
 * voltage always-on regulator.
 */
-   if (!host->vcc)
+   if (!mmc->supply.vmmc)
return 0;
 
if (mmc_pdata(host)->before_set_reg)
@@ -295,23 +287,23 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (host->vcc)
-   ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd);
+   if (mmc->supply.vmmc)
+   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
/* Enable interface voltage rail, if needed */
-   if (ret == 0 && host->vcc_aux) {
-   ret = regulator_enable(host->vcc_aux);
-   if (ret < 0 && host->vcc)
-   ret = mmc_regulator_set_ocr(host->mmc,
-   host->vcc, 0);
+   if (ret == 0 && mmc->supply.vqmmc) {
+   ret = regulator_enable(mmc->supply.vqmmc);
+   if (ret < 0 && mmc->supply.vmmc)
+   ret = mmc_regulator_set_ocr(mmc,
+   mmc->supply.vmmc,
+   0);
}
} else {
/* Shut down the rail */
-   if (host->vcc_aux)
-   ret = regulator_disable(host->vcc_aux);
-   if (host->vcc) {
+   if (mmc->supply.vqmmc)
+   ret = regulator_disable(mmc->supply.vqmmc);
+   if (mmc->supply.vmmc) {
/* Then proceed to shut down the local regulator */
-   ret = mmc_regulator_set_ocr(host->mmc,
-   host->vcc, 0);
+   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
}
}
 
@@ -343,31 +335,32 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
 {
int ocr_value = 0;
int ret;
+   struct mmc_host *mmc = host->mmc;
 
-   host->vcc = devm_regulator_get_optional(host->dev, "vmmc");
-   if (IS_ERR(host->vcc)) {
-   ret = PTR_ERR(host->vcc);
+   mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc");
+   if (IS_ERR(mmc->supply.vmmc)) {
+   ret = PTR_ERR(mmc->supply.vmmc);
if (ret != -ENODEV)
return ret;
dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
-   PTR_ERR(host->vcc));
-   host->vcc = NULL;
+   PTR_ERR(mmc->supply.vmmc));
+   mmc->supply.vmmc = NULL;
} else {
-   ocr_value = mmc_regulator_get_ocrmask(host->vcc);
+   ocr_value = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
if (ocr_value > 0)
mmc_pdata(host)->ocr_mask = ocr_value;
}
mmc_pdata(host)->set_power = omap_hsmmc_set_power;
 
/* Allow an aux regulator */
-   host->vcc_aux = devm_regulator_get_optional(host->dev, "vmmc_aux");
-   if (IS_ERR(host->vcc_aux)) {
-   ret = PTR_ERR(host->vcc_aux);
+   mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux");
+   if (IS_ERR(mmc->supply.vqmmc)) {
+  

[PATCH v2 15/16] mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

2015-08-03 Thread Kishon Vijay Abraham I
Now that support for platforms which have optional regulator is added,
remove CONFIG_REGULATOR check in omap_hsmmc.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   35 +++
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 9a28719..15973f1 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -204,7 +204,6 @@ struct omap_hsmmc_host {
int context_loss;
int protect_card;
int reqs_blocked;
-   int use_reg;
int req_in_progress;
unsigned long   clk_rate;
unsigned intflags;
@@ -245,8 +244,6 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
return mmc_gpio_get_cd(host->mmc);
 }
 
-#ifdef CONFIG_REGULATOR
-
 static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
 {
int ret;
@@ -521,29 +518,6 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host 
*host)
mmc_pdata(host)->set_power = NULL;
 }
 
-static inline int omap_hsmmc_have_reg(void)
-{
-   return 1;
-}
-
-#else
-
-static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
-{
-   return -EINVAL;
-}
-
-static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
-{
-}
-
-static inline int omap_hsmmc_have_reg(void)
-{
-   return 0;
-}
-
-#endif
-
 static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id);
 
 static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
@@ -2204,11 +2178,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (omap_hsmmc_have_reg() && !mmc_pdata(host)->set_power) {
+   if (!mmc_pdata(host)->set_power) {
ret = omap_hsmmc_reg_get(host);
if (ret)
goto err_irq;
-   host->use_reg = 1;
}
 
mmc->ocr_avail = mmc_pdata(host)->ocr_mask;
@@ -2251,8 +2224,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
-   if (host->use_reg)
-   omap_hsmmc_reg_put(host);
+   omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(&pdev->dev, false);
if (host->tx_chan)
@@ -2276,8 +2248,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 
pm_runtime_get_sync(host->dev);
mmc_remove_host(host->mmc);
-   if (host->use_reg)
-   omap_hsmmc_reg_put(host);
+   omap_hsmmc_reg_put(host);
 
if (host->tx_chan)
dma_release_channel(host->tx_chan);
-- 
1.7.9.5

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


[PATCH v2 13/16] mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status

2015-08-03 Thread Kishon Vijay Abraham I
Use regulator_is_enabled of pbias regulator to find pbias regulator
status instead of maintaining a custom bookkeeping
pbias_enabled variable.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 98e0289..e04060b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -182,7 +182,6 @@ struct omap_hsmmc_host {
struct  clk *fclk;
struct  clk *dbclk;
struct  regulator   *pbias;
-   boolpbias_enabled;
void__iomem *base;
int vqmmc_enabled;
resource_size_t mapbase;
@@ -331,22 +330,20 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host 
*host, bool power_on,
return ret;
}
 
-   if (host->pbias_enabled == 0) {
+   if (!regulator_is_enabled(host->pbias)) {
ret = regulator_enable(host->pbias);
if (ret) {
dev_err(host->dev, "pbias reg enable fail\n");
return ret;
}
-   host->pbias_enabled = 1;
}
} else {
-   if (host->pbias_enabled == 1) {
+   if (regulator_is_enabled(host->pbias)) {
ret = regulator_disable(host->pbias);
if (ret) {
dev_err(host->dev, "pbias reg disable fail\n");
return ret;
}
-   host->pbias_enabled = 0;
}
}
 
@@ -2081,7 +2078,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host->base  = base + pdata->reg_offset;
host->power_mode = MMC_POWER_OFF;
host->next_data.cookie = 1;
-   host->pbias_enabled = 0;
host->vqmmc_enabled = 0;
 
ret = omap_hsmmc_gpio_init(mmc, host, pdata);
-- 
1.7.9.5

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


[PATCH v2 12/16] mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on previous state

2015-08-03 Thread Kishon Vijay Abraham I
enable vmmc_aux regulator only if it is in disabled state and disable
vmmc_aux regulator only if it is in enabled state.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 635ac18..98e0289 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -184,6 +184,7 @@ struct omap_hsmmc_host {
struct  regulator   *pbias;
boolpbias_enabled;
void__iomem *base;
+   int vqmmc_enabled;
resource_size_t mapbase;
spinlock_t  irq_lock; /* Prevent races with irq handler */
unsigned intdma_len;
@@ -250,6 +251,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd)
 {
int ret;
+   struct omap_hsmmc_host *host = mmc_priv(mmc);
 
if (mmc->supply.vmmc) {
ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
@@ -258,12 +260,13 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc, 
int vdd)
}
 
/* Enable interface voltage rail, if needed */
-   if (mmc->supply.vqmmc) {
+   if (mmc->supply.vqmmc && !host->vqmmc_enabled) {
ret = regulator_enable(mmc->supply.vqmmc);
if (ret) {
dev_err(mmc_dev(mmc), "vmmc_aux reg enable failed\n");
goto err_vqmmc;
}
+   host->vqmmc_enabled = 1;
}
 
return 0;
@@ -279,13 +282,15 @@ static int omap_hsmmc_disable_supply(struct mmc_host *mmc)
 {
int ret;
int status;
+   struct omap_hsmmc_host *host = mmc_priv(mmc);
 
-   if (mmc->supply.vqmmc) {
+   if (mmc->supply.vqmmc && host->vqmmc_enabled) {
ret = regulator_disable(mmc->supply.vqmmc);
if (ret) {
dev_err(mmc_dev(mmc), "vmmc_aux reg disable failed\n");
return ret;
}
+   host->vqmmc_enabled = 0;
}
 
if (mmc->supply.vmmc) {
@@ -2077,6 +2082,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host->power_mode = MMC_POWER_OFF;
host->next_data.cookie = 1;
host->pbias_enabled = 0;
+   host->vqmmc_enabled = 0;
 
ret = omap_hsmmc_gpio_init(mmc, host, pdata);
if (ret)
-- 
1.7.9.5

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


[PATCH v2 16/16] mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail

2015-08-03 Thread Kishon Vijay Abraham I
From: Roger Quadros 

For platforms that doesn't have explicit regulator control in MMC,
populate voltage-ranges in MMC device tree node and use
mmc_of_parse_voltage to get ocr_avail

Signed-off-by: Roger Quadros 
Signed-off-by: Lokesh Vutla 
Signed-off-by: Murali Karicheri 
Signed-off-by: Franklin S Cooper Jr 
Signed-off-by: Kishon Vijay Abraham I 
---
 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 ++
 drivers/mmc/host/omap_hsmmc.c  |9 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 76bf087..2408e87 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -22,6 +22,8 @@ ti,dual-volt: boolean, supports dual voltage cards
 ti,non-removable: non-removable slot (like eMMC)
 ti,needs-special-reset: Requires a special softreset sequence
 ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High 
Speed
+voltage-ranges: Specify the voltage range supported if regulator framework
+isn't enabled.
 dmas: List of DMA specifiers with the controller specific format
 as described in the generic DMA client binding. A tx and rx
 specifier is required.
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 15973f1..d884d8f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2184,7 +2184,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
goto err_irq;
}
 
-   mmc->ocr_avail = mmc_pdata(host)->ocr_mask;
+   if (!mmc_pdata(host)->ocr_mask) {
+   ret = mmc_of_parse_voltage(pdev->dev.of_node, &mmc->ocr_avail);
+   if (ret)
+   goto err_parse_voltage;
+   } else {
+   mmc->ocr_avail = mmc_pdata(host)->ocr_mask;
+   }
 
omap_hsmmc_disable_irq(host);
 
@@ -2224,6 +2230,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
+err_parse_voltage:
omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(&pdev->dev, false);
-- 
1.7.9.5

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


[PATCH v2 11/16] mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator state

2015-08-03 Thread Kishon Vijay Abraham I
If the regulator is enabled on boot (checked using regulator_is_enabled),
invoke regulator_enable() so that the usecount reflects the correct
state of the regulator and then disable the regulator so that the
initial state of the regulator is disabled. Avoid using ->set_power,
since set_power also takes care of setting the voltages which is not
needed at this point.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   66 ++---
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4af902d..635ac18 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -407,6 +407,59 @@ err_set_voltage:
return ret;
 }
 
+static int omap_hsmmc_disable_boot_regulator(struct regulator *reg)
+{
+   int ret;
+
+   if (!reg)
+   return 0;
+
+   if (regulator_is_enabled(reg)) {
+   ret = regulator_enable(reg);
+   if (ret)
+   return ret;
+
+   ret = regulator_disable(reg);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int omap_hsmmc_disable_boot_regulators(struct omap_hsmmc_host *host)
+{
+   struct mmc_host *mmc = host->mmc;
+   int ret;
+
+   /*
+* disable regulators enabled during boot and get the usecount
+* right so that regulators can be enabled/disabled by checking
+* the return value of regulator_is_enabled
+*/
+   ret = omap_hsmmc_disable_boot_regulator(mmc->supply.vmmc);
+   if (ret) {
+   dev_err(host->dev, "fail to disable boot enabled vmmc reg\n");
+   return ret;
+   }
+
+   ret = omap_hsmmc_disable_boot_regulator(mmc->supply.vqmmc);
+   if (ret) {
+   dev_err(host->dev,
+   "fail to disable boot enabled vmmc_aux reg\n");
+   return ret;
+   }
+
+   ret = omap_hsmmc_disable_boot_regulator(host->pbias);
+   if (ret) {
+   dev_err(host->dev,
+   "failed to disable boot enabled pbias reg\n");
+   return ret;
+   }
+
+   return 0;
+}
+
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
int ocr_value = 0;
@@ -452,17 +505,10 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
/* For eMMC do not power off when not in sleep state */
if (mmc_pdata(host)->no_regulator_off_init)
return 0;
-   /*
-* To disable boot_on regulator, enable regulator
-* to increase usecount and then disable it.
-*/
-   if ((mmc->supply.vmmc && regulator_is_enabled(mmc->supply.vmmc) > 0) ||
-   (mmc->supply.vqmmc && regulator_is_enabled(mmc->supply.vqmmc))) {
-   int vdd = ffs(mmc_pdata(host)->ocr_mask) - 1;
 
-   mmc_pdata(host)->set_power(host->dev, 1, vdd);
-   mmc_pdata(host)->set_power(host->dev, 0, 0);
-   }
+   ret = omap_hsmmc_disable_boot_regulators(host);
+   if (ret)
+   return ret;
 
return 0;
 }
-- 
1.7.9.5

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


[PATCH v2 09/16] mmc: host: omap_hsmmc: add separate function to set pbias

2015-08-03 Thread Kishon Vijay Abraham I
No functional change. Cleanup omap_hsmmc_set_power by adding separate
functions to set pbias and invoke it from omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   78 +
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 81bec66..194c59f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -306,6 +306,48 @@ err_set_ocr:
return ret;
 }
 
+static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
+   int vdd)
+{
+   int ret;
+
+   if (!host->pbias)
+   return 0;
+
+   if (power_on) {
+   if (vdd <= VDD_165_195)
+   ret = regulator_set_voltage(host->pbias, VDD_1V8,
+   VDD_1V8);
+   else
+   ret = regulator_set_voltage(host->pbias, VDD_3V0,
+   VDD_3V0);
+   if (ret < 0) {
+   dev_err(host->dev, "pbias set voltage fail\n");
+   return ret;
+   }
+
+   if (host->pbias_enabled == 0) {
+   ret = regulator_enable(host->pbias);
+   if (ret) {
+   dev_err(host->dev, "pbias reg enable fail\n");
+   return ret;
+   }
+   host->pbias_enabled = 1;
+   }
+   } else {
+   if (host->pbias_enabled == 1) {
+   ret = regulator_disable(host->pbias);
+   if (ret) {
+   dev_err(host->dev, "pbias reg disable fail\n");
+   return ret;
+   }
+   host->pbias_enabled = 0;
+   }
+   }
+
+   return 0;
+}
+
 static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_host *host =
@@ -323,16 +365,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (mmc_pdata(host)->before_set_reg)
mmc_pdata(host)->before_set_reg(dev, power_on, vdd);
 
-   if (host->pbias) {
-   if (host->pbias_enabled == 1) {
-   ret = regulator_disable(host->pbias);
-   if (ret) {
-   dev_err(dev, "pbias reg disable failed\n");
-   return ret;
-   }
-   host->pbias_enabled = 0;
-   }
-   }
+   ret = omap_hsmmc_set_pbias(host, false, 0);
+   if (ret)
+   return ret;
 
/*
 * Assume Vcc regulator is used only to power the card ... OMAP
@@ -357,26 +392,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
return ret;
}
 
-   if (host->pbias) {
-   if (vdd <= VDD_165_195)
-   ret = regulator_set_voltage(host->pbias, VDD_1V8,
-   VDD_1V8);
-   else
-   ret = regulator_set_voltage(host->pbias, VDD_3V0,
-   VDD_3V0);
-   if (ret < 0)
-   goto err_set_voltage;
-
-   if (host->pbias_enabled == 0) {
-   ret = regulator_enable(host->pbias);
-   if (ret) {
-   dev_err(dev, "pbias reg enable failed\n");
-   goto err_set_voltage;
-   } else {
-   host->pbias_enabled = 1;
-   }
-   }
-   }
+   ret = omap_hsmmc_set_pbias(host, true, vdd);
+   if (ret)
+   goto err_set_voltage;
 
if (mmc_pdata(host)->after_set_reg)
mmc_pdata(host)->after_set_reg(dev, power_on, vdd);
-- 
1.7.9.5

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


[PATCH v2 10/16] mmc: host: omap_hsmmc: avoid pbias regulator enable on power off

2015-08-03 Thread Kishon Vijay Abraham I
Fix omap_hsmmc_set_power so that pbias regulator is not enabled
during power off.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 194c59f..4af902d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -386,16 +386,16 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
ret = omap_hsmmc_enable_supply(mmc, vdd);
if (ret)
return ret;
+
+   ret = omap_hsmmc_set_pbias(host, true, vdd);
+   if (ret)
+   goto err_set_voltage;
} else {
ret = omap_hsmmc_disable_supply(mmc);
if (ret)
return ret;
}
 
-   ret = omap_hsmmc_set_pbias(host, true, vdd);
-   if (ret)
-   goto err_set_voltage;
-
if (mmc_pdata(host)->after_set_reg)
mmc_pdata(host)->after_set_reg(dev, power_on, vdd);
 
-- 
1.7.9.5

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


[PATCH v2 08/16] mmc: host: omap_hsmmc: add separate functions for enable/disable supply

2015-08-03 Thread Kishon Vijay Abraham I
No functional change. Cleanup omap_hsmmc_set_power by adding separate
functions for enable/disable supply and invoke it from
omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |  101 +++--
 1 file changed, 66 insertions(+), 35 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 63c9fe7..81bec66 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -247,6 +247,65 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 
 #ifdef CONFIG_REGULATOR
 
+static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd)
+{
+   int ret;
+
+   if (mmc->supply.vmmc) {
+   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+   if (ret)
+   return ret;
+   }
+
+   /* Enable interface voltage rail, if needed */
+   if (mmc->supply.vqmmc) {
+   ret = regulator_enable(mmc->supply.vqmmc);
+   if (ret) {
+   dev_err(mmc_dev(mmc), "vmmc_aux reg enable failed\n");
+   goto err_vqmmc;
+   }
+   }
+
+   return 0;
+
+err_vqmmc:
+   if (mmc->supply.vmmc)
+   mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
+   return ret;
+}
+
+static int omap_hsmmc_disable_supply(struct mmc_host *mmc)
+{
+   int ret;
+   int status;
+
+   if (mmc->supply.vqmmc) {
+   ret = regulator_disable(mmc->supply.vqmmc);
+   if (ret) {
+   dev_err(mmc_dev(mmc), "vmmc_aux reg disable failed\n");
+   return ret;
+   }
+   }
+
+   if (mmc->supply.vmmc) {
+   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+   if (ret)
+   goto err_set_ocr;
+   }
+
+   return 0;
+
+err_set_ocr:
+   if (mmc->supply.vqmmc) {
+   status = regulator_enable(mmc->supply.vqmmc);
+   if (status)
+   dev_err(mmc_dev(mmc), "vmmc_aux re-enable failed\n");
+   }
+
+   return ret;
+}
+
 static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_host *host =
@@ -289,36 +348,13 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (mmc->supply.vmmc) {
-   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
-   if (ret)
-   return ret;
-   }
-
-   /* Enable interface voltage rail, if needed */
-   if (mmc->supply.vqmmc) {
-   ret = regulator_enable(mmc->supply.vqmmc);
-   if (ret) {
-   dev_err(dev, "vmmc_aux reg enable failed\n");
-   goto err_set_vqmmc;
-   }
-   }
+   ret = omap_hsmmc_enable_supply(mmc, vdd);
+   if (ret)
+   return ret;
} else {
-   /* Shut down the rail */
-   if (mmc->supply.vqmmc) {
-   ret = regulator_disable(mmc->supply.vqmmc);
-   if (ret) {
-   dev_err(dev, "vmmc_aux reg disable failed\n");
-   return ret;
-   }
-   }
-
-   if (mmc->supply.vmmc) {
-   /* Then proceed to shut down the local regulator */
-   ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
-   if (ret)
-   return ret;
-   }
+   ret = omap_hsmmc_disable_supply(mmc);
+   if (ret)
+   return ret;
}
 
if (host->pbias) {
@@ -348,12 +384,7 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
return 0;
 
 err_set_voltage:
-   if (mmc->supply.vqmmc)
-   regulator_disable(mmc->supply.vqmmc);
-
-err_set_vqmmc:
-   if (mmc->supply.vmmc)
-   mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+   omap_hsmmc_disable_supply(mmc);
 
return ret;
 }
-- 
1.7.9.5

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


[PATCH v2 06/16] mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage

2015-08-03 Thread Kishon Vijay Abraham I
Remove the unnecessary pbias regulator_set_voltage done after
pbias regulator_disable in omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I 
Reviewed-by: Roger Quadros 
---
 drivers/mmc/host/omap_hsmmc.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f6b056f..d635a38 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -270,7 +270,6 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (!ret)
host->pbias_enabled = 0;
}
-   regulator_set_voltage(host->pbias, VDD_3V0, VDD_3V0);
}
 
/*
-- 
1.7.9.5

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


[PATCH v2 07/16] mmc: host: omap_hsmmc: return error if any of the regulator APIs fail

2015-08-03 Thread Kishon Vijay Abraham I
Return error if any of the regulator APIs (regulator_enable,
regulator_disable, regulator_set_voltage) fails in
omap_hsmmc_set_power to avoid undefined behavior.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   52 +++--
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d635a38..63c9fe7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -267,8 +267,11 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (host->pbias) {
if (host->pbias_enabled == 1) {
ret = regulator_disable(host->pbias);
-   if (!ret)
-   host->pbias_enabled = 0;
+   if (ret) {
+   dev_err(dev, "pbias reg disable failed\n");
+   return ret;
+   }
+   host->pbias_enabled = 0;
}
}
 
@@ -286,23 +289,35 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (mmc->supply.vmmc)
+   if (mmc->supply.vmmc) {
ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+   if (ret)
+   return ret;
+   }
+
/* Enable interface voltage rail, if needed */
-   if (ret == 0 && mmc->supply.vqmmc) {
+   if (mmc->supply.vqmmc) {
ret = regulator_enable(mmc->supply.vqmmc);
-   if (ret < 0 && mmc->supply.vmmc)
-   ret = mmc_regulator_set_ocr(mmc,
-   mmc->supply.vmmc,
-   0);
+   if (ret) {
+   dev_err(dev, "vmmc_aux reg enable failed\n");
+   goto err_set_vqmmc;
+   }
}
} else {
/* Shut down the rail */
-   if (mmc->supply.vqmmc)
+   if (mmc->supply.vqmmc) {
ret = regulator_disable(mmc->supply.vqmmc);
+   if (ret) {
+   dev_err(dev, "vmmc_aux reg disable failed\n");
+   return ret;
+   }
+   }
+
if (mmc->supply.vmmc) {
/* Then proceed to shut down the local regulator */
ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+   if (ret)
+   return ret;
}
}
 
@@ -314,19 +329,32 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
ret = regulator_set_voltage(host->pbias, VDD_3V0,
VDD_3V0);
if (ret < 0)
-   goto error_set_power;
+   goto err_set_voltage;
 
if (host->pbias_enabled == 0) {
ret = regulator_enable(host->pbias);
-   if (!ret)
+   if (ret) {
+   dev_err(dev, "pbias reg enable failed\n");
+   goto err_set_voltage;
+   } else {
host->pbias_enabled = 1;
+   }
}
}
 
if (mmc_pdata(host)->after_set_reg)
mmc_pdata(host)->after_set_reg(dev, power_on, vdd);
 
-error_set_power:
+   return 0;
+
+err_set_voltage:
+   if (mmc->supply.vqmmc)
+   regulator_disable(mmc->supply.vqmmc);
+
+err_set_vqmmc:
+   if (mmc->supply.vmmc)
+   mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
return ret;
 }
 
-- 
1.7.9.5

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


[PATCH v2 03/16] mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()

2015-08-03 Thread Kishon Vijay Abraham I
No functional change. Instead of using a local regulator variable
in omap_hsmmc_reg_get() for holding the return value of
devm_regulator_get_optional() and then assigning to omap_hsmmc_host
regulator members: vcc, vcc_aux and pbias, directly use the
omap_hsmmc_host regulator members.

Signed-off-by: Kishon Vijay Abraham I 
Reviewed-by: Roger Quadros 
---
 drivers/mmc/host/omap_hsmmc.c |   38 --
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5637793..9d062a1 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -341,21 +341,19 @@ error_set_power:
 
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
-   struct regulator *reg;
int ocr_value = 0;
int ret;
 
-   reg = devm_regulator_get_optional(host->dev, "vmmc");
-   if (IS_ERR(reg)) {
-   ret = PTR_ERR(reg);
+   host->vcc = devm_regulator_get_optional(host->dev, "vmmc");
+   if (IS_ERR(host->vcc)) {
+   ret = PTR_ERR(host->vcc);
if (ret != -ENODEV)
return ret;
-   host->vcc = NULL;
dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
-   PTR_ERR(reg));
+   PTR_ERR(host->vcc));
+   host->vcc = NULL;
} else {
-   host->vcc = reg;
-   ocr_value = mmc_regulator_get_ocrmask(reg);
+   ocr_value = mmc_regulator_get_ocrmask(host->vcc);
if (!mmc_pdata(host)->ocr_mask) {
mmc_pdata(host)->ocr_mask = ocr_value;
} else {
@@ -370,28 +368,24 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
mmc_pdata(host)->set_power = omap_hsmmc_set_power;
 
/* Allow an aux regulator */
-   reg = devm_regulator_get_optional(host->dev, "vmmc_aux");
-   if (IS_ERR(reg)) {
-   ret = PTR_ERR(reg);
+   host->vcc_aux = devm_regulator_get_optional(host->dev, "vmmc_aux");
+   if (IS_ERR(host->vcc_aux)) {
+   ret = PTR_ERR(host->vcc_aux);
if (ret != -ENODEV)
return ret;
-   host->vcc_aux = NULL;
dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n",
-   PTR_ERR(reg));
-   } else {
-   host->vcc_aux = reg;
+   PTR_ERR(host->vcc_aux));
+   host->vcc_aux = NULL;
}
 
-   reg = devm_regulator_get_optional(host->dev, "pbias");
-   if (IS_ERR(reg)) {
-   ret = PTR_ERR(reg);
+   host->pbias = devm_regulator_get_optional(host->dev, "pbias");
+   if (IS_ERR(host->pbias)) {
+   ret = PTR_ERR(host->pbias);
if (ret != -ENODEV)
return ret;
-   host->pbias = NULL;
dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
-   PTR_ERR(reg));
-   } else {
-   host->pbias = reg;
+   PTR_ERR(host->pbias));
+   host->pbias = NULL;
}
 
/* For eMMC do not power off when not in sleep state */
-- 
1.7.9.5

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


[PATCH v2 02/16] mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get

2015-08-03 Thread Kishon Vijay Abraham I
Now return error only if the return value of
devm_regulator_get_optional() is not the same as -ENODEV, since with
-EPROBE_DEFER, the regulator can be obtained later and all other
errors are fatal.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b4b1bde..5637793 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -371,10 +371,28 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
 
/* Allow an aux regulator */
reg = devm_regulator_get_optional(host->dev, "vmmc_aux");
-   host->vcc_aux = IS_ERR(reg) ? NULL : reg;
+   if (IS_ERR(reg)) {
+   ret = PTR_ERR(reg);
+   if (ret != -ENODEV)
+   return ret;
+   host->vcc_aux = NULL;
+   dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n",
+   PTR_ERR(reg));
+   } else {
+   host->vcc_aux = reg;
+   }
 
reg = devm_regulator_get_optional(host->dev, "pbias");
-   host->pbias = IS_ERR(reg) ? NULL : reg;
+   if (IS_ERR(reg)) {
+   ret = PTR_ERR(reg);
+   if (ret != -ENODEV)
+   return ret;
+   host->pbias = NULL;
+   dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
+   PTR_ERR(reg));
+   } else {
+   host->pbias = reg;
+   }
 
/* For eMMC do not power off when not in sleep state */
if (mmc_pdata(host)->no_regulator_off_init)
-- 
1.7.9.5

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


[PATCH v2 04/16] mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator

2015-08-03 Thread Kishon Vijay Abraham I
If the vmmc regulator provides a valid ocrmask, use it. By this even if
the pdata has a valid ocrmask, it will be overwritten with the ocrmask
of the vmmc regulator.
Also remove the unnecessary compatibility check between the ocrmask in
the pdata and the ocrmask from the vmmc regulator.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 9d062a1..8cf040f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -354,16 +354,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
host->vcc = NULL;
} else {
ocr_value = mmc_regulator_get_ocrmask(host->vcc);
-   if (!mmc_pdata(host)->ocr_mask) {
+   if (ocr_value > 0)
mmc_pdata(host)->ocr_mask = ocr_value;
-   } else {
-   if (!(mmc_pdata(host)->ocr_mask & ocr_value)) {
-   dev_err(host->dev, "ocrmask %x is not 
supported\n",
-   mmc_pdata(host)->ocr_mask);
-   mmc_pdata(host)->ocr_mask = 0;
-   return -EINVAL;
-   }
-   }
}
mmc_pdata(host)->set_power = omap_hsmmc_set_power;
 
-- 
1.7.9.5

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


[PATCH v2 00/16] omap_hsmmc: regulator usage cleanup and fixes

2015-08-03 Thread Kishon Vijay Abraham I
Changes from v1:
*) return on -EPROBE_DEFER and other fatal errors. (Don't return only
   if the return value is -ENODEV)
*) Remove the beagle x15 dts patch. It can be part of a different
   series.
*) Avoid using regulator_is_enabled for vqmmc since if the regulator
   is shared and the other users are not using regulator_is_enabled
   then there can be unbalanced regulator_enable/regulator_disable

This patch series does the following
*) Uses devm_regulator_get_optional() for vmmc and then removes the
   CONFIG_REGULATOR check altogether.
*) return on -EPROBE_DEFER and any other fatal errors
*) enable/disable vmmc_aux regulator based on prior state

I've pushed this patch series to
git://git.ti.com/linux-phy/linux-phy.git mmc_regulator_cleanup_fixes_v2

Please note the branch also has the pbias fixes [1] & [2].
[1] -> https://lkml.org/lkml/2015/7/27/358
[2] -> https://lkml.org/lkml/2015/7/27/391

This series is in preparation for implementing the voltage switch
sequence so that UHS cards can be supported.

Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.

Kishon Vijay Abraham I (15):
  mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
  mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get
  mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
  mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
  mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
  mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
  mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
  mmc: host: omap_hsmmc: add separate functions for enable/disable
supply
  mmc: host: omap_hsmmc: add separate function to set pbias
  mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
  mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator
state
  mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
previous state
  mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
  mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage
  mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

Roger Quadros (1):
  mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
 drivers/mmc/host/omap_hsmmc.c  |  340 +---
 2 files changed, 224 insertions(+), 118 deletions(-)

-- 
1.7.9.5

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


[PATCH v2 01/16] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc

2015-08-03 Thread Kishon Vijay Abraham I
Since vmmc can be optional for some platforms, use
devm_regulator_get_optional() for vmmc. Now return error only
if the return value of devm_regulator_get_optional() is not the
same as -ENODEV, since with -EPROBE_DEFER, the regulator can be
obtained later and all other errors are fatal.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/mmc/host/omap_hsmmc.c |   10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4d12032..b4b1bde 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -343,12 +343,16 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
 {
struct regulator *reg;
int ocr_value = 0;
+   int ret;
 
-   reg = devm_regulator_get(host->dev, "vmmc");
+   reg = devm_regulator_get_optional(host->dev, "vmmc");
if (IS_ERR(reg)) {
-   dev_err(host->dev, "unable to get vmmc regulator %ld\n",
+   ret = PTR_ERR(reg);
+   if (ret != -ENODEV)
+   return ret;
+   host->vcc = NULL;
+   dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
PTR_ERR(reg));
-   return PTR_ERR(reg);
} else {
host->vcc = reg;
ocr_value = mmc_regulator_get_ocrmask(reg);
-- 
1.7.9.5

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


[PATCH] usb: musb: Allow building in all the DMA code

2015-08-03 Thread Tony Lindgren
With recent changes to MUSB code, we can now now get rid of
the Kconfig choise for the DMA code and allow building in any
of the desired DMA code. This makes life easier for distros.

Signed-off-by: Tony Lindgren 
---

This should be safe to dow now. Felipe, I've ran some randcocnfig
builds on it but it's probably a good idea to run some more.

---
 drivers/usb/musb/Kconfig | 38 ++
 1 file changed, 14 insertions(+), 24 deletions(-)

--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -124,19 +124,20 @@ config USB_MUSB_JZ4740
 config USB_MUSB_AM335X_CHILD
tristate
 
-choice
-   prompt 'MUSB DMA mode'
-   default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM || USB_MUSB_JZ4740
-   default USB_UX500_DMA if USB_MUSB_UX500
-   default USB_INVENTRA_DMA if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
-   default USB_TI_CPPI_DMA if USB_MUSB_DAVINCI
-   default USB_TUSB_OMAP_DMA if USB_MUSB_TUSB6010
-   default MUSB_PIO_ONLY if USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || 
USB_MUSB_AM35X \
-   || USB_MUSB_DSPS
+comment "MUSB DMA mode"
+
+config MUSB_PIO_ONLY
+   bool 'Disable DMA (always use PIO)'
help
- Unfortunately, only one option can be enabled here. Ideally one
- should be able to build all these drivers into one kernel to
- allow using DMA on multiplatform kernels.
+ All data is copied between memory and FIFO by the CPU.
+ DMA controllers are ignored.
+
+ Do not choose this unless DMA support for your SOC or board
+ is unavailable (or unstable).  When DMA is enabled at compile time,
+ you can still disable it at run time using the "use_dma=n" module
+ parameter.
+
+if !MUSB_PIO_ONLY
 
 config USB_UX500_DMA
bool 'ST Ericsson Ux500'
@@ -168,17 +169,6 @@ config USB_TUSB_OMAP_DMA
help
  Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
 
-config MUSB_PIO_ONLY
-   bool 'Disable DMA (always use PIO)'
-   help
- All data is copied between memory and FIFO by the CPU.
- DMA controllers are ignored.
-
- Do not choose this unless DMA support for your SOC or board
- is unavailable (or unstable).  When DMA is enabled at compile time,
- you can still disable it at run time using the "use_dma=n" module
- parameter.
-
-endchoice
+endif # !MUSB_PIO_ONLY
 
 endif # USB_MUSB_HDRC
-- 
2.1.4

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


Re: [PATCH 03/12] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2015-08-03 Thread Tony Lindgren
* Roger Quadros  [150731 03:24]:
> 
> One more observation I've had is that using irqchip modelling for
> the 2 NAND events causes a performance impact.
> 
> Using mtd_oobtest I see the following on dra7-evm
> 
> 1) v4.2-rc4 with prefetch-polled (no IRQs used)
> mtd_speedtest: eraseblock write speed is 7142 KiB/s
> mtd_speedtest: eraseblock read speed is 13721 KiB/s
> 
> 2) v4.2-rc4 with prefetch-irq (IRQchip model)
> eraseblock write speed is 5475 KiB/s
> eraseblock read speed is 6420 KiB/s
> 
> 3) this series (*) with prefetch-irq (no IRQchip model, nand driver
> directly accesses irqstatus/irqenable)
> eraseblock write speed is 6564 KiB/s
> eraseblock read speed is 10850 KiB/s
> 
> (*) diff at the end is required on top to fix an issue with this series.
> 
> So should we continue IRQchip modelling for the NAND events
> or use the GPMC interrupt as shared and add APIs to access
> the NAND bits of the IRQSTATUS/ENABLE register.

In the long run chained IRQ would be the most flexible solution
for sure.

It might be worth checking why we have so much overhead with
the irqchip modelling compared to shared IRQ. If the overhead
is really all the extra IRQ handling then it seems the shared
interrupt plus an API to access IRQSTATUS/ENABLE is the way
to go. Up to you.

Regards,

Tony

 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index fecc054..26ef2bd 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1832,13 +1832,14 @@ static int omap_get_dt_info(struct device *dev, 
> struct omap_nand_info *info)
>   for (i = 0; i < ARRAY_SIZE(nand_xfer_types); i++) {
>   if (!strcasecmp(s, nand_xfer_types[i])) {
>   info->xfer_type = i;
> - break;
> + goto next;
>   }
>   }
>  
>   dev_err(dev, "unrecognized value for ti,nand-xfer-type\n");
>   return -EINVAL;
>   }
> +next:
>  
>   of_get_nand_on_flash_bbt(child);
>  
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 26ef2bd..e8bdff5 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -670,17 +670,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void 
> *dev)
>   goto done;
>   }
>  
> - /* Clear FIFOEVENT STATUS */
> - irqstatus &= ~GPMC_IRQ_FIFOEVENT;
> - writel(irqstatus, info->reg.gpmc_irqstatus);
> -
>   return IRQ_HANDLED;
>  
>  done:
>   complete(&info->comp);
>  
> - /* Clear FIFOEVENT and TERMCOUNT STATUS */
> - irqstatus &= ~(GPMC_IRQ_TERMCOUNT | GPMC_IRQ_FIFOEVENT);
> + /* Clear IRQ STATUS */
>   writel(irqstatus, info->reg.gpmc_irqstatus);
>  
>   /* Disable Interrupt generation */
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: cpuidle results in ethernet degredation ?

2015-08-03 Thread Tony Lindgren
* Ran Shalit  [150801 11:34]:
> Hi ,
> 
> I've accidently omitted linux-omap in last message, so please here it is 
> again:
> 
> I think that if someone here understand cpuidle it may lead me to a 
> solution...
> 
> 1. I'm using TI's kernel 2.6.37
> http://git.kernel.org/cgit/linux/kernel/git/tmlind/linux-omap.git/

Hmm that's not the TI kernel, that's where we keep the omap patches
heading to the mainline kernel tree :)

> 2. I think it is related to the menu governer who decides on c-state change.
> But I'm not sure what and how I need to change so that the ethernet
> test for small windows will have same performance as without PM.
> 3. I see that the performace as tested with iperf has the same
> performace results with large packets but with small packets (smaller
> then 2000 bytes) there is high degredation (only if cpuidle is used)
> I also see that the counter for C3(core inactive - not retention yet)
> state is icremented with the small packet test.
> Does anyone have any idea why the small packet test results in
> entering (and exit ) several times the core inactive state? Why does
> not it happen with big packet test? And what can I do to overcome this
> degredation?
> 4. Can anyone try to run iperf with small packet (2000 bytes or below)
> for checking ethernet bandwidth? And then compare this with results in
> kernel without power management support?

If you don't have anything blocking deeper idle states from the
Ethernet controller then the hardware can start entering deeper
idle states. I can see this happening when transferring data with
DMA over Ethernet especially if you have an external Ethernet
controller connected to GPMC. If you cannot rely on the hardware
IDLEST bits to keep the system from entering deeper idle states,
then you have to use the runtime PM API to do it somehow.

Regards,

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


Re: [PATCH 00/11] Some OMAP IOMMU cleanup patches

2015-08-03 Thread Joerg Roedel
On Mon, Jul 20, 2015 at 05:33:22PM -0500, Suman Anna wrote:
> Suman Anna (11):
>   Documentation: dt: Add #iommu-cells info to OMAP iommu bindings
>   iommu/omap: Remove all module references
>   iommu/omap: Move debugfs functions to omap-iommu-debug.c
>   iommu/omap: Protect omap-iopgtable.h against double inclusion
>   iommu/omap: Remove unused union fields
>   iommu/omap: Remove trailing semi-colon from a macro
>   iommu/omap: Remove unnecessary error traces on alloc failures
>   iommu/omap: Use BIT(x) macros in omap-iopgtable.h
>   iommu/omap: Use BIT(x) macros in omap-iommu.h
>   iommu/omap: Align code with open parenthesis

Applied these patches to arm/omap.

>   iommu/omap: Split multiple assignments into separate lines

Did not apply this one, there is nothing wrong with multiple
assignments.


Joerg

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


Re: cpuidle results in ethernet degredation ?

2015-08-03 Thread Ran Shalit
On Mon, Aug 3, 2015 at 4:21 PM, Tony Lindgren  wrote:
> * Ran Shalit  [150801 11:34]:
>> Hi ,
>>
>> I've accidently omitted linux-omap in last message, so please here it is 
>> again:
>>
>> I think that if someone here understand cpuidle it may lead me to a 
>> solution...
>>
>> 1. I'm using TI's kernel 2.6.37
>> http://git.kernel.org/cgit/linux/kernel/git/tmlind/linux-omap.git/
>
> Hmm that's not the TI kernel, that's where we keep the omap patches
> heading to the mainline kernel tree :)
>
>> 2. I think it is related to the menu governer who decides on c-state change.
>> But I'm not sure what and how I need to change so that the ethernet
>> test for small windows will have same performance as without PM.
>> 3. I see that the performace as tested with iperf has the same
>> performace results with large packets but with small packets (smaller
>> then 2000 bytes) there is high degredation (only if cpuidle is used)
>> I also see that the counter for C3(core inactive - not retention yet)
>> state is icremented with the small packet test.
>> Does anyone have any idea why the small packet test results in
>> entering (and exit ) several times the core inactive state? Why does
>> not it happen with big packet test? And what can I do to overcome this
>> degredation?
>> 4. Can anyone try to run iperf with small packet (2000 bytes or below)
>> for checking ethernet bandwidth? And then compare this with results in
>> kernel without power management support?
>
> If you don't have anything blocking deeper idle states from the
> Ethernet controller then the hardware can start entering deeper
> idle states. I can see this happening when transferring data with
> DMA over Ethernet especially if you have an external Ethernet
> controller connected to GPMC. If you cannot rely on the hardware
> IDLEST bits to keep the system from entering deeper idle states,
> then you have to use the runtime PM API to do it somehow.
>
> Regards,
>
> Tony

Hi,

I am using GPMC with smsc911x controller.
If I understand you correctly, I can overcome this, but asking the
hardware not get into inactive state.
I actully need that the code won't get into inactive state (I don't
think that anyelse is inactive, except the core - this is C3 state).
The problem with this approach is that I'm not sure I can determine
when to decide "turn cpuidle off" and when to decide "turn cpuidle
on".
I thought that if there is a way to ask the governer (in tickless
kernel, it is menu governer), to wait for a longer time, before
deciding to get into sleep.
I think that if it waits longer time, it will see that there are tasks
to do (small packets in iperf test), and will not enter sleep state.
Is that possible ? Is there any parameter in governer which control this ?

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


[PATCH v4 1/2] extcon: palmas: Support GPIO based USB ID detection

2015-08-03 Thread Roger Quadros
Some palmas based chip variants do not have OTG based ID logic.
For these variants we rely on GPIO based USB ID detection.

These chips do have VBUS comparator for VBUS detection so we
continue to use the old way of detecting VBUS.

Acked-by: Chanwoo Choi 
Signed-off-by: Roger Quadros 
---
v4: updated gpio debounce logic to use delayed_workqueue.

 .../devicetree/bindings/extcon/extcon-palmas.txt   |   5 +-
 drivers/extcon/extcon-palmas.c | 129 ++---
 drivers/extcon/extcon-usb-gpio.c   |   1 +
 include/linux/mfd/palmas.h |   7 ++
 4 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/extcon/extcon-palmas.txt 
b/Documentation/devicetree/bindings/extcon/extcon-palmas.txt
index 45414bb..f61d5af 100644
--- a/Documentation/devicetree/bindings/extcon/extcon-palmas.txt
+++ b/Documentation/devicetree/bindings/extcon/extcon-palmas.txt
@@ -10,8 +10,11 @@ Required Properties:
 
 Optional Properties:
  - ti,wakeup : To enable the wakeup comparator in probe
- - ti,enable-id-detection: Perform ID detection.
+ - ti,enable-id-detection: Perform ID detection. If id-gpio is specified
+   it performs id-detection using GPIO else using OTG core.
  - ti,enable-vbus-detection: Perform VBUS detection.
+ - id-gpio: gpio for GPIO ID detection. See gpio binding.
+ - debounce-delay-ms: debounce delay for GPIO ID pin in milliseconds.
 
 palmas-usb {
compatible = "ti,twl6035-usb", "ti,palmas-usb";
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index 8933e7e..662e917 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+
+#define USB_GPIO_DEBOUNCE_MS   20  /* ms */
 
 static const unsigned int palmas_extcon_cable[] = {
EXTCON_USB,
@@ -118,19 +122,54 @@ static irqreturn_t palmas_id_irq_handler(int irq, void 
*_palmas_usb)
return IRQ_HANDLED;
 }
 
+static void palmas_gpio_id_detect(struct work_struct *work)
+{
+   int id;
+   struct palmas_usb *palmas_usb = container_of(to_delayed_work(work),
+struct palmas_usb,
+wq_detectid);
+   struct extcon_dev *edev = palmas_usb->edev;
+
+   if (!palmas_usb->id_gpiod)
+   return;
+
+   id = gpiod_get_value_cansleep(palmas_usb->id_gpiod);
+
+   if (id) {
+   extcon_set_cable_state_(edev, EXTCON_USB_HOST, false);
+   dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
+   } else {
+   extcon_set_cable_state_(edev, EXTCON_USB_HOST, true);
+   dev_info(palmas_usb->dev, "USB-HOST cable is attached\n");
+   }
+}
+
+static irqreturn_t palmas_gpio_id_irq_handler(int irq, void *_palmas_usb)
+{
+   struct palmas_usb *palmas_usb = _palmas_usb;
+
+   queue_delayed_work(system_power_efficient_wq, &palmas_usb->wq_detectid,
+  palmas_usb->sw_debounce_jiffies);
+
+   return IRQ_HANDLED;
+}
+
 static void palmas_enable_irq(struct palmas_usb *palmas_usb)
 {
palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
PALMAS_USB_VBUS_CTRL_SET,
PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP);
 
-   palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
-   PALMAS_USB_ID_CTRL_SET, PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP);
+   if (palmas_usb->enable_id_detection) {
+   palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+PALMAS_USB_ID_CTRL_SET,
+PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP);
 
-   palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
-   PALMAS_USB_ID_INT_EN_HI_SET,
-   PALMAS_USB_ID_INT_EN_HI_SET_ID_GND |
-   PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT);
+   palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+PALMAS_USB_ID_INT_EN_HI_SET,
+PALMAS_USB_ID_INT_EN_HI_SET_ID_GND |
+PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT);
+   }
 
if (palmas_usb->enable_vbus_detection)
palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb);
@@ -169,20 +208,36 @@ static int palmas_usb_probe(struct platform_device *pdev)
palmas_usb->wakeup = pdata->wakeup;
}
 
+   palmas_usb->id_gpiod = devm_gpiod_get_optional(&pdev->dev, "id");
+   if (IS_ERR(palmas_usb->id_gpiod)) {
+   dev_err(&pdev->dev, "failed to get id gpio\n");
+   return PTR_ERR(palmas_usb->id_gpiod);
+   }
+
+   if (palmas_usb->enable_id_detection && palmas_usb->id_gpiod) {
+   palmas_usb->enable_id_detection = false;
+   palmas_usb->enable_gpio_id_detection = true;
+   }
+
+   if (palmas_

Re: [PATCH v2 3/3] ARM: dts: dra7: Add scm_conf@1c04 node

2015-08-03 Thread Kishon Vijay Abraham I
Hi Roger,

On Monday 27 July 2015 03:57 PM, Roger Quadros wrote:
> This region contains CTRL_CORE_SMA_SW2..9 registers which
> are not specific to any domain and can be reasonably
> accessed via syscon driver.
> 
> Signed-off-by: Roger Quadros 
> ---
>  arch/arm/boot/dts/dra7.dtsi | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index 913032b..43b5074 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -149,6 +149,13 @@
>   pinctrl-single,register-width = <32>;
>   pinctrl-single,function-mask = 
> <0x3fff>;
>   };
> +
> + scm_conf1: scm_conf@1c04 {
> + compatible = "syscon";
> + reg = <0x1c04 0x0020>;
> + #address-cells = <1>;
> + #size-cells = <1>;

Why do you need address-cells and size-cells property here? AFAIK it is usually
used to decode childs reg property.

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


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2015-07-30 20:51:10 [-0400]:

>Hi John,
Hi Peter,

>I was never really a fan of the deferred set_termios();
>I think it's more appropriate to wait for tx dma to
>complete in omap_8250_set_termios().

So you want something like this? This was only compile + boot tested
(without triggering the corner case) and I know that 8250.h piece has to
go in a separated patch (as requested in 2/3 of this series). Just checking
if this is what you had in mind.

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index c43f74c53cd9..a407757dcecc 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -42,9 +42,9 @@ struct uart_8250_dma {
size_t  rx_size;
size_t  tx_size;
 
-   unsigned char   tx_running:1;
-   unsigned char   tx_err: 1;
-   unsigned char   rx_running:1;
+   unsigned char   tx_running;
+   unsigned char   tx_err;
+   unsigned char   rx_running;
 };
 
 struct old_serial_port {
diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index d9a37191a1ae..12249125a218 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -100,9 +100,9 @@ struct omap8250_priv {
u8 wer;
u8 xon;
u8 xoff;
-   u8 delayed_restore;
u16 quot;
 
+   wait_queue_head_t termios_wait;
bool is_suspending;
int wakeirq;
int wakeups_enabled;
@@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port *up,
 static void omap8250_restore_regs(struct uart_8250_port *up)
 {
struct omap8250_priv *priv = up->port.private_data;
-   struct uart_8250_dma*dma = up->dma;
-
-   if (dma && dma->tx_running) {
-   /*
-* TCSANOW requests the change to occur immediately however if
-* we have a TX-DMA operation in progress then it has been
-* observed that it might stall and never complete. Therefore we
-* delay DMA completes to prevent this hang from happen.
-*/
-   priv->delayed_restore = 1;
-   return;
-   }
 
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
@@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
up->port.ops->set_mctrl(&up->port, up->port.mctrl);
 }
 
+static void omap_8250_dma_tx_complete(void *param);
 /*
  * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have
  * some differences in how we want to handle flow control.
@@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port *port,
struct omap8250_priv *priv = up->port.private_data;
unsigned char cval = 0;
unsigned int baud;
+   unsigned int complete_dma = 0;
 
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port *port,
if (termios->c_iflag & IXANY)
up->mcr |= UART_MCR_XONANY;
}
+
+   if (up->dma && up->dma->tx_running) {
+   struct uart_8250_dma*dma = up->dma;
+
+   /*
+* TCSANOW requests the change to occur immediately however if
+* we have a TX-DMA operation in progress then it has been
+* observed that it might stall and never complete. Therefore we
+* wait until DMA completes to prevent this hang from happen.
+*/
+
+   dma->tx_running = 2;
+
+   spin_unlock_irq(&up->port.lock);
+   wait_event(priv->termios_wait,
+  dma->tx_running == 3);
+   spin_lock_irq(&up->port.lock);
+   complete_dma = 1;
+   }
omap8250_restore_regs(up);
 
spin_unlock_irq(&up->port.lock);
@@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port *port,
/* Don't rewrite B0 */
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
+   if (complete_dma)
+   omap_8250_dma_tx_complete(up);
 }
 
 /* same as 8250 except that we may have extra flow bits set in EFR */
@@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
 
spin_lock_irqsave(&p->port.lock, flags);
 
+   if (dma->tx_running == 2) {
+   dma->tx_running = 3;
+   wake_up(&priv->termios_wait);
+   goto out;
+   }
+
dma->tx_running = 0;
 
xmit->tail += dma->tx_size;
xmit->tail &= UART_XMIT_SIZE - 1;
p->port.icount.tx += dma->tx_size;
 
-   if (priv->delayed_restore) {
-   priv->delayed_restore = 0;
-   omap8250_restore_regs(p);
-   }
-
if (uart_circ_chars_pending(xmit) 

Re: [PATCH 00/11] Some OMAP IOMMU cleanup patches

2015-08-03 Thread Suman Anna
On 08/03/2015 08:55 AM, Joerg Roedel wrote:
> On Mon, Jul 20, 2015 at 05:33:22PM -0500, Suman Anna wrote:
>> Suman Anna (11):
>>   Documentation: dt: Add #iommu-cells info to OMAP iommu bindings
>>   iommu/omap: Remove all module references
>>   iommu/omap: Move debugfs functions to omap-iommu-debug.c
>>   iommu/omap: Protect omap-iopgtable.h against double inclusion
>>   iommu/omap: Remove unused union fields
>>   iommu/omap: Remove trailing semi-colon from a macro
>>   iommu/omap: Remove unnecessary error traces on alloc failures
>>   iommu/omap: Use BIT(x) macros in omap-iopgtable.h
>>   iommu/omap: Use BIT(x) macros in omap-iommu.h
>>   iommu/omap: Align code with open parenthesis
> 
> Applied these patches to arm/omap.

Thanks Joerg.

> 
>>   iommu/omap: Split multiple assignments into separate lines
> 
> Did not apply this one, there is nothing wrong with multiple
> assignments.

Yeah, that was just to satisfy checkpatch --strict.

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



Re: [PATCH 0/2] DRA7 DSP MMU config support

2015-08-03 Thread Joerg Roedel
On Tue, Jul 21, 2015 at 06:55:34PM -0500, Suman Anna wrote:
> The patches are baselined on 4.2-rc3 + the recent OMAP IOMMU
> cleanup series [1]. I will post the DTS patches separately to
> allow Tony to pick them up independently.

>From the discussion it looks like some more work is necessary here.
Before you repost, please also test on older omap hardware to make sure
nothing breaks there. Please also describe the testing you did in the
repost.


Joerg

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


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Peter Hurley
[ +cc Heikki ]

Hi Sebastian,

On 08/03/2015 12:09 PM, Sebastian Andrzej Siewior wrote:
> * Peter Hurley | 2015-07-30 20:51:10 [-0400]:
> 
>> Hi John,
> Hi Peter,
> 
>> I was never really a fan of the deferred set_termios();
>> I think it's more appropriate to wait for tx dma to
>> complete in omap_8250_set_termios().
> 
> So you want something like this? This was only compile + boot tested
> (without triggering the corner case) and I know that 8250.h piece has to
> go in a separated patch (as requested in 2/3 of this series). Just checking
> if this is what you had in mind.
> 
> diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
> index c43f74c53cd9..a407757dcecc 100644
> --- a/drivers/tty/serial/8250/8250.h
> +++ b/drivers/tty/serial/8250/8250.h
> @@ -42,9 +42,9 @@ struct uart_8250_dma {
>   size_t  rx_size;
>   size_t  tx_size;
>  
> - unsigned char   tx_running:1;
> - unsigned char   tx_err: 1;
> - unsigned char   rx_running:1;
> + unsigned char   tx_running;
> + unsigned char   tx_err;
> + unsigned char   rx_running;
>  };

This part is ok.

>  struct old_serial_port {
> diff --git a/drivers/tty/serial/8250/8250_omap.c 
> b/drivers/tty/serial/8250/8250_omap.c
> index d9a37191a1ae..12249125a218 100644
> --- a/drivers/tty/serial/8250/8250_omap.c
> +++ b/drivers/tty/serial/8250/8250_omap.c
> @@ -100,9 +100,9 @@ struct omap8250_priv {
>   u8 wer;
>   u8 xon;
>   u8 xoff;
> - u8 delayed_restore;
>   u16 quot;
>  
> + wait_queue_head_t termios_wait;
>   bool is_suspending;
>   int wakeirq;
>   int wakeups_enabled;
> @@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port 
> *up,
>  static void omap8250_restore_regs(struct uart_8250_port *up)
>  {
>   struct omap8250_priv *priv = up->port.private_data;
> - struct uart_8250_dma*dma = up->dma;
> -
> - if (dma && dma->tx_running) {
> - /*
> -  * TCSANOW requests the change to occur immediately however if
> -  * we have a TX-DMA operation in progress then it has been
> -  * observed that it might stall and never complete. Therefore we
> -  * delay DMA completes to prevent this hang from happen.
> -  */
> - priv->delayed_restore = 1;
> - return;
> - }
>  
>   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>   serial_out(up, UART_EFR, UART_EFR_ECB);
> @@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port 
> *up)
>   up->port.ops->set_mctrl(&up->port, up->port.mctrl);
>  }
>  
> +static void omap_8250_dma_tx_complete(void *param);
>  /*
>   * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have
>   * some differences in how we want to handle flow control.
> @@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port *port,
>   struct omap8250_priv *priv = up->port.private_data;
>   unsigned char cval = 0;
>   unsigned int baud;
> + unsigned int complete_dma = 0;
>  
>   switch (termios->c_cflag & CSIZE) {
>   case CS5:
> @@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port *port,
>   if (termios->c_iflag & IXANY)
>   up->mcr |= UART_MCR_XONANY;
>   }
> +
> + if (up->dma && up->dma->tx_running) {
> + struct uart_8250_dma*dma = up->dma;
> +
> + /*
> +  * TCSANOW requests the change to occur immediately however if
> +  * we have a TX-DMA operation in progress then it has been
> +  * observed that it might stall and never complete. Therefore we
> +  * wait until DMA completes to prevent this hang from happen.
> +  */
> +
> + dma->tx_running = 2;
> +
> + spin_unlock_irq(&up->port.lock);
> + wait_event(priv->termios_wait,
> +dma->tx_running == 3);

Doesn't the dmaengine api offer a race-free way to wait for pending tx dma
to complete?

Maybe we could wrap that in the 8250 dma api?

Regards,
Peter Hurley

> + spin_lock_irq(&up->port.lock);
> + complete_dma = 1;
> + }
>   omap8250_restore_regs(up);
>  
>   spin_unlock_irq(&up->port.lock);
> @@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port *port,
>   /* Don't rewrite B0 */
>   if (tty_termios_baud_rate(termios))
>   tty_termios_encode_baud_rate(termios, baud, baud);
> + if (complete_dma)
> + omap_8250_dma_tx_complete(up);
>  }
>  
>  /* same as 8250 except that we may have extra flow bits set in EFR */
> @@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
>  
>   spin_lock_irqsave(&p->port.lock, flags);
>  
> + if (dma->tx_running == 2) {
> + dma->tx_running = 3;
> + wake_up(&priv->

Re: [PATCH 0/2] DRA7 DSP MMU config support

2015-08-03 Thread Suman Anna
On 08/03/2015 11:31 AM, Joerg Roedel wrote:
> On Tue, Jul 21, 2015 at 06:55:34PM -0500, Suman Anna wrote:
>> The patches are baselined on 4.2-rc3 + the recent OMAP IOMMU
>> cleanup series [1]. I will post the DTS patches separately to
>> allow Tony to pick them up independently.
> 
> From the discussion it looks like some more work is necessary here.
> Before you repost, please also test on older omap hardware to make sure
> nothing breaks there. Please also describe the testing you did in the
> repost.

Yes, sure will do. I will repost once the next -rc1 is out.

regards
Suman

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


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Sebastian Andrzej Siewior
On 08/03/2015 06:34 PM, Peter Hurley wrote:
> Hi Sebastian,

Hi Peter,

>>  struct old_serial_port {
>> diff --git a/drivers/tty/serial/8250/8250_omap.c 
>> b/drivers/tty/serial/8250/8250_omap.c
>> index d9a37191a1ae..12249125a218 100644
>> --- a/drivers/tty/serial/8250/8250_omap.c
>> +++ b/drivers/tty/serial/8250/8250_omap.c
>> @@ -100,9 +100,9 @@ struct omap8250_priv {
>>  u8 wer;
>>  u8 xon;
>>  u8 xoff;
>> -u8 delayed_restore;
>>  u16 quot;
>>  
>> +wait_queue_head_t termios_wait;
>>  bool is_suspending;
>>  int wakeirq;
>>  int wakeups_enabled;
>> @@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port 
>> *up,
>>  static void omap8250_restore_regs(struct uart_8250_port *up)
>>  {
>>  struct omap8250_priv *priv = up->port.private_data;
>> -struct uart_8250_dma*dma = up->dma;
>> -
>> -if (dma && dma->tx_running) {
>> -/*
>> - * TCSANOW requests the change to occur immediately however if
>> - * we have a TX-DMA operation in progress then it has been
>> - * observed that it might stall and never complete. Therefore we
>> - * delay DMA completes to prevent this hang from happen.
>> - */
>> -priv->delayed_restore = 1;
>> -return;
>> -}
>>  
>>  serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>>  serial_out(up, UART_EFR, UART_EFR_ECB);
>> @@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port 
>> *up)
>>  up->port.ops->set_mctrl(&up->port, up->port.mctrl);
>>  }
>>  
>> +static void omap_8250_dma_tx_complete(void *param);
>>  /*
>>   * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have 
>> have
>>   * some differences in how we want to handle flow control.
>> @@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port *port,
>>  struct omap8250_priv *priv = up->port.private_data;
>>  unsigned char cval = 0;
>>  unsigned int baud;
>> +unsigned int complete_dma = 0;
>>  
>>  switch (termios->c_cflag & CSIZE) {
>>  case CS5:
>> @@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port 
>> *port,
>>  if (termios->c_iflag & IXANY)
>>  up->mcr |= UART_MCR_XONANY;
>>  }
>> +
>> +if (up->dma && up->dma->tx_running) {
>> +struct uart_8250_dma*dma = up->dma;
>> +
>> +/*
>> + * TCSANOW requests the change to occur immediately however if
>> + * we have a TX-DMA operation in progress then it has been
>> + * observed that it might stall and never complete. Therefore we
>> + * wait until DMA completes to prevent this hang from happen.
>> + */
>> +
>> +dma->tx_running = 2;
>> +
>> +spin_unlock_irq(&up->port.lock);
>> +wait_event(priv->termios_wait,
>> +   dma->tx_running == 3);
> 
> Doesn't the dmaengine api offer a race-free way to wait for pending tx dma
> to complete?

Not that I know of. You still need to ensure that once that DMA
completed, nobody triggers another TX transfer before you do what you
planned. This is ensures by the tx_running != 0 and the spin lock.

> Maybe we could wrap that in the 8250 dma api?

You mean a function in 8250-dma API which does what I did just here
with the wait_event() and the wake_up in the callback? That way I could
move the termios_wait into the dma struct instead of keeping in the
omap specific part. I am also not sure if OMAP is the only one that may
hang here or the other people just didn't notice it yet.

> Regards,
> Peter Hurley
> 
>> +spin_lock_irq(&up->port.lock);
>> +complete_dma = 1;
>> +}
>>  omap8250_restore_regs(up);
>>  
>>  spin_unlock_irq(&up->port.lock);
>> @@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port *port,
>>  /* Don't rewrite B0 */
>>  if (tty_termios_baud_rate(termios))
>>  tty_termios_encode_baud_rate(termios, baud, baud);
>> +if (complete_dma)
>> +omap_8250_dma_tx_complete(up);
>>  }
>>  
>>  /* same as 8250 except that we may have extra flow bits set in EFR */
>> @@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
>>  
>>  spin_lock_irqsave(&p->port.lock, flags);
>>  
>> +if (dma->tx_running == 2) {
>> +dma->tx_running = 3;
>> +wake_up(&priv->termios_wait);
>> +goto out;
>> +}
>> +
>>  dma->tx_running = 0;
>>  
>>  xmit->tail += dma->tx_size;
>>  xmit->tail &= UART_XMIT_SIZE - 1;
>>  p->port.icount.tx += dma->tx_size;
>>  
>> -if (priv->delayed_restore) {
>> -priv->delayed_restore = 0;
>> -omap8250_restore_regs(p);
>> -}
>> -
>>  if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
>>  uart_write_wakeup(&p->port);
>>  
>> @@ -899,7 +911,7 @@ static void omap_8250_dma_tx_complete(void *pa

Re: Nokia N900 - audio TPA6130A2 problems

2015-08-03 Thread Pali Rohár
On Monday 03 August 2015 20:03:16 Jarkko Nikula wrote:
> Hi
> 
> On 08/01/2015 01:18 PM, Pali Rohár wrote:
> > On Saturday 25 July 2015 15:17:13 Lars-Peter Clausen wrote:
> >> On 07/25/2015 12:28 PM, Pali Rohár wrote:
> >>> Hello,
> >>> 
> >>> sometimes after rebooting Nokia N900 initializing alsa audio
> >>> fails. Here output from dmesg log when it happen:
> >>> 
> >>> [6.925140] tpa6130a2 2-0060: Write failed
> >>> [6.929534] tpa6130a2 2-0060: Failed to initialize chip
> >>> [6.935272] tpa6130a2: probe of 2-0060 failed with error -121
> >>> [7.624237] rx51-audio n900-audio: Failed to add TPA6130A2
> >>> controls [7.635101] rx51-audio n900-audio: ASoC: failed to
> >>> init TLV320AIC34: -19 [7.645874] rx51-audio n900-audio: ASoC:
> >>> failed to instantiate card -19 [7.665740] rx51-audio
> >>> n900-audio: snd_soc_register_card failed (-19) [8.063049]
> >>> ALSA device list:
> >>> [8.070343]   No soundcards found.
> >>> 
> >>> Any idea what to do?
> >> 
> >> Looks like the chip is not responding. Try to add a small delay
> >> after powerup to give the device to be fully ready, something
> >> like the following:
> >> 
> >> --- a/sound/soc/codecs/tpa6130a2.c
> >> +++ b/sound/soc/codecs/tpa6130a2.c
> >> @@ -152,6 +152,8 @@ static int tpa6130a2_power(u8 power)
> >> 
> >>if (data->power_gpio >= 0)
> >>
> >>gpio_set_value(data->power_gpio, 1);
> >> 
> >> +  msleep(5);
> >> +
> >> 
> >>data->power_state = 1;
> >>ret = tpa6130a2_initialize();
> >>if (ret < 0) {
> > 
> > Hello, your patch did not helped. Problem is still there...
> 
> For me v4.2-rc5 works, i.e. TPA6130A2 can still play loudly to
> headphones. Don't know were there any i2c etc regression before it or
> how easy it would be to reproduce.
> 

Did you tested it on Nokia N900? Or other device?

> Logs below made me thinking can it be a HW issue? Although if it is
> an HW issue it shouldn't work sometimes I guess. Do you have any
> earlier well known configuration you could try is it an SW
> regression or something else?
> 

Stock Nokia's 2.6.28 kernel works always. With that kernel I have never 
seen this problem. So I do not think this is HW problem.

This problem is there in more kernel versions, maybe in some older (like 
v3.5) is was there not so often. But do not remember correctly...

> > [5.962585] tpa6130a2 2-0060: Write failed
> > [5.962707] tpa6130a2 2-0060: Failed to initialize chip
> > [5.962860] tpa6130a2: probe of 2-0060 failed with error -121
> 
> -121 == EREMOTEIO which is returned from i2c-omap.c when there is no
> ACK from the chip.
> 

Maybe some power management problem? Something is not always initialized 
correctly?

I remember that there is some problem (maybe in NoLo - Nokia bootloader) 
that sometimes chainloaded U-Boot (booted via NoLo) is not able to 
initialize mmc chip (all read operation fails). In U-Boot I added some 
code to enable some parts in twl4030 regulator and after that mmc is 
working always...

So maybe something similar? Kernel expects that some PM or regulator 
parts are initialized, but they are only sometimes? Just speculation...

> > [   28.102233] omap_i2c 48072000.i2c: controller timed out
> > [   29.463653] lp5523x 2-0032: lp5523 Programmable led chip found
> > [   30.734191] omap_i2c 48072000.i2c: controller timed out waiting
> > for start condition to finish [   32.142333] i2c i2c-2: SCL is
> > stuck low, exit recovery
> 
> If SCL is really stuck it also explains why chip doesn't acknowledge.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: This is a digitally signed message part.


Re: Nokia N900 - audio TPA6130A2 problems

2015-08-03 Thread Jarkko Nikula
Hi

On 08/01/2015 01:18 PM, Pali Rohár wrote:
> On Saturday 25 July 2015 15:17:13 Lars-Peter Clausen wrote:
>> On 07/25/2015 12:28 PM, Pali Rohár wrote:
>>> Hello,
>>>
>>> sometimes after rebooting Nokia N900 initializing alsa audio fails.
>>> Here output from dmesg log when it happen:
>>>
>>> [6.925140] tpa6130a2 2-0060: Write failed
>>> [6.929534] tpa6130a2 2-0060: Failed to initialize chip
>>> [6.935272] tpa6130a2: probe of 2-0060 failed with error -121
>>> [7.624237] rx51-audio n900-audio: Failed to add TPA6130A2
>>> controls [7.635101] rx51-audio n900-audio: ASoC: failed to
>>> init TLV320AIC34: -19 [7.645874] rx51-audio n900-audio: ASoC:
>>> failed to instantiate card -19 [7.665740] rx51-audio
>>> n900-audio: snd_soc_register_card failed (-19) [8.063049] ALSA
>>> device list:
>>> [8.070343]   No soundcards found.
>>>
>>> Any idea what to do?
>>
>> Looks like the chip is not responding. Try to add a small delay after
>> powerup to give the device to be fully ready, something like the
>> following:
>>
>> --- a/sound/soc/codecs/tpa6130a2.c
>> +++ b/sound/soc/codecs/tpa6130a2.c
>> @@ -152,6 +152,8 @@ static int tpa6130a2_power(u8 power)
>>  if (data->power_gpio >= 0)
>>  gpio_set_value(data->power_gpio, 1);
>>
>> +msleep(5);
>> +
>>  data->power_state = 1;
>>  ret = tpa6130a2_initialize();
>>  if (ret < 0) {
> 
> 
> Hello, your patch did not helped. Problem is still there...
> 
For me v4.2-rc5 works, i.e. TPA6130A2 can still play loudly to
headphones. Don't know were there any i2c etc regression before it or
how easy it would be to reproduce.

Logs below made me thinking can it be a HW issue? Although if it is an
HW issue it shouldn't work sometimes I guess. Do you have any earlier
well known configuration you could try is it an SW regression or
something else?

> [5.962585] tpa6130a2 2-0060: Write failed
> [5.962707] tpa6130a2 2-0060: Failed to initialize chip
> [5.962860] tpa6130a2: probe of 2-0060 failed with error -121

-121 == EREMOTEIO which is returned from i2c-omap.c when there is no ACK
from the chip.

> [   28.102233] omap_i2c 48072000.i2c: controller timed out
> [   29.463653] lp5523x 2-0032: lp5523 Programmable led chip found
> [   30.734191] omap_i2c 48072000.i2c: controller timed out waiting for start 
> condition to finish
> [   32.142333] i2c i2c-2: SCL is stuck low, exit recovery

If SCL is really stuck it also explains why chip doesn't acknowledge.

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


Re: Nokia N900 - audio TPA6130A2 problems

2015-08-03 Thread Jarkko Nikula
On 08/03/2015 09:17 PM, Pali Rohár wrote:
> On Monday 03 August 2015 20:03:16 Jarkko Nikula wrote:
>> Hi
>>
>> On 08/01/2015 01:18 PM, Pali Rohár wrote:
>>> On Saturday 25 July 2015 15:17:13 Lars-Peter Clausen wrote:
>>> Hello, your patch did not helped. Problem is still there...
>>
>> For me v4.2-rc5 works, i.e. TPA6130A2 can still play loudly to
>> headphones. Don't know were there any i2c etc regression before it or
>> how easy it would be to reproduce.
>>
> 
> Did you tested it on Nokia N900? Or other device?
> 
N900. Seems to be only user of TPA6130A2 in mainline :-)

>> Logs below made me thinking can it be a HW issue? Although if it is
>> an HW issue it shouldn't work sometimes I guess. Do you have any
>> earlier well known configuration you could try is it an SW
>> regression or something else?
>>
> 
> Stock Nokia's 2.6.28 kernel works always. With that kernel I have never 
> seen this problem. So I do not think this is HW problem.
> 
> This problem is there in more kernel versions, maybe in some older (like 
> v3.5) is was there not so often. But do not remember correctly...
>
It is well possible that some regression got introduced to TPA6130A2 I2C
communication over the years without nobody than you now notices. We
used to do QA back in Meego N900 days but that was pre 3.x kernels.

> Maybe some power management problem? Something is not always initialized 
> correctly?
> 
> I remember that there is some problem (maybe in NoLo - Nokia bootloader) 
> that sometimes chainloaded U-Boot (booted via NoLo) is not able to 
> initialize mmc chip (all read operation fails). In U-Boot I added some 
> code to enable some parts in twl4030 regulator and after that mmc is 
> working always...
> 
> So maybe something similar? Kernel expects that some PM or regulator 
> parts are initialized, but they are only sometimes? Just speculation...
>
I'm thinking the same. I could figure SCL could be stuck low if TPA or
some other chip connected to the same I2C bus is without power and is
pulling I2C signals down.

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


Re: Nokia N900 - audio TPA6130A2 problems

2015-08-03 Thread Pali Rohár
On Monday 03 August 2015 20:48:28 Jarkko Nikula wrote:
> On 08/03/2015 09:17 PM, Pali Rohár wrote:
> > On Monday 03 August 2015 20:03:16 Jarkko Nikula wrote:
> >> Hi
> >> 
> >> On 08/01/2015 01:18 PM, Pali Rohár wrote:
> >>> On Saturday 25 July 2015 15:17:13 Lars-Peter Clausen wrote:
> >>> Hello, your patch did not helped. Problem is still there...
> >> 
> >> For me v4.2-rc5 works, i.e. TPA6130A2 can still play loudly to
> >> headphones. Don't know were there any i2c etc regression before it
> >> or how easy it would be to reproduce.
> > 
> > Did you tested it on Nokia N900? Or other device?
> 
> N900. Seems to be only user of TPA6130A2 in mainline :-)
> 

Great, can you do more tests? I get this error often after I reboot N900 
(without power off) more times. But no idea if this is just "sometimes".

> >> Logs below made me thinking can it be a HW issue? Although if it
> >> is an HW issue it shouldn't work sometimes I guess. Do you have
> >> any earlier well known configuration you could try is it an SW
> >> regression or something else?
> > 
> > Stock Nokia's 2.6.28 kernel works always. With that kernel I have
> > never seen this problem. So I do not think this is HW problem.
> > 
> > This problem is there in more kernel versions, maybe in some older
> > (like v3.5) is was there not so often. But do not remember
> > correctly...
> 
> It is well possible that some regression got introduced to TPA6130A2
> I2C communication over the years without nobody than you now
> notices. We used to do QA back in Meego N900 days but that was pre
> 3.x kernels.
> 

Do you still have these pre 3.x kernels? This could be good starting 
point as 2.6.28 kernel is tooo old and heavily patches...

> > Maybe some power management problem? Something is not always
> > initialized correctly?
> > 
> > I remember that there is some problem (maybe in NoLo - Nokia
> > bootloader) that sometimes chainloaded U-Boot (booted via NoLo) is
> > not able to initialize mmc chip (all read operation fails). In
> > U-Boot I added some code to enable some parts in twl4030 regulator
> > and after that mmc is working always...
> > 
> > So maybe something similar? Kernel expects that some PM or
> > regulator parts are initialized, but they are only sometimes? Just
> > speculation...
> 
> I'm thinking the same. I could figure SCL could be stuck low if TPA
> or some other chip connected to the same I2C bus is without power
> and is pulling I2C signals down.

We should know which devices are connected to which i2c bus. So maybe 
detecting which i2c device is incorrectly initialized?

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: This is a digitally signed message part.


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Peter Hurley
On 08/03/2015 12:54 PM, Sebastian Andrzej Siewior wrote:
> On 08/03/2015 06:34 PM, Peter Hurley wrote:
>> Hi Sebastian,
> 
> Hi Peter,
> 
>>>  struct old_serial_port {
>>> diff --git a/drivers/tty/serial/8250/8250_omap.c 
>>> b/drivers/tty/serial/8250/8250_omap.c
>>> index d9a37191a1ae..12249125a218 100644
>>> --- a/drivers/tty/serial/8250/8250_omap.c
>>> +++ b/drivers/tty/serial/8250/8250_omap.c
>>> @@ -100,9 +100,9 @@ struct omap8250_priv {
>>> u8 wer;
>>> u8 xon;
>>> u8 xoff;
>>> -   u8 delayed_restore;
>>> u16 quot;
>>>  
>>> +   wait_queue_head_t termios_wait;
>>> bool is_suspending;
>>> int wakeirq;
>>> int wakeups_enabled;
>>> @@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port 
>>> *up,
>>>  static void omap8250_restore_regs(struct uart_8250_port *up)
>>>  {
>>> struct omap8250_priv *priv = up->port.private_data;
>>> -   struct uart_8250_dma*dma = up->dma;
>>> -
>>> -   if (dma && dma->tx_running) {
>>> -   /*
>>> -* TCSANOW requests the change to occur immediately however if
>>> -* we have a TX-DMA operation in progress then it has been
>>> -* observed that it might stall and never complete. Therefore we
>>> -* delay DMA completes to prevent this hang from happen.
>>> -*/
>>> -   priv->delayed_restore = 1;
>>> -   return;
>>> -   }
>>>  
>>> serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>>> serial_out(up, UART_EFR, UART_EFR_ECB);
>>> @@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port 
>>> *up)
>>> up->port.ops->set_mctrl(&up->port, up->port.mctrl);
>>>  }
>>>  
>>> +static void omap_8250_dma_tx_complete(void *param);
>>>  /*
>>>   * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have 
>>> have
>>>   * some differences in how we want to handle flow control.
>>> @@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port 
>>> *port,
>>> struct omap8250_priv *priv = up->port.private_data;
>>> unsigned char cval = 0;
>>> unsigned int baud;
>>> +   unsigned int complete_dma = 0;
>>>  
>>> switch (termios->c_cflag & CSIZE) {
>>> case CS5:
>>> @@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port 
>>> *port,
>>> if (termios->c_iflag & IXANY)
>>> up->mcr |= UART_MCR_XONANY;
>>> }
>>> +
>>> +   if (up->dma && up->dma->tx_running) {
>>> +   struct uart_8250_dma*dma = up->dma;
>>> +
>>> +   /*
>>> +* TCSANOW requests the change to occur immediately however if
>>> +* we have a TX-DMA operation in progress then it has been
>>> +* observed that it might stall and never complete. Therefore we
>>> +* wait until DMA completes to prevent this hang from happen.
>>> +*/
>>> +
>>> +   dma->tx_running = 2;
>>> +
>>> +   spin_unlock_irq(&up->port.lock);
>>> +   wait_event(priv->termios_wait,
>>> +  dma->tx_running == 3);
>>
>> Doesn't the dmaengine api offer a race-free way to wait for pending tx dma
>> to complete?
> 
> Not that I know of. You still need to ensure that once that DMA
> completed, nobody triggers another TX transfer before you do what you
> planned. This is ensures by the tx_running != 0 and the spin lock.
> 
>> Maybe we could wrap that in the 8250 dma api?
> 
> You mean a function in 8250-dma API which does what I did just here
> with the wait_event() and the wake_up in the callback? That way I could
> move the termios_wait into the dma struct instead of keeping in the
> omap specific part. I am also not sure if OMAP is the only one that may
> hang here or the other people just didn't notice it yet.

Exactly; and we need to fix DMA wrt x_char anyway.

Going back to the dmaengine api, I think something like this might work
(as a first approximation):

dma_sync_wait(dma->txchan, dma->tx_cookie);
dmaengine_pause(dma->txchan);

/* remainder of set_termios */

dmaengine_resume(dma->txchan);

We could require 8250 core dma to support pause/resume.


>>> +   spin_lock_irq(&up->port.lock);
>>> +   complete_dma = 1;
>>> +   }
>>> omap8250_restore_regs(up);
>>>  
>>> spin_unlock_irq(&up->port.lock);
>>> @@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port 
>>> *port,
>>> /* Don't rewrite B0 */
>>> if (tty_termios_baud_rate(termios))
>>> tty_termios_encode_baud_rate(termios, baud, baud);
>>> +   if (complete_dma)
>>> +   omap_8250_dma_tx_complete(up);
>>>  }
>>>  
>>>  /* same as 8250 except that we may have extra flow bits set in EFR */
>>> @@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
>>>  
>>> spin_lock_irqsave(&p->port.lock, flags);
>>>  
>>> +   if (dma->tx_running == 2) {
>>> +   dma->tx_running = 3;
>>> +   wake_up(&priv->termios_wait);
>>> +   goto o