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 kis...@ti.com:
 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-mmc 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] mmc: host: omap_hsmmc: Add custom card detect irq handler

2015-07-21 Thread Andreas Fenkart
Hi Vignesh,

Generally I don't like this patch, it will make it harder, not easier,
to maintain the omap hsmmc driver. Also given that the bug occurs
rarely, people will be reluctant to clean it up later or accept
patches.

see also comments below

2015-06-22 15:18 GMT+02:00 Vignesh R vigne...@ti.com:


 On Sunday 21 June 2015 04:15 AM, Andreas Fenkart wrote:
 I haven't managed to produce a hang without this patch

 Reproducing this hang is not straight forward. It takes 40-50 card
 insertion/removal to see this case (sometimes even 100 tries).


 see also comments below

 2015-06-16 12:37 GMT+02:00 Vignesh R vigne...@ti.com:
 Usually when there is an error in transfer, DTO/CTO or other error
 interrupts are raised. But if the card is unplugged in the middle of a
 data transfer, it is observed that, neither completion(success) or
 timeout(error) interrupts are raised. Hence, the mmc-core is waiting
 for-ever for the transfer to complete. This results failure to recognise
 sd card on the next insertion.
 The only way to solve this is to introduce code to detect this condition
 and recover on card insertion (in hsmmc specific cd_irq). Hence,
 introduce cd_irq and add code to clear mmc_request that is pending from
 the failed transaction.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  drivers/mmc/host/omap_hsmmc.c | 73 ++-
  1 file changed, 72 insertions(+), 1 deletion(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index fb4bfefd9250..ec1fff3c0c9c 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -221,6 +221,12 @@ struct omap_hsmmc_host {
  #define HSMMC_WAKE_IRQ_ENABLED (1  2)
 struct omap_hsmmc_next  next_data;
 struct  omap_hsmmc_platform_data*pdata;
 +   /*
 +* flag to determine whether card was removed during data
 +* transfer
 +*/
 +   booltransfer_incomplete;
 +

 /* return MMC cover switch state, can be NULL if not supported.
  *
 @@ -867,6 +873,26 @@ static void omap_hsmmc_request_done(struct 
 omap_hsmmc_host *host, struct mmc_req
  }

  /*
 + * Cleanup incomplete card removal sequence. This will make sure the
 + * next card enumeration is clean.
 + */
 +static void omap_hsmmc_request_clear(struct omap_hsmmc_host *host,
 +struct mmc_request *mrq)
 +{
 +   unsigned long flags;
 +
 +   spin_lock_irqsave(host-irq_lock, flags);
 +   host-req_in_progress = 0;
 +   host-dma_ch = -1;
 +   spin_unlock_irqrestore(host-irq_lock, flags);
 +
 +   mmc_request_done(host-mmc, mrq);
 +   if (host-mmc-card)
 +   mmc_card_set_removed(host-mmc-card);
 +   host-mrq = NULL;
 +}
 +
 +/*
   * Notify the transfer complete to MMC core
   */
  static void
 @@ -1248,6 +1274,47 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, 
 void *dev_id)
 return IRQ_HANDLED;
  }

 +/*
 + * irq handler to notify the core about card insertion/removal
 + */
 +static irqreturn_t omap_hsmmc_cd_irq(int irq, void *dev_id)
 +{

 Move this code to 'omap_hsmmc_get_cd' function. Or rather clear
 any pending transfer upon '.init_card/omap_hsmmc_init_card'

 I tried using omap_hsmmc_init initially, but here is the problem:

 card inserted -- cd_irq_isr-- schedule mmc_rescan()
 --- after some time ---
 mmc_rescan() --
 mmc_sd_alive() --
 -- card removed ---
 mmc_send_status --
 mmc_wait_for_req()--
 wait_for_completion()
 ^^^ Here the mmc_rescan thread waits forever because, it doesn't get
 timeout interrupt for the cmd/req it sent (because card was removed).

ok, I see

 But calls to omap_hsmmc_card_init or omap_hsmmc_get_cd are in the same
 mmc_rescan thread. Hence, moving the recovery code to init_card does not
 help.

what about clearing any pending transfer in
- mmc_gpio_cd_irqt, or
- mmc_detect_change

e.g. trigger the later mentioned .card_event callback from those
functions, instead mmc_rescan? Then you can install your
omap_hsmmc_request_clear as the card_event callback. This makes your
custom isr handler redundant, actually your isr handler became
standard.

 I guess other hosts also have some housekeeping upon unexpected
 card removals. So I guess there is some generic code to this problem.
 Did you check?

 I did try to find generic code in mmc-core, but couldn't find any.
 However, I did see some driver specific cleanups related to unexpected
 card removal in sdhci.c. sdhci handles this in .card_event call back.
 This does not help in my case as .card_event  is also called from
 mmc_rescan. I think cleanup code (in sdhci driver) for unexpected card
 removal was introduced when .card_event call was outside mmc_rescan.

interesting

 +   struct omap_hsmmc_host *host = mmc_priv(dev_id);
 +   int carddetect = mmc_gpio_get_cd(host-mmc);
 +   struct mmc_request *mrq = host-mrq;
 +
 +   /*
 +* If the card was removed in the middle of data

[PATCH] Documentation: dt: update ti,am33xx-hsmmc swakeup workaround

2015-07-07 Thread Andreas Fenkart
Before 5b83b2234be6733cf the driver was hard coding the wakeup irq to
be active low. The generic pm wakeirq does not override the active
high/low parameter, hence it must be specified correctly in the
device tree.
Mind that SDIO IRQ is active low as defined in the SDIO specification

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 76bf087..74166a0 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -102,7 +102,7 @@ not every application needs SDIO irq, e.g. MMC cards.
pinctrl-1 = mmc1_idle;
pinctrl-2 = mmc1_sleep;
...
-   interrupts-extended = intc 64 gpio2 28 0;
+   interrupts-extended = intc 64 gpio2 28 GPIO_ACTIVE_LOW;
};
 
mmc1_idle : pinmux_cirq_pin {
-- 
2.1.4

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


[PATCH 1/2] mmc: omap_hsmmc: call omap_hsmmc_set_power directly

2015-07-07 Thread Andreas Fenkart
If no pdata.set_power was set by the platform code, the driver
was updating pdata with its own fallback function. This is a no-no
since pdata shall be read-only.
This patch pushes the check 'pdata-set_power != NULL' down into
the fallback functions. If pdata.set_power is really set, it calls them
and exits, otherwise the fallback code is used.

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 32 +---
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b2b411d..fe7cee5 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -213,7 +213,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;
@@ -262,6 +261,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
platform_get_drvdata(to_platform_device(dev));
int ret = 0;
 
+   if (mmc_pdata(host)-set_power)
+   return mmc_pdata(host)-set_power(dev, power_on, vdd);
+
/*
 * If we don't see a Vcc regulator, assume it's a fixed
 * voltage always-on regulator.
@@ -344,6 +346,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
struct regulator *reg;
int ocr_value = 0;
 
+   if (mmc_pdata(host)-set_power)
+   return 0;
+
reg = devm_regulator_get(host-dev, vmmc);
if (IS_ERR(reg)) {
dev_err(host-dev, unable to get vmmc regulator %ld\n,
@@ -363,7 +368,6 @@ 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);
@@ -383,8 +387,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
(host-vcc_aux  regulator_is_enabled(host-vcc_aux))) {
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);
+   omap_hsmmc_set_power(host-dev, 1, vdd);
+   omap_hsmmc_set_power(host-dev, 0, 0);
}
 
return 0;
@@ -392,7 +396,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 
 static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
 {
-   mmc_pdata(host)-set_power = NULL;
+   if (mmc_pdata(host)-set_power)
+   return;
 }
 
 static inline int omap_hsmmc_have_reg(void)
@@ -1148,11 +1153,11 @@ static int omap_hsmmc_switch_opcond(struct 
omap_hsmmc_host *host, int vdd)
clk_disable_unprepare(host-dbclk);
 
/* Turn the power off */
-   ret = mmc_pdata(host)-set_power(host-dev, 0, 0);
+   ret = omap_hsmmc_set_power(host-dev, 0, 0);
 
/* Turn the power ON with given VDD 1.8 or 3.0v */
if (!ret)
-   ret = mmc_pdata(host)-set_power(host-dev, 1, vdd);
+   ret = omap_hsmmc_set_power(host-dev, 1, vdd);
pm_runtime_get_sync(host-dev);
if (host-dbclk)
clk_prepare_enable(host-dbclk);
@@ -1551,10 +1556,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
if (ios-power_mode != host-power_mode) {
switch (ios-power_mode) {
case MMC_POWER_OFF:
-   mmc_pdata(host)-set_power(host-dev, 0, 0);
+   omap_hsmmc_set_power(host-dev, 0, 0);
break;
case MMC_POWER_UP:
-   mmc_pdata(host)-set_power(host-dev, 1, ios-vdd);
+   omap_hsmmc_set_power(host-dev, 1, ios-vdd);
break;
case MMC_POWER_ON:
do_send_init_stream = 1;
@@ -2077,11 +2082,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (omap_hsmmc_have_reg()  !mmc_pdata(host)-set_power) {
+   if (omap_hsmmc_have_reg()) {
ret = omap_hsmmc_reg_get(host);
if (ret)
goto err_irq;
-   host-use_reg = 1;
}
 
mmc-ocr_avail = mmc_pdata(host)-ocr_mask;
@@ -2124,8 +2128,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)
@@ -2149,8 +2152,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev

[PATCH v2 0/2] mmc: omap_hsmmc: omap_hsmmc_set_power cleanup

2015-07-07 Thread Andreas Fenkart
v2:
- add empty omap_hsmmc_set_power in case CONFIG_REGULATOR is undefined

Andreas Fenkart (2):
  mmc: omap_hsmmc: call omap_hsmmc_set_power directly
  mmc: omap_hsmmc: regulator automatically released by devm

 drivers/mmc/host/omap_hsmmc.c | 39 +--
 1 file changed, 17 insertions(+), 22 deletions(-)

-- 
2.1.4

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


[PATCH v2 2/2] mmc: omap_hsmmc: regulator automatically released by devm

2015-07-07 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 806867b..ec1bcc7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -394,12 +394,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
return 0;
 }
 
-static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
-{
-   if (mmc_pdata(host)-set_power)
-   return;
-}
-
 static inline int omap_hsmmc_have_reg(void)
 {
return 1;
@@ -417,10 +411,6 @@ 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;
@@ -2133,7 +2123,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
-   omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(pdev-dev, false);
if (host-tx_chan)
@@ -2157,7 +2146,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 
pm_runtime_get_sync(host-dev);
mmc_remove_host(host-mmc);
-   omap_hsmmc_reg_put(host);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
-- 
2.1.4

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


[PATCH v2 1/2] mmc: omap_hsmmc: call omap_hsmmc_set_power directly

2015-07-07 Thread Andreas Fenkart
If no pdata.set_power was set by the platform code, the driver
was updating pdata with its own fallback function. This is a no-no
since pdata shall be read-only.
This patch pushes the check 'pdata-set_power != NULL' down into
the fallback functions. If pdata.set_power is really set, it calls them
and exits, otherwise the fallback code is used.

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b2b411d..806867b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -213,7 +213,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;
@@ -262,6 +261,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
platform_get_drvdata(to_platform_device(dev));
int ret = 0;
 
+   if (mmc_pdata(host)-set_power)
+   return mmc_pdata(host)-set_power(dev, power_on, vdd);
+
/*
 * If we don't see a Vcc regulator, assume it's a fixed
 * voltage always-on regulator.
@@ -344,6 +346,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
struct regulator *reg;
int ocr_value = 0;
 
+   if (mmc_pdata(host)-set_power)
+   return 0;
+
reg = devm_regulator_get(host-dev, vmmc);
if (IS_ERR(reg)) {
dev_err(host-dev, unable to get vmmc regulator %ld\n,
@@ -363,7 +368,6 @@ 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);
@@ -383,8 +387,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
(host-vcc_aux  regulator_is_enabled(host-vcc_aux))) {
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);
+   omap_hsmmc_set_power(host-dev, 1, vdd);
+   omap_hsmmc_set_power(host-dev, 0, 0);
}
 
return 0;
@@ -392,7 +396,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 
 static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
 {
-   mmc_pdata(host)-set_power = NULL;
+   if (mmc_pdata(host)-set_power)
+   return;
 }
 
 static inline int omap_hsmmc_have_reg(void)
@@ -402,6 +407,11 @@ static inline int omap_hsmmc_have_reg(void)
 
 #else
 
+static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
+{
+   return 0;
+}
+
 static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
return -EINVAL;
@@ -1148,11 +1158,11 @@ static int omap_hsmmc_switch_opcond(struct 
omap_hsmmc_host *host, int vdd)
clk_disable_unprepare(host-dbclk);
 
/* Turn the power off */
-   ret = mmc_pdata(host)-set_power(host-dev, 0, 0);
+   ret = omap_hsmmc_set_power(host-dev, 0, 0);
 
/* Turn the power ON with given VDD 1.8 or 3.0v */
if (!ret)
-   ret = mmc_pdata(host)-set_power(host-dev, 1, vdd);
+   ret = omap_hsmmc_set_power(host-dev, 1, vdd);
pm_runtime_get_sync(host-dev);
if (host-dbclk)
clk_prepare_enable(host-dbclk);
@@ -1551,10 +1561,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
if (ios-power_mode != host-power_mode) {
switch (ios-power_mode) {
case MMC_POWER_OFF:
-   mmc_pdata(host)-set_power(host-dev, 0, 0);
+   omap_hsmmc_set_power(host-dev, 0, 0);
break;
case MMC_POWER_UP:
-   mmc_pdata(host)-set_power(host-dev, 1, ios-vdd);
+   omap_hsmmc_set_power(host-dev, 1, ios-vdd);
break;
case MMC_POWER_ON:
do_send_init_stream = 1;
@@ -2077,11 +2087,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (omap_hsmmc_have_reg()  !mmc_pdata(host)-set_power) {
+   if (omap_hsmmc_have_reg()) {
ret = omap_hsmmc_reg_get(host);
if (ret)
goto err_irq;
-   host-use_reg = 1;
}
 
mmc-ocr_avail = mmc_pdata(host)-ocr_mask;
@@ -2124,8 +2133,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name

[PATCH 2/2] mmc: omap_hsmmc: regulator automatically released by devm

2015-07-07 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fe7cee5..9761e12 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -394,12 +394,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
return 0;
 }
 
-static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
-{
-   if (mmc_pdata(host)-set_power)
-   return;
-}
-
 static inline int omap_hsmmc_have_reg(void)
 {
return 1;
@@ -412,10 +406,6 @@ 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;
@@ -2128,7 +2118,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
-   omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(pdev-dev, false);
if (host-tx_chan)
@@ -2152,7 +2141,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 
pm_runtime_get_sync(host-dev);
mmc_remove_host(host-mmc);
-   omap_hsmmc_reg_put(host);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
-- 
2.1.4

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


Re: [PATCH 1/3] mmc: host: omap_hsmmc: Fix DTO and DCRC handling

2015-06-20 Thread Andreas Fenkart
Hi Vignesh,

2015-06-16 12:37 GMT+02:00 Vignesh R vigne...@ti.com:
 From: Kishon Vijay Abraham I kis...@ti.com

 DTO/DCRC errors were not being informed to the mmc core since
 commit ae4bf788ee9b (mmc: omap_hsmmc: consolidate error report handling of
 HSMMC IRQ). This commit made sure 'end_trans' is never set on DTO/DCRC
 errors. This is because after this commit 'host-data' is checked after
 it has been cleared to NULL by omap_hsmmc_dma_cleanup().

 Because 'end_trans' is never set, omap_hsmmc_xfer_done() is never invoked
 making core layer not to be aware of DTO/DCRC errors. Because of this
 any command invoked after DTO/DCRC error leads to a hang.

 Fix this by checking for 'host-data' before it is actually cleared.

This really fixes the problem, thanks for the analysis
TESTED-BY


 Fixes: ae4bf788ee9b (mmc: omap_hsmmc: consolidate error report handling of
 HSMMC IRQ)

 CC: sta...@vger.kernel.org
 Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  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 9df2b6801f76..d0abdffb0d7c 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -1062,6 +1062,10 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
 *host, int status)

 if (status  (CTO_EN | CCRC_EN))
 end_cmd = 1;
 +   if (host-data || host-response_busy) {
 +   end_trans = !end_cmd;
 +   host-response_busy = 0;
 +   }
 if (status  (CTO_EN | DTO_EN))
 hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
 else if (status  (CCRC_EN | DCRC_EN))
 @@ -1081,10 +1085,6 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
 *host, int status)
 }
 dev_dbg(mmc_dev(host-mmc), AC12 err: 0x%x\n, ac12);
 }
 -   if (host-data || host-response_busy) {
 -   end_trans = !end_cmd;
 -   host-response_busy = 0;
 -   }
 }

 OMAP_HSMMC_WRITE(host-base, STAT, status);
 --
 2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-mmc in


Re: [PATCH 2/3] mmc: host: omap_hsmmc: Handle BADA, DEB and CEB interrupts

2015-06-20 Thread Andreas Fenkart
TESTED-BY

2015-06-16 12:37 GMT+02:00 Vignesh R vigne...@ti.com:
 Sometimes BADA, DEB or CEB error interrupts occur when sd card is
 unplugged during data transfer. These interrupts are currently ignored
 by the interrupt handler. But, this results in card not being
 recognised on subsequent insertion. This is because mmcqd is waiting
 forever for the data transfer(for which error occurred) to complete.
 Fix this, by reporting BADA, DEB, CEB errors to mmc-core as -EILSEQ, so
 that the core can do appropriate handling.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  drivers/mmc/host/omap_hsmmc.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index d0abdffb0d7c..fb4bfefd9250 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -1068,7 +1068,8 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
 *host, int status)
 }
 if (status  (CTO_EN | DTO_EN))
 hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
 -   else if (status  (CCRC_EN | DCRC_EN))
 +   else if (status  (CCRC_EN | DCRC_EN | DEB_EN | CEB_EN |
 +  BADA_EN))
 hsmmc_command_incomplete(host, -EILSEQ, end_cmd);

 if (status  ACE_EN) {
 --
 2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-mmc in


Re: [PATCH 3/3] mmc: host: omap_hsmmc: Add custom card detect irq handler

2015-06-20 Thread Andreas Fenkart
I haven't managed to produce a hang without this patch

see also comments below

2015-06-16 12:37 GMT+02:00 Vignesh R vigne...@ti.com:
 Usually when there is an error in transfer, DTO/CTO or other error
 interrupts are raised. But if the card is unplugged in the middle of a
 data transfer, it is observed that, neither completion(success) or
 timeout(error) interrupts are raised. Hence, the mmc-core is waiting
 for-ever for the transfer to complete. This results failure to recognise
 sd card on the next insertion.
 The only way to solve this is to introduce code to detect this condition
 and recover on card insertion (in hsmmc specific cd_irq). Hence,
 introduce cd_irq and add code to clear mmc_request that is pending from
 the failed transaction.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  drivers/mmc/host/omap_hsmmc.c | 73 ++-
  1 file changed, 72 insertions(+), 1 deletion(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index fb4bfefd9250..ec1fff3c0c9c 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -221,6 +221,12 @@ struct omap_hsmmc_host {
  #define HSMMC_WAKE_IRQ_ENABLED (1  2)
 struct omap_hsmmc_next  next_data;
 struct  omap_hsmmc_platform_data*pdata;
 +   /*
 +* flag to determine whether card was removed during data
 +* transfer
 +*/
 +   booltransfer_incomplete;
 +

 /* return MMC cover switch state, can be NULL if not supported.
  *
 @@ -867,6 +873,26 @@ static void omap_hsmmc_request_done(struct 
 omap_hsmmc_host *host, struct mmc_req
  }

  /*
 + * Cleanup incomplete card removal sequence. This will make sure the
 + * next card enumeration is clean.
 + */
 +static void omap_hsmmc_request_clear(struct omap_hsmmc_host *host,
 +struct mmc_request *mrq)
 +{
 +   unsigned long flags;
 +
 +   spin_lock_irqsave(host-irq_lock, flags);
 +   host-req_in_progress = 0;
 +   host-dma_ch = -1;
 +   spin_unlock_irqrestore(host-irq_lock, flags);
 +
 +   mmc_request_done(host-mmc, mrq);
 +   if (host-mmc-card)
 +   mmc_card_set_removed(host-mmc-card);
 +   host-mrq = NULL;
 +}
 +
 +/*
   * Notify the transfer complete to MMC core
   */
  static void
 @@ -1248,6 +1274,47 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, void 
 *dev_id)
 return IRQ_HANDLED;
  }

 +/*
 + * irq handler to notify the core about card insertion/removal
 + */
 +static irqreturn_t omap_hsmmc_cd_irq(int irq, void *dev_id)
 +{

Move this code to 'omap_hsmmc_get_cd' function. Or rather clear
any pending transfer upon '.init_card/omap_hsmmc_init_card'

I guess other hosts also have some housekeeping upon unexpected
card removals. So I guess there is some generic code to this problem.
Did you check?

 +   struct omap_hsmmc_host *host = mmc_priv(dev_id);
 +   int carddetect = mmc_gpio_get_cd(host-mmc);
 +   struct mmc_request *mrq = host-mrq;
 +
 +   /*
 +* If the card was removed in the middle of data transfer last
 +* time, the TC/CC/timeout interrupt is not raised due to which
 +* mmc_request is not cleared. Hence, this card insertion will
 +* still see pending mmc_request. Clear the request to make sure
 +* that this card enumeration is successful.
 +*/
 +   if (!carddetect  mrq  host-transfer_incomplete) {
 +   omap_hsmmc_disable_irq(host);
 +   dev_info(host-dev,
 +card removed during transfer last time\n);
 +   hsmmc_command_incomplete(host, -ENOMEDIUM, 1);
 +   omap_hsmmc_request_clear(host, host-mrq);
 +   dev_info(host-dev, recovery done\n);
 +   }
 +   host-transfer_incomplete = false;
 +
 +   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
 +
 +   /*
 +* The current mmc_request is usually null before card removal
 +* sequence is complete. It may not be null if TC/CC interrupt
 +* never happens due to removal of card during a data
 +* transfer. Set a flag to indicate mmc_request was not null
 +* in order to do cleanup on next card insertion.
 +*/
 +   if (carddetect  mrq)
 +   host-transfer_incomplete = true;
 +
 +   return IRQ_HANDLED;
 +}
 +
  static void omap_hsmmc_dma_callback(void *param)
  {
 struct omap_hsmmc_host *host = param;
 @@ -1918,7 +1985,7 @@ static int omap_hsmmc_probe(struct platform_device 
 *pdev)
 struct mmc_host *mmc;
 struct omap_hsmmc_host *host = NULL;
 struct resource *res;
 -   int ret, irq;
 +   int ret, irq, len;
 const struct of_device_id *match;
 dma_cap_mask_t mask;
 unsigned tx_req, rx_req;
 @@ -1980,6 +2047,10 @@ static int omap_hsmmc_probe(struct platform_device 
 *pdev)
 if (ret)
 goto 

[PATCH v2] mmc: sdio: add reset callback to bus operations

2015-04-23 Thread Andreas Fenkart
Some drivers schedule automatic hw resets. An example is mwifiex,
which schedules a card reset if the command handler between driver
and card firmware becomes out of sync

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/core/sdio.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index ce6cc47..01255ef 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1064,6 +1064,12 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
return mmc_sdio_power_restore(host);
 }
 
+static int mmc_sdio_reset(struct mmc_host *host)
+{
+   mmc_power_cycle(host, host-card-ocr);
+   return mmc_sdio_power_restore(host);
+}
+
 static const struct mmc_bus_ops mmc_sdio_ops = {
.remove = mmc_sdio_remove,
.detect = mmc_sdio_detect,
@@ -1074,6 +1080,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
.runtime_resume = mmc_sdio_runtime_resume,
.power_restore = mmc_sdio_power_restore,
.alive = mmc_sdio_alive,
+   .reset = mmc_sdio_reset,
 };
 
 
-- 
2.1.4

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


[PATCH] mmc: pwrseq: dt: example with reset clock and active low pin

2015-04-16 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt 
b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index a462c50..ce0e767 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -21,5 +21,7 @@ Example:
 
sdhci0_pwrseq {
compatible = mmc-pwrseq-simple;
-   reset-gpios = gpio1 12 0;
+   reset-gpios = gpio1 12 GPIO_ACTIVE_LOW;
+   clocks = clk_32768_ck;
+   clock-names = ext_clock;
}
-- 
2.1.4

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


[PATCH] mmc: sdio: add reset callback to bus operations

2015-04-13 Thread Andreas Fenkart
Some drivers schedule automatic hw resets. An example is mwifiex,
which schedules a card reset if the command handler between driver
and card firmware becomes out of sync

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/core/sdio.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index ce6cc47..01255ef 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1064,6 +1064,12 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
return mmc_sdio_power_restore(host);
 }
 
+static int mmc_sdio_reset(struct mmc_host *host)
+{
+   mmc_power_cycle(host, host-card-ocr);
+   return mmc_sdio_power_restore(host);
+}
+
 static const struct mmc_bus_ops mmc_sdio_ops = {
.remove = mmc_sdio_remove,
.detect = mmc_sdio_detect,
@@ -1074,6 +1080,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
.runtime_resume = mmc_sdio_runtime_resume,
.power_restore = mmc_sdio_power_restore,
.alive = mmc_sdio_alive,
+   .reset = mmc_sdio_reset,
 };
 
 
-- 
2.1.4

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


[PATCH] ARM: OMAP2: HSMMC: explicit fields to declare cover/card detect pin

