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

2014-05-09 Thread Balaji T K

On Friday 09 May 2014 04:50 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.

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


Hi Andreas,
Thanks for the new patch series.
Minor nit below,

other than that
Acked-by: Balaji T K balaj...@ti.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_3V0   300 /* 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, 

[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);
-