2015-03-20 Thread Andreas Fenkart
board-rx51 has no card detect pin in the mmc slot, but can detect that
the (cell-phone) cover has been removed and the card is accessible.
The semantics between cover/card detect differ, the gpio on the slot
informs you after the card has been removed, cover removal does not
necessarily mean that the card has been removed.
This means different code paths are necessary. To complete this we
also want different fields in the platform data for cover and card
detect. This separation is not pushed all the way down into struct
omap2_hsmmc_info which is used to initialize the platform data.
If we did that we had to go over all board files and set the new
gpio_cod pin to -EINVAL. If we forget one board or some out-of-tree
archicture forgets that the default '0' is used which is a valid pin
number.

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 33 
 drivers/mmc/host/omap_hsmmc.c| 11 ++-
 include/linux/platform_data/hsmmc-omap.h |  6 ++
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index dc6e79c..9a8611a 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -150,9 +150,13 @@ static int nop_mmc_set_power(struct device *dev, int 
power_on, int vdd)
 static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
  *mmc_controller, int controller_nr)
 {
-   if (gpio_is_valid(mmc_controller-switch_pin) 
-   (mmc_controller-switch_pin  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-switch_pin,
+   if (gpio_is_valid(mmc_controller-gpio_cd) 
+   (mmc_controller-gpio_cd  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_cd,
+  OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-gpio_cod) 
+   (mmc_controller-gpio_cod  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_cod,
   OMAP_PIN_INPUT_PULLUP);
if (gpio_is_valid(mmc_controller-gpio_wp) 
(mmc_controller-gpio_wp  OMAP_MAX_GPIO_LINES))
@@ -250,15 +254,20 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
 
-   mmc-switch_pin = c-gpio_cd;
+   if (c-cover_only) {
+   /* detect if mobile phone cover removed */
+   mmc-gpio_cd = -EINVAL;
+   mmc-gpio_cod = c-gpio_cd;
+   } else {
+   /* card detect pin on the mmc socket itself */
+   mmc-gpio_cd = c-gpio_cd;
+   mmc-gpio_cod = -EINVAL;
+   }
mmc-gpio_wp = c-gpio_wp;
 
mmc-remux = c-remux;
mmc-init_card = c-init_card;
 
-   if (c-cover_only)
-   mmc-cover = 1;
-
if (c-nonremovable)
mmc-nonremovable = 1;
 
@@ -358,7 +367,15 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
if (!mmc_pdata)
continue;
 
-   mmc_pdata-switch_pin = c-gpio_cd;
+   if (c-cover_only) {
+   /* detect if mobile phone cover removed */
+   mmc_pdata-gpio_cd = -EINVAL;
+   mmc_pdata-gpio_cod = c-gpio_cd;
+   } else {
+   /* card detect pin on the mmc socket itself */
+   mmc_pdata-gpio_cd = c-gpio_cd;
+   mmc_pdata-gpio_cod = -EINVAL;
+   }
mmc_pdata-gpio_wp = c-gpio_wp;
 
res = omap_device_register(pdev);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 053cd38..265391f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -427,15 +427,15 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
 {
int ret;
 
-   if (pdata-cover  gpio_is_valid(pdata-switch_pin)) {
-   ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
+   if (gpio_is_valid(pdata-gpio_cod)) {
+   ret = mmc_gpio_request_cd(mmc, pdata-gpio_cod, 0);
if (ret)
return ret;
 
host-get_cover_state = omap_hsmmc_get_cover_state;
mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq);
-   } else if (!pdata-cover  gpio_is_valid(pdata-switch_pin)) {
-   ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
+   } else if (gpio_is_valid(pdata-gpio_cd)) {
+   ret = mmc_gpio_request_cd(mmc, pdata-gpio_cd, 0);
if (ret)
return ret;
 
@@ -1932,7 +1932,8 @@ static struct omap_hsmmc_platform_data 
*of_get_hsmmc_pdata(struct device *dev)
if (of_find_property(np, ti,dual-volt, NULL))
pdata-controller_flags

Re: [PATCH 0/6] mmc: omap_hsmmc: simplify cover/card detect logic

2015-03-04 Thread Andreas Fenkart
2015-03-04 6:31 GMT+01:00 NeilBrown ne...@suse.de:
 On Tue,  3 Mar 2015 13:28:12 +0100 Andreas Fenkart afenk...@gmail.com wrote:
 While cover detect is only used by one platform (rx51), it
 complicates the card detect logic. By separating the code
 paths they both become easier to understand and maintain

 Patches have been tested by reverting: 95bebb5696ab
 'mmc: omap_hsmmc: use mmc_of_parse to parse common mmc configuration'
 otherwise gpio detection is handled by mmc_of_parse

 Wouldn't it make more sense to put this core  in mmc/core rather than in just
 one host controller?
Yes, I would very welcome that, since it would free the omap_hsmmc of the
'protection' mechanism that makes the driver clumsy. But as an initial step
separating cover from card detect already seems enough for this series.
Another thought was, that since only one platform is using it, the prospect of
getting it merged into the core was minimal.

 That way it would be available to all hosts, and you
 wouldn't need to revert that patch.
Oh sorry, seems I was unclear. I definitely do not want to revert that patch
permanently, the opposite is true, I very much welcome it. Thanks for your work
by the way.
I only reverted it temporarily so I could test that the card detect
logic still works
with legacy board files, non-device-tree platforms. But since mmc_of_parse is
setting the card detect pin, my changes could not be tested with my
device-tree platform (bbone). So I reverted the above patch only for testing,
afterwards I rebased the patches on top of it, before submitting


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


[PATCH 3/6] mmc: omap_hsmmc: use distinctive code paths for cover / card detect logic

2015-03-03 Thread Andreas Fenkart
Mobile phones (some) have no card detect pin, but can detect if the
cover is removed. The purpose is the same; detect if card is being
added/removed, but the details differ.
When the cover is removed, it does not mean the card is gone. But it
might, since it is accessible now. It's like a warning. All the driver
does is to limit write access to the card, see protect_card flag.
In contrast, card detect notifies us after the fact, e.g.
card is gone, card is inserted. We can't take precautions, but we can
rely on those events, -- the card is really gone, or do scan the card.
To summarize there is not much code sharing between cover and card
detect, it only increases confusion. By splitting, both will be
simplified in a followup patch.

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 56 +--
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 77ad471..38239fb 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -230,9 +230,6 @@ struct omap_hsmmc_host {
 */
int (*get_cover_state)(struct device *dev);
 
-   /* Card detection IRQs */
-   int card_detect_irq;
-
int (*card_detect)(struct device *dev);
 };
 
@@ -422,6 +419,7 @@ static inline int omap_hsmmc_have_reg(void)
 #endif
 
 static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id);
+static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id);
 
 static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
struct omap_hsmmc_host *host,
@@ -429,20 +427,20 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
 {
int ret;
 
-   if (gpio_is_valid(pdata-switch_pin)) {
-   if (pdata-cover)
-   host-get_cover_state =
-   omap_hsmmc_get_cover_state;
-   else
-   host-card_detect = omap_hsmmc_card_detect;
-   host-card_detect_irq =
-   gpio_to_irq(pdata-switch_pin);
-   mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect);
+   if (pdata-cover  gpio_is_valid(pdata-switch_pin)) {
ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
if (ret)
return ret;
-   } else {
-   pdata-switch_pin = -EINVAL;
+
+   host-get_cover_state = omap_hsmmc_get_cover_state;
+   mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq);
+   } else if (!pdata-cover  gpio_is_valid(pdata-switch_pin)) {
+   ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
+   if (ret)
+   return ret;
+
+   host-card_detect = omap_hsmmc_card_detect;
+   mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect);
}
 
if (gpio_is_valid(pdata-gpio_wp)) {
@@ -1236,15 +1234,37 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 }
 
 /*
- * irq handler to notify the core about card insertion/removal
+ * irq handler when (cell-phone) cover is mounted/removed
  */
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
int carddetect;
 
sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
+   if (host-card_detect) {
+   carddetect = host-card_detect(host-dev);
+   } else {
+   omap_hsmmc_protect_card(host);
+   carddetect = -ENOSYS;
+   }
+
+   if (carddetect)
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
+   else
+   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   return IRQ_HANDLED;
+}
+
+/*
+ * irq handler to notify the core about card insertion/removal
+ */
+static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+{
+   struct omap_hsmmc_host *host = dev_id;
+   int carddetect;
+
if (host-card_detect)
carddetect = host-card_detect(host-dev);
else {
@@ -2164,9 +2184,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
if (ret  0)
goto err_slot_name;
}
-   if (host-card_detect_irq  host-get_cover_state) {
+   if (host-get_cover_state) {
ret = device_create_file(mmc-class_dev,
-   dev_attr_cover_switch);
+dev_attr_cover_switch);
if (ret  0)
goto err_slot_name;
}
-- 
2.1.4

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


[PATCH 4/6] ARM: OMAP2: HSMMC: platform_data: explicit gpio_cover / gpio_cd fields

2015-03-03 Thread Andreas Fenkart
Cover detection and card detection are not equivalent, cover detection
is like a warning that something might happen (cover removed, card is
accessible), card detection a notification that something has happened.
You could use both in parallel.
Technically this is not possible, since there is only one gpio for both
and a 'cover' flag to indicate either or. With this commit we push that
de-multiplexing of that gpio + flag out of the driver into the platform
specific init code.
It's not pushed down into omap2_hsmmc_info which is used to initialize
the platform data, since we would have to go over all board files
and set the new gpio_cover pin to -EINVAL. That would be dangerous
since '0' is a valid pin number.
FYI: only board-rx51 uses cover_only detection

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 33 
 drivers/mmc/host/omap_hsmmc.c| 11 ++-
 include/linux/platform_data/hsmmc-omap.h |  6 ++
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index dc6e79c..0e54aac 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -150,9 +150,13 @@ static int nop_mmc_set_power(struct device *dev, int 
power_on, int vdd)
 static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
  *mmc_controller, int controller_nr)
 {
-   if (gpio_is_valid(mmc_controller-switch_pin) 
-   (mmc_controller-switch_pin  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-switch_pin,
+   if (gpio_is_valid(mmc_controller-gpio_cd) 
+   (mmc_controller-gpio_cd  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_cd,
+  OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-gpio_cover) 
+   (mmc_controller-gpio_cover  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_cover,
   OMAP_PIN_INPUT_PULLUP);
if (gpio_is_valid(mmc_controller-gpio_wp) 
(mmc_controller-gpio_wp  OMAP_MAX_GPIO_LINES))
@@ -250,15 +254,20 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
 
-   mmc-switch_pin = c-gpio_cd;
+   if (c-cover_only) {
+   /* detect if mobile phone cover removed */
+   mmc-gpio_cd = -EINVAL;
+   mmc-gpio_cover = c-gpio_cd;
+   } else {
+   /* card detect pin on the mmc socket itself */
+   mmc-gpio_cd = c-gpio_cd;
+   mmc-gpio_cover = -EINVAL;
+   }
mmc-gpio_wp = c-gpio_wp;
 
mmc-remux = c-remux;
mmc-init_card = c-init_card;
 
-   if (c-cover_only)
-   mmc-cover = 1;
-
if (c-nonremovable)
mmc-nonremovable = 1;
 
@@ -358,7 +367,15 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
if (!mmc_pdata)
continue;
 
-   mmc_pdata-switch_pin = c-gpio_cd;
+   if (c-cover_only) {
+   /* detect if mobile phone cover removed */
+   mmc_pdata-gpio_cd = -EINVAL;
+   mmc_pdata-gpio_cover = c-gpio_cd;
+   } else {
+   /* card detect pin on the mmc socket itself */
+   mmc_pdata-gpio_cd = c-gpio_cd;
+   mmc_pdata-gpio_cover = -EINVAL;
+   }
mmc_pdata-gpio_wp = c-gpio_wp;
 
res = omap_device_register(pdev);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 38239fb..ed68e55 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -427,15 +427,15 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
 {
int ret;
 
-   if (pdata-cover  gpio_is_valid(pdata-switch_pin)) {
-   ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
+   if (gpio_is_valid(pdata-gpio_cover)) {
+   ret = mmc_gpio_request_cd(mmc, pdata-gpio_cover, 0);
if (ret)
return ret;
 
host-get_cover_state = omap_hsmmc_get_cover_state;
mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq);
-   } else if (!pdata-cover  gpio_is_valid(pdata-switch_pin)) {
-   ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0);
+   } else if (gpio_is_valid(pdata-gpio_cd)) {
+   ret = mmc_gpio_request_cd(mmc, pdata-gpio_cd, 0);
if (ret)
return ret;
 
@@ -1932,7 +1932,8 @@ static struct omap_hsmmc_platform_data 
*of_get_hsmmc_pdata(struct device *dev)
if (of_find_property(np, ti,dual-volt, NULL))
pdata-controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT

[PATCH 5/6] mmc: omap_hsmmc: simplify card/cover detect isr

2015-03-03 Thread Andreas Fenkart
strip the card dectet logic from cover detect isr and vice versa
the generic mmc_gpio_cd_irqt isr, uses 200ms on removal/insertion,
hence that should be fine here as well

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 27 +++
 1 file changed, 3 insertions(+), 24 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index ed68e55..4f6fbe5 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1239,21 +1239,11 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   int carddetect;
 
sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
-   if (host-card_detect) {
-   carddetect = host-card_detect(host-dev);
-   } else {
-   omap_hsmmc_protect_card(host);
-   carddetect = -ENOSYS;
-   }
-
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   omap_hsmmc_protect_card(host);
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
return IRQ_HANDLED;
 }
 
@@ -1263,19 +1253,8 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, void 
*dev_id)
 static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   int carddetect;
-
-   if (host-card_detect)
-   carddetect = host-card_detect(host-dev);
-   else {
-   omap_hsmmc_protect_card(host);
-   carddetect = -ENOSYS;
-   }
 
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
return IRQ_HANDLED;
 }
 
-- 
2.1.4

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


[PATCH 2/6] mmc: omap_hsmmc: use slot-gpio functions to manage read-only pin directly

2015-03-03 Thread Andreas Fenkart
The indirection via omap_hsmmc_get_ro and omap_hsmmc_get_wp is
redundant. Also dropped setting gpio_wp to EINVAL since platform date
is read-only
Untested: no device with ro pin was available, but change is fairly
simple

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 23 +--
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2276d58..77ad471 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -234,8 +234,6 @@ struct omap_hsmmc_host {
int card_detect_irq;
 
int (*card_detect)(struct device *dev);
-   int (*get_ro)(struct device *dev);
-
 };
 
 struct omap_mmc_of_data {
@@ -252,13 +250,6 @@ static int omap_hsmmc_card_detect(struct device *dev)
return mmc_gpio_get_cd(host-mmc);
 }
 
-static int omap_hsmmc_get_wp(struct device *dev)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-
-   return mmc_gpio_get_ro(host-mmc);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -455,12 +446,9 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
}
 
if (gpio_is_valid(pdata-gpio_wp)) {
-   host-get_ro = omap_hsmmc_get_wp;
ret = mmc_gpio_request_ro(mmc, pdata-gpio_wp);
if (ret)
return ret;
-   } else {
-   pdata-gpio_wp = -EINVAL;
}
 
return 0;
@@ -1637,15 +1625,6 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
return host-card_detect(host-dev);
 }
 
-static int omap_hsmmc_get_ro(struct mmc_host *mmc)
-{
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   if (!host-get_ro)
-   return -ENOSYS;
-   return host-get_ro(host-dev);
-}
-
 static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1811,7 +1790,7 @@ static struct mmc_host_ops omap_hsmmc_ops = {
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
-   .get_ro = omap_hsmmc_get_ro,
+   .get_ro = mmc_gpio_get_ro,
.init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 };
-- 
2.1.4

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


[PATCH 0/6] mmc: omap_hsmmc: simplify cover/card detect logic

2015-03-03 Thread Andreas Fenkart
These patches are trying to clean up the cover/card detect logic.

  Mobile phones (some) have no card detect pin, but
  can detect if the cover is removed. The purpose is the
  same; detect if card is being added/removed, but the
  details differ.
  When the cover is removed, it does not mean the card is
  gone. But it might, since it is accessible now. It's like
  a warning. All the driver does is to limit write access to
  the card, see protect_card flag. In contrast, card detect
  notifies us after the fact, e.g. card is gone, card is
  inserted.

While cover detect is only used by one platform (rx51), it
complicates the card detect logic. By separating the code
paths they both become easier to understand and maintain 

Patches have been tested by reverting: 95bebb5696ab
'mmc: omap_hsmmc: use mmc_of_parse to parse common mmc configuration'
otherwise gpio detection is handled by mmc_of_parse

compile tested
OMAP2:
CONFIG_MACH_OMAP2_TUSB6010=y
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_N810=y
CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y
CONFIG_MACH_TI8168EVM=y
CONFIG_MACH_TI8148EVM=y

Andreas Fenkart (6):
  mmc: omap_hsmmc: remove unused fields from struct omap_hsmmc_host
  mmc: omap_hsmmc: use slot-gpio functions to manage read-only pin
directly
  mmc: omap_hsmmc: use distinctive code paths for cover / card detect
logic
  ARM: OMAP2: HSMMC: platform_data: explicit gpio_cover / gpio_cd fields
  mmc: omap_hsmmc: simplify card/cover detect isr
  mmc: omap_hsmmc: use generic slot-gpio isr to manage card detect pin

 arch/arm/mach-omap2/hsmmc.c  | 33 +
 drivers/mmc/host/omap_hsmmc.c| 80 +---
 include/linux/platform_data/hsmmc-omap.h |  6 +--
 3 files changed, 48 insertions(+), 71 deletions(-)

-- 
2.1.4

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


[PATCH 1/6] mmc: omap_hsmmc: remove unused fields from struct omap_hsmmc_host

2015-03-03 Thread Andreas Fenkart
addon to: 09108968b7b72b6083a3bfc8f8259a74ed57255e
mmc: omap_hsmmc: remove prepare/complete system suspend support

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8d87e08..2276d58 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -222,10 +222,6 @@ struct omap_hsmmc_host {
struct omap_hsmmc_next  next_data;
struct  omap_hsmmc_platform_data*pdata;
 
-   /* To handle board related suspend/resume functionality for MMC */
-   int (*suspend)(struct device *dev);
-   int (*resume)(struct device *dev);
-
/* return MMC cover switch state, can be NULL if not supported.
 *
 * possible return values:
-- 
2.1.4

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


[PATCH 6/6] mmc: omap_hsmmc: use generic slot-gpio isr to manage card detect pin

2015-03-03 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4f6fbe5..0c3368e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -418,7 +418,6 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id);
 static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id);
 
 static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
@@ -440,7 +439,6 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
return ret;
 
host-card_detect = omap_hsmmc_card_detect;
-   mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect);
}
 
if (gpio_is_valid(pdata-gpio_wp)) {
@@ -1247,17 +1245,6 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
-/*
- * irq handler to notify the core about card insertion/removal
- */
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
-{
-   struct omap_hsmmc_host *host = dev_id;
-
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   return IRQ_HANDLED;
-}
-
 static void omap_hsmmc_dma_callback(void *param)
 {
struct omap_hsmmc_host *host = param;
-- 
2.1.4

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


Re: [RFC PATCH 2/3] mmc: omap_hsmmc: add tuning support

2014-11-14 Thread Andreas Fenkart
2014-11-13 13:56 GMT+01:00 Kishon Vijay Abraham I kis...@ti.com:
 From: Balaji T K balaj...@ti.com

 MMC tuning procedure is required to support SD card
 UHS1-SDR104 mode and EMMC HS200 mode.

 The tuning function omap_execute_tuning() will only
 be called by the MMC/SD core if the corresponding
 speed modes are supported by the OMAP silicon which
 is set in the mmc host caps field.

 Signed-off-by: Viswanath Puttagunta vi...@ti.com
 Signed-off-by: Sourav Poddar sourav.pod...@ti.com
 [ kis...@ti.com : Set the functional clock to 192MHz if the contoller
   supports HS200 ]
 Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
 ---
  drivers/mmc/host/omap_hsmmc.c |  325 
 -
  1 file changed, 322 insertions(+), 3 deletions(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index 2e42ed3..675bd31d 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -22,6 +22,7 @@
  #include linux/dmaengine.h
  #include linux/seq_file.h
  #include linux/sizes.h
 +#include linux/slab.h
  #include linux/interrupt.h
  #include linux/delay.h
  #include linux/dma-mapping.h
 @@ -47,6 +48,7 @@
  /* OMAP HSMMC Host Controller Registers */
  #define OMAP_HSMMC_SYSSTATUS   0x0014
  #define OMAP_HSMMC_CON 0x002C
 +#define OMAP_HSMMC_DLL 0x0034
  #define OMAP_HSMMC_SDMASA  0x0100
  #define OMAP_HSMMC_BLK 0x0104
  #define OMAP_HSMMC_ARG 0x0108
 @@ -100,6 +102,7 @@
  #define CLKEXTFREE (1  16)
  #define CTPL   (1  11)
  #define DW8(1  5)
 +#define BRR(1  5)
  #define OD 0x1
  #define STAT_CLEAR 0x
  #define INIT_STREAM_CMD0x
 @@ -129,6 +132,20 @@
  #define CERR_EN(1  28)
  #define BADA_EN(1  29)

 +#define V1V8_SIGEN (1  19)
 +#define AC12_SCLK_SEL  (1  23)
 +#define AC12_UHSMC_MASK(7  16)
 +#define AC12_UHSMC_SDR50   (2  16)
 +#define AC12_UHSMC_SDR104  (3  16)
 +#define DLL_LOCK   (1  0)
 +#define DLL_CALIB  (1  1)
 +#define DLL_UNLOCK_STICKY  (1  2)
 +#define DLL_SWT(1  20)
 +#define DLL_FORCE_SR_C_MASK(0x7F  13)
 +#define DLL_FORCE_SR_C_SHIFT   13
 +#define DLL_FORCE_VALUE(1  12)
 +#define DLL_RESET  (1  31)
 +
  #define INT_EN_MASK (BADA_EN | CERR_EN | ACE_EN | DEB_EN | DCRC_EN |\
 DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \
 BRR_EN | BWR_EN | TC_EN | CC_EN)
 @@ -143,18 +160,23 @@
  #define SDR50  (1  0)
  #define SDR104 (1  1)
  #define DDR50  (1  2)
 +#define CAPA2_TSDR50   (1  13)

  #define MMC_AUTOSUSPEND_DELAY  100
  #define MMC_TIMEOUT_MS 20  /* 20 mSec */
  #define MMC_TIMEOUT_US 2   /* 2 micro Sec */
  #define OMAP_MMC_MIN_CLOCK 40
  #define OMAP_MMC_MAX_CLOCK 5200
 +#define MAX_PHASE_DELAY0x7F
  #define DRIVER_NAMEomap_hsmmc

  #define VDD_1V8180 /* 18 uV */
  #define VDD_3V0300 /* 30 uV */
  #define VDD_165_195(ffs(MMC_VDD_165_195) - 1)

 +#define EMMC_HSDDR_SD_SDR25_MAX5200
 +#define SD_SDR50_MAX_FREQ  10400
 +
  /*
   * One controller can have multiple slots, like on some omap boards using
   * omap.c controller driver. Luckily this is not currently done on any known
 @@ -198,6 +220,7 @@ struct omap_hsmmc_host {
 void__iomem *base;
 resource_size_t mapbase;
 spinlock_t  irq_lock; /* Prevent races with irq handler */
 +   struct completion   buf_ready;
 unsigned intdma_len;
 unsigned intdma_sg_idx;
 unsigned char   bus_mode;
 @@ -224,6 +247,13 @@ struct omap_hsmmc_host {
  #define AUTO_CMD23 (1  0)/* Auto CMD23 support */
  #define HSMMC_SDIO_IRQ_ENABLED (1  1)/* SDIO irq enabled */
  #define HSMMC_WAKE_IRQ_ENABLED (1  2)
 +
 +   u32 *tuning_data;
 +   int tuning_size;
 +   int tuning_done;
 +   int tuning_fsrc;
 +   u32 tuning_uhsmc;
 +   u32 tuning_opcode;
 struct omap_hsmmc_next  next_data;
 struct  omap_mmc_platform_data  *pdata;
  };
 @@ -233,6 +263,48 @@ struct omap_mmc_of_data {
 u8 controller_flags;
  };

 +static const u32 ref_tuning_4bits[] = {
 +   0x00FF0FFF, 0xCCC3CCFF, 0xFFCC3CC3, 0xEFFEFFFE,
 +   0xDDFFDFFF, 0xFBFFFBFF, 0xFF7FFFBF, 0xEFBDF777,
 +   0xF0FFF0FF, 0x3CCCFC0F, 0xCFCC33CC, 0xEEFFEFFF,
 +   0xFDFFFDFF, 0xFFBFFFDF, 0xFFF7FFBB, 0xDE7B7FF7
 +};
 +
 +static const u32 ref_tuning_8bits[] 

[PATCH v4 10/10] omap_hsmmc: remove unused slot_id parameter

2014-11-08 Thread Andreas Fenkart
omap_hsmmc only supports one slot. So slot id is always zero, and
slot id was never used in the callbacks anyway

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/board-rx51-peripherals.c |  2 +-
 arch/arm/mach-omap2/hsmmc.c  | 21 -
 arch/arm/mach-omap2/hsmmc.h  |  2 +-
 drivers/mmc/host/omap_hsmmc.c| 65 +++-
 include/linux/platform_data/hsmmc-omap.h | 14 ++
 5 files changed, 40 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 0a8ac84..3d5040f 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -484,7 +484,7 @@ static struct omap_mux_partition *partition;
  * Current flows to eMMC when eMMC is off and the data lines are pulled up,
  * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
  */
-static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
+static void rx51_mmc2_remux(struct device *dev, int power_on)
 {
if (power_on)
omap_mux_write_array(partition, rx51_mmc2_on_mux);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 4e2896a..dc6e79c 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -33,14 +33,14 @@ static u16 control_devconf1_offset;
 
 #define HSMMC_NAME_LEN 9
 
-static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
- int power_on, int vdd)
+static void omap_hsmmc1_before_set_reg(struct device *dev,
+  int power_on, int vdd)
 {
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-remux)
-   mmc-remux(dev, slot, power_on);
+   mmc-remux(dev, power_on);
 
/*
 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
@@ -86,8 +86,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void omap_hsmmc1_after_set_reg(struct device *dev, int slot,
-int power_on, int vdd)
+static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int 
vdd)
 {
u32 reg;
 
@@ -122,20 +121,18 @@ static void hsmmc2_select_input_clk_src(struct 
omap_hsmmc_platform_data *mmc)
omap_ctrl_writel(reg, control_devconf1_offset);
 }
 
-static void hsmmc2_before_set_reg(struct device *dev, int slot,
-  int power_on, int vdd)
+static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-remux)
-   mmc-remux(dev, slot, power_on);
+   mmc-remux(dev, power_on);
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
 }
 
-static int am35x_hsmmc2_set_power(struct device *dev, int slot,
- int power_on, int vdd)
+static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
@@ -145,8 +142,7 @@ static int am35x_hsmmc2_set_power(struct device *dev, int 
slot,
return 0;
 }
 
-static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
-   int vdd)
+static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
 {
return 0;
 }
@@ -250,7 +246,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
snprintf(hc_name, (HSMMC_NAME_LEN + 1), mmc%islot%i,
c-mmc, 1);
mmc-name = hc_name;
-   mmc-nr_slots = 1;
mmc-caps = c-caps;
mmc-internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 30c78c1..148cd9b 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -23,7 +23,7 @@ struct omap2_hsmmc_info {
struct platform_device *pdev;   /* mmc controller instance */
int ocr_mask;   /* temporary HACK */
/* Remux (pad configuration) when powering on/off */
-   void (*remux)(struct device *dev, int slot, int power_on);
+   void (*remux)(struct device *dev, int power_on);
/* init some special card */
void (*init_card)(struct mmc_card *card);
 };
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f4f1bcd..82b40b8 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -207,7 +207,6 @@ struct omap_hsmmc_host {
int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
-   int

[PATCH v4 09/10] omap_hsmmc: Remove unnecessary callbacks from platform data

2014-11-08 Thread Andreas Fenkart
These callbacks are set during driver probe and not from the platform
init, -- evtl. they had been for oamp 1/2 -- for omap3 they are local
functions of the driver. These indirection could be dropped
altogether in favor of regular function calls TODO

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c| 75 +++-
 include/linux/platform_data/hsmmc-omap.h | 18 
 2 files changed, 45 insertions(+), 48 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8a216c9..f4f1bcd 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -221,6 +221,25 @@ struct omap_hsmmc_host {
 #define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_hsmmc_platform_data*pdata;
+
+   /* To handle board related suspend/resume functionality for MMC */
+   int (*suspend)(struct device *dev, int slot);
+   int (*resume)(struct device *dev, int slot);
+
+   /* return MMC cover switch state, can be NULL if not supported.
+*
+* possible return values:
+*   0 - closed
+*   1 - open
+*/
+   int (*get_cover_state)(struct device *dev, int slot);
+
+   /* Card detection IRQs */
+   int card_detect_irq;
+
+   int (*card_detect)(struct device *dev, int slot);
+   int (*get_ro)(struct device *dev, int slot);
+
 };
 
 struct omap_mmc_of_data {
@@ -262,18 +281,16 @@ static int omap_hsmmc_get_cover_state(struct device *dev, 
int slot)
 static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_hsmmc_platform_data *mmc = host-pdata;
 
-   disable_irq(mmc-card_detect_irq);
+   disable_irq(host-card_detect_irq);
return 0;
 }
 
 static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_hsmmc_platform_data *mmc = host-pdata;
 
-   enable_irq(mmc-card_detect_irq);
+   enable_irq(host-card_detect_irq);
return 0;
 }
 
@@ -456,11 +473,11 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host 
*host,
 
if (gpio_is_valid(pdata-switch_pin)) {
if (pdata-cover)
-   pdata-get_cover_state =
-   omap_hsmmc_get_cover_state;
+   host-get_cover_state =
+   omap_hsmmc_get_cover_state;
else
-   pdata-card_detect = omap_hsmmc_card_detect;
-   pdata-card_detect_irq =
+   host-card_detect = omap_hsmmc_card_detect;
+   host-card_detect_irq =
gpio_to_irq(pdata-switch_pin);
ret = gpio_request(pdata-switch_pin, mmc_cd);
if (ret)
@@ -473,7 +490,7 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host 
*host,
}
 
if (gpio_is_valid(pdata-gpio_wp)) {
-   pdata-get_ro = omap_hsmmc_get_wp;
+   host-get_ro = omap_hsmmc_get_wp;
ret = gpio_request(pdata-gpio_wp, mmc_wp);
if (ret)
goto err_free_cd;
@@ -795,8 +812,8 @@ int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host)
 {
int r = 1;
 
-   if (mmc_pdata(host)-get_cover_state)
-   r = mmc_pdata(host)-get_cover_state(host-dev, host-slot_id);
+   if (host-get_cover_state)
+   r = host-get_cover_state(host-dev, host-slot_id);
return r;
 }
 
@@ -1263,11 +1280,11 @@ err:
 /* Protect the card while the cover is open */
 static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
 {
-   if (!mmc_pdata(host)-get_cover_state)
+   if (!host-get_cover_state)
return;
 
host-reqs_blocked = 0;
-   if (mmc_pdata(host)-get_cover_state(host-dev, host-slot_id)) {
+   if (host-get_cover_state(host-dev, host-slot_id)) {
if (host-protect_card) {
dev_info(host-dev, %s: cover is closed, 
 card is now accessible\n,
@@ -1290,13 +1307,12 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   struct omap_hsmmc_platform_data *pdata = host-pdata;
int carddetect;
 
sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
-   if (pdata-card_detect)
-   carddetect = pdata-card_detect(host-dev, host-slot_id);
+   if (host-card_detect)
+   carddetect = host-card_detect(host-dev, host-slot_id);
else {
omap_hsmmc_protect_card(host);
carddetect = -ENOSYS;
@@ -1672,18 +1688,18 @@ static int

[PATCH v4 00/10] ARM: OMAP1/2+: MMC: separate platform data for mmc and mmc hs driver

2014-11-08 Thread Andreas Fenkart
v4:
- rework patch descriptions
- dropped patch removing unused defines in mach-omap2/mmc.h
- rebase 3.18.0-rc3
- compile test omap1 and omap2

compile tested
OMAP1:
CONFIG_MACH_OMAP_INNOVATOR=y
CONFIG_MACH_OMAP_H2=y
CONFIG_MACH_OMAP_H3=y
CONFIG_MACH_HERALD=y
CONFIG_MACH_OMAP_OSK=y
CONFIG_MACH_OMAP_PERSEUS2=y
CONFIG_MACH_OMAP_FSAMPLE=y
CONFIG_MACH_VOICEBLUE=y
CONFIG_MACH_OMAP_PALMTE=y
CONFIG_MACH_OMAP_PALMZ71=y
CONFIG_MACH_OMAP_PALMTT=y
CONFIG_MACH_SX1=y
CONFIG_MACH_NOKIA770=y
CONFIG_MACH_AMS_DELTA=y
CONFIG_MACH_OMAP_GENERIC=y

OMAP2:
CONFIG_MACH_OMAP2_TUSB6010=y
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_N810=y
CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y
CONFIG_MACH_TI8168EVM=y
CONFIG_MACH_TI8148EVM=y

Andreas Fenkart (10):
  ARM: OMAP2: MMC: include mmc-omap platform header directly
  ARM: OMAP1/2+: MMC: separate platform data for mmc and mmc hs driver
  omap_hsmmc: remove unused fields in platform_data
  omap_hsmmc: remove un-initialized callbacks from platform data
  omap_hsmmc: remove never read power_saving field in omap2_hsmmc_info
  omap_hsmmc: remove unused get_context_loss_count callback
  omap_hsmmc: remove unnecessary omap_hsmmc_slot_data indirection
  omap_hsmmc: pass mmc_priv struct to gpio init / free
  omap_hsmmc: Remove unnecessary callbacks from platform data
  omap_hsmmc: remove unused slot_id parameter

 arch/arm/mach-omap2/board-n8x0.c   |   2 +
 arch/arm/mach-omap2/board-rx51-peripherals.c   |   4 +-
 arch/arm/mach-omap2/hsmmc.c| 158 +---
 arch/arm/mach-omap2/hsmmc.h|   9 +-
 arch/arm/mach-omap2/mmc.h  |  10 -
 arch/arm/mach-omap2/omap4-common.c |   1 -
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   4 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |   1 -
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  |   4 +-
 drivers/mmc/host/omap_hsmmc.c  | 282 ++---
 include/linux/platform_data/hsmmc-omap.h   |  90 +++
 include/linux/platform_data/mmc-omap.h |  27 --
 16 files changed, 312 insertions(+), 304 deletions(-)
 create mode 100644 include/linux/platform_data/hsmmc-omap.h

-- 
2.1.1

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


[PATCH v4 03/10] omap_hsmmc: remove unused fields in platform_data

2014-11-08 Thread Andreas Fenkart
platform data is built from omap2_hsmmc_info, remove all fields that
are never set in omap_hsmmc_info, hence never copied to platform data.
Note that the omap_hsmmc driver is not affected by this patch those
fields were completely unused.

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 14 --
 arch/arm/mach-omap2/hsmmc.h  |  6 --
 include/linux/platform_data/hsmmc-omap.h | 19 ---
 3 files changed, 39 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 9edd759..75b75b9 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -263,9 +263,7 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].name = hc_name;
mmc-nr_slots = 1;
mmc-slots[0].caps = c-caps;
-   mmc-slots[0].pm_caps = c-pm_caps;
mmc-slots[0].internal_clock = !c-ext_clock;
-   mmc-max_freq = c-max_freq;
mmc-reg_offset = 0;
mmc-get_context_loss_count = hsmmc_get_context_loss;
 
@@ -281,18 +279,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
if (c-nonremovable)
mmc-slots[0].nonremovable = 1;
 
-   if (c-power_saving)
-   mmc-slots[0].power_saving = 1;
-
-   if (c-no_off)
-   mmc-slots[0].no_off = 1;
-
-   if (c-no_off_init)
-   mmc-slots[0].no_regulator_off_init = c-no_off_init;
-
-   if (c-vcc_aux_disable_is_sleep)
-   mmc-slots[0].vcc_aux_disable_is_sleep = 1;
-
/*
 * NOTE:  MMC slots should have a Vcc regulator set up.
 * This may be from a TWL4030-family chip, another
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 7f2e790..bdc8870 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -12,23 +12,17 @@ struct omap2_hsmmc_info {
u8  mmc;/* controller 1/2/3 */
u32 caps;   /* 4/8 wires and any additional host
 * capabilities OR'd (ref. linux/mmc/host.h) */
-   u32 pm_caps;/* PM capabilities */
booltransceiver;/* MMC-2 option */
boolext_clock;  /* use external pin for input clock */
boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
boolpower_saving;   /* Try to sleep or power off when possible */
-   boolno_off; /* power_saving and power is not to go off */
-   boolno_off_init;/* no power off when not in MMC sleep state */
-   boolvcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
char*name;  /* or NULL for default */
struct platform_device *pdev;   /* mmc controller instance */
int ocr_mask;   /* temporary HACK */
-   int max_freq;   /* maximum clock, if constrained by external
-* circuitry, or 0 for default */
/* Remux (pad configuration) when powering on/off */
void (*remux)(struct device *dev, int slot, int power_on);
/* init some special card */
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 7dd42e5..11d7ed9 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -73,16 +73,9 @@ struct omap_hsmmc_platform_data {
 * 4/8 wires and any additional host capabilities
 * need to OR'd all capabilities (ref. linux/mmc/host.h)
 */
-   u8  wires;  /* Used for the MMC driver on omap1 and 2420 */
u32 caps;   /* Used for the MMC driver on 2430 and later */
u32 pm_caps;/* PM capabilities of the mmc */
 
-   /*
-* nomux means standard muxing is wrong on this board, and
-* that board-specific code handled it before common init logic.
-*/
-   unsigned nomux:1;
-
/* switch pin can be for card detect (default) or card cover */
unsigned cover:1;
 
@@ -92,18 +85,9 @@ struct omap_hsmmc_platform_data {
/* nonremovable e.g. eMMC */
unsigned nonremovable:1;
 
-   /* Try to sleep or power off when possible */
-   unsigned power_saving:1;
-
-   /* If using power_saving and the MMC power is not to go off */
-   unsigned no_off:1;
-
/* eMMC does not handle power off when not in sleep state */
unsigned no_regulator_off_init:1;
 
-   /* Regulator off

[PATCH v4 04/10] omap_hsmmc: remove un-initialized callbacks from platform data

2014-11-08 Thread Andreas Fenkart
these callbacks are not set, probably legacy omap 1/2 features

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c| 15 +--
 include/linux/platform_data/hsmmc-omap.h |  9 -
 2 files changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4957c5f..03e8e9a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2204,18 +2204,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (pdata-init != NULL) {
-   if (pdata-init(pdev-dev) != 0) {
-   dev_err(mmc_dev(host-mmc),
-   Unable to configure MMC IRQs\n);
-   goto err_irq;
-   }
-   }
-
if (omap_hsmmc_have_reg()  !mmc_slot(host).set_power) {
ret = omap_hsmmc_reg_get(host);
if (ret)
-   goto err_reg;
+   goto err_irq;
host-use_reg = 1;
}
 
@@ -2278,9 +2270,6 @@ err_slot_name:
 err_irq_cd:
if (host-use_reg)
omap_hsmmc_reg_put(host);
-err_reg:
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 err_irq:
if (host-tx_chan)
dma_release_channel(host-tx_chan);
@@ -2306,8 +2295,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
mmc_remove_host(host-mmc);
if (host-use_reg)
omap_hsmmc_reg_put(host);
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 11d7ed9..7e70e15 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -47,14 +47,6 @@ struct omap_hsmmc_platform_data {
 * maximum frequency on the MMC bus */
unsigned int max_freq;
 
-   /* switch the bus to a new slot */
-   int (*switch_slot)(struct device *dev, int slot);
-   /* initialize board-specific MMC functionality, can be NULL if
-* not supported */
-   int (*init)(struct device *dev);
-   void (*cleanup)(struct device *dev);
-   void (*shutdown)(struct device *dev);
-
/* To handle board related suspend/resume functionality for MMC */
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
@@ -97,7 +89,6 @@ struct omap_hsmmc_platform_data {
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
 
-   int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (*set_power)(struct device *dev, int slot,
 int power_on, int vdd);
int (*get_ro)(struct device *dev, int slot);
-- 
2.1.1

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


[PATCH v4 05/10] omap_hsmmc: remove never read power_saving field in omap2_hsmmc_info

2014-11-08 Thread Andreas Fenkart
these fields are never read, probably an unimplemented feature
or superseded by pm_runtime

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/board-rx51-peripherals.c | 2 --
 arch/arm/mach-omap2/hsmmc.h  | 1 -
 2 files changed, 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ddfc8df..0a8ac84 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -500,7 +500,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.cover_only = true,
.gpio_cd= 160,
.gpio_wp= -EINVAL,
-   .power_saving   = true,
},
{
.name   = internal,
@@ -510,7 +509,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.gpio_cd= -EINVAL,
.gpio_wp= -EINVAL,
.nonremovable   = true,
-   .power_saving   = true,
.remux  = rx51_mmc2_remux,
},
{}  /* Terminator */
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index bdc8870..30c78c1 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -16,7 +16,6 @@ struct omap2_hsmmc_info {
boolext_clock;  /* use external pin for input clock */
boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
-   boolpower_saving;   /* Try to sleep or power off when possible */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
-- 
2.1.1

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


[PATCH v4 02/10] ARM: OMAP1/2+: MMC: separate platform data for mmc and mmc hs driver

2014-11-08 Thread Andreas Fenkart
- omap mmc driver supports multiplexing, omap_mmc_hs doesn't
this leads to one of the major confusions in the omap_hsmmc driver

- platform data should be read-only for the driver
most callbacks are not set by the omap3 platform init code while still
required. So they are set from the driver probe function, which is against
the paradigm that platform-data should not be modified by the driver
typical examples are card_detect, read_only callbacks

un-bundling by searching for driver name \omap_hsmmc in the
arch/arm folder. omap_hsmmc_platform_data is not initialized directly,
but from omap2_hsmmc_info, which is defined in a separate header file
not touched by this patch

hwmod includes platform headers to declare features of the platform. All
the declared features are prefixed OMAP_HSMMC. There is no need to
include platform header from hwmod other except for feature defines

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c|  26 ++--
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   4 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  |   4 +-
 drivers/mmc/host/omap_hsmmc.c  |  28 ++--
 include/linux/platform_data/hsmmc-omap.h   | 149 +
 include/linux/platform_data/mmc-omap.h |  27 
 10 files changed, 192 insertions(+), 70 deletions(-)
 create mode 100644 include/linux/platform_data/hsmmc-omap.h

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 73e28ac..9edd759 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -16,7 +16,7 @@
 #include linux/gpio.h
 #include linux/mmc/host.h
 #include linux/platform_data/gpio-omap.h
-#include linux/platform_data/mmc-omap.h
+#include linux/platform_data/hsmmc-omap.h
 
 #include soc.h
 #include omap_device.h
@@ -48,7 +48,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
  int power_on, int vdd)
 {
u32 reg, prog_io;
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -121,7 +121,7 @@ static void omap_hsmmc1_after_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
+static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
 {
u32 reg;
 
@@ -136,7 +136,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_mmc_platform_data *mmc)
 static void hsmmc2_before_set_reg(struct device *dev, int slot,
   int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -148,7 +148,7 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 static int am35x_hsmmc2_set_power(struct device *dev, int slot,
  int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -162,8 +162,8 @@ static int nop_mmc_set_power(struct device *dev, int slot, 
int power_on,
return 0;
 }
 
-static inline void omap_hsmmc_mux(struct omap_mmc_platform_data 
*mmc_controller,
-   int controller_nr)
+static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
+ *mmc_controller, int controller_nr)
 {
if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
(mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
@@ -244,7 +244,7 @@ static inline void omap_hsmmc_mux(struct 
omap_mmc_platform_data *mmc_controller,
 }
 
 static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-   struct omap_mmc_platform_data *mmc)
+   struct omap_hsmmc_platform_data *mmc)
 {
char *hc_name;
 
@@ -369,7 +369,7 @@ static int omap_hsmmc_done;
 void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
 {
struct platform_device *pdev;
-   struct omap_mmc_platform_data *mmc_pdata;
+   struct omap_hsmmc_platform_data *mmc_pdata;
int res;
 
if (omap_hsmmc_done != 1)
@@ -409,12 +409,12 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
struct omap_device *od;
struct

[PATCH v4 06/10] omap_hsmmc: remove unused get_context_loss_count callback

2014-11-08 Thread Andreas Fenkart
trigger of this callback has been removed in 0a82e06e6183

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 12 
 include/linux/platform_data/hsmmc-omap.h |  3 ---
 2 files changed, 15 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 75b75b9..c65efc3 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -33,17 +33,6 @@ static u16 control_devconf1_offset;
 
 #define HSMMC_NAME_LEN 9
 
-#if defined(CONFIG_ARCH_OMAP3)  defined(CONFIG_PM)
-
-static int hsmmc_get_context_loss(struct device *dev)
-{
-   return omap_pm_get_dev_context_loss_count(dev);
-}
-
-#else
-#define hsmmc_get_context_loss NULL
-#endif
-
 static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
  int power_on, int vdd)
 {
@@ -265,7 +254,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].caps = c-caps;
mmc-slots[0].internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
-   mmc-get_context_loss_count = hsmmc_get_context_loss;
 
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 7e70e15..35d494f 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -51,9 +51,6 @@ struct omap_hsmmc_platform_data {
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
 
-   /* Return context loss count due to PM states changing */
-   int (*get_context_loss_count)(struct device *dev);
-
/* Integrating attributes from the omap_hwmod layer */
u8 controller_flags;
 
-- 
2.1.1

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


[PATCH v4 01/10] ARM: OMAP2: MMC: include mmc-omap platform header directly

2014-11-08 Thread Andreas Fenkart
Only a few files really need that platform header. When later splitting
omap_mmc_platform_data into omap_mmc and omap_mmc_hs, those files
declaring an hs mmc platform data will have to change the platform
include, which is a good sanity check.
Also removing omap242x_init_mmc, which is not used anywhere, checked
with grep.

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/board-n8x0.c|  2 ++
 arch/arm/mach-omap2/hsmmc.c |  3 ++-
 arch/arm/mach-omap2/mmc.h   | 10 --
 arch/arm/mach-omap2/omap4-common.c  |  1 -
 arch/arm/mach-omap2/omap_hwmod_2430_data.c  |  2 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c  |  1 -
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c  |  2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c  |  2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c  |  2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c   |  2 +-
 11 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 97767a2..e0ad64f 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -21,8 +21,10 @@
 #include linux/i2c.h
 #include linux/spi/spi.h
 #include linux/usb/musb.h
+#include linux/mmc/host.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include linux/platform_data/mtd-onenand-omap2.h
+#include linux/platform_data/mmc-omap.h
 #include linux/mfd/menelaus.h
 #include sound/tlv320aic3x.h
 
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 07d4c7b..73e28ac 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -14,14 +14,15 @@
 #include linux/string.h
 #include linux/delay.h
 #include linux/gpio.h
+#include linux/mmc/host.h
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 
 #include soc.h
 #include omap_device.h
 #include omap-pm.h
 
 #include mux.h
-#include mmc.h
 #include hsmmc.h
 #include control.h
 
diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
index 0cd4b08..30d39b9 100644
--- a/arch/arm/mach-omap2/mmc.h
+++ b/arch/arm/mach-omap2/mmc.h
@@ -1,5 +1,3 @@
-#include linux/mmc/host.h
-#include linux/platform_data/mmc-omap.h
 
 #define OMAP24XX_NR_MMC2
 #define OMAP2420_MMC_SIZE  OMAP1_MMC_SIZE
@@ -7,14 +5,6 @@
 
 #define OMAP4_MMC_REG_OFFSET   0x100
 
-#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data);
-#else
-static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
-{
-}
-#endif
-
 struct omap_hwmod;
 int omap_msdi_reset(struct omap_hwmod *oh);
 
diff --git a/arch/arm/mach-omap2/omap4-common.c 
b/arch/arm/mach-omap2/omap4-common.c
index 16b20ce..b7cb44a 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -36,7 +36,6 @@
 #include soc.h
 #include iomap.h
 #include common.h
-#include mmc.h
 #include prminst44xx.h
 #include prcm_mpu44xx.h
 #include omap4-sar-layout.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index c2555cb..cd95e82 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -15,12 +15,12 @@
 
 #include linux/i2c-omap.h
 #include linux/platform_data/asoc-ti-mcbsp.h
+#include linux/platform_data/mmc-omap.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include linux/omap-dma.h
 #include plat/dmtimer.h
 
 #include omap_hwmod.h
-#include mmc.h
 #include l3_2xxx.h
 
 #include soc.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c 
b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
index a579b89..bf8c12d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -15,10 +15,10 @@
  */
 
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include omap_hwmod.h
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 #include cm33xx.h
 #include prm33xx.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 6b406ca..0cf7b56 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -27,7 +27,6 @@
 #include prm33xx.h
 #include prm-regbits-33xx.h
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 #include omap_hwmod_33xx_43xx_common_data.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 2a78b09..5f244a9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -18,6 +18,7 @@
 #include linux/i2c

[PATCH v4 07/10] omap_hsmmc: remove unnecessary omap_hsmmc_slot_data indirection

2014-11-08 Thread Andreas Fenkart
omap_hsmmc supports only one slot per controller, see OMAP_MMC_MAX_SLOTS.
This unnecessary indirection leads to confusion in the omap_hsmmc driver.
For example the card_detect callback is not installed by platform code
but from the driver probe function. So it should be a field of
omap_hsmmc_host. But since it is declared under the platform slot while
the drivers struct omap_hsmmc_host has no slot abstraction, this looks
like a bug, especially when not familiar that this driver only supports
1 slot anyway.
Either we should add a slot abstraction to omap_hsmmc_host or remove
it from the platform data struct. Removed since slot multiplexing is
an un-implemented feature

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  |  88 
 drivers/mmc/host/omap_hsmmc.c| 175 ---
 include/linux/platform_data/hsmmc-omap.h | 100 +-
 3 files changed, 181 insertions(+), 182 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index c65efc3..4e2896a 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -39,8 +39,8 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
+   if (mmc-remux)
+   mmc-remux(dev, slot, power_on);
 
/*
 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
@@ -62,7 +62,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
}
 
-   if (mmc-slots[0].internal_clock) {
+   if (mmc-internal_clock) {
reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
reg |= OMAP2_MMCSDIO1ADPCLKISEL;
omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
@@ -115,7 +115,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_hsmmc_platform_data *mmc)
u32 reg;
 
reg = omap_ctrl_readl(control_devconf1_offset);
-   if (mmc-slots[0].internal_clock)
+   if (mmc-internal_clock)
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
else
reg = ~OMAP2_MMCSDIO2ADPCLKISEL;
@@ -127,8 +127,8 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
+   if (mmc-remux)
+   mmc-remux(dev, slot, power_on);
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -154,14 +154,14 @@ static int nop_mmc_set_power(struct device *dev, int 
slot, int power_on,
 static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
  *mmc_controller, int controller_nr)
 {
-   if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
-   (mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-slots[0].switch_pin,
-   OMAP_PIN_INPUT_PULLUP);
-   if (gpio_is_valid(mmc_controller-slots[0].gpio_wp) 
-   (mmc_controller-slots[0].gpio_wp  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-slots[0].gpio_wp,
-   OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-switch_pin) 
+   (mmc_controller-switch_pin  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-switch_pin,
+  OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-gpio_wp) 
+   (mmc_controller-gpio_wp  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_wp,
+  OMAP_PIN_INPUT_PULLUP);
if (cpu_is_omap34xx()) {
if (controller_nr == 0) {
omap_mux_init_signal(sdmmc1_clk,
@@ -170,7 +170,7 @@ static inline void omap_hsmmc_mux(struct 
omap_hsmmc_platform_data
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal(sdmmc1_dat0,
OMAP_PIN_INPUT_PULLUP);
-   if (mmc_controller-slots[0].caps 
+   if (mmc_controller-caps 
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal(sdmmc1_dat1,
OMAP_PIN_INPUT_PULLUP);
@@ -179,7 +179,7 @@ static inline void omap_hsmmc_mux(struct 
omap_hsmmc_platform_data
omap_mux_init_signal(sdmmc1_dat3

[PATCH v4 08/10] omap_hsmmc: pass mmc_priv struct to gpio init / free

2014-11-08 Thread Andreas Fenkart
this is needed when installing callbacks in the host struct and not
in the platform data, e.g. cover detect irq should be stored in
omap_hsmmc_host and not platform data

Acked-by: Tony Lindgren t...@atomide.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 291b9e1..8a216c9 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -449,7 +449,8 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_hsmmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host,
+   struct omap_hsmmc_platform_data *pdata)
 {
int ret;
 
@@ -494,7 +495,8 @@ err_free_sp:
return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_hsmmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host,
+struct omap_hsmmc_platform_data *pdata)
 {
if (gpio_is_valid(pdata-gpio_wp))
gpio_free(pdata-gpio_wp);
@@ -2064,14 +2066,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
if (IS_ERR(base))
return PTR_ERR(base);
 
-   ret = omap_hsmmc_gpio_init(pdata);
-   if (ret)
-   goto err;
-
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), pdev-dev);
if (!mmc) {
ret = -ENOMEM;
-   goto err_alloc;
+   goto err;
}
 
host= mmc_priv(mmc);
@@ -2088,6 +2086,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host-next_data.cookie = 1;
host-pbias_enabled = 0;
 
+   ret = omap_hsmmc_gpio_init(host, pdata);
+   if (ret)
+   goto err_gpio;
+
platform_set_drvdata(pdev, host);
 
if (pdev-dev.of_node)
@@ -2283,9 +2285,9 @@ err_irq:
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 err1:
+   omap_hsmmc_gpio_free(host, pdata);
+err_gpio:
mmc_free_host(mmc);
-err_alloc:
-   omap_hsmmc_gpio_free(pdata);
 err:
return ret;
 }
@@ -2309,7 +2311,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 
-   omap_hsmmc_gpio_free(host-pdata);
+   omap_hsmmc_gpio_free(host, host-pdata);
mmc_free_host(host-mmc);
 
return 0;
-- 
2.1.1

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


[PATCH v3 3/3] ARM: OMAP2+: use separate platform data for omap3 and omap 1/2 driver

2014-10-04 Thread Andreas Fenkart
- mmci driver supports multiple slots, omap_hsmmc only one
this leads to one of the major confusions in the omap_hsmmc driver

- platform data should be read-only for the driver
most callbacks are not set by the omap3 platform init code while being
required by the driver, leading to the fact that they are set by the
driver during it's probe function
typical example are card detect / read only detect callbacks

un-bundling by searching for driver name \omap_hsmmc in the
arch/arm folder. omap_hsmmc_platform_data is not initialized directly,
but from omap2_hsmmc_info, which is defined in a separate header file
not touched by this patch

additionally hwmod is used to initialize platform data. use
omap_mmc_dev_attr as a key which hwmod uses omap_hsmmc driver.
since all possible values assigned to omap_mmc_dev_attr.flags
are hsmmc specific:
#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT   BIT(0)
#define OMAP_HSMMC_BROKEN_MULTIBLOCK_READ   BIT(1)
#define OMAP_HSMMC_SWAKEUP_MISSING  BIT(2)

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 73e28ac..9edd759 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -16,7 +16,7 @@
 #include linux/gpio.h
 #include linux/mmc/host.h
 #include linux/platform_data/gpio-omap.h
-#include linux/platform_data/mmc-omap.h
+#include linux/platform_data/hsmmc-omap.h
 
 #include soc.h
 #include omap_device.h
@@ -48,7 +48,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
  int power_on, int vdd)
 {
u32 reg, prog_io;
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -121,7 +121,7 @@ static void omap_hsmmc1_after_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
+static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
 {
u32 reg;
 
@@ -136,7 +136,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_mmc_platform_data *mmc)
 static void hsmmc2_before_set_reg(struct device *dev, int slot,
   int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -148,7 +148,7 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 static int am35x_hsmmc2_set_power(struct device *dev, int slot,
  int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -162,8 +162,8 @@ static int nop_mmc_set_power(struct device *dev, int slot, 
int power_on,
return 0;
 }
 
-static inline void omap_hsmmc_mux(struct omap_mmc_platform_data 
*mmc_controller,
-   int controller_nr)
+static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
+ *mmc_controller, int controller_nr)
 {
if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
(mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
@@ -244,7 +244,7 @@ static inline void omap_hsmmc_mux(struct 
omap_mmc_platform_data *mmc_controller,
 }
 
 static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-   struct omap_mmc_platform_data *mmc)
+   struct omap_hsmmc_platform_data *mmc)
 {
char *hc_name;
 
@@ -369,7 +369,7 @@ static int omap_hsmmc_done;
 void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
 {
struct platform_device *pdev;
-   struct omap_mmc_platform_data *mmc_pdata;
+   struct omap_hsmmc_platform_data *mmc_pdata;
int res;
 
if (omap_hsmmc_done != 1)
@@ -409,12 +409,12 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
struct omap_device *od;
struct platform_device *pdev;
char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
-   struct omap_mmc_platform_data *mmc_data;
-   struct omap_mmc_dev_attr *mmc_dev_attr;
+   struct omap_hsmmc_platform_data *mmc_data;
+   struct omap_hsmmc_dev_attr *mmc_dev_attr;
char *name;
int res;
 
-   mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+   mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data) {
pr_err(Cannot allocate memory for mmc device!\n);
return;
@@ -464,7 +464,7 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo

[PATCH v3 0/3] ARM: OMAP2+: MMC: use separate platform data for omap3 and omap 1/2 driver

2014-10-04 Thread Andreas Fenkart
v3:
- fix compile break, by include proper platform header 
  tested with these architectures
CONFIG_MACH_OMAP2_TUSB6010=y
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_N810=y
CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y
CONFIG_MACH_TI8168EVM=y
CONFIG_MACH_TI8148EVM=y
- dropped all patches simplifying the hsmmc-omap platform struct,
  will resubmit once the platform data split is successful

Andreas Fenkart (3):
  ARM: OMAP2+: remove unused defines from mach-omap2/mmc header
  ARM: OMAP2+: include mmc-omap platform directly in hwmod data files
  ARM: OMAP2+: use separate platform data for omap3 and omap 1/2 driver

 arch/arm/mach-omap2/board-n8x0.c   |   2 +
 arch/arm/mach-omap2/hsmmc.c|  27 ++--
 arch/arm/mach-omap2/mmc.h  |  14 --
 arch/arm/mach-omap2/omap4-common.c |   1 -
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   4 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |   1 -
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   8 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c |   4 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  |   4 +-
 drivers/mmc/host/omap_hsmmc.c  |  28 ++--
 include/linux/platform_data/hsmmc-omap.h   | 152 +
 include/linux/platform_data/mmc-omap.h |  24 
 14 files changed, 198 insertions(+), 83 deletions(-)
 create mode 100644 include/linux/platform_data/hsmmc-omap.h

-- 
2.1.0

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


[PATCH v3 2/3] ARM: OMAP2+: include mmc-omap platform directly in hwmod data files

2014-10-04 Thread Andreas Fenkart
When splitting platform data of omap mmc/hsmmc driver it will
allow to check which hwomod uses easily by looking at which header is
included

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index aead77a..fa70d1c 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -21,8 +21,10 @@
 #include linux/i2c.h
 #include linux/spi/spi.h
 #include linux/usb/musb.h
+#include linux/mmc/host.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include linux/platform_data/mtd-onenand-omap2.h
+#include linux/platform_data/mmc-omap.h
 #include linux/mfd/menelaus.h
 #include sound/tlv320aic3x.h
 
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 07d4c7b..73e28ac 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -14,14 +14,15 @@
 #include linux/string.h
 #include linux/delay.h
 #include linux/gpio.h
+#include linux/mmc/host.h
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 
 #include soc.h
 #include omap_device.h
 #include omap-pm.h
 
 #include mux.h
-#include mmc.h
 #include hsmmc.h
 #include control.h
 
diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
index ea4fddf..6799fa5 100644
--- a/arch/arm/mach-omap2/mmc.h
+++ b/arch/arm/mach-omap2/mmc.h
@@ -1,5 +1,3 @@
-#include linux/mmc/host.h
-#include linux/platform_data/mmc-omap.h
 
 #define OMAP24XX_NR_MMC2
 
diff --git a/arch/arm/mach-omap2/omap4-common.c 
b/arch/arm/mach-omap2/omap4-common.c
index 539e810..9d8dc85 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -35,7 +35,6 @@
 #include soc.h
 #include iomap.h
 #include common.h
-#include mmc.h
 #include prminst44xx.h
 #include prcm_mpu44xx.h
 #include omap4-sar-layout.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 6d1b609..29450da 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -15,13 +15,13 @@
 
 #include linux/i2c-omap.h
 #include linux/platform_data/asoc-ti-mcbsp.h
+#include linux/platform_data/mmc-omap.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include linux/omap-dma.h
 #include linux/platform_data/mailbox-omap.h
 #include plat/dmtimer.h
 
 #include omap_hwmod.h
-#include mmc.h
 #include l3_2xxx.h
 
 #include soc.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c 
b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
index a579b89..bf8c12d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -15,10 +15,10 @@
  */
 
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 #include linux/platform_data/spi-omap2-mcspi.h
 #include omap_hwmod.h
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 #include cm33xx.h
 #include prm33xx.h
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 6b406ca..0cf7b56 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -27,7 +27,6 @@
 #include prm33xx.h
 #include prm-regbits-33xx.h
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 #include omap_hwmod_33xx_43xx_common_data.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 1cd0cfd..70b14fe 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -18,6 +18,7 @@
 #include linux/i2c-omap.h
 #include linux/power/smartreflex.h
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 
 #include linux/omap-dma.h
 #include l3_3xxx.h
@@ -37,7 +38,6 @@
 #include cm-regbits-34xx.h
 
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 #include serial.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 41e54f7..1107926 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -22,6 +22,7 @@
 
 #include linux/io.h
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 #include linux/power/smartreflex.h
 #include linux/i2c-omap.h
 
@@ -39,7 +40,6 @@
 #include prm44xx.h
 #include prm-regbits-44xx.h
 #include i2c.h
-#include mmc.h
 #include wd_timer.h
 
 /* Base offset for all OMAP4 interrupts external to MPUSS */
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 1103aa0..13bf6a7 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -19,6 +19,7 @@
 
 #include linux/io.h
 #include linux/platform_data/gpio-omap.h
+#include linux/platform_data/mmc-omap.h
 #include linux/power/smartreflex.h
 #include linux/i2c-omap.h

[PATCH v3 1/3] ARM: OMAP2+: remove unused defines from mach-omap2/mmc header

2014-10-04 Thread Andreas Fenkart
build tested for these architectures
CONFIG_MACH_OMAP2_TUSB6010=y
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_N810=y
CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y
CONFIG_MACH_TI8168EVM=y
CONFIG_MACH_TI8148EVM=y

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
index 0cd4b08..ea4fddf 100644
--- a/arch/arm/mach-omap2/mmc.h
+++ b/arch/arm/mach-omap2/mmc.h
@@ -2,18 +2,6 @@
 #include linux/platform_data/mmc-omap.h
 
 #define OMAP24XX_NR_MMC2
-#define OMAP2420_MMC_SIZE  OMAP1_MMC_SIZE
-#define OMAP2_MMC1_BASE0x4809c000
-
-#define OMAP4_MMC_REG_OFFSET   0x100
-
-#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data);
-#else
-static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
-{
-}
-#endif
 
 struct omap_hwmod;
 int omap_msdi_reset(struct omap_hwmod *oh);
-- 
2.1.0

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


[PATCH v2 3/9] omap_hsmmc: remove un-initialized callbacks from platform data

2014-09-29 Thread Andreas Fenkart
these callbacks are not set, probably legacy omap 1/2 features

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5f2b5b7..f68ac1a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2204,18 +2204,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (pdata-init != NULL) {
-   if (pdata-init(pdev-dev) != 0) {
-   dev_err(mmc_dev(host-mmc),
-   Unable to configure MMC IRQs\n);
-   goto err_irq;
-   }
-   }
-
if (omap_hsmmc_have_reg()  !mmc_slot(host).set_power) {
ret = omap_hsmmc_reg_get(host);
if (ret)
-   goto err_reg;
+   goto err_irq;
host-use_reg = 1;
}
 
@@ -2278,9 +2270,6 @@ err_slot_name:
 err_irq_cd:
if (host-use_reg)
omap_hsmmc_reg_put(host);
-err_reg:
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 err_irq:
if (host-tx_chan)
dma_release_channel(host-tx_chan);
@@ -2306,8 +2295,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
mmc_remove_host(host-mmc);
if (host-use_reg)
omap_hsmmc_reg_put(host);
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 026efb6..2807786 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -45,14 +45,6 @@ struct omap_hsmmc_platform_data {
 * maximum frequency on the MMC bus */
unsigned int max_freq;
 
-   /* switch the bus to a new slot */
-   int (*switch_slot)(struct device *dev, int slot);
-   /* initialize board-specific MMC functionality, can be NULL if
-* not supported */
-   int (*init)(struct device *dev);
-   void (*cleanup)(struct device *dev);
-   void (*shutdown)(struct device *dev);
-
/* To handle board related suspend/resume functionality for MMC */
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
@@ -95,7 +87,6 @@ struct omap_hsmmc_platform_data {
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
 
-   int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (*set_power)(struct device *dev, int slot,
 int power_on, int vdd);
int (*get_ro)(struct device *dev, int slot);
-- 
2.1.0

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


[PATCH v2 2/9] omap_hsmmc: remove unused fields in platform_data

2014-09-29 Thread Andreas Fenkart
platform data is built from omap2_hsmmc_info, remove all fields that
are never set in omap_hsmmc_info, hence never copied to platform data.
Note that the omap_hsmmc driver never used any of these fields, they were
completely unused

compile tested for these platforms
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index e3555f2..1c10402 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -262,9 +262,7 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].name = hc_name;
mmc-nr_slots = 1;
mmc-slots[0].caps = c-caps;
-   mmc-slots[0].pm_caps = c-pm_caps;
mmc-slots[0].internal_clock = !c-ext_clock;
-   mmc-max_freq = c-max_freq;
mmc-reg_offset = 0;
mmc-get_context_loss_count = hsmmc_get_context_loss;
 
@@ -280,18 +278,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
if (c-nonremovable)
mmc-slots[0].nonremovable = 1;
 
-   if (c-power_saving)
-   mmc-slots[0].power_saving = 1;
-
-   if (c-no_off)
-   mmc-slots[0].no_off = 1;
-
-   if (c-no_off_init)
-   mmc-slots[0].no_regulator_off_init = c-no_off_init;
-
-   if (c-vcc_aux_disable_is_sleep)
-   mmc-slots[0].vcc_aux_disable_is_sleep = 1;
-
/*
 * NOTE:  MMC slots should have a Vcc regulator set up.
 * This may be from a TWL4030-family chip, another
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 7f2e790..bdc8870 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -12,23 +12,17 @@ struct omap2_hsmmc_info {
u8  mmc;/* controller 1/2/3 */
u32 caps;   /* 4/8 wires and any additional host
 * capabilities OR'd (ref. linux/mmc/host.h) */
-   u32 pm_caps;/* PM capabilities */
booltransceiver;/* MMC-2 option */
boolext_clock;  /* use external pin for input clock */
boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
boolpower_saving;   /* Try to sleep or power off when possible */
-   boolno_off; /* power_saving and power is not to go off */
-   boolno_off_init;/* no power off when not in MMC sleep state */
-   boolvcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
char*name;  /* or NULL for default */
struct platform_device *pdev;   /* mmc controller instance */
int ocr_mask;   /* temporary HACK */
-   int max_freq;   /* maximum clock, if constrained by external
-* circuitry, or 0 for default */
/* Remux (pad configuration) when powering on/off */
void (*remux)(struct device *dev, int slot, int power_on);
/* init some special card */
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index cb91db4..026efb6 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -30,8 +30,6 @@
 #define OMAP_HSMMC_BROKEN_MULTIBLOCK_READ  BIT(1)
 #define OMAP_HSMMC_SWAKEUP_MISSING BIT(2)
 
-struct mmc_card;
-
 struct omap_hsmmc_dev_attr {
u8 flags;
 };
@@ -73,16 +71,9 @@ struct omap_hsmmc_platform_data {
 * 4/8 wires and any additional host capabilities
 * need to OR'd all capabilities (ref. linux/mmc/host.h)
 */
-   u8  wires;  /* Used for the MMC driver on omap1 and 2420 */
u32 caps;   /* Used for the MMC driver on 2430 and later */
u32 pm_caps;/* PM capabilities of the mmc */
 
-   /*
-* nomux means standard muxing is wrong on this board, and
-* that board-specific code handled it before common init logic.
-*/
-   unsigned nomux:1;
-
/* switch pin can be for card detect (default) or card cover */
unsigned cover:1;
 
@@ -92,25 +83,13 @@ struct omap_hsmmc_platform_data {
/* nonremovable e.g. eMMC */
unsigned nonremovable:1

[PATCH v2 5/9] omap_hsmmc: remove unused get_context_loss_count callback

2014-09-29 Thread Andreas Fenkart
trigger of this callback has been removed in 0a82e06e6183

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 1c10402..312f13d 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,17 +32,6 @@ static u16 control_devconf1_offset;
 
 #define HSMMC_NAME_LEN 9
 
-#if defined(CONFIG_ARCH_OMAP3)  defined(CONFIG_PM)
-
-static int hsmmc_get_context_loss(struct device *dev)
-{
-   return omap_pm_get_dev_context_loss_count(dev);
-}
-
-#else
-#define hsmmc_get_context_loss NULL
-#endif
-
 static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
  int power_on, int vdd)
 {
@@ -264,7 +253,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].caps = c-caps;
mmc-slots[0].internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
-   mmc-get_context_loss_count = hsmmc_get_context_loss;
 
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 2807786..dc44dfb 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -49,9 +49,6 @@ struct omap_hsmmc_platform_data {
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
 
-   /* Return context loss count due to PM states changing */
-   int (*get_context_loss_count)(struct device *dev);
-
/* Integrating attributes from the omap_hwmod layer */
u8 controller_flags;
 
-- 
2.1.0

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


[PATCH v2 0/9] unshare and simplify omap_hsmmc platform struct

2014-09-29 Thread Andreas Fenkart
v2:
- replace erroneous mmci by omap1/2
- add description to all patches
- full compile check with:
CONFIG_MACH_OMAP3_BEAGLE=y
CONFIG_MACH_DEVKIT8000=y
CONFIG_MACH_OMAP_LDP=y
CONFIG_MACH_OMAP3530_LV_SOM=y
CONFIG_MACH_OMAP3_TORPEDO=y
CONFIG_MACH_OVERO=y
CONFIG_MACH_OMAP3517EVM=y
CONFIG_MACH_CRANEBOARD=y
CONFIG_MACH_OMAP3_PANDORA=y
CONFIG_MACH_TOUCHBOOK=y
CONFIG_MACH_OMAP_3430SDP=y
CONFIG_MACH_NOKIA_RX51=y
CONFIG_MACH_CM_T35=y
CONFIG_MACH_CM_T3517=y
CONFIG_MACH_CM_T3730=y
CONFIG_MACH_SBC3530=y
- reorganized and added more patches, hence no blank ack added


Andreas Fenkart (9):
  omap_hsmmc: use separate platform data for ompa3 and omap 1/2 driver
  omap_hsmmc: remove unused fields in platform_data
  omap_hsmmc: remove un-initialized callbacks from platform data
  omap_hsmmc: remove un-ready power_saving field in omap2_hsmmc_info
  omap_hsmmc: remove unused get_context_loss_count callback
  omap_hsmmc: remove unnecessary omap_hsmmc_slot_data indirection
  omap_hsmmc: pass mmc_priv struct to gpio init / free
  omap_hsmmc: Remove unnecessary callbacks from platform data
  omap_hsmmc: remove unused slot_id parameter

 arch/arm/mach-omap2/board-rx51-peripherals.c   |   4 +-
 arch/arm/mach-omap2/hsmmc.c| 155 +--
 arch/arm/mach-omap2/hsmmc.h|   9 +-
 arch/arm/mach-omap2/mmc.h  |   6 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   6 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   6 +-
 drivers/mmc/host/omap_hsmmc.c  | 282 ++---
 include/linux/platform_data/hsmmc-omap.h   |  88 +++
 8 files changed, 299 insertions(+), 257 deletions(-)
 create mode 100644 include/linux/platform_data/hsmmc-omap.h

-- 
2.1.0

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


[PATCH v2 9/9] omap_hsmmc: remove unused slot_id parameter

2014-09-29 Thread Andreas Fenkart
omap_hsmmc only supports one slot. So slot id is always zero, and
slot id is never used in the callbacks

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 0a8ac84..3d5040f 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -484,7 +484,7 @@ static struct omap_mux_partition *partition;
  * Current flows to eMMC when eMMC is off and the data lines are pulled up,
  * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
  */
-static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
+static void rx51_mmc2_remux(struct device *dev, int power_on)
 {
if (power_on)
omap_mux_write_array(partition, rx51_mmc2_on_mux);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index a535cd3..bdc0402 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,14 +32,14 @@ static u16 control_devconf1_offset;
 
 #define HSMMC_NAME_LEN 9
 
-static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
- int power_on, int vdd)
+static void omap_hsmmc1_before_set_reg(struct device *dev,
+  int power_on, int vdd)
 {
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-remux)
-   mmc-remux(dev, slot, power_on);
+   mmc-remux(dev, power_on);
 
/*
 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
@@ -85,8 +85,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void omap_hsmmc1_after_set_reg(struct device *dev, int slot,
-int power_on, int vdd)
+static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int 
vdd)
 {
u32 reg;
 
@@ -121,20 +120,18 @@ static void hsmmc2_select_input_clk_src(struct 
omap_hsmmc_platform_data *mmc)
omap_ctrl_writel(reg, control_devconf1_offset);
 }
 
-static void hsmmc2_before_set_reg(struct device *dev, int slot,
-  int power_on, int vdd)
+static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-remux)
-   mmc-remux(dev, slot, power_on);
+   mmc-remux(dev, power_on);
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
 }
 
-static int am35x_hsmmc2_set_power(struct device *dev, int slot,
- int power_on, int vdd)
+static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
@@ -144,8 +141,7 @@ static int am35x_hsmmc2_set_power(struct device *dev, int 
slot,
return 0;
 }
 
-static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
-   int vdd)
+static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
 {
return 0;
 }
@@ -249,7 +245,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
snprintf(hc_name, (HSMMC_NAME_LEN + 1), mmc%islot%i,
c-mmc, 1);
mmc-name = hc_name;
-   mmc-nr_slots = 1;
mmc-caps = c-caps;
mmc-internal_clock = !c-ext_clock;
mmc-reg_offset = 0;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 30c78c1..148cd9b 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -23,7 +23,7 @@ struct omap2_hsmmc_info {
struct platform_device *pdev;   /* mmc controller instance */
int ocr_mask;   /* temporary HACK */
/* Remux (pad configuration) when powering on/off */
-   void (*remux)(struct device *dev, int slot, int power_on);
+   void (*remux)(struct device *dev, int power_on);
/* init some special card */
void (*init_card)(struct mmc_card *card);
 };
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 0a1398a..c063882 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -207,7 +207,6 @@ struct omap_hsmmc_host {
int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
-   int slot_id;
int response_busy;
int context_loss;
int protect_card;
@@ -223,8 +222,8 @@ struct omap_hsmmc_host {
struct  omap_hsmmc_platform_data*pdata;
 
/* To handle board related suspend/resume functionality for MMC */
-   int (*suspend)(struct device *dev, int slot);
-   int

[PATCH v2 7/9] omap_hsmmc: pass mmc_priv struct to gpio init / free

2014-09-29 Thread Andreas Fenkart
this is needed when installing callbacks in the host struct and not
in the platform data, e.g. cover detect irq should be stored in
omap_hsmmc_host and not platform data

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d05b7f3..f8cd3b3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -449,7 +449,8 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_hsmmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host,
+   struct omap_hsmmc_platform_data *pdata)
 {
int ret;
 
@@ -494,7 +495,8 @@ err_free_sp:
return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_hsmmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host,
+struct omap_hsmmc_platform_data *pdata)
 {
if (gpio_is_valid(pdata-gpio_wp))
gpio_free(pdata-gpio_wp);
@@ -2054,14 +2056,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
if (IS_ERR(base))
return PTR_ERR(base);
 
-   ret = omap_hsmmc_gpio_init(pdata);
-   if (ret)
-   goto err;
-
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), pdev-dev);
if (!mmc) {
ret = -ENOMEM;
-   goto err_alloc;
+   goto err;
}
 
host= mmc_priv(mmc);
@@ -2078,6 +2076,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host-next_data.cookie = 1;
host-pbias_enabled = 0;
 
+   ret = omap_hsmmc_gpio_init(host, pdata);
+   if (ret)
+   goto err_gpio;
+
platform_set_drvdata(pdev, host);
 
if (pdev-dev.of_node)
@@ -2283,9 +2285,9 @@ err_irq:
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 err1:
+   omap_hsmmc_gpio_free(host, pdata);
+err_gpio:
mmc_free_host(mmc);
-err_alloc:
-   omap_hsmmc_gpio_free(pdata);
 err:
return ret;
 }
@@ -2309,7 +2311,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 
-   omap_hsmmc_gpio_free(host-pdata);
+   omap_hsmmc_gpio_free(host, host-pdata);
mmc_free_host(host-mmc);
 
return 0;
-- 
2.1.0

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


[PATCH v2 4/9] omap_hsmmc: remove un-ready power_saving field in omap2_hsmmc_info

2014-09-29 Thread Andreas Fenkart
these fields are never read, probably an unimplemented feature
or superseded by pm_runtime

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ddfc8df..0a8ac84 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -500,7 +500,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.cover_only = true,
.gpio_cd= 160,
.gpio_wp= -EINVAL,
-   .power_saving   = true,
},
{
.name   = internal,
@@ -510,7 +509,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.gpio_cd= -EINVAL,
.gpio_wp= -EINVAL,
.nonremovable   = true,
-   .power_saving   = true,
.remux  = rx51_mmc2_remux,
},
{}  /* Terminator */
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index bdc8870..30c78c1 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -16,7 +16,6 @@ struct omap2_hsmmc_info {
boolext_clock;  /* use external pin for input clock */
boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
-   boolpower_saving;   /* Try to sleep or power off when possible */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
-- 
2.1.0

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


[PATCH v2 6/9] omap_hsmmc: remove unnecessary omap_hsmmc_slot_data indirection

2014-09-29 Thread Andreas Fenkart
omap_hsmmc supports only one slot per controller, see OMAP_MMC_MAX_SLOTS.
This unnecessary indirection leads to confusion in the omap_hsmmc driver.
For example the card_detect callback is not installed by platform code
but from the driver probe function. So it should be a field of
omap_hsmmc_host. But since it is declared under the platform slot while
the drivers struct omap_hsmmc_host has no slot abstraction, this looks
like a bug, especially when not familiar that this driver only supports
1 slot anyway.
Either we should add a slot abstraction to omap_hsmmc_host or remove
it from the platform data struct. Removed since slot support is
an un-implemented feature

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 312f13d..a535cd3 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -38,8 +38,8 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
+   if (mmc-remux)
+   mmc-remux(dev, slot, power_on);
 
/*
 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
@@ -61,7 +61,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
}
 
-   if (mmc-slots[0].internal_clock) {
+   if (mmc-internal_clock) {
reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
reg |= OMAP2_MMCSDIO1ADPCLKISEL;
omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
@@ -114,7 +114,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_hsmmc_platform_data *mmc)
u32 reg;
 
reg = omap_ctrl_readl(control_devconf1_offset);
-   if (mmc-slots[0].internal_clock)
+   if (mmc-internal_clock)
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
else
reg = ~OMAP2_MMCSDIO2ADPCLKISEL;
@@ -126,8 +126,8 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
+   if (mmc-remux)
+   mmc-remux(dev, slot, power_on);
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -153,14 +153,14 @@ static int nop_mmc_set_power(struct device *dev, int 
slot, int power_on,
 static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
  *mmc_controller, int controller_nr)
 {
-   if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
-   (mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-slots[0].switch_pin,
-   OMAP_PIN_INPUT_PULLUP);
-   if (gpio_is_valid(mmc_controller-slots[0].gpio_wp) 
-   (mmc_controller-slots[0].gpio_wp  OMAP_MAX_GPIO_LINES))
-   omap_mux_init_gpio(mmc_controller-slots[0].gpio_wp,
-   OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-switch_pin) 
+   (mmc_controller-switch_pin  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-switch_pin,
+  OMAP_PIN_INPUT_PULLUP);
+   if (gpio_is_valid(mmc_controller-gpio_wp) 
+   (mmc_controller-gpio_wp  OMAP_MAX_GPIO_LINES))
+   omap_mux_init_gpio(mmc_controller-gpio_wp,
+  OMAP_PIN_INPUT_PULLUP);
if (cpu_is_omap34xx()) {
if (controller_nr == 0) {
omap_mux_init_signal(sdmmc1_clk,
@@ -169,7 +169,7 @@ static inline void omap_hsmmc_mux(struct 
omap_hsmmc_platform_data
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal(sdmmc1_dat0,
OMAP_PIN_INPUT_PULLUP);
-   if (mmc_controller-slots[0].caps 
+   if (mmc_controller-caps 
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal(sdmmc1_dat1,
OMAP_PIN_INPUT_PULLUP);
@@ -178,7 +178,7 @@ static inline void omap_hsmmc_mux(struct 
omap_hsmmc_platform_data
omap_mux_init_signal(sdmmc1_dat3,
OMAP_PIN_INPUT_PULLUP);
}
-   if (mmc_controller-slots[0].caps 
+   if (mmc_controller-caps 
MMC_CAP_8_BIT_DATA) {
omap_mux_init_signal(sdmmc1_dat4

[PATCH v2 1/9] omap_hsmmc: use separate platform data for ompa3 and omap 1/2 driver

2014-09-29 Thread Andreas Fenkart
- mmci driver supports multiple slots, omap_hsmmc only one
this leads to one of the major confusions in the omap_hsmmc driver

- platform data should be read-only for the driver
most callbacks are not set by the omap3 platform init code while being
required by the driver, leading to the fact that they are set by the
driver during it's probe function
typical example are card detect / read only detect callbacks

un-bundling by searching for driver name \omap_hsmmc in the
arch/arm folder. omap_hsmmc_platform_data is not initialized directly,
but from omap2_hsmmc_info, which is defined in a separate header file
not touched by this patch

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 07d4c7b..e3555f2 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -47,7 +47,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
  int power_on, int vdd)
 {
u32 reg, prog_io;
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -120,7 +120,7 @@ static void omap_hsmmc1_after_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
+static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
 {
u32 reg;
 
@@ -135,7 +135,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_mmc_platform_data *mmc)
 static void hsmmc2_before_set_reg(struct device *dev, int slot,
   int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -147,7 +147,7 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 static int am35x_hsmmc2_set_power(struct device *dev, int slot,
  int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -161,8 +161,8 @@ static int nop_mmc_set_power(struct device *dev, int slot, 
int power_on,
return 0;
 }
 
-static inline void omap_hsmmc_mux(struct omap_mmc_platform_data 
*mmc_controller,
-   int controller_nr)
+static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
+ *mmc_controller, int controller_nr)
 {
if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
(mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
@@ -243,7 +243,7 @@ static inline void omap_hsmmc_mux(struct 
omap_mmc_platform_data *mmc_controller,
 }
 
 static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-   struct omap_mmc_platform_data *mmc)
+   struct omap_hsmmc_platform_data *mmc)
 {
char *hc_name;
 
@@ -368,7 +368,7 @@ static int omap_hsmmc_done;
 void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
 {
struct platform_device *pdev;
-   struct omap_mmc_platform_data *mmc_pdata;
+   struct omap_hsmmc_platform_data *mmc_pdata;
int res;
 
if (omap_hsmmc_done != 1)
@@ -408,12 +408,12 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
struct omap_device *od;
struct platform_device *pdev;
char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
-   struct omap_mmc_platform_data *mmc_data;
-   struct omap_mmc_dev_attr *mmc_dev_attr;
+   struct omap_hsmmc_platform_data *mmc_data;
+   struct omap_hsmmc_dev_attr *mmc_dev_attr;
char *name;
int res;
 
-   mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+   mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data) {
pr_err(Cannot allocate memory for mmc device!\n);
return;
@@ -463,7 +463,7 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
}
 
res = platform_device_add_data(pdev, mmc_data,
- sizeof(struct omap_mmc_platform_data));
+ sizeof(struct omap_hsmmc_platform_data));
if (res) {
pr_err(Could not add pdata for %s\n, name);
goto put_pdev;
diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
index 0cd4b08..db28c14 100644
--- a/arch/arm/mach-omap2/mmc.h
+++ b/arch/arm/mach-omap2/mmc.h
@@ -1,5 +1,5 @@
 #include linux/mmc/host.h
-#include linux/platform_data/mmc-omap.h
+#include linux/platform_data/hsmmc-omap.h
 
 #define

[PATCH v2 8/9] omap_hsmmc: Remove unnecessary callbacks from platform data

2014-09-29 Thread Andreas Fenkart
These callbacks are set during driver probe and not from the platform
init, -- evtl. they had been for oamp 1/2 -- for omap3 they are local
functions of the driver. These indirection could be dropped
altogether in favor of regular function calls TODO

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f8cd3b3..0a1398a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -221,6 +221,25 @@ struct omap_hsmmc_host {
 #define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_hsmmc_platform_data*pdata;
+
+   /* To handle board related suspend/resume functionality for MMC */
+   int (*suspend)(struct device *dev, int slot);
+   int (*resume)(struct device *dev, int slot);
+
+   /* return MMC cover switch state, can be NULL if not supported.
+*
+* possible return values:
+*   0 - closed
+*   1 - open
+*/
+   int (*get_cover_state)(struct device *dev, int slot);
+
+   /* Card detection IRQs */
+   int card_detect_irq;
+
+   int (*card_detect)(struct device *dev, int slot);
+   int (*get_ro)(struct device *dev, int slot);
+
 };
 
 struct omap_mmc_of_data {
@@ -262,18 +281,16 @@ static int omap_hsmmc_get_cover_state(struct device *dev, 
int slot)
 static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_hsmmc_platform_data *mmc = host-pdata;
 
-   disable_irq(mmc-card_detect_irq);
+   disable_irq(host-card_detect_irq);
return 0;
 }
 
 static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_hsmmc_platform_data *mmc = host-pdata;
 
-   enable_irq(mmc-card_detect_irq);
+   enable_irq(host-card_detect_irq);
return 0;
 }
 
@@ -456,11 +473,11 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host 
*host,
 
if (gpio_is_valid(pdata-switch_pin)) {
if (pdata-cover)
-   pdata-get_cover_state =
-   omap_hsmmc_get_cover_state;
+   host-get_cover_state =
+   omap_hsmmc_get_cover_state;
else
-   pdata-card_detect = omap_hsmmc_card_detect;
-   pdata-card_detect_irq =
+   host-card_detect = omap_hsmmc_card_detect;
+   host-card_detect_irq =
gpio_to_irq(pdata-switch_pin);
ret = gpio_request(pdata-switch_pin, mmc_cd);
if (ret)
@@ -473,7 +490,7 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host 
*host,
}
 
if (gpio_is_valid(pdata-gpio_wp)) {
-   pdata-get_ro = omap_hsmmc_get_wp;
+   host-get_ro = omap_hsmmc_get_wp;
ret = gpio_request(pdata-gpio_wp, mmc_wp);
if (ret)
goto err_free_cd;
@@ -795,8 +812,8 @@ int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host)
 {
int r = 1;
 
-   if (mmc_pdata(host)-get_cover_state)
-   r = mmc_pdata(host)-get_cover_state(host-dev, host-slot_id);
+   if (host-get_cover_state)
+   r = host-get_cover_state(host-dev, host-slot_id);
return r;
 }
 
@@ -1263,11 +1280,11 @@ err:
 /* Protect the card while the cover is open */
 static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
 {
-   if (!mmc_pdata(host)-get_cover_state)
+   if (!host-get_cover_state)
return;
 
host-reqs_blocked = 0;
-   if (mmc_pdata(host)-get_cover_state(host-dev, host-slot_id)) {
+   if (host-get_cover_state(host-dev, host-slot_id)) {
if (host-protect_card) {
dev_info(host-dev, %s: cover is closed, 
 card is now accessible\n,
@@ -1290,13 +1307,12 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   struct omap_hsmmc_platform_data *pdata = host-pdata;
int carddetect;
 
sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
-   if (pdata-card_detect)
-   carddetect = pdata-card_detect(host-dev, host-slot_id);
+   if (host-card_detect)
+   carddetect = host-card_detect(host-dev, host-slot_id);
else {
omap_hsmmc_protect_card(host);
carddetect = -ENOSYS;
@@ -1672,18 +1688,18 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
 
-   if (!mmc_pdata(host)-card_detect)
+   if (!host-card_detect)
return -ENOSYS;
-   return mmc_pdata(host

[PATCH 0/6] unshare and simplify omap_hsmmc platform struct

2014-09-22 Thread Andreas Fenkart
mmci and omap_hsmmc share very little fields in the platform
struct. unsharing significantly simplifies the omap_hsmmc driver

Andreas Fenkart (6):
  omap_hsmmc: unshare platform data struct with mmci driver
  omap_hsmmc: remove unused callbacks from platform data struct
  omap_hsmmc: remove unused fields in platform_data
  omap_hsmmc: remove unused get_context_loss_count callback
  omap_hsmmc: remove un-initialized callbacks from platform data
  omap_hsmmc: remove un-initialized get_cover_state callback

 arch/arm/mach-omap2/hsmmc.c|  61 ++
 arch/arm/mach-omap2/hsmmc.h|  10 --
 arch/arm/mach-omap2/mmc.h  |   6 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   6 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   6 +-
 drivers/mmc/host/omap_hsmmc.c  | 133 +++--
 include/linux/platform_data/hsmmc-omap.h   | 103 
 7 files changed, 142 insertions(+), 183 deletions(-)
 create mode 100644 include/linux/platform_data/hsmmc-omap.h

-- 
2.1.0

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


[PATCH 2/6] omap_hsmmc: remove unused callbacks from platform data struct

2014-09-22 Thread Andreas Fenkart
driver never references these fields

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 9 -
 arch/arm/mach-omap2/hsmmc.h  | 4 
 drivers/mmc/host/omap_hsmmc.c| 9 -
 include/linux/platform_data/hsmmc-omap.h | 4 
 4 files changed, 26 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index e3555f2..d599195 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -49,9 +49,6 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
-
/*
 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
 * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
@@ -137,9 +134,6 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 {
struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
-   if (mmc-slots[0].remux)
-   mmc-slots[0].remux(dev, slot, power_on);
-
if (power_on)
hsmmc2_select_input_clk_src(mmc);
 }
@@ -271,9 +265,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
 
-   mmc-slots[0].remux = c-remux;
-   mmc-slots[0].init_card = c-init_card;
-
if (c-cover_only)
mmc-slots[0].cover = 1;
 
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 7f2e790..a8bc0c2 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -29,10 +29,6 @@ struct omap2_hsmmc_info {
int ocr_mask;   /* temporary HACK */
int max_freq;   /* maximum clock, if constrained by external
 * circuitry, or 0 for default */
-   /* Remux (pad configuration) when powering on/off */
-   void (*remux)(struct device *dev, int slot, int power_on);
-   /* init some special card */
-   void (*init_card)(struct mmc_card *card);
 };
 
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5f2b5b7..02f3438 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1682,14 +1682,6 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc)
return mmc_slot(host).get_ro(host-dev, 0);
 }
 
-static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
-{
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   if (mmc_slot(host).init_card)
-   mmc_slot(host).init_card(card);
-}
-
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1838,7 +1830,6 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
.get_ro = omap_hsmmc_get_ro,
-   .init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 };
 
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index cb91db4..7620c21 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -116,19 +116,15 @@ struct omap_hsmmc_platform_data {
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
 
-   int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (*set_power)(struct device *dev, int slot,
 int power_on, int vdd);
int (*get_ro)(struct device *dev, int slot);
-   void (*remux)(struct device *dev, int slot, int power_on);
/* Call back before enabling / disabling regulators */
void (*before_set_reg)(struct device *dev, int slot,
   int power_on, int vdd);
/* Call back after enabling / disabling regulators */
void (*after_set_reg)(struct device *dev, int slot,
  int power_on, int vdd);
-   /* if we have special card, init it using this callback */
-   void (*init_card)(struct mmc_card *card);
 
/* return MMC cover switch state, can be NULL if not supported.
 *
-- 
2.1.0

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


[PATCH 5/6] omap_hsmmc: remove un-initialized callbacks from platform data

2014-09-22 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 drivers/mmc/host/omap_hsmmc.c| 15 +--
 include/linux/platform_data/hsmmc-omap.h |  8 
 2 files changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 02f3438..465c34e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2195,18 +2195,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (pdata-init != NULL) {
-   if (pdata-init(pdev-dev) != 0) {
-   dev_err(mmc_dev(host-mmc),
-   Unable to configure MMC IRQs\n);
-   goto err_irq;
-   }
-   }
-
if (omap_hsmmc_have_reg()  !mmc_slot(host).set_power) {
ret = omap_hsmmc_reg_get(host);
if (ret)
-   goto err_reg;
+   goto err_irq;
host-use_reg = 1;
}
 
@@ -2269,9 +2261,6 @@ err_slot_name:
 err_irq_cd:
if (host-use_reg)
omap_hsmmc_reg_put(host);
-err_reg:
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 err_irq:
if (host-tx_chan)
dma_release_channel(host-tx_chan);
@@ -2297,8 +2286,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
mmc_remove_host(host-mmc);
if (host-use_reg)
omap_hsmmc_reg_put(host);
-   if (host-pdata-cleanup)
-   host-pdata-cleanup(pdev-dev);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 28b8cff..066075c 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -45,14 +45,6 @@ struct omap_hsmmc_platform_data {
 * maximum frequency on the MMC bus */
unsigned int max_freq;
 
-   /* switch the bus to a new slot */
-   int (*switch_slot)(struct device *dev, int slot);
-   /* initialize board-specific MMC functionality, can be NULL if
-* not supported */
-   int (*init)(struct device *dev);
-   void (*cleanup)(struct device *dev);
-   void (*shutdown)(struct device *dev);
-
/* To handle board related suspend/resume functionality for MMC */
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
-- 
2.1.0

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


[PATCH 3/6] omap_hsmmc: remove unused fields in platform_data

2014-09-22 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 13 -
 arch/arm/mach-omap2/hsmmc.h  |  5 -
 include/linux/platform_data/hsmmc-omap.h | 24 
 3 files changed, 42 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index d599195..2f202bf 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -256,7 +256,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].name = hc_name;
mmc-nr_slots = 1;
mmc-slots[0].caps = c-caps;
-   mmc-slots[0].pm_caps = c-pm_caps;
mmc-slots[0].internal_clock = !c-ext_clock;
mmc-max_freq = c-max_freq;
mmc-reg_offset = 0;
@@ -271,18 +270,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
if (c-nonremovable)
mmc-slots[0].nonremovable = 1;
 
-   if (c-power_saving)
-   mmc-slots[0].power_saving = 1;
-
-   if (c-no_off)
-   mmc-slots[0].no_off = 1;
-
-   if (c-no_off_init)
-   mmc-slots[0].no_regulator_off_init = c-no_off_init;
-
-   if (c-vcc_aux_disable_is_sleep)
-   mmc-slots[0].vcc_aux_disable_is_sleep = 1;
-
/*
 * NOTE:  MMC slots should have a Vcc regulator set up.
 * This may be from a TWL4030-family chip, another
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index a8bc0c2..b18059b 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -12,15 +12,10 @@ struct omap2_hsmmc_info {
u8  mmc;/* controller 1/2/3 */
u32 caps;   /* 4/8 wires and any additional host
 * capabilities OR'd (ref. linux/mmc/host.h) */
-   u32 pm_caps;/* PM capabilities */
booltransceiver;/* MMC-2 option */
boolext_clock;  /* use external pin for input clock */
boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
-   boolpower_saving;   /* Try to sleep or power off when possible */
-   boolno_off; /* power_saving and power is not to go off */
-   boolno_off_init;/* no power off when not in MMC sleep state */
-   boolvcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index 7620c21..b80460d 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -30,8 +30,6 @@
 #define OMAP_HSMMC_BROKEN_MULTIBLOCK_READ  BIT(1)
 #define OMAP_HSMMC_SWAKEUP_MISSING BIT(2)
 
-struct mmc_card;
-
 struct omap_hsmmc_dev_attr {
u8 flags;
 };
@@ -73,16 +71,9 @@ struct omap_hsmmc_platform_data {
 * 4/8 wires and any additional host capabilities
 * need to OR'd all capabilities (ref. linux/mmc/host.h)
 */
-   u8  wires;  /* Used for the MMC driver on omap1 and 2420 */
u32 caps;   /* Used for the MMC driver on 2430 and later */
u32 pm_caps;/* PM capabilities of the mmc */
 
-   /*
-* nomux means standard muxing is wrong on this board, and
-* that board-specific code handled it before common init logic.
-*/
-   unsigned nomux:1;
-
/* switch pin can be for card detect (default) or card cover */
unsigned cover:1;
 
@@ -92,25 +83,13 @@ struct omap_hsmmc_platform_data {
/* nonremovable e.g. eMMC */
unsigned nonremovable:1;
 
-   /* Try to sleep or power off when possible */
-   unsigned power_saving:1;
-
-   /* If using power_saving and the MMC power is not to go off */
-   unsigned no_off:1;
-
/* eMMC does not handle power off when not in sleep state */
unsigned no_regulator_off_init:1;
 
-   /* Regulator off remapped to sleep */
-   unsigned vcc_aux_disable_is_sleep:1;
-
/* we can put the features above into this variable */
 #define HSMMC_HAS_PBIAS(1  0)
 #define HSMMC_HAS_UPDATED_RESET(1  1)
 #define HSMMC_HAS_HSPE_SUPPORT (1  2)
-#define MMC_OMAP7XX(1  3)
-#define MMC_OMAP15XX   (1  4)
-#define MMC_OMAP16XX   (1  5)
unsigned features;
 
int switch_pin; /* gpio (card detect) */
@@ -141,8 +120,5 @@ struct omap_hsmmc_platform_data {
int card_detect_irq;
 
int

[PATCH 4/6] omap_hsmmc: remove unused get_context_loss_count callback

2014-09-22 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  | 12 
 include/linux/platform_data/hsmmc-omap.h |  3 ---
 2 files changed, 15 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 2f202bf..9ed9f70 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,17 +32,6 @@ static u16 control_devconf1_offset;
 
 #define HSMMC_NAME_LEN 9
 
-#if defined(CONFIG_ARCH_OMAP3)  defined(CONFIG_PM)
-
-static int hsmmc_get_context_loss(struct device *dev)
-{
-   return omap_pm_get_dev_context_loss_count(dev);
-}
-
-#else
-#define hsmmc_get_context_loss NULL
-#endif
-
 static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
  int power_on, int vdd)
 {
@@ -259,7 +248,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].internal_clock = !c-ext_clock;
mmc-max_freq = c-max_freq;
mmc-reg_offset = 0;
-   mmc-get_context_loss_count = hsmmc_get_context_loss;
 
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
diff --git a/include/linux/platform_data/hsmmc-omap.h 
b/include/linux/platform_data/hsmmc-omap.h
index b80460d..28b8cff 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -57,9 +57,6 @@ struct omap_hsmmc_platform_data {
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
 
-   /* Return context loss count due to PM states changing */
-   int (*get_context_loss_count)(struct device *dev);
-
/* Integrating attributes from the omap_hwmod layer */
u8 controller_flags;
 
-- 
2.1.0

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


[PATCH 6/6] omap_hsmmc: remove un-initialized get_cover_state callback

2014-09-22 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c  |  3 --
 arch/arm/mach-omap2/hsmmc.h  |  1 -
 drivers/mmc/host/omap_hsmmc.c| 83 ++--
 include/linux/platform_data/hsmmc-omap.h | 10 
 4 files changed, 4 insertions(+), 93 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 9ed9f70..068ccf5 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -252,9 +252,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
 
-   if (c-cover_only)
-   mmc-slots[0].cover = 1;
-
if (c-nonremovable)
mmc-slots[0].nonremovable = 1;
 
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index b18059b..1c4a363 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -14,7 +14,6 @@ struct omap2_hsmmc_info {
 * capabilities OR'd (ref. linux/mmc/host.h) */
booltransceiver;/* MMC-2 option */
boolext_clock;  /* use external pin for input clock */
-   boolcover_only; /* No card detect - just cover switch */
boolnonremovable;   /* Nonremovable e.g. eMMC */
booldeferred;   /* mmc needs a deferred probe */
int gpio_cd;/* or -EINVAL */
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 465c34e..a558c87 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -248,15 +248,6 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot)
return gpio_get_value_cansleep(mmc-slots[0].gpio_wp);
 }
 
-static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_hsmmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes card detect signal is active-low */
-   return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
-}
-
 #ifdef CONFIG_PM
 
 static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
@@ -454,11 +445,7 @@ static int omap_hsmmc_gpio_init(struct 
omap_hsmmc_platform_data *pdata)
int ret;
 
if (gpio_is_valid(pdata-slots[0].switch_pin)) {
-   if (pdata-slots[0].cover)
-   pdata-slots[0].get_cover_state =
-   omap_hsmmc_get_cover_state;
-   else
-   pdata-slots[0].card_detect = omap_hsmmc_card_detect;
+   pdata-slots[0].card_detect = omap_hsmmc_card_detect;
pdata-slots[0].card_detect_irq =
gpio_to_irq(pdata-slots[0].switch_pin);
ret = gpio_request(pdata-slots[0].switch_pin, mmc_cd);
@@ -786,29 +773,6 @@ static void send_init_stream(struct omap_hsmmc_host *host)
enable_irq(host-irq);
 }
 
-static inline
-int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host)
-{
-   int r = 1;
-
-   if (mmc_slot(host).get_cover_state)
-   r = mmc_slot(host).get_cover_state(host-dev, host-slot_id);
-   return r;
-}
-
-static ssize_t
-omap_hsmmc_show_cover_switch(struct device *dev, struct device_attribute *attr,
-  char *buf)
-{
-   struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   return sprintf(buf, %s\n,
-   omap_hsmmc_cover_is_closed(host) ? closed : open);
-}
-
-static DEVICE_ATTR(cover_switch, S_IRUGO, omap_hsmmc_show_cover_switch, NULL);
-
 static ssize_t
 omap_hsmmc_show_slot_name(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1256,30 +1220,6 @@ err:
return ret;
 }
 
-/* Protect the card while the cover is open */
-static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
-{
-   if (!mmc_slot(host).get_cover_state)
-   return;
-
-   host-reqs_blocked = 0;
-   if (mmc_slot(host).get_cover_state(host-dev, host-slot_id)) {
-   if (host-protect_card) {
-   dev_info(host-dev, %s: cover is closed, 
-card is now accessible\n,
-mmc_hostname(host-mmc));
-   host-protect_card = 0;
-   }
-   } else {
-   if (!host-protect_card) {
-   dev_info(host-dev, %s: cover is open, 
-card is now inaccessible\n,
-mmc_hostname(host-mmc));
-   host-protect_card = 1;
-   }
-   }
-}
-
 /*
  * irq handler to notify the core about card insertion/removal
  */
@@ -1289,15 +1229,10 @@ static irqreturn_t omap_hsmmc_detect

[PATCH 1/6] omap_hsmmc: unshare platform data struct with mmci driver

2014-09-22 Thread Andreas Fenkart
- mmci driver supports multiple slots, omap_hsmmc only one
this leads to one of the major confusions in the omap_hsmmc driver

- platform data should be read-only for the driver
most callbacks are not set by the platform init code while being
required by the driver, leading to the fact that they are set by the
driver during it's probe function
typical example are card detect / read only detect callbacks

Signed-off-by: Andreas Fenkart afenk...@gmail.com
---
 arch/arm/mach-omap2/hsmmc.c|  24 ++--
 arch/arm/mach-omap2/mmc.h  |   6 +-
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |   6 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   6 +-
 drivers/mmc/host/omap_hsmmc.c  |  28 ++--
 include/linux/platform_data/hsmmc-omap.h   | 152 +
 6 files changed, 187 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 07d4c7b..e3555f2 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -47,7 +47,7 @@ static void omap_hsmmc1_before_set_reg(struct device *dev, 
int slot,
  int power_on, int vdd)
 {
u32 reg, prog_io;
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -120,7 +120,7 @@ static void omap_hsmmc1_after_set_reg(struct device *dev, 
int slot,
}
 }
 
-static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
+static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
 {
u32 reg;
 
@@ -135,7 +135,7 @@ static void hsmmc2_select_input_clk_src(struct 
omap_mmc_platform_data *mmc)
 static void hsmmc2_before_set_reg(struct device *dev, int slot,
   int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (mmc-slots[0].remux)
mmc-slots[0].remux(dev, slot, power_on);
@@ -147,7 +147,7 @@ static void hsmmc2_before_set_reg(struct device *dev, int 
slot,
 static int am35x_hsmmc2_set_power(struct device *dev, int slot,
  int power_on, int vdd)
 {
-   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   struct omap_hsmmc_platform_data *mmc = dev-platform_data;
 
if (power_on)
hsmmc2_select_input_clk_src(mmc);
@@ -161,8 +161,8 @@ static int nop_mmc_set_power(struct device *dev, int slot, 
int power_on,
return 0;
 }
 
-static inline void omap_hsmmc_mux(struct omap_mmc_platform_data 
*mmc_controller,
-   int controller_nr)
+static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
+ *mmc_controller, int controller_nr)
 {
if (gpio_is_valid(mmc_controller-slots[0].switch_pin) 
(mmc_controller-slots[0].switch_pin  OMAP_MAX_GPIO_LINES))
@@ -243,7 +243,7 @@ static inline void omap_hsmmc_mux(struct 
omap_mmc_platform_data *mmc_controller,
 }
 
 static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-   struct omap_mmc_platform_data *mmc)
+   struct omap_hsmmc_platform_data *mmc)
 {
char *hc_name;
 
@@ -368,7 +368,7 @@ static int omap_hsmmc_done;
 void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
 {
struct platform_device *pdev;
-   struct omap_mmc_platform_data *mmc_pdata;
+   struct omap_hsmmc_platform_data *mmc_pdata;
int res;
 
if (omap_hsmmc_done != 1)
@@ -408,12 +408,12 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
struct omap_device *od;
struct platform_device *pdev;
char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
-   struct omap_mmc_platform_data *mmc_data;
-   struct omap_mmc_dev_attr *mmc_dev_attr;
+   struct omap_hsmmc_platform_data *mmc_data;
+   struct omap_hsmmc_dev_attr *mmc_dev_attr;
char *name;
int res;
 
-   mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+   mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data) {
pr_err(Cannot allocate memory for mmc device!\n);
return;
@@ -463,7 +463,7 @@ static void __init omap_hsmmc_init_one(struct 
omap2_hsmmc_info *hsmmcinfo,
}
 
res = platform_device_add_data(pdev, mmc_data,
- sizeof(struct omap_mmc_platform_data));
+ sizeof(struct omap_hsmmc_platform_data));
if (res) {
pr_err(Could not add pdata for %s\n, name);
goto put_pdev;
diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h
index 0cd4b08

Re: [PATCH v14 1/6] mmc: omap_hsmmc: Enable SDIO interrupt

2014-08-24 Thread Andreas Fenkart
Hi Florian

2014-08-24 10:26 GMT+02:00 Florian Vaussard florian.vauss...@epfl.ch:
 Hi Andreas,

 On 05/29/2014 10:28 AM, Andreas Fenkart wrote:
 There have been various patches floating around for enabling
 the SDIO IRQ for hsmmc, but none of them ever got merged.


 [...]

 For now, only support SDIO interrupt if we are booted with
 a separate wake-irq configued via device tree. This is
 because omaps need the wake-irq for idle states, and some
 omaps need special quirks. And we don't want to add new
 legacy mux platform init code callbacks any longer as we
 are moving to DT based booting anyways.

 To use it, you need to specify the wake-irq using the
 interrupts-extended property.


 First, thanks a lot for your tenacity on this patchset, this was a long
 needed feature. I enabled the SDIO interrupt, and got the throughput of
 my 88W8686-based chip multiplied by 15. Nice! I just have an issue with
 the wake-up path, and maybe you could help me.

 According to the DM3730 TRM, the MMC2 has the SWAKEUP path. So first I
 tried to give the same wake-irq as the MMC's one, but
 omap_hsmmc_configure_wake_irq() fails to request it, as they are not
 IRQF_SHARED.

Why can't it be shared?

 So I used the DAT1 for the wake-irq (see patch below), and things are
 working. But I get ~2000 wake-irq per seconds, even without any activity
 on the WiFi. As a result, the driver is ping-ponging between
 omap_hsmmc_runtime_suspend() and omap_hsmmc_runtime_resume(), causing
 kworker to eat most of my CPU.

 Am I missing something obvious?

 Thanks!
 Florian


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


[PATCH 0/3 resend] omap_hsmmc: reuse mmc/slot-gpio functions

2014-08-08 Thread Andreas Fenkart
Hi,

I would like to reuse mmc_of_parse for standard mmc features: 
- cd-gpios / wp-gpios
- bus-width 
- max-frequency
- keep-power-in-suspend
- enable-sdio-wakeup
- ti,non-removable, evtl.

Currently these are open-coded in of_get_hsmmc_pdata. I tried
removing them from of_get_hsmmc_pdata and call mmc_of_parse
at the end of the probe function:

@@ -2241,8 +2264,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_protect_card(host);
+   mmc_of_parse(host-mmc);
mmc_add_host(mmc);

This could work transparently for most features but definitely
not for cd-gpios/wp-gpios. Pls can somebody have a look at the
followup patches? I tried an intermediate step mapping card
detect / read-only detect onto mmc/slot-gpio, that are used by
mmc_of_parse. I don't have card detect/read-only detect pins, so
patches are untested, :-( 

Do we need cover_detect functionality or could it be merged with
card detect?

Another issue is 'ti,non-removable' which could be mappend to
stanadard 'non-removable' if 'no_regulator_off_init' was handled
in a different way.

if (of_find_property(np, ti,non-removable, NULL)) {  
pdata-slots[0].nonremovable = true; 
pdata-slots[0].no_regulator_off_init = true;  
}   

/Andreas

Andreas Fenkart (3):
  omap_hsmmc: reuse mmc/slot-gpio for write protect detection
  omap_hsmmc: separate card_detect/cover detect logic
  omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded
version

 drivers/mmc/host/omap_hsmmc.c  | 172 ++---
 include/linux/platform_data/mmc-omap.h |   6 +-
 2 files changed, 73 insertions(+), 105 deletions(-)

-- 
2.0.0

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


[PATCH 1/3 resend] omap_hsmmc: reuse mmc/slot-gpio for write protect detection

2014-08-08 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2f944d7..1c10e6c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -36,6 +36,7 @@
 #include linux/mmc/host.h
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
+#include linux/mmc/slot-gpio.h
 #include linux/io.h
 #include linux/irq.h
 #include linux/gpio.h
@@ -239,15 +240,6 @@ static int omap_hsmmc_card_detect(struct device *dev, int 
slot)
return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
 }
 
-static int omap_hsmmc_get_wp(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes write protect signal is active-high */
-   return gpio_get_value_cansleep(mmc-slots[0].gpio_wp);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -449,7 +441,8 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
+   struct omap_mmc_platform_data *pdata)
 {
int ret;
 
@@ -471,31 +464,31 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
pdata-slots[0].switch_pin = -EINVAL;
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
-   pdata-slots[0].get_ro = omap_hsmmc_get_wp;
-   ret = gpio_request(pdata-slots[0].gpio_wp, mmc_wp);
-   if (ret)
-   goto err_free_cd;
-   ret = gpio_direction_input(pdata-slots[0].gpio_wp);
-   if (ret)
-   goto err_free_wp;
-   } else
-   pdata-slots[0].gpio_wp = -EINVAL;
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_ro(mmc, pdata-slots[0].gpio_wp);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request WP GPIO: %d!\n, ret);
+   goto err;
+   } else {
+   dev_info(pdata-dev, Got WP GPIO #%d.\n,
+pdata-slots[0].gpio_wp);
+   }
+   }
 
return 0;
 
-err_free_wp:
-   gpio_free(pdata-slots[0].gpio_wp);
-err_free_cd:
+err:
if (gpio_is_valid(pdata-slots[0].switch_pin))
 err_free_sp:
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
+struct omap_mmc_platform_data *pdata)
 {
-   if (gpio_is_valid(pdata-slots[0].gpio_wp))
-   gpio_free(pdata-slots[0].gpio_wp);
+   mmc_gpio_free_ro(mmc);
if (gpio_is_valid(pdata-slots[0].switch_pin))
gpio_free(pdata-slots[0].switch_pin);
 }
@@ -1673,15 +1666,6 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
return mmc_slot(host).card_detect(host-dev, host-slot_id);
 }
 
-static int omap_hsmmc_get_ro(struct mmc_host *mmc)
-{
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   if (!mmc_slot(host).get_ro)
-   return -ENOSYS;
-   return mmc_slot(host).get_ro(host-dev, 0);
-}
-
 static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1837,7 +1821,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
-   .get_ro = omap_hsmmc_get_ro,
+   .get_ro = mmc_gpio_get_ro,
.init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 };
@@ -2063,16 +2047,15 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
if (IS_ERR(base))
return PTR_ERR(base);
 
-   ret = omap_hsmmc_gpio_init(pdata);
-   if (ret)
-   goto err;
-
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), pdev-dev);
if (!mmc) {
-   ret = -ENOMEM;
-   goto err_alloc;
+   return -ENOMEM;
}
 
+   ret = omap_hsmmc_gpio_init(mmc, pdata);
+   if (ret)
+   goto err;
+
host= mmc_priv(mmc);
host-mmc   = mmc;
host-pdata = pdata;
@@ -2302,10 +2285,9 @@ err_irq:
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 err1:
-   mmc_free_host(mmc);
-err_alloc:
-   omap_hsmmc_gpio_free(pdata);
+   omap_hsmmc_gpio_free(mmc, pdata);
 err:
+   mmc_free_host(mmc);
return ret;
 }
 
@@ -2330,7 +2312,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host

[PATCH 3/3 resend] omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded version

2014-08-08 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1b9f279..25aafa6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -231,15 +231,6 @@ struct omap_mmc_of_data {
 
 static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host);
 
-static int omap_hsmmc_card_detect(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes card detect signal is active-low */
-   return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -256,7 +247,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   disable_irq(mmc-slots[0].card_detect_irq);
+   disable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -265,7 +256,7 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   enable_irq(mmc-slots[0].card_detect_irq);
+   enable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -458,23 +449,26 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
if (ret)
return ret;
ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   if (ret) {
+   gpio_free(pdata-slots[0].switch_pin);
+   return ret;
+   }
} else {
-   pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
-   gpio_to_irq(pdata-slots[0].switch_pin);
-
-   ret = gpio_request(pdata-slots[0].switch_pin,
-  mmc_cd);
-   if (ret)
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_cd(mmc,
+ pdata-slots[0].switch_pin,
+ 0);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request CD GPIO #%d: %d!\n,
+   pdata-slots[0].switch_pin, ret);
return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   } else {
+   dev_info(pdata-dev, Got CD GPIO #%d.\n,
+   pdata-slots[0].switch_pin);
+   }
}
-   } else
-   pdata-slots[0].switch_pin = -EINVAL;
+   }
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
/* copy  paste from from mmc_of_parse */
@@ -492,8 +486,9 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
return 0;
 
 err:
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
-err_free_sp:
+   mmc_gpio_free_cd(mmc);
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
@@ -501,8 +496,11 @@ err_free_sp:
 static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
 struct omap_mmc_platform_data *pdata)
 {
+   mmc_gpio_free_cd(mmc);
mmc_gpio_free_ro(mmc);
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
+
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
 }
 
@@ -1289,24 +1287,13 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 /*
  * irq handler to notify the core about card insertion/removal
  */
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+static irqreturn_t omap_hsmmc_cover_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   struct omap_mmc_slot_data *slot = mmc_slot(host);
-   int carddetect;
-
-   if (slot-card_detect) {
-   carddetect = slot-card_detect(host-dev, host-slot_id);
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
-   } else

[PATCH 2/3 resend] omap_hsmmc: separate card_detect/cover detect logic

2014-08-08 Thread Andreas Fenkart
assuming cover is the door like thing on cameras that needs to be closed
after replacing sd cards. card detect is a gpio connected to sdio slot.
in a follow up patch card_detect will be replaced by generic mmc/slot-gpio
a git bisect patch

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1c10e6c..1b9f279 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -447,19 +447,32 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
int ret;
 
if (gpio_is_valid(pdata-slots[0].switch_pin)) {
-   if (pdata-slots[0].cover)
+   if (pdata-slots[0].cover) {
pdata-slots[0].get_cover_state =
omap_hsmmc_get_cover_state;
-   else
+   pdata-slots[0].cover_detect_irq =
+   gpio_to_irq(pdata-slots[0].switch_pin);
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   } else {
pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
+   pdata-slots[0].card_detect_irq =
gpio_to_irq(pdata-slots[0].switch_pin);
-   ret = gpio_request(pdata-slots[0].switch_pin, mmc_cd);
-   if (ret)
-   return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   }
} else
pdata-slots[0].switch_pin = -EINVAL;
 
@@ -1282,19 +1295,18 @@ static irqreturn_t omap_hsmmc_detect(int irq, void 
*dev_id)
struct omap_mmc_slot_data *slot = mmc_slot(host);
int carddetect;
 
-   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
-
-   if (slot-card_detect)
+   if (slot-card_detect) {
carddetect = slot-card_detect(host-dev, host-slot_id);
-   else {
+   if (carddetect)
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
+   else
+   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   } else {
+   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
omap_hsmmc_protect_card(host);
-   carddetect = -ENOSYS;
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
}
 
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
return IRQ_HANDLED;
 }
 
diff --git a/include/linux/platform_data/mmc-omap.h 
b/include/linux/platform_data/mmc-omap.h
index 7fe0c14..d113005 100644
--- a/include/linux/platform_data/mmc-omap.h
+++ b/include/linux/platform_data/mmc-omap.h
@@ -136,6 +136,7 @@ struct omap_mmc_platform_data {
 *   0 - closed
 *   1 - open
 */
+   int cover_detect_irq;
int (*get_cover_state)(struct device *dev, int slot);
 
const char *name;
-- 
2.0.0

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


[PATCH 0/3 resend] omap_hsmmc: reuse mmc/slot-gpio functions

2014-07-26 Thread Andreas Fenkart
Hi,

I would like to reuse mmc_of_parse for standard mmc features: 
- cd-gpios / wp-gpios
- bus-width 
- max-frequency
- keep-power-in-suspend
- enable-sdio-wakeup
- ti,non-removable, evtl.

Currently these are open-coded in of_get_hsmmc_pdata. I tried
removing them from of_get_hsmmc_pdata and call mmc_of_parse
at the end of the probe function:

@@ -2241,8 +2264,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_protect_card(host);
+   mmc_of_parse(host-mmc);
mmc_add_host(mmc);

This could work transparently for most features but definitely
not for cd-gpios/wp-gpios. Pls can somebody have a look at the
followup patches? I tried an intermediate step mapping card
detect / read-only detect onto mmc/slot-gpio, that are used by
mmc_of_parse. I don't have card detect/read-only detect pins, so
patches are untested, :-( 

Do we need cover_detect functionality or could it be merged with
card detect?

Another issue is 'ti,non-removable' which could be mappend to
stanadard 'non-removable' if 'no_regulator_off_init' was handled
in a different way.

if (of_find_property(np, ti,non-removable, NULL)) {  
pdata-slots[0].nonremovable = true; 
pdata-slots[0].no_regulator_off_init = true;  
}   

/Andreas

Andreas Fenkart (3):
  omap_hsmmc: reuse mmc/slot-gpio for write protect detection
  omap_hsmmc: separate card_detect/cover detect logic
  omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded
version

 drivers/mmc/host/omap_hsmmc.c  | 172 ++---
 include/linux/platform_data/mmc-omap.h |   6 +-
 2 files changed, 73 insertions(+), 105 deletions(-)

-- 
2.0.0

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


[PATCH 3/3 resend] omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded version

2014-07-26 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1b9f279..25aafa6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -231,15 +231,6 @@ struct omap_mmc_of_data {
 
 static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host);
 
-static int omap_hsmmc_card_detect(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes card detect signal is active-low */
-   return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -256,7 +247,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   disable_irq(mmc-slots[0].card_detect_irq);
+   disable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -265,7 +256,7 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   enable_irq(mmc-slots[0].card_detect_irq);
+   enable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -458,23 +449,26 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
if (ret)
return ret;
ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   if (ret) {
+   gpio_free(pdata-slots[0].switch_pin);
+   return ret;
+   }
} else {
-   pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
-   gpio_to_irq(pdata-slots[0].switch_pin);
-
-   ret = gpio_request(pdata-slots[0].switch_pin,
-  mmc_cd);
-   if (ret)
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_cd(mmc,
+ pdata-slots[0].switch_pin,
+ 0);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request CD GPIO #%d: %d!\n,
+   pdata-slots[0].switch_pin, ret);
return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   } else {
+   dev_info(pdata-dev, Got CD GPIO #%d.\n,
+   pdata-slots[0].switch_pin);
+   }
}
-   } else
-   pdata-slots[0].switch_pin = -EINVAL;
+   }
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
/* copy  paste from from mmc_of_parse */
@@ -492,8 +486,9 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
return 0;
 
 err:
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
-err_free_sp:
+   mmc_gpio_free_cd(mmc);
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
@@ -501,8 +496,11 @@ err_free_sp:
 static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
 struct omap_mmc_platform_data *pdata)
 {
+   mmc_gpio_free_cd(mmc);
mmc_gpio_free_ro(mmc);
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
+
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
 }
 
@@ -1289,24 +1287,13 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 /*
  * irq handler to notify the core about card insertion/removal
  */
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+static irqreturn_t omap_hsmmc_cover_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   struct omap_mmc_slot_data *slot = mmc_slot(host);
-   int carddetect;
-
-   if (slot-card_detect) {
-   carddetect = slot-card_detect(host-dev, host-slot_id);
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
-   } else

[PATCH 1/3 resend] omap_hsmmc: reuse mmc/slot-gpio for write protect detection

2014-07-26 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2f944d7..1c10e6c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -36,6 +36,7 @@
 #include linux/mmc/host.h
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
+#include linux/mmc/slot-gpio.h
 #include linux/io.h
 #include linux/irq.h
 #include linux/gpio.h
@@ -239,15 +240,6 @@ static int omap_hsmmc_card_detect(struct device *dev, int 
slot)
return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
 }
 
-static int omap_hsmmc_get_wp(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes write protect signal is active-high */
-   return gpio_get_value_cansleep(mmc-slots[0].gpio_wp);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -449,7 +441,8 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
+   struct omap_mmc_platform_data *pdata)
 {
int ret;
 
@@ -471,31 +464,31 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
pdata-slots[0].switch_pin = -EINVAL;
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
-   pdata-slots[0].get_ro = omap_hsmmc_get_wp;
-   ret = gpio_request(pdata-slots[0].gpio_wp, mmc_wp);
-   if (ret)
-   goto err_free_cd;
-   ret = gpio_direction_input(pdata-slots[0].gpio_wp);
-   if (ret)
-   goto err_free_wp;
-   } else
-   pdata-slots[0].gpio_wp = -EINVAL;
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_ro(mmc, pdata-slots[0].gpio_wp);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request WP GPIO: %d!\n, ret);
+   goto err;
+   } else {
+   dev_info(pdata-dev, Got WP GPIO #%d.\n,
+pdata-slots[0].gpio_wp);
+   }
+   }
 
return 0;
 
-err_free_wp:
-   gpio_free(pdata-slots[0].gpio_wp);
-err_free_cd:
+err:
if (gpio_is_valid(pdata-slots[0].switch_pin))
 err_free_sp:
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
+struct omap_mmc_platform_data *pdata)
 {
-   if (gpio_is_valid(pdata-slots[0].gpio_wp))
-   gpio_free(pdata-slots[0].gpio_wp);
+   mmc_gpio_free_ro(mmc);
if (gpio_is_valid(pdata-slots[0].switch_pin))
gpio_free(pdata-slots[0].switch_pin);
 }
@@ -1673,15 +1666,6 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
return mmc_slot(host).card_detect(host-dev, host-slot_id);
 }
 
-static int omap_hsmmc_get_ro(struct mmc_host *mmc)
-{
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   if (!mmc_slot(host).get_ro)
-   return -ENOSYS;
-   return mmc_slot(host).get_ro(host-dev, 0);
-}
-
 static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1837,7 +1821,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
-   .get_ro = omap_hsmmc_get_ro,
+   .get_ro = mmc_gpio_get_ro,
.init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 };
@@ -2063,16 +2047,15 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
if (IS_ERR(base))
return PTR_ERR(base);
 
-   ret = omap_hsmmc_gpio_init(pdata);
-   if (ret)
-   goto err;
-
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), pdev-dev);
if (!mmc) {
-   ret = -ENOMEM;
-   goto err_alloc;
+   return -ENOMEM;
}
 
+   ret = omap_hsmmc_gpio_init(mmc, pdata);
+   if (ret)
+   goto err;
+
host= mmc_priv(mmc);
host-mmc   = mmc;
host-pdata = pdata;
@@ -2302,10 +2285,9 @@ err_irq:
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 err1:
-   mmc_free_host(mmc);
-err_alloc:
-   omap_hsmmc_gpio_free(pdata);
+   omap_hsmmc_gpio_free(mmc, pdata);
 err:
+   mmc_free_host(mmc);
return ret;
 }
 
@@ -2330,7 +2312,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host

[PATCH 2/3 resend] omap_hsmmc: separate card_detect/cover detect logic

2014-07-26 Thread Andreas Fenkart
assuming cover is the door like thing on cameras that needs to be closed
after replacing sd cards. card detect is a gpio connected to sdio slot.
in a follow up patch card_detect will be replaced by generic mmc/slot-gpio
a git bisect patch

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1c10e6c..1b9f279 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -447,19 +447,32 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
int ret;
 
if (gpio_is_valid(pdata-slots[0].switch_pin)) {
-   if (pdata-slots[0].cover)
+   if (pdata-slots[0].cover) {
pdata-slots[0].get_cover_state =
omap_hsmmc_get_cover_state;
-   else
+   pdata-slots[0].cover_detect_irq =
+   gpio_to_irq(pdata-slots[0].switch_pin);
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   } else {
pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
+   pdata-slots[0].card_detect_irq =
gpio_to_irq(pdata-slots[0].switch_pin);
-   ret = gpio_request(pdata-slots[0].switch_pin, mmc_cd);
-   if (ret)
-   return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   }
} else
pdata-slots[0].switch_pin = -EINVAL;
 
@@ -1282,19 +1295,18 @@ static irqreturn_t omap_hsmmc_detect(int irq, void 
*dev_id)
struct omap_mmc_slot_data *slot = mmc_slot(host);
int carddetect;
 
-   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
-
-   if (slot-card_detect)
+   if (slot-card_detect) {
carddetect = slot-card_detect(host-dev, host-slot_id);
-   else {
+   if (carddetect)
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
+   else
+   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   } else {
+   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
omap_hsmmc_protect_card(host);
-   carddetect = -ENOSYS;
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
}
 
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
return IRQ_HANDLED;
 }
 
diff --git a/include/linux/platform_data/mmc-omap.h 
b/include/linux/platform_data/mmc-omap.h
index 7fe0c14..d113005 100644
--- a/include/linux/platform_data/mmc-omap.h
+++ b/include/linux/platform_data/mmc-omap.h
@@ -136,6 +136,7 @@ struct omap_mmc_platform_data {
 *   0 - closed
 *   1 - open
 */
+   int cover_detect_irq;
int (*get_cover_state)(struct device *dev, int slot);
 
const char *name;
-- 
2.0.0

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


[PATCH 1/3] omap_hsmmc: reuse mmc/slot-gpio for write protect detection

2014-07-18 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2f944d7..1c10e6c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -36,6 +36,7 @@
 #include linux/mmc/host.h
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
+#include linux/mmc/slot-gpio.h
 #include linux/io.h
 #include linux/irq.h
 #include linux/gpio.h
@@ -239,15 +240,6 @@ static int omap_hsmmc_card_detect(struct device *dev, int 
slot)
return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
 }
 
-static int omap_hsmmc_get_wp(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes write protect signal is active-high */
-   return gpio_get_value_cansleep(mmc-slots[0].gpio_wp);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -449,7 +441,8 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
+   struct omap_mmc_platform_data *pdata)
 {
int ret;
 
@@ -471,31 +464,31 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
pdata-slots[0].switch_pin = -EINVAL;
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
-   pdata-slots[0].get_ro = omap_hsmmc_get_wp;
-   ret = gpio_request(pdata-slots[0].gpio_wp, mmc_wp);
-   if (ret)
-   goto err_free_cd;
-   ret = gpio_direction_input(pdata-slots[0].gpio_wp);
-   if (ret)
-   goto err_free_wp;
-   } else
-   pdata-slots[0].gpio_wp = -EINVAL;
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_ro(mmc, pdata-slots[0].gpio_wp);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request WP GPIO: %d!\n, ret);
+   goto err;
+   } else {
+   dev_info(pdata-dev, Got WP GPIO #%d.\n,
+pdata-slots[0].gpio_wp);
+   }
+   }
 
return 0;
 
-err_free_wp:
-   gpio_free(pdata-slots[0].gpio_wp);
-err_free_cd:
+err:
if (gpio_is_valid(pdata-slots[0].switch_pin))
 err_free_sp:
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
+struct omap_mmc_platform_data *pdata)
 {
-   if (gpio_is_valid(pdata-slots[0].gpio_wp))
-   gpio_free(pdata-slots[0].gpio_wp);
+   mmc_gpio_free_ro(mmc);
if (gpio_is_valid(pdata-slots[0].switch_pin))
gpio_free(pdata-slots[0].switch_pin);
 }
@@ -1673,15 +1666,6 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
return mmc_slot(host).card_detect(host-dev, host-slot_id);
 }
 
-static int omap_hsmmc_get_ro(struct mmc_host *mmc)
-{
-   struct omap_hsmmc_host *host = mmc_priv(mmc);
-
-   if (!mmc_slot(host).get_ro)
-   return -ENOSYS;
-   return mmc_slot(host).get_ro(host-dev, 0);
-}
-
 static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1837,7 +1821,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
-   .get_ro = omap_hsmmc_get_ro,
+   .get_ro = mmc_gpio_get_ro,
.init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 };
@@ -2063,16 +2047,15 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
if (IS_ERR(base))
return PTR_ERR(base);
 
-   ret = omap_hsmmc_gpio_init(pdata);
-   if (ret)
-   goto err;
-
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), pdev-dev);
if (!mmc) {
-   ret = -ENOMEM;
-   goto err_alloc;
+   return -ENOMEM;
}
 
+   ret = omap_hsmmc_gpio_init(mmc, pdata);
+   if (ret)
+   goto err;
+
host= mmc_priv(mmc);
host-mmc   = mmc;
host-pdata = pdata;
@@ -2302,10 +2285,9 @@ err_irq:
if (host-dbclk)
clk_disable_unprepare(host-dbclk);
 err1:
-   mmc_free_host(mmc);
-err_alloc:
-   omap_hsmmc_gpio_free(pdata);
+   omap_hsmmc_gpio_free(mmc, pdata);
 err:
+   mmc_free_host(mmc);
return ret;
 }
 
@@ -2330,7 +2312,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host

[PATCH 0/3] omap_hsmmc: reuse mmc/slot-gpio functions

2014-07-18 Thread Andreas Fenkart
Hi Balaji,

I'm trying to reuse mmc_of_parse for parsing standard mmc features: 
- cd-gpios / wp-gpios
- bus-width 
- max-frequency
- keep-power-in-suspend
- enable-sdio-wakeup
- ti,non-removable, evtl.

Currently these are open-coded in of_get_hsmmc_pdata. I tried
removing them all from of_get_hsmmc_pdata and call mmc_of_parse
at the end of the probe function:

@@ -2241,8 +2264,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_protect_card(host);
+   mmc_of_parse(host-mmc);
mmc_add_host(mmc);

This should work transparently for most features except,
cd-gpios/wp-gpios. Pls can you have a look at the followup
patches? I tried an intermediate step mapping card detect /
read-only detect onto mmc/slot-gpio that are used by
mmc_of_parse. I don't have card detect/read-only detect pins, :-(

Do we still need cover_detect functionality or could it be merged
with card detect?

Another issue is 'ti,non-removable' which could be mappend to
'non-removable' if 'no_regulator_off_init' could be handled in a
different way.

if (of_find_property(np, ti,non-removable, NULL)) {  
pdata-slots[0].nonremovable = true; 
pdata-slots[0].no_regulator_off_init = true;  
}   

thanks,
Andreas

Andreas Fenkart (3):
  omap_hsmmc: reuse mmc/slot-gpio for write protect detection
  omap_hsmmc: separate card_detect/cover detect logic
  omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded
version

 drivers/mmc/host/omap_hsmmc.c  | 172 ++---
 include/linux/platform_data/mmc-omap.h |   6 +-
 2 files changed, 73 insertions(+), 105 deletions(-)

-- 
2.0.0

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


[PATCH 2/3] omap_hsmmc: separate card_detect/cover detect logic

2014-07-18 Thread Andreas Fenkart
assuming cover is the door like thing on cameras that needs to be closed
after replacing sd cards. card detect is a gpio connected to sdio slot.
in a follow up patch card_detect will be replaced by generic mmc/slot-gpio
a git bisect patch

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1c10e6c..1b9f279 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -447,19 +447,32 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
int ret;
 
if (gpio_is_valid(pdata-slots[0].switch_pin)) {
-   if (pdata-slots[0].cover)
+   if (pdata-slots[0].cover) {
pdata-slots[0].get_cover_state =
omap_hsmmc_get_cover_state;
-   else
+   pdata-slots[0].cover_detect_irq =
+   gpio_to_irq(pdata-slots[0].switch_pin);
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   } else {
pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
+   pdata-slots[0].card_detect_irq =
gpio_to_irq(pdata-slots[0].switch_pin);
-   ret = gpio_request(pdata-slots[0].switch_pin, mmc_cd);
-   if (ret)
-   return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+
+   ret = gpio_request(pdata-slots[0].switch_pin,
+  mmc_cd);
+   if (ret)
+   return ret;
+   ret = gpio_direction_input(pdata-slots[0].switch_pin);
+   if (ret)
+   goto err_free_sp;
+   }
} else
pdata-slots[0].switch_pin = -EINVAL;
 
@@ -1282,19 +1295,18 @@ static irqreturn_t omap_hsmmc_detect(int irq, void 
*dev_id)
struct omap_mmc_slot_data *slot = mmc_slot(host);
int carddetect;
 
-   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
-
-   if (slot-card_detect)
+   if (slot-card_detect) {
carddetect = slot-card_detect(host-dev, host-slot_id);
-   else {
+   if (carddetect)
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
+   else
+   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
+   } else {
+   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
omap_hsmmc_protect_card(host);
-   carddetect = -ENOSYS;
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
}
 
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
return IRQ_HANDLED;
 }
 
diff --git a/include/linux/platform_data/mmc-omap.h 
b/include/linux/platform_data/mmc-omap.h
index 7fe0c14..d113005 100644
--- a/include/linux/platform_data/mmc-omap.h
+++ b/include/linux/platform_data/mmc-omap.h
@@ -136,6 +136,7 @@ struct omap_mmc_platform_data {
 *   0 - closed
 *   1 - open
 */
+   int cover_detect_irq;
int (*get_cover_state)(struct device *dev, int slot);
 
const char *name;
-- 
2.0.0

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


[PATCH 3/3] omap_hsmmc: reuse mmc/slot-gpio for card detect instead of open-coded version

2014-07-18 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1b9f279..25aafa6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -231,15 +231,6 @@ struct omap_mmc_of_data {
 
 static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host);
 
-static int omap_hsmmc_card_detect(struct device *dev, int slot)
-{
-   struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-   struct omap_mmc_platform_data *mmc = host-pdata;
-
-   /* NOTE: assumes card detect signal is active-low */
-   return !gpio_get_value_cansleep(mmc-slots[0].switch_pin);
-}
-
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -256,7 +247,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   disable_irq(mmc-slots[0].card_detect_irq);
+   disable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -265,7 +256,7 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int 
slot)
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host-pdata;
 
-   enable_irq(mmc-slots[0].card_detect_irq);
+   enable_irq(mmc-slots[0].cover_detect_irq);
return 0;
 }
 
@@ -458,23 +449,26 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
if (ret)
return ret;
ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   if (ret) {
+   gpio_free(pdata-slots[0].switch_pin);
+   return ret;
+   }
} else {
-   pdata-slots[0].card_detect = omap_hsmmc_card_detect;
-   pdata-slots[0].card_detect_irq =
-   gpio_to_irq(pdata-slots[0].switch_pin);
-
-   ret = gpio_request(pdata-slots[0].switch_pin,
-  mmc_cd);
-   if (ret)
+   /* copy  paste from from mmc_of_parse */
+   ret = mmc_gpio_request_cd(mmc,
+ pdata-slots[0].switch_pin,
+ 0);
+   if (ret  0) {
+   dev_err(pdata-dev,
+   Failed to request CD GPIO #%d: %d!\n,
+   pdata-slots[0].switch_pin, ret);
return ret;
-   ret = gpio_direction_input(pdata-slots[0].switch_pin);
-   if (ret)
-   goto err_free_sp;
+   } else {
+   dev_info(pdata-dev, Got CD GPIO #%d.\n,
+   pdata-slots[0].switch_pin);
+   }
}
-   } else
-   pdata-slots[0].switch_pin = -EINVAL;
+   }
 
if (gpio_is_valid(pdata-slots[0].gpio_wp)) {
/* copy  paste from from mmc_of_parse */
@@ -492,8 +486,9 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
return 0;
 
 err:
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
-err_free_sp:
+   mmc_gpio_free_cd(mmc);
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
return ret;
 }
@@ -501,8 +496,11 @@ err_free_sp:
 static void omap_hsmmc_gpio_free(struct mmc_host *mmc,
 struct omap_mmc_platform_data *pdata)
 {
+   mmc_gpio_free_cd(mmc);
mmc_gpio_free_ro(mmc);
-   if (gpio_is_valid(pdata-slots[0].switch_pin))
+
+   if (gpio_is_valid(pdata-slots[0].switch_pin) 
+   (pdata-slots[0].cover))
gpio_free(pdata-slots[0].switch_pin);
 }
 
@@ -1289,24 +1287,13 @@ static void omap_hsmmc_protect_card(struct 
omap_hsmmc_host *host)
 /*
  * irq handler to notify the core about card insertion/removal
  */
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+static irqreturn_t omap_hsmmc_cover_detect(int irq, void *dev_id)
 {
struct omap_hsmmc_host *host = dev_id;
-   struct omap_mmc_slot_data *slot = mmc_slot(host);
-   int carddetect;
-
-   if (slot-card_detect) {
-   carddetect = slot-card_detect(host-dev, host-slot_id);
-   if (carddetect)
-   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
-   else
-   mmc_detect_change(host-mmc, (HZ * 50) / 1000);
-   } else

Re: mwifiex card reset

2014-07-15 Thread Andreas Fenkart
2014-07-01 17:09 GMT+02:00 Doug Anderson diand...@chromium.org:
 +Olof who posted the patch that Yuvaraj referenced.

 On Tue, Jul 1, 2014 at 5:20 AM, Yuvaraj Cd yuvaraj.l...@gmail.com wrote:
 On Tue, Jul 1, 2014 at 12:27 PM, James Cameron qu...@laptop.org wrote:
 On Mon, Jun 30, 2014 at 11:44:29PM -0700, Bing Zhao wrote:
 I may have missed something, but doesn't the MMC_POWER_OFF and
 MMC_POWER_ON|UP handling in controller driver help?
 Anyway the clocks/GPIOs/regulators are sort of platform
 dependent. Would it be better putting it in /arch/arm/mach-x/?

 Wouldn't device tree for mmc be better?
 I have come across same problem.Below is the thread in which more
 discussions happened on this.
  http://patchwork.ozlabs.org/patch/312444/
 I am adding few more those who are interested in this solution.

 Thanks to Yuvaraj for referencing the old thread.

http://www.spinics.net/lists/linux-mmc/msg26564.html

Quite a read indeed

Meanwhile I got a working prototype for omap_hsmmc/mwifiex based on this series:
http://www.spinics.net/lists/linux-mmc/msg27228.html

I will post my patches, once the FDT format is set in stone, and Ulf
has had some time to work on v2 of his series.
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: mwifiex card reset

2014-07-01 Thread Andreas Fenkart
Hi Bing,

2014-07-01 8:44 GMT+02:00 Bing Zhao bz...@marvell.com:
[snip]
 Yes, a helper might be the best solution. It could even be a generic one, 
 that
 just takes any number of clocks, reset GPIOs and regulators and takes care
 for sequencing them. However, we need to reference that helper from the
 mwifiex driver, for two reasons.

 a) we need to make sure the reset helper gets to do its job before the
 mwifiex driver scans the SDIO bus, and

 b) the reset helper needs to be called when the mmc host controller wants
 to do a card reset.

 Hence, we'll need some sort of internal API for this, and a phandle in dts. I
 wonder whether that glue logic might be better off living in the mmc core, as
 mwifiex might well be interfaced to other hosts?

 I may have missed something, but doesn't the MMC_POWER_OFF and 
 MMC_POWER_ON|UP handling in controller driver help?
 Anyway the clocks/GPIOs/regulators are sort of platform dependent. Would it 
 be better putting it in /arch/arm/mach-x/?

what about usb? the mwifiex can also be connected via usb to the host,
isn't the reset
logic the same in that case, independent of sdio
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 2/3] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x.

2014-06-30 Thread Andreas Fenkart
Hi,

2013-11-19 16:59 GMT+01:00 Balaji T K balaj...@ti.com:
 On Tuesday 19 November 2013 09:19 PM, Tony Lindgren wrote:

 * Balaji T K balaj...@ti.com [131118 08:23]:

 On Monday 18 November 2013 05:45 PM, Andreas Fenkart wrote:

 2013/11/18 Michael Trimarchi mich...@amarulasolutions.com:

 On Mon, Nov 18, 2013 at 8:53 AM, Andreas Fenkart afenk...@gmail.com
 wrote:

   static int omap_hsmmc_card_detect(struct device *dev, int slot)
   {
  struct omap_hsmmc_host *host = dev_get_drvdata(dev);
 @@ -452,10 +474,25 @@ static int omap_hsmmc_gpio_init(struct
 omap_mmc_platform_data *pdata)
  } else
  pdata-slots[0].gpio_wp = -EINVAL;

 +   if (gpio_is_valid(pdata-slots[0].gpio_cirq)) {
 +   pdata-slots[0].sdio_irq =
 +
 gpio_to_irq(pdata-slots[0].gpio_cirq);


 What is this? re-assign the platform data?


 Seems like, I didn't pay attention to this.
 Simply kept in line how the write protection/read only pins are managed.
 I'd rather not change this part, or not changing it as part of adding
 sdio IRQ support it.

 Maybe somebody else on the list can explain why the platform data
 contains elements
 that are modified during runtime.

 - set_power / get_ro function callbacks
 - ocr_mask.

 Hi,

 few params were passed via platform data in non-DT case and never cached
 in internal data structure, with non-dt support going away soon, I am
 planning to cleanup pdata usage in the driver when it gets to DT only
 support.


any news on this?

I'd like to reuse generic mmc_of_parse, kind of difficult with the
current driver state
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: mwifiex card reset

2014-06-29 Thread Andreas Fenkart
2014-06-28 9:23 GMT+02:00 Tony Lindgren t...@atomide.com:
 * James Cameron qu...@laptop.org [140628 08:24]:
 On Fri, Jun 27, 2014 at 04:39:42PM +0200, Andreas Fenkart wrote:
  I have an mwifiex module(sd8787) behind omap_hsmmc(am33xx-soc)
  The module is non-removable wired fix to soc. Now the wifi module
  needs 2 clocks; one is a sleep clock the other used when not
  sleeping.
  While the sleep clock is fixed, @32 kHz, the system clock can be
  one out of several values, but can be be derived automatically
  from the sleep clock. But this requires the clock to be present
  when the wifi module comes out of reset.
 

ref 1)

  Another problem is software reboot, at initial power on the wifi
  card will react to mmc discovery. After a software reset of the
  host it will not, because it has already been discovered and
  didn't notice the host rebooted, unless we reset it as well.
  While this seems obvious, the problem is that the reset is needed
  before the card can be discovered. Which means we cannot move the
  reset logic into the mwifiex driver, since that driver has not
  yet been selected through vendor/product id.
 

 we had same problem with sd8787 and a different system design.  we
 added reset-gpios property [1] and used it in sdhci-pxav3.c [2] as
 sdhci_pxav3_toggle_reset_gpio()

 1.

 http://code.coreboot.org/p/openfirmware/source/tree/HEAD/cpu/arm/olpc/sdhci.fth#L104

 2.

 http://dev.laptop.org/git/olpc-kernel/tree/drivers/mmc/host/sdhci-pxav3.c?h=arm-3.5#n229

  the reset logic:
  gpiod_set_value(card-gpiod_reset, 0);
  clk_enable(card-sleep_clock);
  udelay(1000);
  gpiod_set_value(card-gpiod_reset, 1);
 
  The idea so far was to extend the device-tree node of the
  mmc slot by some reset leafs;
 
  mmc {
  ti,non-removable;
  ..
  peripheral-clocks = clk clk2 ...;
  peripheral-reset-gpios = gpio0 1 1 gpio1 2 3 ...;
  }
 
  in mmc_add_host, all clocks will be enabled and gpios be pulled
  low for 1 msec

 we used 5ms.

  Is this a feasible solution?
 
 
  Another related issue, is the card reset in mwifiex driver:
 
  static void sdio_card_reset_worker(struct work_struct *work)
  {
  struct mmc_host *target = reset_host;
 
  pr_err(Resetting card...\n);
  mmc_remove_host(target);
  /* 20ms delay is based on experiment with sdhci controller */
  mdelay(20);
  mmc_add_host(target);
  }
  static DECLARE_WORK(card_reset_work, sdio_card_reset_worker);
 
  There are obviously a lot of problems with this, e.g. custom debugfs
  entries created in the driver will be lost. But sometimes this
  code might avert disaster in case the command handlers between
  driver and firmware lost synchronization
 
  How could this be done in a better way?

 i'm interested as well.

 Wouldn't it be best to have the mwifiex properly handle the
 reset GPIOs and idle status pins?

doesn't work see ref 1) above

 Those are not part of the SDIO spec AFAIK, and the mmc
 controller should not need to care about those.

 Also, at least omaps also have an issue where suspend won't
 work with mwifiex loaded FYI.

first command after resume needs to be cmd52, not cmd53 as the
driver would by default. it's another issue


 Regards,

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


mwifiex card reset

2014-06-27 Thread Andreas Fenkart
I have an mwifiex module(sd8787) behind omap_hsmmc(am33xx-soc)
The module is non-removable wired fix to soc. Now the wifi module
needs 2 clocks; one is a sleep clock the other used when not
sleeping.
While the sleep clock is fixed, @32 kHz, the system clock can be
one out of several values, but can be be derived automatically
from the sleep clock. But this requires the clock to be present
when the wifi module comes out of reset.

Another problem is software reboot, at initial power on the wifi
card will react to mmc discovery. After a software reset of the
host it will not, because it has already been disvovered and
didn't notice the host rebooted, unless we reset it as well.
While this seems obvious, the problem is that the reset is needed
before the card can be discovered. Which means we cannot move the
reset logic into the mwifiex driver, since that driver has not
yet been selected through vendor/product id.

the reset logic:
gpiod_set_value(card-gpiod_reset, 0);
clk_enable(card-sleep_clock);
udelay(1000);
gpiod_set_value(card-gpiod_reset, 1);

The idea so far was to extend the device-tree node of the
mmc slot by some reset leafs;

mmc {
ti,non-removable;
..
peripheral-clocks = clk clk2 ...;
peripheral-reset-gpios = gpio0 1 1 gpio1 2 3 ...;
}

in mmc_add_host, all clocks will be enabled and gpios be pulled
low for 1 msec

Is this a feasible solution?


Another related issue, is the card reset in mwifiex driver:

static void sdio_card_reset_worker(struct work_struct *work)
{
struct mmc_host *target = reset_host;

pr_err(Resetting card...\n);
mmc_remove_host(target);
/* 20ms delay is based on experiment with sdhci controller */
mdelay(20);
mmc_add_host(target);
}
static DECLARE_WORK(card_reset_work, sdio_card_reset_worker);

There are obviously a lot of problems with this, e.g. custom debugfs
entries created in the driver will be lost. But sometimes this
code might avert disaster in case the command handlers between
driver and firmware lost synchronization

How could this be done in a better way?
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v14 0/6] mmc: omap_hsmmc: Enable SDIO IRQ

2014-05-29 Thread Andreas Fenkart
Hi Balaji, Tony, Ulf, all

v14
- drop all ifdef/endif introduced by v13
-- rely on pinctrl_lookup_state to prevent ifdef CONFIG_PM
-- benefit: all code is compile tested no matter the configuration
-- drawback: require wake_irq/pinctrl configuration even when
   runtime suspend is not configured
- drop runtime state from debugfs output
- rebased onto current mmc-next 06732b84b4cf

v13
- fix compile breaks if !CONFIG_PM
- additional patch: install dummy pm runtime hooks if !CONFIG_PM_RUNTIME

v12
- drop !CONFIG_OF compile break only exists when
  #undef CONFIG_OF after include headers 1/7(Sebastian Reichel)
- do not emit falling back to polling if wake_irq not specified
  since MMC does not need it, and it might confuse users
  only emit if pinmux default/idle is not present or claiming
  the irq failed 2/7(Balaji)
- dropped out-of-tree patches 6/7(Balaji)
- mention ti,am33xx-hsmmc compatible section in bindings
  documentation 1/5

v11
- split !CONFIG_OF compile break into separate patch
- enable IWE/CLKEXTFREE in CON/HCTL register needed for omap4
- '' vs '' in omap_hsmmc_resume, 1/5 (Andreas Müller)
- #define DLEV_DAT instead of BIT(21) 2/5 (Balaji)
- pinctrl_pm_select_default_state() removed, 4/5 (Balaji)
- drop _irqsave/_irqrestore from omap_hsmmc_wake_irq handler since it
  can't be preempted by same priority omap_hsmmc_irq handler 1/5(Joel Fernandes)
- replace devres_open_group by explicit devm_free calls 1/5 (Balaji)
- disable_irq_nosync wake_irq since we handle it thread safe 1/5 (Balaji)
- drop 'gpio_dat1' pinctrl states and rework documentation 5/5 (Balaji)

v10
- bug fix on multi-core, untested
- incorporated changes from Balaji
- use devres / RAII mechanism to configure wake_up /
  sdio irq capabilities
- drop pinctrl state 'active'
  rely on driver-model states 'default', 'idle'
- add specific 'gpio_dat1' state for am335x SWAKEUP hack
- reorganized patches; +1 patch multi-core bugfix / +1 for pinctrl
- rebased 455c6fdbd21916 / cherry-picks from mmc-next

v9
- extended comment about why wake-irq is needed
- drop double '(' ')' around card_detect_irq
- drop final '.' in in subject line of patch

v8
- rebased on top of Tony Lindgrent...@atomide.com changes
  - improved changelog describing the earlier work
  - improved wakeup irq setup
  - works for am3730 es platform now
- my changes on top:
  - compile tested with #undef CONFIG_OF
  - disable wake_irq in handler to prevent infinite loop  
  - fixed typo and added comment about wake-irq

v7
- rebase on 3.14.0-rc3-49726-g77e15ec
- split omap_hsmmc_pin_init due to regression on omap-3730 platform

v6
- rebase on Linux 3.13-rc3
- reformatting debugfs

v5
- fix compile error introduced by last minute one line fix

v4:
- switch to interrupts-extended format
- drop ti,swakeup-missing flag convert to comaptible section

v3:
- removed gpio_irq from platform_data

v2:
- incorparated changes as suggested by reviewers
- simplified workaround for am335x, gpio will now only wake
  the module from runtime suspend, not handle the sdio irq
  itself 

Andreas Fenkart (6):
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: enable wakeup event for sdio OMAP4
  mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on
AM335x

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |   54 
 drivers/mmc/host/omap_hsmmc.c  |  283 ++--
 include/linux/platform_data/mmc-omap.h |1 +
 3 files changed, 317 insertions(+), 21 deletions(-)

-- 
1.7.10.4

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


[PATCH v14 5/6] mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks

2014-05-29 Thread Andreas Fenkart
These are predefined states of the driver model. When not present,
as if not set in the device tree, they become no-ops.
Explicitly selecting the default state is not needed since the
device core layer sets pin mux to default state before probe.
This is not the simplest implementation, on AM335x at least, we could
switch to idle at any point in the suspend hook, only the default state
needs to be set before writing to the irq registers or an IRQ might get
lost.

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2408ec9..0febb17 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1998,7 +1998,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
-   struct pinctrl *pinctrl;
const struct omap_mmc_of_data *data;
void __iomem *base;
 
@@ -,11 +2221,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
omap_hsmmc_disable_irq(host);
 
-   pinctrl = devm_pinctrl_get_select_default(pdev-dev);
-   if (IS_ERR(pinctrl))
-   dev_warn(pdev-dev,
-   pins are not configured from the driver\n);
-
/*
 * For now, only support SDIO interrupt if we have a separate
 * wake-up interrupt configured from device tree. This is because
@@ -2428,10 +2422,15 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
goto abort;
}
 
+   pinctrl_pm_select_idle_state(dev);
+
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
+   } else {
+   pinctrl_pm_select_idle_state(dev);
}
+
 abort:
spin_unlock_irqrestore(host-irq_lock, flags);
return ret;
@@ -2455,9 +2454,14 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
host-flags = ~HSMMC_WAKE_IRQ_ENABLED;
}
 
+   pinctrl_pm_select_default_state(host-dev);
+
+   /* irq lost, if pinmux incorrect */
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   } else {
+   pinctrl_pm_select_default_state(host-dev);
}
spin_unlock_irqrestore(host-irq_lock, flags);
return 0;
-- 
1.7.10.4

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


[PATCH v14 3/6] mmc: omap_hsmmc: enable wakeup event for sdio OMAP4

2014-05-29 Thread Andreas Fenkart
From: Balaji T K balaj...@ti.com

To detect sdio irqs properly without spurious events,
OMAP4 needs IWE in CON and CTPL, CLKEXTFREE in HCTL to be set

Tested-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Balaji T K balaj...@ti.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 332d3d2..b8be438 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -94,7 +94,10 @@
 #define BCE(1  1)
 #define FOUR_BIT   (1  1)
 #define HSPE   (1  2)
+#define IWE(1  24)
 #define DDR(1  19)
+#define CLKEXTFREE (1  16)
+#define CTPL   (1  11)
 #define DW8(1  5)
 #define OD 0x1
 #define STAT_CLEAR 0x
@@ -687,6 +690,9 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
capa = VS18;
}
 
+   if (host-mmc-caps  MMC_CAP_SDIO_IRQ)
+   hctl |= IWE;
+
OMAP_HSMMC_WRITE(host-base, HCTL,
OMAP_HSMMC_READ(host-base, HCTL) | hctl);
 
@@ -1684,19 +1690,23 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, 
struct mmc_card *card)
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   u32 irq_mask;
+   u32 irq_mask, con;
unsigned long flags;
 
spin_lock_irqsave(host-irq_lock, flags);
 
+   con = OMAP_HSMMC_READ(host-base, CON);
irq_mask = OMAP_HSMMC_READ(host-base, ISE);
if (enable) {
host-flags |= HSMMC_SDIO_IRQ_ENABLED;
irq_mask |= CIRQ_EN;
+   con |= CTPL | CLKEXTFREE;
} else {
host-flags = ~HSMMC_SDIO_IRQ_ENABLED;
irq_mask = ~CIRQ_EN;
+   con = ~(CTPL | CLKEXTFREE);
}
+   OMAP_HSMMC_WRITE(host-base, CON, con);
OMAP_HSMMC_WRITE(host-base, IE, irq_mask);
 
/*
@@ -1746,6 +1756,8 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
goto err;
}
 
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
 err:
-- 
1.7.10.4

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


[PATCH v14 4/6] mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected

2014-05-29 Thread Andreas Fenkart
On multicores, an sdio irq handler could be running in parallel to
runtime suspend. In the worst case it could be waiting for the spinlock
held by the runtime suspend. When runtime suspend is complete and the
functional clock (fclk) turned off, the irq handler will continue and
cause a SIGBUS on the first register access.

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b8be438..2408ec9 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -107,6 +107,9 @@
 #define SRD(1  26)
 #define SOFTRESET  (1  1)
 
+/* PSTATE */
+#define DLEV_DAT(x)(1  (20 + (x)))
+
 /* Interrupt masks for IE and ISE register */
 #define CC_EN  (1  0)
 #define TC_EN  (1  1)
@@ -2397,6 +2400,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
 {
struct omap_hsmmc_host *host;
unsigned long flags;
+   int ret = 0;
 
host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_save(host);
@@ -2408,14 +2412,29 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
/* disable sdio irq handling to prevent race */
OMAP_HSMMC_WRITE(host-base, ISE, 0);
OMAP_HSMMC_WRITE(host-base, IE, 0);
-   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+
+   if (!(OMAP_HSMMC_READ(host-base, PSTATE)  DLEV_DAT(1))) {
+   /*
+* dat1 line low, pending sdio irq
+* race condition: possible irq handler running on
+* multi-core, abort
+*/
+   dev_dbg(dev, pending sdio irq, abort suspend\n);
+   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+   OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
+   OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   pm_runtime_mark_last_busy(dev);
+   ret = -EBUSY;
+   goto abort;
+   }
 
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
}
+abort:
spin_unlock_irqrestore(host-irq_lock, flags);
-   return 0;
+   return ret;
 }
 
 static int omap_hsmmc_runtime_resume(struct device *dev)
-- 
1.7.10.4

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


[PATCH v14 2/6] mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state

2014-05-29 Thread Andreas Fenkart
Add SDIO IRQ entries to debugfs entry. Note that PSTATE shows current
state of data lines, incl. SDIO IRQ pending

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 129569d..332d3d2 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
 #define OMAP_HSMMC_RSP54   0x0118
 #define OMAP_HSMMC_RSP76   0x011C
 #define OMAP_HSMMC_DATA0x0120
+#define OMAP_HSMMC_PSTATE  0x0124
 #define OMAP_HSMMC_HCTL0x0128
 #define OMAP_HSMMC_SYSCTL  0x012C
 #define OMAP_HSMMC_STAT0x0130
@@ -1815,13 +1816,23 @@ static int omap_hsmmc_regs_show(struct seq_file *s, 
void *data)
struct mmc_host *mmc = s-private;
struct omap_hsmmc_host *host = mmc_priv(mmc);
 
-   seq_printf(s, mmc%d:\n ctx_loss:\t%d\n\nregs:\n,
-   mmc-index, host-context_loss);
+   seq_printf(s, mmc%d:\n, mmc-index);
+   seq_printf(s, sdio irq mode\t%s\n,
+  (mmc-caps  MMC_CAP_SDIO_IRQ) ? interrupt : polling);
 
-   pm_runtime_get_sync(host-dev);
+   if (mmc-caps  MMC_CAP_SDIO_IRQ) {
+   seq_printf(s, sdio irq \t%s\n,
+  (host-flags  HSMMC_SDIO_IRQ_ENABLED) ?  enabled
+  : disabled);
+   }
+   seq_printf(s, ctx_loss:\t%d\n, host-context_loss);
 
+   pm_runtime_get_sync(host-dev);
+   seq_puts(s, \nregs:\n);
seq_printf(s, CON:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, CON));
+   seq_printf(s, PSTATE:\t\t0x%08x\n,
+  OMAP_HSMMC_READ(host-base, PSTATE));
seq_printf(s, HCTL:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, HCTL));
seq_printf(s, SYSCTL:\t\t0x%08x\n,
-- 
1.7.10.4

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


Re: [mmc:mmc-next 79/96] drivers/mmc/host/omap_hsmmc.c:1841:30: error: 'struct dev_pm_info' has no member named 'runtime_status'

2014-05-23 Thread Andreas Fenkart
2014-05-22 16:24 GMT+02:00 Tony Lindgren t...@atomide.com:
 * Chris Ball ch...@printf.net [140522 05:42]:
 Hi,

 On Thu, May 22 2014, Ulf Hansson wrote:
  I had a second look at Andreas Fenkart's patchset to enable SDIO irq
  for omap. Those needs an additional iteration, since there are
  unresolved dependencies to CONFIG_PM_RUNTIME (and possibly to other
  Kconfigs as well). Apparently I had all the needed Kconfigs enabled
  while I compile tested them. :-(

 Did you find this out with make randconfig?

FYI

after this patch I could deselect CONFIG_PM
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -111,7 +111,6 @@ config ARCH_OMAP2PLUS_TYPICAL
select I2C_OMAP
select MENELAUS if ARCH_OMAP2
select NEON if CPU_V7
-   select PM_RUNTIME
select REGULATOR
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4



  I tried out doing a local re-base, to remove the related omap patches.
  If you remove the patches below you won't get any conflicts for
  omap_hsmmc. Can you do that?
 
  Andreas:
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: enable wakeup event for sdio OMAP4
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x
 
  Balaji:
  mmc: omap_hsmmc: use IS_ERR macro for error checking

 Done.  Thanks!

 Andreas, can you fix this ASAP? Would be nice to have those
 working for v3.16 :)
will send out updated patches soon

 Once you have updated patches available I'll include them
 also to my randconfig builds. Unless the Kconfig options
 are nested they are exposed after few builds typically.

 Regards,

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


[PATCH v13 6/7] mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks

2014-05-23 Thread Andreas Fenkart
These are predefined states of the driver model. When not present,
as if not set in the device tree, they become no-ops.
Explicitly selecting the default state is not needed since the
device core layer sets pin mux to default state before probe.
This is not the simplest implementation, on AM335x at least, we could
switch to idle at any point in the suspend hook, only the default state
needs to be set before writing to the irq registers or an IRQ might get
lost.

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index aafef29..760b0ac 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2008,7 +2008,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
-   struct pinctrl *pinctrl;
const struct omap_mmc_of_data *data;
 
match = of_match_device(of_match_ptr(omap_mmc_of_match), pdev-dev);
@@ -2234,11 +2233,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
omap_hsmmc_disable_irq(host);
 
-   pinctrl = devm_pinctrl_get_select_default(pdev-dev);
-   if (IS_ERR(pinctrl))
-   dev_warn(pdev-dev,
-   pins are not configured from the driver\n);
-
/*
 * For now, only support SDIO interrupt if we have a separate
 * wake-up interrupt configured from device tree. This is because
@@ -2463,10 +2457,15 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
goto abort;
}
 
+   pinctrl_pm_select_idle_state(dev);
+
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
+   } else {
+   pinctrl_pm_select_idle_state(dev);
}
+
 abort:
spin_unlock_irqrestore(host-irq_lock, flags);
return ret;
@@ -2490,9 +2489,14 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
host-flags = ~HSMMC_WAKE_IRQ_ENABLED;
}
 
+   pinctrl_pm_select_default_state(host-dev);
+
+   /* irq lost, if pinmux incorrect */
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   } else {
+   pinctrl_pm_select_default_state(host-dev);
}
spin_unlock_irqrestore(host-irq_lock, flags);
return 0;
-- 
1.7.10.4

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


[PATCH v13 2/7] mmc: omap_hsmmc: Enable SDIO interrupt

2014-05-23 Thread Andreas Fenkart
There have been various patches floating around for enabling
the SDIO IRQ for hsmmc, but none of them ever got merged.

Probably the reason for not merging the SDIO interrupt patches
has been the lack of wake-up path for SDIO on some omaps that
has also needed remuxing the SDIO DAT1 line to a GPIO making
the patches complex.

This patch adds the minimal SDIO IRQ support to hsmmc for
omaps that do have the wake-up path. For those omaps, the
DAT1 line need to have the wake-up enable bit set, and the
wake-up interrupt is the same as for the MMC controller.

This patch has been tested on am3730 es1.2 with mwifiex
connected to MMC3 with mwifiex waking to Ethernet traffic
from off-idle mode. Note that for omaps that do not have
the SDIO wake-up path, this patch will not work for idle
modes and further patches for remuxing DAT1 to GPIO are
needed.

Based on earlier patches [1][2] by David Vrabel
david.vra...@csr.com, Steve Sakoman st...@sakoman.com

For now, only support SDIO interrupt if we are booted with
a separate wake-irq configued via device tree. This is
because omaps need the wake-irq for idle states, and some
omaps need special quirks. And we don't want to add new
legacy mux platform init code callbacks any longer as we
are moving to DT based booting anyways.

To use it, you need to specify the wake-irq using the
interrupts-extended property.

[1] 
http://www.sakoman.com/cgi-bin/gitweb.cgi?p=linux.git;a=commitdiff_plain;h=010810d22f6f49ac03da4ba384969432e0320453
[2] http://comments.gmane.org/gmane.linux.kernel.mmc/20446

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index ce80561..0233ba7 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -12,6 +12,7 @@ Required properties:
  Should be ti,omap3-hsmmc, for OMAP3 controllers
  Should be ti,omap3-pre-es3-hsmmc for OMAP3 controllers pre ES3.0
  Should be ti,omap4-hsmmc, for OMAP4 controllers
+ Should be ti,am33xx-hsmmc, for AM335x controllers
 - ti,hwmods: Must be mmcn, n is controller instance starting 1
 
 Optional properties:
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index c62d9dd..0125eea 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -29,6 +29,7 @@
 #include linux/timer.h
 #include linux/clk.h
 #include linux/of.h
+#include linux/of_irq.h
 #include linux/of_gpio.h
 #include linux/of_device.h
 #include linux/omap-dma.h
@@ -36,6 +37,7 @@
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
 #include linux/io.h
+#include linux/irq.h
 #include linux/gpio.h
 #include linux/regulator/consumer.h
 #include linux/pinctrl/consumer.h
@@ -106,6 +108,7 @@
 #define TC_EN  (1  1)
 #define BWR_EN (1  4)
 #define BRR_EN (1  5)
+#define CIRQ_EN(1  8)
 #define ERR_EN (1  15)
 #define CTO_EN (1  16)
 #define CCRC_EN(1  17)
@@ -140,7 +143,6 @@
 #define VDD_3V0300 /* 30 uV */
 #define VDD_165_195(ffs(MMC_VDD_165_195) - 1)
 
-#define AUTO_CMD23 (1  1)/* Auto CMD23 support */
 /*
  * One controller can have multiple slots, like on some omap boards using
  * omap.c controller driver. Luckily this is not currently done on any known
@@ -200,6 +202,7 @@ struct omap_hsmmc_host {
int slot_id;
int response_busy;
 #ifdef CONFIG_PM
+   int wake_irq;
int context_loss;
 #endif
int protect_card;
@@ -208,6 +211,9 @@ struct omap_hsmmc_host {
int req_in_progress;
unsigned long   clk_rate;
unsigned intflags;
+#define AUTO_CMD23 (1  0)/* Auto CMD23 support */
+#define HSMMC_SDIO_IRQ_ENABLED (1  1)/* SDIO irq enabled */
+#define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_mmc_platform_data  *pdata;
 };
@@ -512,27 +518,40 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host 
*host)
 static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
  struct mmc_command *cmd)
 {
-   unsigned int irq_mask;
+   u32 irq_mask = INT_EN_MASK;
+   unsigned long flags;
 
if (host-use_dma)
-   irq_mask = INT_EN_MASK  ~(BRR_EN | BWR_EN);
-   else
-   irq_mask = INT_EN_MASK;
+   irq_mask = ~(BRR_EN | BWR_EN);
 
/* Disable timeout for erases */
if (cmd-opcode == MMC_ERASE)
irq_mask = ~DTO_EN;
 
+   spin_lock_irqsave(host-irq_lock, flags

[PATCH v13 0/7] mmc: omap_hsmmc: Enable SDIO IRQ

2014-05-23 Thread Andreas Fenkart
Hi Balaji, Tony, Ulf, all

v13
- fix compile breaks if !CONFIG_PM
- additional patch: install dummy pm runtime hooks if !CONFIG_PM_RUNTIME

v12
- drop !CONFIG_OF compile break only exists when
  #undef CONFIG_OF after include headers 1/7(Sebastian Reichel)
- do not emit falling back to polling if wake_irq not specified
  since MMC does not need it, and it might confuse users
  only emit if pinmux default/idle is not present or claiming
  the irq failed 2/7(Balaji)
- dropped out-of-tree patches 6/7(Balaji)
- mention ti,am33xx-hsmmc compatible section in bindings
  documentation 1/5

v11
- split !CONFIG_OF compile break into separate patch
- enable IWE/CLKEXTFREE in CON/HCTL register needed for omap4
- '' vs '' in omap_hsmmc_resume, 1/5 (Andreas Müller)
- #define DLEV_DAT instead of BIT(21) 2/5 (Balaji)
- pinctrl_pm_select_default_state() removed, 4/5 (Balaji)
- drop _irqsave/_irqrestore from omap_hsmmc_wake_irq handler since it
  can't be preempted by same priority omap_hsmmc_irq handler 1/5(Joel Fernandes)
- replace devres_open_group by explicit devm_free calls 1/5 (Balaji)
- disable_irq_nosync wake_irq since we handle it thread safe 1/5 (Balaji)
- drop 'gpio_dat1' pinctrl states and rework documentation 5/5 (Balaji)

v10
- bug fix on multi-core, untested
- incorporated changes from Balaji
- use devres / RAII mechanism to configure wake_up /
  sdio irq capabilities
- drop pinctrl state 'active'
  rely on driver-model states 'default', 'idle'
- add specific 'gpio_dat1' state for am335x SWAKEUP hack
- reorganized patches; +1 patch multi-core bugfix / +1 for pinctrl
- rebased 455c6fdbd21916 / cherry-picks from mmc-next

v9
- extended comment about why wake-irq is needed
- drop double '(' ')' around card_detect_irq
- drop final '.' in in subject line of patch

v8
- rebased on top of Tony Lindgrent...@atomide.com changes
  - improved changelog describing the earlier work
  - improved wakeup irq setup
  - works for am3730 es platform now
- my changes on top:
  - compile tested with #undef CONFIG_OF
  - disable wake_irq in handler to prevent infinite loop  
  - fixed typo and added comment about wake-irq

v7
- rebase on 3.14.0-rc3-49726-g77e15ec
- split omap_hsmmc_pin_init due to regression on omap-3730 platform

v6
- rebase on Linux 3.13-rc3
- reformatting debugfs

v5
- fix compile error introduced by last minute one line fix

v4:
- switch to interrupts-extended format
- drop ti,swakeup-missing flag convert to comaptible section

v3:
- removed gpio_irq from platform_data

v2:
- incorparated changes as suggested by reviewers
- simplified workaround for am335x, gpio will now only wake
  the module from runtime suspend, not handle the sdio irq
  itself 

Andreas Fenkart (7):
  mmc: omap_hsmmc: install dummy pm runtime hooks if !CONFIG_PM_RUNTIME
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: enable wakeup event for sdio OMAP4
  mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on
AM335x

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |   54 
 drivers/mmc/host/omap_hsmmc.c  |  309 ++--
 include/linux/platform_data/mmc-omap.h |1 +
 3 files changed, 335 insertions(+), 29 deletions(-)

-- 
1.7.10.4

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


[PATCH v13 7/7] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x

2014-05-23 Thread Andreas Fenkart
The am335x can't detect pending cirq in PM runtime suspend.
This patch reconfigures dat1 as a GPIO before going to suspend.
SDIO interrupts are detected with the GPIO, the GPIO will only wake
the module from suspend, SDIO irq detection will still happen through the
IP block.

Idea of remuxing the pins by Tony Lindgren. Code contributions from
Tony Lindgren and Balaji T K balaj...@ti.com

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 0233ba7..76bf087 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -57,3 +57,56 @@ Examples:
edma 25;
dma-names = tx, rx;
};
+
+[workaround for missing swakeup on am33xx]
+
+This SOC is missing the swakeup line, it will not detect SDIO irq
+while in suspend.
+
+ --
+ | PRCM |
+  --
+   ^ |
+   swakeup | | fclk
+   | v
+   -----   -
+  | card | -- CIRQ --  | hsmmc | -- IRQ --  | CPU |
+   -----   -
+
+In suspend the fclk is off and the module is disfunctional. Even register reads
+will fail. A small logic in the host will request fclk restore, when an
+external event is detected. Once the clock is restored, the host detects the
+event normally. Since am33xx doesn't have this line it never wakes from
+suspend.
+
+The workaround is to reconfigure the dat1 line as a GPIO upon suspend. To make
+this work, we need to set the named pinctrl states default and idle.
+Prepare idle to remux dat1 as a gpio, and default to remux it back as sdio
+dat1. The MMC driver will then toggle between idle and default state during
+runtime.
+
+In summary:
+1. select matching 'compatible' section, see example below.
+2. specify pinctrl states default and idle, sleep is optional.
+3. specify the gpio irq used for detecting sdio irq in suspend
+
+If configuration is incomplete, a warning message is emitted falling back to
+polling. Also check the sdio irq mode in /sys/kernel/debug/mmc0/regs. Mind
+not every application needs SDIO irq, e.g. MMC cards.
+
+   mmc1: mmc@48060100 {
+   compatible = ti,am33xx-hsmmc;
+   ...
+   pinctrl-names = default, idle, sleep
+   pinctrl-0 = mmc1_pins;
+   pinctrl-1 = mmc1_idle;
+   pinctrl-2 = mmc1_sleep;
+   ...
+   interrupts-extended = intc 64 gpio2 28 0;
+   };
+
+   mmc1_idle : pinmux_cirq_pin {
+   pinctrl-single,pins = 
+   0x0f8 0x3f  /* GPIO2_28 */
+   ;
+   };
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 760b0ac..1238506 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1752,15 +1752,25 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
 * and need to remux SDIO DAT1 to GPIO for wake-up from idle.
 */
if (host-pdata-controller_flags  OMAP_HSMMC_SWAKEUP_MISSING) {
-   ret = -ENODEV;
-   devm_free_irq(host-dev, host-wake_irq, host);
-   goto err;
+   if (IS_ERR(host-dev-pins-default_state)) {
+   dev_info(host-dev, missing default pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
+
+   if (IS_ERR(host-dev-pins-idle_state)) {
+   dev_info(host-dev, missing idle pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
}
 
OMAP_HSMMC_WRITE(host-base, HCTL,
 OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
+err_free_irq:
+   devm_free_irq(host-dev, host-wake_irq, host);
 err:
dev_warn(host-dev, no SDIO IRQ support, falling back to polling\n);
host-wake_irq = 0;
-- 
1.7.10.4

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


[PATCH v11 2/6] mmc: omap_hsmmc: enable wakeup event for sdio OMAP4

2014-05-11 Thread Andreas Fenkart
To detect sdio irqs properly without spurious events,
OMAP4 needs IWE in CON and CTPL, CLKEXTFREE in HCTL to be set

Tested-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Balaji T K balaj...@ti.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index edd53adc..4ee4645 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -93,7 +93,10 @@
 #define BCE(1  1)
 #define FOUR_BIT   (1  1)
 #define HSPE   (1  2)
+#define IWE(1  24)
 #define DDR(1  19)
+#define CLKEXTFREE (1  16)
+#define CTPL   (1  11)
 #define DW8(1  5)
 #define OD 0x1
 #define STAT_CLEAR 0x
@@ -686,6 +689,9 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
capa = VS18;
}
 
+   if (host-mmc-caps  MMC_CAP_SDIO_IRQ)
+   hctl |= IWE;
+
OMAP_HSMMC_WRITE(host-base, HCTL,
OMAP_HSMMC_READ(host-base, HCTL) | hctl);
 
@@ -1682,19 +1688,23 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, 
struct mmc_card *card)
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   u32 irq_mask;
+   u32 irq_mask, con;
unsigned long flags;
 
spin_lock_irqsave(host-irq_lock, flags);
 
+   con = OMAP_HSMMC_READ(host-base, CON);
irq_mask = OMAP_HSMMC_READ(host-base, ISE);
if (enable) {
host-flags |= HSMMC_SDIO_IRQ_ENABLED;
irq_mask |= CIRQ_EN;
+   con |= CTPL | CLKEXTFREE;
} else {
host-flags = ~HSMMC_SDIO_IRQ_ENABLED;
irq_mask = ~CIRQ_EN;
+   con = ~(CTPL | CLKEXTFREE);
}
+   OMAP_HSMMC_WRITE(host-base, CON, con);
OMAP_HSMMC_WRITE(host-base, IE, irq_mask);
 
/*
@@ -1744,6 +1754,8 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
goto err;
}
 
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
 err:
-- 
1.7.10.4

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


[PATCH v11 1/6] mmc: omap_hsmmc: Enable SDIO interrupt

2014-05-11 Thread Andreas Fenkart
There have been various patches floating around for enabling
the SDIO IRQ for hsmmc, but none of them ever got merged.

Probably the reason for not merging the SDIO interrupt patches
has been the lack of wake-up path for SDIO on some omaps that
has also needed remuxing the SDIO DAT1 line to a GPIO making
the patches complex.

This patch adds the minimal SDIO IRQ support to hsmmc for
omaps that do have the wake-up path. For those omaps, the
DAT1 line need to have the wake-up enable bit set, and the
wake-up interrupt is the same as for the MMC controller.

This patch has been tested on am3730 es1.2 with mwifiex
connected to MMC3 with mwifiex waking to Ethernet traffic
from off-idle mode. Note that for omaps that do not have
the SDIO wake-up path, this patch will not work for idle
modes and further patches for remuxing DAT1 to GPIO are
needed.

Based on earlier patches [1][2] by David Vrabel
david.vra...@csr.com, Steve Sakoman st...@sakoman.com

For now, only support SDIO interrupt if we are booted with
a separate wake-irq configued via device tree. This is
because omaps need the wake-irq for idle states, and some
omaps need special quirks. And we don't want to add new
legacy mux platform init code callbacks any longer as we
are moving to DT based booting anyways.

To use it, you need to specify the wake-irq using the
interrupts-extended property.

[1] 
http://www.sakoman.com/cgi-bin/gitweb.cgi?p=linux.git;a=commitdiff_plain;h=010810d22f6f49ac03da4ba384969432e0320453
[2] http://comments.gmane.org/gmane.linux.kernel.mmc/20446

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index ce80561..0233ba7 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -12,6 +12,7 @@ Required properties:
  Should be ti,omap3-hsmmc, for OMAP3 controllers
  Should be ti,omap3-pre-es3-hsmmc for OMAP3 controllers pre ES3.0
  Should be ti,omap4-hsmmc, for OMAP4 controllers
+ Should be ti,am33xx-hsmmc, for AM335x controllers
 - ti,hwmods: Must be mmcn, n is controller instance starting 1
 
 Optional properties:
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 32bcebd..edd53adc 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -29,6 +29,7 @@
 #include linux/timer.h
 #include linux/clk.h
 #include linux/of.h
+#include linux/of_irq.h
 #include linux/of_gpio.h
 #include linux/of_device.h
 #include linux/omap-dma.h
@@ -36,6 +37,7 @@
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
 #include linux/io.h
+#include linux/irq.h
 #include linux/gpio.h
 #include linux/regulator/consumer.h
 #include linux/pinctrl/consumer.h
@@ -106,6 +108,7 @@
 #define TC_EN  (1  1)
 #define BWR_EN (1  4)
 #define BRR_EN (1  5)
+#define CIRQ_EN(1  8)
 #define ERR_EN (1  15)
 #define CTO_EN (1  16)
 #define CCRC_EN(1  17)
@@ -140,7 +143,6 @@
 #define VDD_3V0300 /* 30 uV */
 #define VDD_165_195(ffs(MMC_VDD_165_195) - 1)
 
-#define AUTO_CMD23 (1  1)/* Auto CMD23 support */
 /*
  * One controller can have multiple slots, like on some omap boards using
  * omap.c controller driver. Luckily this is not currently done on any known
@@ -194,6 +196,7 @@ struct omap_hsmmc_host {
u32 sysctl;
u32 capa;
int irq;
+   int wake_irq;
int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
@@ -206,6 +209,9 @@ struct omap_hsmmc_host {
int req_in_progress;
unsigned long   clk_rate;
unsigned intflags;
+#define AUTO_CMD23 (1  0)/* Auto CMD23 support */
+#define HSMMC_SDIO_IRQ_ENABLED (1  1)/* SDIO irq enabled */
+#define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_mmc_platform_data  *pdata;
 };
@@ -510,27 +516,40 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host 
*host)
 static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
  struct mmc_command *cmd)
 {
-   unsigned int irq_mask;
+   u32 irq_mask = INT_EN_MASK;
+   unsigned long flags;
 
if (host-use_dma)
-   irq_mask = INT_EN_MASK  ~(BRR_EN | BWR_EN);
-   else
-   irq_mask = INT_EN_MASK;
+   irq_mask = ~(BRR_EN | BWR_EN);
 
/* Disable timeout for erases */
if (cmd-opcode == MMC_ERASE)
irq_mask = ~DTO_EN

[PATCH v11 0/6] mmc: omap_hsmmc: Enable SDIO IRQ

2014-05-11 Thread Andreas Fenkart
Hi Balaji, Tony, all

v12
- drop !CONFIG_OF compile break only exists when
  #undef CONFIG_OF after include headers 1/7(Sebastian Reichel)
- do not emit falling back to polling if wake_irq not specified
  since MMC does not need it, and it might confuse users
  only emit if pinmux default/idle is not present or claiming
  the irq failed 2/7(Balaji)
- dropped out-of-tree patches 6/7(Balaji)
- mention ti,am33xx-hsmmc compatible section in bindings
  documentation 1/5

v11
- split !CONFIG_OF compile break into separate patch
- enable IWE/CLKEXTFREE in CON/HCTL register needed for omap4
- '' vs '' in omap_hsmmc_resume, 1/5 (Andreas Müller)
- #define DLEV_DAT instead of BIT(21) 2/5 (Balaji)
- pinctrl_pm_select_default_state() removed, 4/5 (Balaji)
- drop _irqsave/_irqrestore from omap_hsmmc_wake_irq handler since it
  can't be preempted by same priority omap_hsmmc_irq handler 1/5(Joel Fernandes)
- replace devres_open_group by explicit devm_free calls 1/5 (Balaji)
- disable_irq_nosync wake_irq since we handle it thread safe 1/5 (Balaji)
- drop 'gpio_dat1' pinctrl states and rework documentation 5/5 (Balaji)

v10
- bug fix on multi-core, untested
- incorporated changes from Balaji
- use devres / RAII mechanism to configure wake_up /
  sdio irq capabilities
- drop pinctrl state 'active'
  rely on driver-model states 'default', 'idle'
- add specific 'gpio_dat1' state for am335x SWAKEUP hack
- reorganized patches; +1 patch multi-core bugfix / +1 for pinctrl
- rebased 455c6fdbd21916 / cherry-picks from mmc-next

v9
- extended comment about why wake-irq is needed
- drop double '(' ')' around card_detect_irq
- drop final '.' in in subject line of patch

v8
- rebased on top of Tony Lindgrent...@atomide.com changes
  - improved changelog describing the earlier work
  - improved wakeup irq setup
  - works for am3730 es platform now
- my changes on top:
  - compile tested with #undef CONFIG_OF
  - disable wake_irq in handler to prevent infinite loop  
  - fixed typo and added comment about wake-irq

v7
- rebase on 3.14.0-rc3-49726-g77e15ec
- split omap_hsmmc_pin_init due to regression on omap-3730 platform

v6
- rebase on Linux 3.13-rc3
- reformatting debugfs

v5
- fix compile error introduced by last minute one line fix

v4:
- switch to interrupts-extended format
- drop ti,swakeup-missing flag convert to comaptible section

v3:
- removed gpio_irq from platform_data

v2:
- incorparated changes as suggested by reviewers
- simplified workaround for am335x, gpio will now only wake
  the module from runtime suspend, not handle the sdio irq
  itself 

Andreas Fenkart (6):
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: enable wakeup event for sdio OMAP4
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on
AM335x

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |   54 
 drivers/mmc/host/omap_hsmmc.c  |  280 ++--
 include/linux/platform_data/mmc-omap.h |1 +
 3 files changed, 314 insertions(+), 21 deletions(-)

-- 
1.7.10.4

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


[PATCH v11 3/6] mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state

2014-05-11 Thread Andreas Fenkart
Add SDIO IRQ entries to debugfs entry. Note that PSTATE shows current
state of data lines, incl. SDIO IRQ pending

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4ee4645..1a9d31f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
 #define OMAP_HSMMC_RSP54   0x0118
 #define OMAP_HSMMC_RSP76   0x011C
 #define OMAP_HSMMC_DATA0x0120
+#define OMAP_HSMMC_PSTATE  0x0124
 #define OMAP_HSMMC_HCTL0x0128
 #define OMAP_HSMMC_SYSCTL  0x012C
 #define OMAP_HSMMC_STAT0x0130
@@ -1825,14 +1826,29 @@ static int omap_hsmmc_regs_show(struct seq_file *s, 
void *data)
 {
struct mmc_host *mmc = s-private;
struct omap_hsmmc_host *host = mmc_priv(mmc);
+   bool suspended;
 
-   seq_printf(s, mmc%d:\n ctx_loss:\t%d\n\nregs:\n,
-   mmc-index, host-context_loss);
+   seq_printf(s, mmc%d:\n, mmc-index);
+   seq_printf(s, sdio irq mode\t%s\n,
+  (mmc-caps  MMC_CAP_SDIO_IRQ) ? interrupt : polling);
 
-   pm_runtime_get_sync(host-dev);
+   if (mmc-caps  MMC_CAP_SDIO_IRQ) {
+   seq_printf(s, sdio irq \t%s\n,
+  (host-flags  HSMMC_SDIO_IRQ_ENABLED) ?  enabled
+  : disabled);
+   }
+
+   suspended = host-dev-power.runtime_status != RPM_ACTIVE;
+   seq_printf(s, runtime state\t%s\n, (suspended ?  idle : active));
 
+   seq_printf(s, ctx_loss:\t%d\n, host-context_loss);
+
+   pm_runtime_get_sync(host-dev);
+   seq_puts(s, \nregs:\n);
seq_printf(s, CON:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, CON));
+   seq_printf(s, PSTATE:\t\t0x%08x\n,
+  OMAP_HSMMC_READ(host-base, PSTATE));
seq_printf(s, HCTL:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, HCTL));
seq_printf(s, SYSCTL:\t\t0x%08x\n,
-- 
1.7.10.4

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


[PATCH v11 5/6] mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks

2014-05-11 Thread Andreas Fenkart
These are predefined states of the driver model. When not present,
as if not set in the device tree, they become no-ops.
Explicitly selecting the default state is not needed since the
device core layer sets pin mux to default state before probe.
This is not the simplest implementation, on AM335x at least, we could
switch to idle at any point in the suspend hook, only the default state
needs to be set before writing to the irq registers or an IRQ might get
lost.

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 30365f5..3c8b183 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2002,7 +2002,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
-   struct pinctrl *pinctrl;
const struct omap_mmc_of_data *data;
 
match = of_match_device(of_match_ptr(omap_mmc_of_match), pdev-dev);
@@ -2226,11 +2225,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
omap_hsmmc_disable_irq(host);
 
-   pinctrl = devm_pinctrl_get_select_default(pdev-dev);
-   if (IS_ERR(pinctrl))
-   dev_warn(pdev-dev,
-   pins are not configured from the driver\n);
-
/*
 * For now, only support SDIO interrupt if we have a separate
 * wake-up interrupt configured from device tree. This is because
@@ -2454,10 +2448,15 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
goto abort;
}
 
+   pinctrl_pm_select_idle_state(dev);
+
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
+   } else {
+   pinctrl_pm_select_idle_state(dev);
}
+
 abort:
spin_unlock_irqrestore(host-irq_lock, flags);
return ret;
@@ -2481,9 +2480,14 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
host-flags = ~HSMMC_WAKE_IRQ_ENABLED;
}
 
+   pinctrl_pm_select_default_state(host-dev);
+
+   /* irq lost, if pinmux incorrect */
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   } else {
+   pinctrl_pm_select_default_state(host-dev);
}
spin_unlock_irqrestore(host-irq_lock, flags);
return 0;
-- 
1.7.10.4

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


[PATCH v11 4/6] mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected

2014-05-11 Thread Andreas Fenkart
On multicores, an sdio irq handler could be running in parallel to
runtime suspend. In the worst case it could be waiting for the spinlock
held by the runtime suspend. When runtime suspend is complete and the
functional clock (fclk) turned off, the irq handler will continue and
cause a SIGBUS on the first register access.

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1a9d31f..30365f5 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -107,6 +107,9 @@
 #define SRD(1  26)
 #define SOFTRESET  (1  1)
 
+/* PSTATE */
+#define DLEV_DAT(x)(1  (20 + (x)))
+
 /* Interrupt masks for IE and ISE register */
 #define CC_EN  (1  0)
 #define TC_EN  (1  1)
@@ -2423,6 +2426,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
 {
struct omap_hsmmc_host *host;
unsigned long flags;
+   int ret = 0;
 
host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_save(host);
@@ -2434,14 +2438,29 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
/* disable sdio irq handling to prevent race */
OMAP_HSMMC_WRITE(host-base, ISE, 0);
OMAP_HSMMC_WRITE(host-base, IE, 0);
-   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+
+   if (!(OMAP_HSMMC_READ(host-base, PSTATE)  DLEV_DAT(1))) {
+   /*
+* dat1 line low, pending sdio irq
+* race condition: possible irq handler running on
+* multi-core, abort
+*/
+   dev_dbg(dev, pending sdio irq, abort suspend\n);
+   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+   OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
+   OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   pm_runtime_mark_last_busy(dev);
+   ret = -EBUSY;
+   goto abort;
+   }
 
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
}
+abort:
spin_unlock_irqrestore(host-irq_lock, flags);
-   return 0;
+   return ret;
 }
 
 static int omap_hsmmc_runtime_resume(struct device *dev)
-- 
1.7.10.4

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


[PATCH v11 6/6] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x

2014-05-11 Thread Andreas Fenkart
The am335x can't detect pending cirq in PM runtime suspend.
This patch reconfigures dat1 as a GPIO before going to suspend.
SDIO interrupts are detected with the GPIO, the GPIO will only wake
the module from suspend, SDIO irq detection will still happen through the
IP block.

Idea of remuxing the pins by Tony Lindgren. Code contributions from
Tony Lindgren and Balaji T K balaj...@ti.com

Acked-by: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 0233ba7..76bf087 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -57,3 +57,56 @@ Examples:
edma 25;
dma-names = tx, rx;
};
+
+[workaround for missing swakeup on am33xx]
+
+This SOC is missing the swakeup line, it will not detect SDIO irq
+while in suspend.
+
+ --
+ | PRCM |
+  --
+   ^ |
+   swakeup | | fclk
+   | v
+   -----   -
+  | card | -- CIRQ --  | hsmmc | -- IRQ --  | CPU |
+   -----   -
+
+In suspend the fclk is off and the module is disfunctional. Even register reads
+will fail. A small logic in the host will request fclk restore, when an
+external event is detected. Once the clock is restored, the host detects the
+event normally. Since am33xx doesn't have this line it never wakes from
+suspend.
+
+The workaround is to reconfigure the dat1 line as a GPIO upon suspend. To make
+this work, we need to set the named pinctrl states default and idle.
+Prepare idle to remux dat1 as a gpio, and default to remux it back as sdio
+dat1. The MMC driver will then toggle between idle and default state during
+runtime.
+
+In summary:
+1. select matching 'compatible' section, see example below.
+2. specify pinctrl states default and idle, sleep is optional.
+3. specify the gpio irq used for detecting sdio irq in suspend
+
+If configuration is incomplete, a warning message is emitted falling back to
+polling. Also check the sdio irq mode in /sys/kernel/debug/mmc0/regs. Mind
+not every application needs SDIO irq, e.g. MMC cards.
+
+   mmc1: mmc@48060100 {
+   compatible = ti,am33xx-hsmmc;
+   ...
+   pinctrl-names = default, idle, sleep
+   pinctrl-0 = mmc1_pins;
+   pinctrl-1 = mmc1_idle;
+   pinctrl-2 = mmc1_sleep;
+   ...
+   interrupts-extended = intc 64 gpio2 28 0;
+   };
+
+   mmc1_idle : pinmux_cirq_pin {
+   pinctrl-single,pins = 
+   0x0f8 0x3f  /* GPIO2_28 */
+   ;
+   };
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3c8b183..d22ac3f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1753,15 +1753,25 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
 * and need to remux SDIO DAT1 to GPIO for wake-up from idle.
 */
if (host-pdata-controller_flags  OMAP_HSMMC_SWAKEUP_MISSING) {
-   ret = -ENODEV;
-   devm_free_irq(host-dev, host-wake_irq, host);
-   goto err;
+   if (IS_ERR(host-dev-pins-default_state)) {
+   dev_info(host-dev, missing default pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
+
+   if (IS_ERR(host-dev-pins-idle_state)) {
+   dev_info(host-dev, missing idle pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
}
 
OMAP_HSMMC_WRITE(host-base, HCTL,
 OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
+err_free_irq:
+   devm_free_irq(host-dev, host-wake_irq, host);
 err:
dev_warn(host-dev, no SDIO IRQ support, falling back to polling\n);
host-wake_irq = 0;
-- 
1.7.10.4

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


[PATCH v11 0/7] mmc: omap_hsmmc: Enable SDIO IRQ.

2014-05-08 Thread Andreas Fenkart
Hi Balaji, Tony, all

v11
- split !CONFIG_OF compile break into separate patch
- enable IWE/CLKEXTFREE in CON/HCTL register needed for omap4
- '' vs '' in omap_hsmmc_resume, 1/5 (Andreas Müller)
- #define DLEV_DAT instead of BIT(21) 2/5 (Balaji)
- pinctrl_pm_select_default_state() removed, 4/5 (Balaji)
- drop _irqsave/_irqrestore from omap_hsmmc_wake_irq handler since it
  can't be preempted by same priority omap_hsmmc_irq handler 1/5(Joel Fernandes)
- replace devres_open_group by explicit devm_free calls 1/5 (Balaji)
- disable_irq_nosync wake_irq since we handle it thread safe 1/5 (Balaji)
- drop 'gpio_dat1' pinctrl states and rework documentation 5/5 (Balaji)

v10
- bug fix on multi-core, untested
- incorporated changes from Balaji
- use devres / RAII mechanism to configure wake_up /
  sdio irq capabilities
- drop pinctrl state 'active'
  rely on driver-model states 'default', 'idle'
- add specific 'gpio_dat1' state for am335x SWAKEUP hack
- reorganized patches; +1 patch multi-core bugfix / +1 for pinctrl
- rebased 455c6fdbd21916 / cherry-picks from mmc-next

v9
- extended comment about why wake-irq is needed
- drop double '(' ')' around card_detect_irq
- drop final '.' in in subject line of patch

v8
- rebased on top of Tony Lindgrent...@atomide.com changes
  - improved changelog describing the earlier work
  - improved wakeup irq setup
  - works for am3730 es platform now
- my changes on top:
  - compile tested with #undef CONFIG_OF
  - disable wake_irq in handler to prevent infinite loop  
  - fixed typo and added comment about wake-irq

v7
- rebase on 3.14.0-rc3-49726-g77e15ec
- split omap_hsmmc_pin_init due to regression on omap-3730 platform

v6
- rebase on Linux 3.13-rc3
- reformatting debugfs

v5
- fix compile error introduced by last minute one line fix

v4:
- switch to interrupts-extended format
- drop ti,swakeup-missing flag convert to comaptible section

v3:
- removed gpio_irq from platform_data

v2:
- incorparated changes as suggested by reviewers
- simplified workaround for am335x, gpio will now only wake
  the module from runtime suspend, not handle the sdio irq
  itself 

Andreas Fenkart (6):
  mmc: omap_hsmmc: compile fix for !CONFIG_OF build
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on
AM335x

Balaji T K (1):
  mmc: omap_hsmmc: enable wakeup event for sdio OMAP4

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |   53 
 drivers/mmc/host/omap_hsmmc.c  |  283 ++--
 include/linux/platform_data/mmc-omap.h |1 +
 3 files changed, 316 insertions(+), 21 deletions(-)

-- 
1.7.10.4

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


[PATCH v11 1/7] mmc: omap_hsmmc: compile fix for !CONFIG_OF build

2014-05-08 Thread Andreas Fenkart
Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8d07e2b..5042a15 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1864,6 +1864,7 @@ static inline struct omap_mmc_platform_data
 {
return ERR_PTR(-EINVAL);
 }
+#define omap_mmc_of_match  NULL
 #endif
 
 static int omap_hsmmc_probe(struct platform_device *pdev)
-- 
1.7.10.4

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


[PATCH v11 2/7] mmc: omap_hsmmc: Enable SDIO interrupt

2014-05-08 Thread Andreas Fenkart
There have been various patches floating around for enabling
the SDIO IRQ for hsmmc, but none of them ever got merged.

Probably the reason for not merging the SDIO interrupt patches
has been the lack of wake-up path for SDIO on some omaps that
has also needed remuxing the SDIO DAT1 line to a GPIO making
the patches complex.

This patch adds the minimal SDIO IRQ support to hsmmc for
omaps that do have the wake-up path. For those omaps, the
DAT1 line need to have the wake-up enable bit set, and the
wake-up interrupt is the same as for the MMC controller.

This patch has been tested on am3730 es1.2 with mwifiex
connected to MMC3 with mwifiex waking to Ethernet traffic
from off-idle mode. Note that for omaps that do not have
the SDIO wake-up path, this patch will not work for idle
modes and further patches for remuxing DAT1 to GPIO are
needed.

Based on earlier patches [1][2] by David Vrabel
david.vra...@csr.com, Steve Sakoman st...@sakoman.com

For now, only support SDIO interrupt if we are booted with
a separate wake-irq configued via device tree. This is
because omaps need the wake-irq for idle states, and some
omaps need special quirks. And we don't want to add new
legacy mux platform init code callbacks any longer as we
are moving to DT based booting anyways.

To use it, you need to specify the wake-irq using the
interrupts-extended property.

[1] 
http://www.sakoman.com/cgi-bin/gitweb.cgi?p=linux.git;a=commitdiff_plain;h=010810d22f6f49ac03da4ba384969432e0320453
[2] http://comments.gmane.org/gmane.linux.kernel.mmc/20446

Cc: Balaji T K balaj...@ti.com
Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5042a15..f43a69e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -29,6 +29,7 @@
 #include linux/timer.h
 #include linux/clk.h
 #include linux/of.h
+#include linux/of_irq.h
 #include linux/of_gpio.h
 #include linux/of_device.h
 #include linux/omap-dma.h
@@ -36,6 +37,7 @@
 #include linux/mmc/core.h
 #include linux/mmc/mmc.h
 #include linux/io.h
+#include linux/irq.h
 #include linux/gpio.h
 #include linux/regulator/consumer.h
 #include linux/pinctrl/consumer.h
@@ -133,6 +135,7 @@ static void apply_clk_hack(struct device *dev)
 #define TC_EN  (1  1)
 #define BWR_EN (1  4)
 #define BRR_EN (1  5)
+#define CIRQ_EN(1  8)
 #define ERR_EN (1  15)
 #define CTO_EN (1  16)
 #define CCRC_EN(1  17)
@@ -167,7 +170,6 @@ static void apply_clk_hack(struct device *dev)
 #define VDD_3V0300 /* 30 uV */
 #define VDD_165_195(ffs(MMC_VDD_165_195) - 1)
 
-#define AUTO_CMD23 (1  1)/* Auto CMD23 support */
 /*
  * One controller can have multiple slots, like on some omap boards using
  * omap.c controller driver. Luckily this is not currently done on any known
@@ -221,6 +223,7 @@ struct omap_hsmmc_host {
u32 sysctl;
u32 capa;
int irq;
+   int wake_irq;
int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
@@ -233,6 +236,9 @@ struct omap_hsmmc_host {
int req_in_progress;
unsigned long   clk_rate;
unsigned intflags;
+#define AUTO_CMD23 (1  0)/* Auto CMD23 support */
+#define HSMMC_SDIO_IRQ_ENABLED (1  1)/* SDIO irq enabled */
+#define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_mmc_platform_data  *pdata;
 };
@@ -537,27 +543,40 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host 
*host)
 static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
  struct mmc_command *cmd)
 {
-   unsigned int irq_mask;
+   u32 irq_mask = INT_EN_MASK;
+   unsigned long flags;
 
if (host-use_dma)
-   irq_mask = INT_EN_MASK  ~(BRR_EN | BWR_EN);
-   else
-   irq_mask = INT_EN_MASK;
+   irq_mask = ~(BRR_EN | BWR_EN);
 
/* Disable timeout for erases */
if (cmd-opcode == MMC_ERASE)
irq_mask = ~DTO_EN;
 
+   spin_lock_irqsave(host-irq_lock, flags);
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host-base, ISE, irq_mask);
+
+   /* latch pending CIRQ, but don't signal MMC core */
+   if (host-flags  HSMMC_SDIO_IRQ_ENABLED)
+   irq_mask |= CIRQ_EN;
OMAP_HSMMC_WRITE(host-base, IE, irq_mask);
+   spin_unlock_irqrestore(host-irq_lock, flags);
 }
 
 static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
 {
-   OMAP_HSMMC_WRITE(host-base, ISE, 0);
-   OMAP_HSMMC_WRITE(host

[PATCH v11 4/7] mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state

2014-05-08 Thread Andreas Fenkart
Add SDIO IRQ entries to debugfs entry. Note that PSTATE shows current
state of data lines, incl. SDIO IRQ pending

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f76462d..14857d7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -83,6 +83,7 @@ static void apply_clk_hack(struct device *dev)
 #define OMAP_HSMMC_RSP54   0x0118
 #define OMAP_HSMMC_RSP76   0x011C
 #define OMAP_HSMMC_DATA0x0120
+#define OMAP_HSMMC_PSTATE  0x0124
 #define OMAP_HSMMC_HCTL0x0128
 #define OMAP_HSMMC_SYSCTL  0x012C
 #define OMAP_HSMMC_STAT0x0130
@@ -1854,14 +1855,29 @@ static int omap_hsmmc_regs_show(struct seq_file *s, 
void *data)
 {
struct mmc_host *mmc = s-private;
struct omap_hsmmc_host *host = mmc_priv(mmc);
+   bool suspended;
 
-   seq_printf(s, mmc%d:\n ctx_loss:\t%d\n\nregs:\n,
-   mmc-index, host-context_loss);
+   seq_printf(s, mmc%d:\n, mmc-index);
+   seq_printf(s, sdio irq mode\t%s\n,
+  (mmc-caps  MMC_CAP_SDIO_IRQ) ? interrupt : polling);
 
-   pm_runtime_get_sync(host-dev);
+   if (mmc-caps  MMC_CAP_SDIO_IRQ) {
+   seq_printf(s, sdio irq \t%s\n,
+  (host-flags  HSMMC_SDIO_IRQ_ENABLED) ?  enabled
+  : disabled);
+   }
+
+   suspended = host-dev-power.runtime_status != RPM_ACTIVE;
+   seq_printf(s, runtime state\t%s\n, (suspended ?  idle : active));
 
+   seq_printf(s, ctx_loss:\t%d\n, host-context_loss);
+
+   pm_runtime_get_sync(host-dev);
+   seq_puts(s, \nregs:\n);
seq_printf(s, CON:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, CON));
+   seq_printf(s, PSTATE:\t\t0x%08x\n,
+  OMAP_HSMMC_READ(host-base, PSTATE));
seq_printf(s, HCTL:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, HCTL));
seq_printf(s, SYSCTL:\t\t0x%08x\n,
-- 
1.7.10.4

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


[PATCH v11 3/7] mmc: omap_hsmmc: enable wakeup event for sdio OMAP4

2014-05-08 Thread Andreas Fenkart
From: Balaji T K balaj...@ti.com

To detect sdio irqs properly without spurious events,
OMAP4 needs IWE in CON and CTPL, CLKEXTFREE in HCTL to be set

Signed-off-by: Balaji T K balaj...@ti.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f43a69e..f76462d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -120,7 +120,10 @@ static void apply_clk_hack(struct device *dev)
 #define BCE(1  1)
 #define FOUR_BIT   (1  1)
 #define HSPE   (1  2)
+#define IWE(1  24)
 #define DDR(1  19)
+#define CLKEXTFREE (1  16)
+#define CTPL   (1  11)
 #define DW8(1  5)
 #define OD 0x1
 #define STAT_CLEAR 0x
@@ -713,6 +716,9 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
capa = VS18;
}
 
+   if (host-mmc-caps  MMC_CAP_SDIO_IRQ)
+   hctl |= IWE;
+
OMAP_HSMMC_WRITE(host-base, HCTL,
OMAP_HSMMC_READ(host-base, HCTL) | hctl);
 
@@ -1709,19 +1715,23 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, 
struct mmc_card *card)
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   u32 irq_mask;
+   u32 irq_mask, con;
unsigned long flags;
 
spin_lock_irqsave(host-irq_lock, flags);
 
+   con = OMAP_HSMMC_READ(host-base, CON);
irq_mask = OMAP_HSMMC_READ(host-base, ISE);
if (enable) {
host-flags |= HSMMC_SDIO_IRQ_ENABLED;
irq_mask |= CIRQ_EN;
+   con |= CTPL | CLKEXTFREE;
} else {
host-flags = ~HSMMC_SDIO_IRQ_ENABLED;
irq_mask = ~CIRQ_EN;
+   con = ~(CTPL | CLKEXTFREE);
}
+   OMAP_HSMMC_WRITE(host-base, CON, con);
OMAP_HSMMC_WRITE(host-base, IE, irq_mask);
 
/*
@@ -1773,6 +1783,8 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
goto err;
}
 
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
 err:
-- 
1.7.10.4

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


[PATCH v11 7/7] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x

2014-05-08 Thread Andreas Fenkart
The am335x can't detect pending cirq in PM runtime suspend.
This patch reconfigures dat1 as a GPIO before going to suspend.
SDIO interrupts are detected with the GPIO, the GPIO will only wake
the module from suspend, SDIO irq detection will still happen through the
IP block.

Idea of remuxing the pins by Tony Lindgren. Code contributions from
Tony Lindgren and Balaji T K balaj...@ti.com

Signed-off-by: Andreas Fenkart afenk...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

Conflicts:
drivers/mmc/host/omap_hsmmc.c

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index ce80561..946bc5f 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -56,3 +56,56 @@ Examples:
edma 25;
dma-names = tx, rx;
};
+
+[workaround for missing swakeup on am33xx]
+
+This SOC is missing the swakeup line, it will not detect SDIO irq
+while in suspend.
+
+ --
+ | PRCM |
+  --
+   ^ |
+   swakeup | | fclk
+   | v
+   -----   -
+  | card | -- CIRQ --  | hsmmc | -- IRQ --  | CPU |
+   -----   -
+
+In suspend the fclk is off and the module is disfunctional. Even register reads
+will fail. A small logic in the host will request fclk restore, when an
+external event is detected. Once the clock is restored, the host detects the
+event normally. Since am33xx doesn't have this line it never wakes from
+suspend.
+
+The workaround is to reconfigure the dat1 line as a GPIO upon suspend. To make
+this work, we need to set the named pinctrl states default and idle.
+Prepare idle to remux dat1 as a gpio, and default to remux it back as sdio
+dat1. The MMC driver will then toggle between idle and default state during
+runtime.
+
+In summary:
+1. select matching 'compatible' section, see example below.
+2. specify pinctrl states default and idle, sleep is optional.
+3. specify the gpio irq used for detecting sdio irq in suspend
+
+If configuration is incomplete, a warning message is emitted falling back to
+polling. Also check the sdio irq mode in /sys/kernel/debug/mmc0/regs. Mind
+not every application needs SDIO irq, e.g. MMC cards.
+
+   mmc1: mmc@48060100 {
+   compatible = ti,am33xx-hsmmc;
+   ...
+   pinctrl-names = default, idle, sleep
+   pinctrl-0 = mmc1_pins;
+   pinctrl-1 = mmc1_idle;
+   pinctrl-2 = mmc1_sleep;
+   ...
+   interrupts-extended = intc 64 gpio2 28 0;
+   };
+
+   mmc1_idle : pinmux_cirq_pin {
+   pinctrl-single,pins = 
+   0x0f8 0x3f  /* GPIO2_28 */
+   ;
+   };
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5a321f98..497b2fc 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1782,15 +1782,25 @@ static int omap_hsmmc_configure_wake_irq(struct 
omap_hsmmc_host *host)
 * and need to remux SDIO DAT1 to GPIO for wake-up from idle.
 */
if (host-pdata-controller_flags  OMAP_HSMMC_SWAKEUP_MISSING) {
-   ret = -ENODEV;
-   devm_free_irq(host-dev, host-wake_irq, host);
-   goto err;
+   if (IS_ERR(host-dev-pins-default_state)) {
+   dev_info(host-dev, missing default pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
+
+   if (IS_ERR(host-dev-pins-idle_state)) {
+   dev_info(host-dev, missing idle pinctrl state\n);
+   ret = -EINVAL;
+   goto err_free_irq;
+   }
}
 
OMAP_HSMMC_WRITE(host-base, HCTL,
 OMAP_HSMMC_READ(host-base, HCTL) | IWE);
return 0;
 
+err_free_irq:
+   devm_free_irq(host-dev, host-wake_irq, host);
 err:
dev_warn(host-dev, no SDIO IRQ support, falling back to polling\n);
host-wake_irq = 0;
-- 
1.7.10.4

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


[PATCH v11 6/7] mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks

2014-05-08 Thread Andreas Fenkart
These are predefined states of the driver model. When not present,
as if not set in the device tree, they become no-ops.
Explicitly selecting the default state is not needed since the
device core layer sets pin mux to default state before probe.
This is not the simplest implementation, on AM335x at least, we could
switch to idle at any point in the suspend hook, only the default state
needs to be set before writing to the irq registers or an IRQ might get
lost.

Signed-off-by: Andreas Fenkart afenk...@gmail.com

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 47a5982..5a321f98 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2032,7 +2032,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
-   struct pinctrl *pinctrl;
const struct omap_mmc_of_data *data;
 
apply_clk_hack(pdev-dev);
@@ -2258,11 +2257,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
omap_hsmmc_disable_irq(host);
 
-   pinctrl = devm_pinctrl_get_select_default(pdev-dev);
-   if (IS_ERR(pinctrl))
-   dev_warn(pdev-dev,
-   pins are not configured from the driver\n);
-
/*
 * For now, only support SDIO interrupt if we have a separate
 * wake-up interrupt configured from device tree. This is because
@@ -2486,10 +2480,15 @@ static int omap_hsmmc_runtime_suspend(struct device 
*dev)
goto abort;
}
 
+   pinctrl_pm_select_idle_state(dev);
+
WARN_ON(host-flags  HSMMC_WAKE_IRQ_ENABLED);
enable_irq(host-wake_irq);
host-flags |= HSMMC_WAKE_IRQ_ENABLED;
+   } else {
+   pinctrl_pm_select_idle_state(dev);
}
+
 abort:
spin_unlock_irqrestore(host-irq_lock, flags);
return ret;
@@ -2513,9 +2512,14 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
host-flags = ~HSMMC_WAKE_IRQ_ENABLED;
}
 
+   pinctrl_pm_select_default_state(host-dev);
+
+   /* irq lost, if pinmux incorrect */
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host-base, ISE, CIRQ_EN);
OMAP_HSMMC_WRITE(host-base, IE, CIRQ_EN);
+   } else {
+   pinctrl_pm_select_default_state(host-dev);
}
spin_unlock_irqrestore(host-irq_lock, flags);
return 0;
-- 
1.7.10.4

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


Re: [PATCH v10 1/5] mmc: omap_hsmmc: Enable SDIO interrupt

2014-04-30 Thread Andreas Fenkart
Hi Andreas,

2014-04-30 14:23 GMT+02:00 Andreas Müller schnitzelt...@googlemail.com:
 On Mon, Apr 28, 2014 at 9:40 AM, Andreas Fenkart afenk...@gmail.com wrote:
 @@ -2201,11 +2346,16 @@ static int omap_hsmmc_suspend(struct device *dev)
 pm_runtime_get_sync(host-dev);

 if (!(host-mmc-pm_flags  MMC_PM_KEEP_POWER)) {
 -   omap_hsmmc_disable_irq(host);
 +   OMAP_HSMMC_WRITE(host-base, ISE, 0);
 +   OMAP_HSMMC_WRITE(host-base, IE, 0);
 +   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
 OMAP_HSMMC_WRITE(host-base, HCTL,
 OMAP_HSMMC_READ(host-base, HCTL)  ~SDBP);
 }

 +   if (host-wake_irq  !(host-mmc-pm_flags  MMC_PM_WAKE_SDIO_IRQ))
 +   disable_irq(host-wake_irq);
 +

I think it says, Do you want to wake up from deep power states when
an SDIO IRQ is pending
Will try to bring this more to the point

 if (host-dbclk)
 clk_disable_unprepare(host-dbclk);

 @@ -2231,6 +2381,9 @@ static int omap_hsmmc_resume(struct device *dev)

 omap_hsmmc_protect_card(host);

 +   if (host-wake_irq  !(host-mmc-pm_flags  MMC_PM_WAKE_SDIO_IRQ))

you're right should be ''

 +   enable_irq(host-wake_irq);
 +
 pm_runtime_mark_last_busy(host-dev);
 pm_runtime_put_autosuspend(host-dev);
 return 0;
 Maybe I misunderstand something here but shouldn't
 disable_irq/enable_irq be swapped here?

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


[PATCH 0/5] mmc: omap_hsmmc: Enable SDIO IRQ.

2014-04-28 Thread Andreas Fenkart
Hi Balaji, Tony, all

v10 
- bug fix on multi-core, untested
- incorporated changes from Balaji
- use devres / RAII mechanism to configure wake_up /
  sdio irq capabilities
- drop pinctrl state 'active'
  rely on driver-model states 'default', 'idle'
- add specific 'gpio_dat1' state for am335x SWAKEUP hack
- reorganized patches; +1 patch multi-core bugfix / +1 for pinctrl 
- rebased 455c6fdbd21916 / cherry-picks from mmc-next 

v9
- extended comment about why wake-irq is needed
- drop double '(' ')' around card_detect_irq
- drop final '.' in in subject line of patch

v8
- rebased on top of Tony Lindgrent...@atomide.com changes
  - improved changelog describing the earlier work
  - improved wakeup irq setup
  - works for am3730 es platform now
- my changes on top:
  - compile tested with #undef CONFIG_OF
  - disable wake_irq in handler to prevent infinite loop  
  - fixed typo and added comment about wake-irq

v7
- rebase on 3.14.0-rc3-49726-g77e15ec
- split omap_hsmmc_pin_init due to regression on omap-3730 platform

v6
- rebase on Linux 3.13-rc3
- reformatting debugfs

v5
- fix compile error introduced by last minute one line fix

v4:
- switch to interrupts-extended format
- drop ti,swakeup-missing flag convert to comaptible section

v3:
- removed gpio_irq from platform_data

v2:
- incorparated changes as suggested by reviewers
- simplified workaround for am335x, gpio will now only wake
  the module from runtime suspend, not handle the sdio irq
  itself 

Andreas Fenkart (5):
  mmc: omap_hsmmc: Enable SDIO interrupt
  mmc: omap_hsmmc: bug: abort runtime suspend if pending sdio irq
detected
  mmc: omap_hsmmc: Extend debugfs by SDIO IRQ handling, runtime state
  mmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks
  mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on
AM335x

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |   51 
 drivers/mmc/host/omap_hsmmc.c  |  285 ++--
 include/linux/platform_data/mmc-omap.h |1 +
 3 files changed, 316 insertions(+), 21 deletions(-)

-- 
1.7.10.4

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


  1   2   >