Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8

2009-09-09 Thread Russell King - ARM Linux
On Wed, Sep 09, 2009 at 10:12:48AM +0530, Syed Mohammed, Khasim wrote:
 Hello all,
 
  -Original Message-
  From: Aguirre Rodriguez, Sergio Alberto
  Sent: Wednesday, September 09, 2009 7:35 AM
  To: Russell King - ARM Linux; Rabin Vincent
  Cc: Syed Mohammed, Khasim; linux-arm-ker...@lists.arm.linux.org.uk; linux-
  o...@vger.kernel.org
  Subject: RE: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8
  
  From: Russell King - ARM Linux [li...@arm.linux.org.uk]
  Sent: Tuesday, September 08, 2009 11:23 PM
   
Acks and tested-bys would be useful please.
  
   Haven't heard anything, so I've committed it as is.  It is my intention
   to push it to Linus as is in the next couple of days.
  
  Russell,
  
  I don't have ways of testing this, but I think Khasim's testing will make
  more sense,
  since he reported the bug... anyways, it's probably too late.
  
 I am really sorry, wanted to try this out when RMK returns from vacation 
 meanwhile forgot :(
 
 The below logic from Rabin works great !!! no issues with this as well.

And how about my revised version, which is the version which is going
to be merged?
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/10] omap mailbox: remove unnecessary arg for omap_mbox_msg_send

2009-09-09 Thread Hiroshi DOYU
From: ext C.A, Subramaniam subramaniam...@ti.com
Subject: RE: [PATCH 6/10] omap mailbox: remove unnecessary arg for 
omap_mbox_msg_send
Date: Mon, 7 Sep 2009 17:32:48 +0200

 Hi Russell,
 'arg' is used later in Patch 10, as part of the tasklet
 implementation, for writing messages to the mailbox. Should I be
 removing it in patch 6 and introduce it only for the tasklet
 implementation?

If just converting work queue to tasklet as below, can we get rid of
the special struct struct omap_msg_tx_data?

http://marc.info/?l=linux-omapm=125248696005088w=2
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 10/10] omap mailbox: OMAP4 Mailbox-driver Patch to support tasklet implementation

2009-09-09 Thread C.A, Subramaniam
 Hi Hiroshi,

 -Original Message-
 From: Hiroshi DOYU [mailto:hiroshi.d...@nokia.com] 
 Sent: Wednesday, September 09, 2009 2:32 PM
 To: C.A, Subramaniam
 Cc: linux-omap@vger.kernel.org; t...@atomide.com; 
 r...@arm.linux.org.uk; Kanigeri, Hari; Gupta, Ramesh
 Subject: Re: [PATCH 10/10] omap mailbox: OMAP4 Mailbox-driver 
 Patch to support tasklet implementation
 
 Hi Subbu,
 
 From: ext C.A, Subramaniam subramaniam...@ti.com
 Subject: RE: [PATCH 10/10] omap mailbox: OMAP4 Mailbox-driver 
 Patch to support tasklet implementation
 Date: Tue, 8 Sep 2009 19:43:48 +0200
 
 [...]
 
   As I described in the comment on [PATCH 8/10], I think 
 that it would 
   be better to keep mach-omap2/mailbox.c simple and to add some 
   additional logic on plat-omap/mailbox.c.
   
   Would it be possbile to move this tasklet implementation to 
   plat-omap/mailbox.c?
  
  The implementation of the tasklet itself is maintained in 
  plat-omap/mailbox.c Since, I wanted to maintain a separate 
 tasklet for 
  each mailbox instance used to send messages from MPU, I had to 
  associate the the tasklet to the mailbox. Hence, the 
 changes were done 
  in mach-omap2/mailbox.c
  
  Please give your comments on this approach.
 
 Wouldn't just converting work_queue to tasklet work like below?
 
 (I havne't tested this at all, though...)
I will try that out and let you know. Also your approach seems better
as you are replacing the work queue implementaion as well.  
 
 diff --git a/arch/arm/plat-omap/include/mach/mailbox.h 
 b/arch/arm/plat-omap/include/mach/mailbox.h
 index b7a6991..1f4e53e 100644
 --- a/arch/arm/plat-omap/include/mach/mailbox.h
 +++ b/arch/arm/plat-omap/include/mach/mailbox.h
 @@ -52,6 +52,8 @@ struct omap_mbox {
  
   struct omap_mbox_queue  *txq, *rxq;
  
 + struct tasklet_struct   tx_tasklet;
 +
   struct omap_mbox_ops*ops;
  
   mbox_msg_t  seq_snd, seq_rcv;
 diff --git a/arch/arm/plat-omap/mailbox.c 
 b/arch/arm/plat-omap/mailbox.c index 40424ed..37267ca 100644
 --- a/arch/arm/plat-omap/mailbox.c
 +++ b/arch/arm/plat-omap/mailbox.c
 @@ -184,22 +184,17 @@ int omap_mbox_msg_send(struct omap_mbox 
 *mbox, mbox_msg_t msg, void* arg)  }  
 EXPORT_SYMBOL(omap_mbox_msg_send);
  
 -static void mbox_tx_work(struct work_struct *work)
 +static void mbox_tx_tasklet(unsigned long data)
  {
   int ret;
   struct request *rq;
 - struct omap_mbox_queue *mq = container_of(work,
 - struct omap_mbox_queue, work);
 - struct omap_mbox *mbox = mq-queue-queuedata;
 + struct omap_mbox *mbox = (struct omap_mbox *)data;
   struct request_queue *q = mbox-txq-queue;
  
   while (1) {
   struct omap_msg_tx_data *tx_data;
  
 - spin_lock(q-queue_lock);
   rq = blk_fetch_request(q);
 - spin_unlock(q-queue_lock);
 -
   if (!rq)
   break;
  
 @@ -208,15 +203,10 @@ static void mbox_tx_work(struct 
 work_struct *work)
   ret = __mbox_msg_send(mbox, tx_data-msg, tx_data-arg);
   if (ret) {
   enable_mbox_irq(mbox, IRQ_TX);
 - spin_lock(q-queue_lock);
   blk_requeue_request(q, rq);
 - spin_unlock(q-queue_lock);
   return;
   }
 -
 - spin_lock(q-queue_lock);
   __blk_end_request_all(rq, 0);
 - spin_unlock(q-queue_lock);
   }
  }
  
 @@ -266,7 +256,7 @@ static void __mbox_tx_interrupt(struct 
 omap_mbox *mbox)  {
   disable_mbox_irq(mbox, IRQ_TX);
   ack_mbox_irq(mbox, IRQ_TX);
 - schedule_work(mbox-txq-work);
 + tasklet_schedule(mbox-tx_tasklet);
  }
  
  static void __mbox_rx_interrupt(struct omap_mbox *mbox) @@ 
 -434,7 +424,9 @@ static int omap_mbox_init(struct omap_mbox *mbox)
   goto fail_request_irq;
   }
  
 - mq = mbox_queue_alloc(mbox, mbox_txq_fn, mbox_tx_work);
 + tasklet_init(mbox-tx_tasklet, mbox_tx_tasklet, 
 (unsigned long)mbox);
 +
 + mq = mbox_queue_alloc(mbox, mbox_txq_fn, NULL);
   if (!mq) {
   ret = -ENOMEM;
   goto fail_alloc_txq;
 
 --
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] OMAP3 : PM : Functions to get freq from opp and vice-versa

2009-09-09 Thread Sanjeev Premi
There is no generic function to get OPP corresponding to frequency
and vice versa.

Function get_opp() - in resource34xx.c - is included only when
CONFIG_OMAP_PM_SRF is enabled. Moreover, it is always called with
an explicit addition of MAX_VDDn_OPP e.g.
  opp = get_opp(mpu_opps + MAX_VDD1_OPP, clk-rate);
  opp = get_opp(l3_opps + MAX_VDD2_OPP, clk-rate);

This is 'addition' is required as there is no encapsulation of
MIN and MAX VDDs associated to the table.

This patch fixes the issue by creating a 'table' object that
encapsulates the MIN and MAX values and the existing rate table.

Signed-off-by: Sanjeev Premi pr...@ti.com
---
 arch/arm/mach-omap2/omap3-opp.h   |   42 +++--
 arch/arm/mach-omap2/pm.c  |   49 +
 arch/arm/mach-omap2/pm34xx.c  |   57 +
 arch/arm/plat-omap/include/mach/omap-pm.h |   25 +
 4 files changed, 137 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-omap2/omap3-opp.h b/arch/arm/mach-omap2/omap3-opp.h
index 3c9a582..52deb4a 100644
--- a/arch/arm/mach-omap2/omap3-opp.h
+++ b/arch/arm/mach-omap2/omap3-opp.h
@@ -21,42 +21,12 @@
 #define S83M8300
 #define S166M   16600
 
-static struct omap_opp omap3_mpu_rate_table[] = {
-   {0, 0, 0},
-   /*OPP1*/
-   {S125M, VDD1_OPP1, 0x1E},
-   /*OPP2*/
-   {S250M, VDD1_OPP2, 0x26},
-   /*OPP3*/
-   {S500M, VDD1_OPP3, 0x30},
-   /*OPP4*/
-   {S550M, VDD1_OPP4, 0x36},
-   /*OPP5*/
-   {S600M, VDD1_OPP5, 0x3C},
-};
+extern struct omap_opp omap3_mpu_rate_table[];
+extern struct omap_opp omap3_dsp_rate_table[];
+extern struct omap_opp omap3_l3_rate_table[];
 
-static struct omap_opp omap3_l3_rate_table[] = {
-   {0, 0, 0},
-   /*OPP1*/
-   {0, VDD2_OPP1, 0x1E},
-   /*OPP2*/
-   {S83M, VDD2_OPP2, 0x24},
-   /*OPP3*/
-   {S166M, VDD2_OPP3, 0x2C},
-};
-
-static struct omap_opp omap3_dsp_rate_table[] = {
-   {0, 0, 0},
-   /*OPP1*/
-   {S90M, VDD1_OPP1, 0x1E},
-   /*OPP2*/
-   {S180M, VDD1_OPP2, 0x26},
-   /*OPP3*/
-   {S360M, VDD1_OPP3, 0x30},
-   /*OPP4*/
-   {S400M, VDD1_OPP4, 0x36},
-   /*OPP5*/
-   {S430M, VDD1_OPP5, 0x3C},
-};
+extern const struct omap_opp_table omap3_mpu_opp_table;
+extern const struct omap_opp_table omap3_dsp_opp_table;
+extern const struct omap_opp_table omap3_l3_opp_table;
 
 #endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index fec7d00..2bbe63f 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -33,6 +33,7 @@
 #include mach/powerdomain.h
 #include mach/resource.h
 #include mach/omap34xx.h
+#include mach/omap-pm.h
 
 #include prm-regbits-34xx.h
 #include pm.h
@@ -281,3 +282,51 @@ static int __init omap_pm_init(void)
return error;
 }
 late_initcall(omap_pm_init);
+
+/*
+ * Get frequency corresponding to an OPP
+ */
+int opp_to_freq(unsigned long* freq, const struct omap_opp_table* table, u8 
opp)
+{
+int i, found=0;
+
+if (table  table-opps) {
+   for (i = table-min; i = table-max; i++) {
+   if (table-opps[i].opp_id == opp) {
+   found = 1;
+   break;
+   }
+   }
+
+   if (found) {
+   *freq = table-opps[i].rate;
+   return 1;
+   }
+   }
+
+return 0;
+}
+
+/*
+ * Get OPP corresponding to a frequency
+ */
+int freq_to_opp(u8* opp, const struct omap_opp_table* table, unsigned long 
freq)
+{
+int i, found=0;
+
+if (table  table-opps) {
+   for (i = table-min; i = table-max; i++) {
+   if (table-opps[i].rate == freq) {
+   found = 1;
+   break;
+   }
+   }
+
+   if (found) {
+   *opp = table-opps[i].opp_id;
+   return 1;
+   }
+   }
+
+return 0;
+}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3d62b06..60b0441 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -50,6 +50,7 @@
 #include prm.h
 #include pm.h
 #include sdrc.h
+#include omap3-opp.h
 
 static int regset_save_on_suspend;
 
@@ -93,6 +94,62 @@ static struct prm_setup_vc prm_setup = {
.vdd1_off = 0x00,   /* 0.6v */
 };
 
+struct omap_opp omap3_mpu_rate_table[] = {
+   {0, 0, 0},
+   /*OPP1*/
+   {S125M, VDD1_OPP1, 0x1E},
+   /*OPP2*/
+   {S250M, VDD1_OPP2, 0x26},
+   /*OPP3*/
+   {S500M, VDD1_OPP3, 0x30},
+   /*OPP4*/
+   {S550M, VDD1_OPP4, 0x36},
+   /*OPP5*/
+   {S600M, VDD1_OPP5, 0x3C},
+};
+
+struct omap_opp omap3_l3_rate_table[] = {
+   {0, 0, 0},
+   /*OPP1*/
+   {0, VDD2_OPP1, 0x1E},
+   /*OPP2*/
+   {S83M, VDD2_OPP2, 

[PATCH V3 0/30] mmc and omap_hsmmc patches

2009-09-09 Thread Adrian Hunter
Hi

Here is version 3 of our 30 patches for mmc and omap_hsmmc.

They exclude Matt Fleming's change for card caps

They split into 2 groups: the first 7 affect mmc core only
and the remaining ones affect omap_hsmmc only.

Madhusudhan Chikkature's patch:
[PATCH V2] omap_hsmmc: Fix for the db clock failure message
still applies cleanly on top.

Adrian Hunter (18):
  mmc: add 'enable' and 'disable' methods to mmc host
  mmc: allow host claim / release nesting
  mmc: add MMC_CAP_NONREMOVABLE host capability
  mmc: add ability to save power by powering off cards
  mmc: check status after MMC SWITCH command
  omap_hsmmc: make use of new enable/disable interface
  omap_hsmmc: keep track of power mode
  omap_hsmmc: ensure workqueues are empty before suspend
  omap_hsmmc: make use of new MMC_CAP_NONREMOVABLE host capability
  ARM: OMAP: mmc-twl4030: add regulator sleep / wake function
  omap_hsmmc: put MMC regulator to sleep
  omap_hsmmc: clear interrupt status after init sequence
  omap_hsmmc: cater for weird CMD6 behaviour
  omap_hsmmc: prevent races with irq handler
  omap_hsmmc: protect the card when the cover is open
  omap_hsmmc: ensure all clock enables and disables are paired
  omap_hsmmc: set a large data timeout for commands with busy signal
  ARM: OMAP: RX51: set MMC capabilities and power-saving flag

Denis Karpov (8):
  mmc: power off once at removal
  omap_hsmmc: add debugfs entry (host registers)
  ARM: OMAP: mmc-twl4030: add context loss counter support
  omap_hsmmc: context save/restore support
  omap_hsmmc: set open drain bit correctly
  omap_hsmmc: support for deeper power saving states
  omap_hsmmc: cleanup macro usage
  omap_hsmmc: code refactoring

Jarkko Lavinen (4):
  mmc: add mmc card sleep and awake support
  omap_hsmmc: fix scatter-gather list sanity checking
  omap_hsmmc: add mmc card sleep and awake support
  omap_hsmmc: fix NULL pointer dereference

 arch/arm/mach-omap2/board-rx51-peripherals.c |4 +
 arch/arm/mach-omap2/mmc-twl4030.c|   78 ++
 arch/arm/mach-omap2/mmc-twl4030.h|2 +
 arch/arm/plat-omap/include/mach/mmc.h|   11 +
 drivers/mmc/core/core.c  |  275 +++-
 drivers/mmc/core/core.h  |4 +
 drivers/mmc/core/host.c  |1 +
 drivers/mmc/core/host.h  |2 +
 drivers/mmc/core/mmc.c   |  130 +++-
 drivers/mmc/core/mmc_ops.c   |   59 ++
 drivers/mmc/core/mmc_ops.h   |1 +
 drivers/mmc/core/sd.c|   52 ++-
 drivers/mmc/host/omap_hsmmc.c| 1035 +-
 include/linux/mmc/card.h |2 +
 include/linux/mmc/core.h |1 +
 include/linux/mmc/host.h |   58 ++
 include/linux/mmc/mmc.h  |3 +
 17 files changed, 1503 insertions(+), 215 deletions(-)

Regards
Adrian

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


[PATCH V3 3/30] mmc: add MMC_CAP_NONREMOVABLE host capability

2009-09-09 Thread Adrian Hunter
From d4af21bc85c82d996401466c71afc10e3723fd87 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Mon, 11 May 2009 10:03:41 +0300
Subject: [PATCH] mmc: add MMC_CAP_NONREMOVABLE host capability

eMMC's are not removable, so unsafe resume is OK always.

To permit this a new host capability MMC_CAP_NONREMOVABLE
has been added and suspend / resume updated accordingly.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/mmc.c   |   41 ++---
 drivers/mmc/core/sd.c|   41 ++---
 include/linux/mmc/host.h |1 +
 3 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 06084db..3e35075 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -507,8 +507,6 @@ static void mmc_detect(struct mmc_host *host)
}
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
 /*
  * Suspend callback from host.
  */
@@ -551,20 +549,49 @@ static void mmc_resume(struct mmc_host *host)
 
 }
 
-#else
+#ifdef CONFIG_MMC_UNSAFE_RESUME
 
-#define mmc_suspend NULL
-#define mmc_resume NULL
+static const struct mmc_bus_ops mmc_ops = {
+   .remove = mmc_remove,
+   .detect = mmc_detect,
+   .suspend = mmc_suspend,
+   .resume = mmc_resume,
+};
 
-#endif
+static void mmc_attach_bus_ops(struct mmc_host *host)
+{
+   mmc_attach_bus(host, mmc_ops);
+}
+
+#else
 
 static const struct mmc_bus_ops mmc_ops = {
.remove = mmc_remove,
.detect = mmc_detect,
+   .suspend = NULL,
+   .resume = NULL,
+};
+
+static const struct mmc_bus_ops mmc_ops_unsafe = {
+   .remove = mmc_remove,
+   .detect = mmc_detect,
.suspend = mmc_suspend,
.resume = mmc_resume,
 };
 
+static void mmc_attach_bus_ops(struct mmc_host *host)
+{
+   const struct mmc_bus_ops *bus_ops;
+
+   if (host-caps  MMC_CAP_NONREMOVABLE)
+   bus_ops = mmc_ops_unsafe;
+   else
+   bus_ops = mmc_ops;
+   mmc_attach_bus(host, bus_ops);
+}
+
+#endif
+
 /*
  * Starting point for MMC card init.
  */
@@ -575,7 +602,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
BUG_ON(!host);
WARN_ON(!host-claimed);
 
-   mmc_attach_bus(host, mmc_ops);
+   mmc_attach_bus_ops(host);
 
/*
 * We need to get OCR a different way for SPI.
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index cd81c39..80cccd2 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -561,8 +561,6 @@ static void mmc_sd_detect(struct mmc_host *host)
}
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
 /*
  * Suspend callback from host.
  */
@@ -605,20 +603,49 @@ static void mmc_sd_resume(struct mmc_host *host)
 
 }
 
-#else
+#ifdef CONFIG_MMC_UNSAFE_RESUME
 
-#define mmc_sd_suspend NULL
-#define mmc_sd_resume NULL
+static const struct mmc_bus_ops mmc_sd_ops = {
+   .remove = mmc_sd_remove,
+   .detect = mmc_sd_detect,
+   .suspend = mmc_sd_suspend,
+   .resume = mmc_sd_resume,
+};
 
-#endif
+static void mmc_sd_attach_bus_ops(struct mmc_host *host)
+{
+   mmc_attach_bus(host, mmc_sd_ops);
+}
+
+#else
 
 static const struct mmc_bus_ops mmc_sd_ops = {
.remove = mmc_sd_remove,
.detect = mmc_sd_detect,
+   .suspend = NULL,
+   .resume = NULL,
+};
+
+static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
+   .remove = mmc_sd_remove,
+   .detect = mmc_sd_detect,
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
 };
 
+static void mmc_sd_attach_bus_ops(struct mmc_host *host)
+{
+   const struct mmc_bus_ops *bus_ops;
+
+   if (host-caps  MMC_CAP_NONREMOVABLE)
+   bus_ops = mmc_sd_ops_unsafe;
+   else
+   bus_ops = mmc_sd_ops;
+   mmc_attach_bus(host, bus_ops);
+}
+
+#endif
+
 /*
  * Starting point for SD card init.
  */
@@ -629,7 +656,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
BUG_ON(!host);
WARN_ON(!host-claimed);
 
-   mmc_attach_bus(host, mmc_sd_ops);
+   mmc_sd_attach_bus_ops(host);
 
/*
 * We need to get OCR a different way for SPI.
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 631a2fe..bb867d2 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -148,6 +148,7 @@ struct mmc_host {
 #define MMC_CAP_NEEDS_POLL (1  5)/* Needs polling for 
card-detection */
 #define MMC_CAP_8_BIT_DATA (1  6)/* Can the host do 8 bit 
transfers */
 #define MMC_CAP_DISABLE(1  7)/* Can the host be 
disabled */
+#define MMC_CAP_NONREMOVABLE   (1  8)/* Nonremovable e.g. eMMC */
 
/* host specific block data */
unsigned intmax_seg_size;   /* see 
blk_queue_max_segment_size */
-- 
1.5.6.3

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

[PATCH V3 2/30] mmc: allow host claim / release nesting

2009-09-09 Thread Adrian Hunter
From 38406738784f19de180db9872a7e10bd02908dc8 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Mon, 27 Apr 2009 13:38:42 +0300
Subject: [PATCH] mmc: allow host claim / release nesting

This change allows the MMC host to be claimed in
situations where the host may or may not have
already been claimed.  Also 'mmc_try_claim_host()'
is now exported.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/core.c  |   34 +-
 include/linux/mmc/core.h |1 +
 include/linux/mmc/host.h |2 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 9bc8d27..bab5015 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -461,16 +461,18 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t 
*abort)
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
stop = abort ? atomic_read(abort) : 0;
-   if (stop || !host-claimed)
+   if (stop || !host-claimed || host-claimer == current)
break;
spin_unlock_irqrestore(host-lock, flags);
schedule();
spin_lock_irqsave(host-lock, flags);
}
set_current_state(TASK_RUNNING);
-   if (!stop)
+   if (!stop) {
host-claimed = 1;
-   else
+   host-claimer = current;
+   host-claim_cnt += 1;
+   } else
wake_up(host-wq);
spin_unlock_irqrestore(host-lock, flags);
remove_wait_queue(host-wq, wait);
@@ -481,29 +483,43 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t 
*abort)
 
 EXPORT_SYMBOL(__mmc_claim_host);
 
-static int mmc_try_claim_host(struct mmc_host *host)
+/**
+ * mmc_try_claim_host - try exclusively to claim a host
+ * @host: mmc host to claim
+ *
+ * Returns %1 if the host is claimed, %0 otherwise.
+ */
+int mmc_try_claim_host(struct mmc_host *host)
 {
int claimed_host = 0;
unsigned long flags;
 
spin_lock_irqsave(host-lock, flags);
-   if (!host-claimed) {
+   if (!host-claimed || host-claimer == current) {
host-claimed = 1;
+   host-claimer = current;
+   host-claim_cnt += 1;
claimed_host = 1;
}
spin_unlock_irqrestore(host-lock, flags);
return claimed_host;
 }
+EXPORT_SYMBOL(mmc_try_claim_host);
 
 static void mmc_do_release_host(struct mmc_host *host)
 {
unsigned long flags;
 
spin_lock_irqsave(host-lock, flags);
-   host-claimed = 0;
-   spin_unlock_irqrestore(host-lock, flags);
-
-   wake_up(host-wq);
+   if (--host-claim_cnt) {
+   /* Release for nested claim */
+   spin_unlock_irqrestore(host-lock, flags);
+   } else {
+   host-claimed = 0;
+   host-claimer = NULL;
+   spin_unlock_irqrestore(host-lock, flags);
+   wake_up(host-wq);
+   }
 }
 
 void mmc_host_deeper_disable(struct work_struct *work)
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 7ac8b50..e4898e9 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -139,6 +139,7 @@ extern unsigned int mmc_align_data_size(struct mmc_card *, 
unsigned int);
 
 extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
 extern void mmc_release_host(struct mmc_host *host);
+extern int mmc_try_claim_host(struct mmc_host *host);
 
 /**
  * mmc_claim_host - exclusively claim a host
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 338a9b3..631a2fe 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -182,6 +182,8 @@ struct mmc_host {
struct mmc_card *card;  /* device attached to this host 
*/
 
wait_queue_head_t   wq;
+   struct task_struct  *claimer;   /* task that has host claimed */
+   int claim_cnt;  /* claim nesting count */
 
struct delayed_work detect;
 
-- 
1.5.6.3

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


[PATCH V3 1/30] mmc: add 'enable' and 'disable' methods to mmc host

2009-09-09 Thread Adrian Hunter
From e1e0cfce4220d9a3f6c969c867cd716f9fb177a5 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Wed, 22 Apr 2009 12:50:45 +0300
Subject: [PATCH] mmc: add 'enable' and 'disable' methods to mmc host

MMC hosts that support power saving can use the 'enable' and
'disable' methods to exit and enter power saving states.
An explanation of their use is provided in the comments
added to include/linux/mmc/host.h.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/core.c  |  177 --
 drivers/mmc/core/host.c  |1 +
 drivers/mmc/core/host.h  |2 +
 include/linux/mmc/host.h |   47 
 4 files changed, 221 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d84c880..9bc8d27 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -344,6 +344,101 @@ unsigned int mmc_align_data_size(struct mmc_card *card, 
unsigned int sz)
 EXPORT_SYMBOL(mmc_align_data_size);
 
 /**
+ * mmc_host_enable - enable a host.
+ * @host: mmc host to enable
+ *
+ * Hosts that support power saving can use the 'enable' and 'disable'
+ * methods to exit and enter power saving states. For more information
+ * see comments for struct mmc_host_ops.
+ */
+int mmc_host_enable(struct mmc_host *host)
+{
+   if (!(host-caps  MMC_CAP_DISABLE))
+   return 0;
+
+   if (host-en_dis_recurs)
+   return 0;
+
+   if (host-nesting_cnt++)
+   return 0;
+
+   cancel_delayed_work_sync(host-disable);
+
+   if (host-enabled)
+   return 0;
+
+   if (host-ops-enable) {
+   int err;
+
+   host-en_dis_recurs = 1;
+   err = host-ops-enable(host);
+   host-en_dis_recurs = 0;
+
+   if (err) {
+   pr_debug(%s: enable error %d\n,
+mmc_hostname(host), err);
+   return err;
+   }
+   }
+   host-enabled = 1;
+   return 0;
+}
+EXPORT_SYMBOL(mmc_host_enable);
+
+static int mmc_host_do_disable(struct mmc_host *host, int lazy)
+{
+   if (host-ops-disable) {
+   int err;
+
+   host-en_dis_recurs = 1;
+   err = host-ops-disable(host, lazy);
+   host-en_dis_recurs = 0;
+
+   if (err  0) {
+   pr_debug(%s: disable error %d\n,
+mmc_hostname(host), err);
+   return err;
+   }
+   if (err  0) {
+   unsigned long delay = msecs_to_jiffies(err);
+
+   mmc_schedule_delayed_work(host-disable, delay);
+   }
+   }
+   host-enabled = 0;
+   return 0;
+}
+
+/**
+ * mmc_host_disable - disable a host.
+ * @host: mmc host to disable
+ *
+ * Hosts that support power saving can use the 'enable' and 'disable'
+ * methods to exit and enter power saving states. For more information
+ * see comments for struct mmc_host_ops.
+ */
+int mmc_host_disable(struct mmc_host *host)
+{
+   int err;
+
+   if (!(host-caps  MMC_CAP_DISABLE))
+   return 0;
+
+   if (host-en_dis_recurs)
+   return 0;
+
+   if (--host-nesting_cnt)
+   return 0;
+
+   if (!host-enabled)
+   return 0;
+
+   err = mmc_host_do_disable(host, 0);
+   return err;
+}
+EXPORT_SYMBOL(mmc_host_disable);
+
+/**
  * __mmc_claim_host - exclusively claim a host
  * @host: mmc host to claim
  * @abort: whether or not the operation should be aborted
@@ -379,11 +474,81 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t 
*abort)
wake_up(host-wq);
spin_unlock_irqrestore(host-lock, flags);
remove_wait_queue(host-wq, wait);
+   if (!stop)
+   mmc_host_enable(host);
return stop;
 }
 
 EXPORT_SYMBOL(__mmc_claim_host);
 
+static int mmc_try_claim_host(struct mmc_host *host)
+{
+   int claimed_host = 0;
+   unsigned long flags;
+
+   spin_lock_irqsave(host-lock, flags);
+   if (!host-claimed) {
+   host-claimed = 1;
+   claimed_host = 1;
+   }
+   spin_unlock_irqrestore(host-lock, flags);
+   return claimed_host;
+}
+
+static void mmc_do_release_host(struct mmc_host *host)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(host-lock, flags);
+   host-claimed = 0;
+   spin_unlock_irqrestore(host-lock, flags);
+
+   wake_up(host-wq);
+}
+
+void mmc_host_deeper_disable(struct work_struct *work)
+{
+   struct mmc_host *host =
+   container_of(work, struct mmc_host, disable.work);
+
+   /* If the host is claimed then we do not want to disable it anymore */
+   if (!mmc_try_claim_host(host))
+   return;
+   mmc_host_do_disable(host, 1);
+   

[PATCH V3 4/30] mmc: add ability to save power by powering off cards

2009-09-09 Thread Adrian Hunter
From ead8ace5804bd9fa2093a5e2e0e80e1ab14d20b0 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Mon, 11 May 2009 12:20:57 +0300
Subject: [PATCH] mmc: add ability to save power by powering off cards

Power can be saved by powering off cards that are not
in use.  This is similar to suspend / resume except
it is under the control of the driver, and does not
require any power management support.  It can only
be used when the driver can monitor whether the card
is removed, otherwise it is unsafe.  This is possible
because, unlike suspend, the driver still receives
card detect and / or cover switch interrupts.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/core.c  |   34 ++
 drivers/mmc/core/core.h  |2 ++
 drivers/mmc/core/mmc.c   |   11 +++
 drivers/mmc/core/sd.c|   11 +++
 include/linux/mmc/host.h |3 +++
 5 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index bab5015..39f7bd1 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1145,6 +1145,40 @@ void mmc_stop_host(struct mmc_host *host)
mmc_power_off(host);
 }
 
+void mmc_power_save_host(struct mmc_host *host)
+{
+   mmc_bus_get(host);
+
+   if (!host-bus_ops || host-bus_dead || !host-bus_ops-power_restore) {
+   mmc_bus_put(host);
+   return;
+   }
+
+   if (host-bus_ops-power_save)
+   host-bus_ops-power_save(host);
+
+   mmc_bus_put(host);
+
+   mmc_power_off(host);
+}
+EXPORT_SYMBOL(mmc_power_save_host);
+
+void mmc_power_restore_host(struct mmc_host *host)
+{
+   mmc_bus_get(host);
+
+   if (!host-bus_ops || host-bus_dead || !host-bus_ops-power_restore) {
+   mmc_bus_put(host);
+   return;
+   }
+
+   mmc_power_up(host);
+   host-bus_ops-power_restore(host);
+
+   mmc_bus_put(host);
+}
+EXPORT_SYMBOL(mmc_power_restore_host);
+
 #ifdef CONFIG_PM
 
 /**
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index c819eff..f7eb4c4 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -20,6 +20,8 @@ struct mmc_bus_ops {
void (*detect)(struct mmc_host *);
void (*suspend)(struct mmc_host *);
void (*resume)(struct mmc_host *);
+   void (*power_save)(struct mmc_host *);
+   void (*power_restore)(struct mmc_host *);
 };
 
 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3e35075..01f7226 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -549,6 +549,14 @@ static void mmc_resume(struct mmc_host *host)
 
 }
 
+static void mmc_power_restore(struct mmc_host *host)
+{
+   host-card-state = ~MMC_STATE_HIGHSPEED;
+   mmc_claim_host(host);
+   mmc_init_card(host, host-ocr, host-card);
+   mmc_release_host(host);
+}
+
 #ifdef CONFIG_MMC_UNSAFE_RESUME
 
 static const struct mmc_bus_ops mmc_ops = {
@@ -556,6 +564,7 @@ static const struct mmc_bus_ops mmc_ops = {
.detect = mmc_detect,
.suspend = mmc_suspend,
.resume = mmc_resume,
+   .power_restore = mmc_power_restore,
 };
 
 static void mmc_attach_bus_ops(struct mmc_host *host)
@@ -570,6 +579,7 @@ static const struct mmc_bus_ops mmc_ops = {
.detect = mmc_detect,
.suspend = NULL,
.resume = NULL,
+   .power_restore = mmc_power_restore,
 };
 
 static const struct mmc_bus_ops mmc_ops_unsafe = {
@@ -577,6 +587,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = {
.detect = mmc_detect,
.suspend = mmc_suspend,
.resume = mmc_resume,
+   .power_restore = mmc_power_restore,
 };
 
 static void mmc_attach_bus_ops(struct mmc_host *host)
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 80cccd2..debe26e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -603,6 +603,14 @@ static void mmc_sd_resume(struct mmc_host *host)
 
 }
 
+static void mmc_sd_power_restore(struct mmc_host *host)
+{
+   host-card-state = ~MMC_STATE_HIGHSPEED;
+   mmc_claim_host(host);
+   mmc_sd_init_card(host, host-ocr, host-card);
+   mmc_release_host(host);
+}
+
 #ifdef CONFIG_MMC_UNSAFE_RESUME
 
 static const struct mmc_bus_ops mmc_sd_ops = {
@@ -610,6 +618,7 @@ static const struct mmc_bus_ops mmc_sd_ops = {
.detect = mmc_sd_detect,
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
+   .power_restore = mmc_sd_power_restore,
 };
 
 static void mmc_sd_attach_bus_ops(struct mmc_host *host)
@@ -624,6 +633,7 @@ static const struct mmc_bus_ops mmc_sd_ops = {
.detect = mmc_sd_detect,
.suspend = NULL,
.resume = NULL,
+   .power_restore = mmc_sd_power_restore,
 };
 
 static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
@@ -631,6 +641,7 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = {

[PATCH V3 5/30] mmc: add mmc card sleep and awake support

2009-09-09 Thread Adrian Hunter
From 93c2813af7edee923a5d46362edfaeb24695d73f Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen jarkko.lavi...@nokia.com
Date: Tue, 12 May 2009 19:46:14 +0300
Subject: [PATCH] mmc: add mmc card sleep and awake support

Add support for the new MMC command SLEEP_AWAKE.

Signed-off-by: Jarkko Lavinen jarkko.lavi...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/core.c|   40 
 drivers/mmc/core/core.h|2 +
 drivers/mmc/core/mmc.c |   54 +++
 drivers/mmc/core/mmc_ops.c |   36 +
 drivers/mmc/core/mmc_ops.h |1 +
 include/linux/mmc/card.h   |2 +
 include/linux/mmc/host.h   |5 
 include/linux/mmc/mmc.h|2 +
 8 files changed, 137 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 39f7bd1..0611bf7 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1179,6 +1179,46 @@ void mmc_power_restore_host(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_power_restore_host);
 
+int mmc_card_awake(struct mmc_host *host)
+{
+   int err = -ENOSYS;
+
+   mmc_bus_get(host);
+
+   if (host-bus_ops  !host-bus_dead  host-bus_ops-awake)
+   err = host-bus_ops-awake(host);
+
+   mmc_bus_put(host);
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_card_awake);
+
+int mmc_card_sleep(struct mmc_host *host)
+{
+   int err = -ENOSYS;
+
+   mmc_bus_get(host);
+
+   if (host-bus_ops  !host-bus_dead  host-bus_ops-awake)
+   err = host-bus_ops-sleep(host);
+
+   mmc_bus_put(host);
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_card_sleep);
+
+int mmc_card_can_sleep(struct mmc_host *host)
+{
+   struct mmc_card *card = host-card;
+
+   if (card  mmc_card_mmc(card)  card-ext_csd.rev = 3)
+   return 1;
+   return 0;
+}
+EXPORT_SYMBOL(mmc_card_can_sleep);
+
 #ifdef CONFIG_PM
 
 /**
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index f7eb4c4..c386348 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -16,6 +16,8 @@
 #define MMC_CMD_RETRIES3
 
 struct mmc_bus_ops {
+   int (*awake)(struct mmc_host *);
+   int (*sleep)(struct mmc_host *);
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
void (*suspend)(struct mmc_host *);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 01f7226..8e2e3d2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -160,7 +160,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 {
int err;
u8 *ext_csd;
-   unsigned int ext_csd_struct;
 
BUG_ON(!card);
 
@@ -207,16 +206,16 @@ static int mmc_read_ext_csd(struct mmc_card *card)
goto out;
}
 
-   ext_csd_struct = ext_csd[EXT_CSD_REV];
-   if (ext_csd_struct  3) {
+   card-ext_csd.rev = ext_csd[EXT_CSD_REV];
+   if (card-ext_csd.rev  3) {
printk(KERN_ERR %s: unrecognised EXT_CSD structure 
version %d\n, mmc_hostname(card-host),
-   ext_csd_struct);
+   card-ext_csd.rev);
err = -EINVAL;
goto out;
}
 
-   if (ext_csd_struct = 2) {
+   if (card-ext_csd.rev = 2) {
card-ext_csd.sectors =
ext_csd[EXT_CSD_SEC_CNT + 0]  0 |
ext_csd[EXT_CSD_SEC_CNT + 1]  8 |
@@ -241,6 +240,15 @@ static int mmc_read_ext_csd(struct mmc_card *card)
goto out;
}
 
+   if (card-ext_csd.rev = 3) {
+   u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
+
+   /* Sleep / awake timeout in 100ns units */
+   if (sa_shift  0  sa_shift = 0x17)
+   card-ext_csd.sa_timeout =
+   1  ext_csd[EXT_CSD_S_A_TIMEOUT];
+   }
+
 out:
kfree(ext_csd);
 
@@ -557,9 +565,41 @@ static void mmc_power_restore(struct mmc_host *host)
mmc_release_host(host);
 }
 
+static int mmc_sleep(struct mmc_host *host)
+{
+   struct mmc_card *card = host-card;
+   int err = -ENOSYS;
+
+   if (card  card-ext_csd.rev = 3) {
+   err = mmc_card_sleepawake(host, 1);
+   if (err  0)
+   pr_debug(%s: Error %d while putting card into sleep,
+mmc_hostname(host), err);
+   }
+
+   return err;
+}
+
+static int mmc_awake(struct mmc_host *host)
+{
+   struct mmc_card *card = host-card;
+   int err = -ENOSYS;
+
+   if (card  card-ext_csd.rev = 3) {
+   err = mmc_card_sleepawake(host, 0);
+   if (err  0)
+   pr_debug(%s: Error %d while awaking sleeping card,
+mmc_hostname(host), err);
+   }
+
+   return err;
+}
+
 #ifdef CONFIG_MMC_UNSAFE_RESUME
 
 static const 

[PATCH V3 6/30] mmc: power off once at removal

2009-09-09 Thread Adrian Hunter
From 1ba831889384b613e36b68476e0d2207deebabe0 Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Thu, 14 May 2009 09:11:38 +0200
Subject: [PATCH] mmc: power off once at removal

Fix MMC host stop sequence: power off once.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/core.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0611bf7..8d03da4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1137,6 +1137,8 @@ void mmc_stop_host(struct mmc_host *host)
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
+   mmc_bus_put(host);
+   return;
}
mmc_bus_put(host);
 
-- 
1.5.6.3

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


[PATCH V3 7/30] mmc: check status after MMC SWITCH command

2009-09-09 Thread Adrian Hunter
From b1b7bb5d722ff81b28b006fa43eca3eb86769add Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Wed, 3 Jun 2009 12:22:29 +0300
Subject: [PATCH] mmc: check status after MMC SWITCH command

According to the standard, the SWITCH command should
be followed by a SEND_STATUS command to check for
errors.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/core/mmc.c |   24 ++--
 drivers/mmc/core/mmc_ops.c |   23 +++
 include/linux/mmc/mmc.h|1 +
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 8e2e3d2..f87cc0b 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -416,12 +416,17 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
(host-caps  MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, 1);
-   if (err)
+   if (err  err != -EBADMSG)
goto free_card;
 
-   mmc_card_set_highspeed(card);
-
-   mmc_set_timing(card-host, MMC_TIMING_MMC_HS);
+   if (err) {
+   printk(KERN_WARNING %s: switch to highspeed failed\n,
+  mmc_hostname(card-host));
+   err = 0;
+   } else {
+   mmc_card_set_highspeed(card);
+   mmc_set_timing(card-host, MMC_TIMING_MMC_HS);
+   }
}
 
/*
@@ -456,10 +461,17 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH, ext_csd_bit);
 
-   if (err)
+   if (err  err != -EBADMSG)
goto free_card;
 
-   mmc_set_bus_width(card-host, bus_width);
+   if (err) {
+   printk(KERN_WARNING %s: switch to bus width %d 
+  failed\n, mmc_hostname(card-host),
+  1  bus_width);
+   err = 0;
+   } else {
+   mmc_set_bus_width(card-host, bus_width);
+   }
}
 
if (!oldcard)
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 355c604..d2cb5c6 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -390,6 +390,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 
value)
 {
int err;
struct mmc_command cmd;
+   u32 status;
 
BUG_ON(!card);
BUG_ON(!card-host);
@@ -407,6 +408,28 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 
value)
if (err)
return err;
 
+   /* Must check status to be sure of no errors */
+   do {
+   err = mmc_send_status(card, status);
+   if (err)
+   return err;
+   if (card-host-caps  MMC_CAP_WAIT_WHILE_BUSY)
+   break;
+   if (mmc_host_is_spi(card-host))
+   break;
+   } while (R1_CURRENT_STATE(status) == 7);
+
+   if (mmc_host_is_spi(card-host)) {
+   if (status  R1_SPI_ILLEGAL_COMMAND)
+   return -EBADMSG;
+   } else {
+   if (status  0xFDFFA000)
+   printk(KERN_WARNING %s: unexpected status %#x after 
+  switch, mmc_hostname(card-host), status);
+   if (status  R1_SWITCH_ERROR)
+   return -EBADMSG;
+   }
+
return 0;
 }
 
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index b2b4095..c02c8db 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -128,6 +128,7 @@
 #define R1_STATUS(x)(x  0xE000)
 #define R1_CURRENT_STATE(x)((x  0x1E00)  9) /* sx, b (4 bits) */
 #define R1_READY_FOR_DATA  (1  8)/* sx, a */
+#define R1_SWITCH_ERROR(1  7)/* sx, c */
 #define R1_APP_CMD (1  5)/* sr, c */
 
 /*
-- 
1.5.6.3

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


[PATCH V3 8/30] omap_hsmmc: add debugfs entry (host registers)

2009-09-09 Thread Adrian Hunter
From 9ef69fd17bbd1d598a7f262d5940f88dbfff526c Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Wed, 22 Apr 2009 14:21:34 +0200
Subject: [PATCH] omap_hsmmc: add debugfs entry (host registers)

Adds debugfs_root/kernel/debug/mmcN/regs entry,
contents show registers' state and some driver internal
state variables.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   57 +
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1cf9cfb..cbd8376 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -17,6 +17,8 @@
 
 #include linux/module.h
 #include linux/init.h
+#include linux/debugfs.h
+#include linux/seq_file.h
 #include linux/interrupt.h
 #include linux/delay.h
 #include linux/dma-mapping.h
@@ -967,6 +969,59 @@ static struct mmc_host_ops mmc_omap_ops = {
/* NYET -- enable_sdio_irq */
 };
 
+#ifdef CONFIG_DEBUG_FS
+
+static int mmc_regs_show(struct seq_file *s, void *data)
+{
+   struct mmc_host *mmc = s-private;
+   struct mmc_omap_host *host = mmc_priv(mmc);
+
+   seq_printf(s, mmc%d regs:\n, mmc-index);
+
+   seq_printf(s, SYSCONFIG:\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, SYSCONFIG));
+   seq_printf(s, CON:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, CON));
+   seq_printf(s, HCTL:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, HCTL));
+   seq_printf(s, SYSCTL:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, SYSCTL));
+   seq_printf(s, IE:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, IE));
+   seq_printf(s, ISE:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, ISE));
+   seq_printf(s, CAPA:\t\t0x%08x\n,
+   OMAP_HSMMC_READ(host-base, CAPA));
+   return 0;
+}
+
+static int mmc_regs_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, mmc_regs_show, inode-i_private);
+}
+
+static const struct file_operations mmc_regs_fops = {
+   .open   = mmc_regs_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static void omap_mmc_debugfs(struct mmc_host *mmc)
+{
+   if (mmc-debugfs_root)
+   debugfs_create_file(regs, S_IRUSR, mmc-debugfs_root,
+   mmc, mmc_regs_fops);
+}
+
+#else
+
+static void omap_mmc_debugfs(struct mmc_host *mmc)
+{
+}
+
+#endif
+
 static int __init omap_mmc_probe(struct platform_device *pdev)
 {
struct omap_mmc_platform_data *pdata = pdev-dev.platform_data;
@@ -1150,6 +1205,8 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
goto err_cover_switch;
}
 
+   omap_mmc_debugfs(mmc);
+
return 0;
 
 err_cover_switch:
-- 
1.5.6.3

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


[PATCH V3 9/30] omap_hsmmc: make use of new enable/disable interface

2009-09-09 Thread Adrian Hunter
From bd1f7622b77a370f3750a7823462dffa2267d09a Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Thu, 23 Apr 2009 10:01:29 +0300
Subject: [PATCH] omap_hsmmc: make use of new enable/disable interface

For the moment enable / disable just turns the fclk
on and off.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   68 +++--
 1 files changed, 58 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index cbd8376..b1bee52 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -598,7 +598,9 @@ static void mmc_omap_detect(struct work_struct *work)
if (host-carddetect) {
mmc_detect_change(host-mmc, (HZ * 200) / 1000);
} else {
+   mmc_host_enable(host-mmc);
mmc_omap_reset_controller_fsm(host, SRD);
+   mmc_host_lazy_disable(host-mmc);
mmc_detect_change(host-mmc, (HZ * 50) / 1000);
}
 }
@@ -811,6 +813,27 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct 
mmc_request *req)
return 0;
 }
 
+static int omap_mmc_enable(struct mmc_host *mmc)
+{
+   struct mmc_omap_host *host = mmc_priv(mmc);
+   int err;
+
+   err = clk_enable(host-fclk);
+   if (err)
+   return err;
+   dev_dbg(mmc_dev(host-mmc), mmc_fclk: enabled\n);
+   return 0;
+}
+
+static int omap_mmc_disable(struct mmc_host *mmc, int lazy)
+{
+   struct mmc_omap_host *host = mmc_priv(mmc);
+
+   clk_disable(host-fclk);
+   dev_dbg(mmc_dev(host-mmc), mmc_fclk: disabled\n);
+   return 0;
+}
+
 /*
  * Request function. for read/write operation
  */
@@ -834,6 +857,8 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
unsigned long timeout;
u32 con;
 
+   mmc_host_enable(host-mmc);
+
switch (ios-power_mode) {
case MMC_POWER_OFF:
mmc_slot(host).set_power(host-dev, host-slot_id, 0, 0);
@@ -912,6 +937,8 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
OMAP_HSMMC_WRITE(host-base, CON,
OMAP_HSMMC_READ(host-base, CON) | OD);
+
+   mmc_host_lazy_disable(host-mmc);
 }
 
 static int omap_hsmmc_get_cd(struct mmc_host *mmc)
@@ -962,6 +989,8 @@ static void omap_hsmmc_init(struct mmc_omap_host *host)
 }
 
 static struct mmc_host_ops mmc_omap_ops = {
+   .enable = omap_mmc_enable,
+   .disable = omap_mmc_disable,
.request = omap_mmc_request,
.set_ios = omap_mmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
@@ -976,7 +1005,16 @@ static int mmc_regs_show(struct seq_file *s, void *data)
struct mmc_host *mmc = s-private;
struct mmc_omap_host *host = mmc_priv(mmc);
 
-   seq_printf(s, mmc%d regs:\n, mmc-index);
+   seq_printf(s, mmc%d:\n
+enabled:\t%d\n
+nesting_cnt:\t%d\n
+   \nregs:\n,
+   mmc-index, mmc-enabled ? 1 : 0, mmc-nesting_cnt);
+
+   if (clk_enable(host-fclk) != 0) {
+   seq_printf(s, can't read the regs\n);
+   goto err;
+   }
 
seq_printf(s, SYSCONFIG:\t0x%08x\n,
OMAP_HSMMC_READ(host-base, SYSCONFIG));
@@ -992,6 +1030,9 @@ static int mmc_regs_show(struct seq_file *s, void *data)
OMAP_HSMMC_READ(host-base, ISE));
seq_printf(s, CAPA:\t\t0x%08x\n,
OMAP_HSMMC_READ(host-base, CAPA));
+
+   clk_disable(host-fclk);
+err:
return 0;
 }
 
@@ -1092,14 +1133,16 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
goto err1;
}
 
-   if (clk_enable(host-fclk) != 0) {
+   mmc-caps |= MMC_CAP_DISABLE;
+   mmc_set_disable_delay(mmc, 100);
+   if (mmc_host_enable(host-mmc) != 0) {
clk_put(host-iclk);
clk_put(host-fclk);
goto err1;
}
 
if (clk_enable(host-iclk) != 0) {
-   clk_disable(host-fclk);
+   mmc_host_disable(host-mmc);
clk_put(host-iclk);
clk_put(host-fclk);
goto err1;
@@ -1190,6 +1233,8 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
OMAP_HSMMC_WRITE(host-base, ISE, INT_EN_MASK);
OMAP_HSMMC_WRITE(host-base, IE, INT_EN_MASK);
 
+   mmc_host_lazy_disable(host-mmc);
+
mmc_add_host(mmc);
 
if (host-pdata-slots[host-slot_id].name != NULL) {
@@ -1218,7 +1263,7 @@ err_irq_cd:
 err_irq_cd_init:
free_irq(host-irq, host);
 err_irq:
-   clk_disable(host-fclk);
+   mmc_host_disable(host-mmc);
clk_disable(host-iclk);
clk_put(host-fclk);
clk_put(host-iclk);
@@ -1243,6 +1288,7 @@ static int 

[PATCH V3 10/30] ARM: OMAP: mmc-twl4030: add context loss counter support

2009-09-09 Thread Adrian Hunter
From 027d57463031f291c704f3048c49765c02e661b1 Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Tue, 7 Jul 2009 15:54:44 +0300
Subject: [PATCH] ARM: OMAP: mmc-twl4030: add context loss counter support

PM dynamic OFF state results in context loss.  That is, the host
controller has been powered off at some point, which means the
registers have been reset.  The driver must detect when this
happens, and restore the context.  This patch adds the means
to detect context loss.

Note, the PM side is not yet implemented.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/mmc-twl4030.c |   15 +++
 arch/arm/plat-omap/include/mach/mmc.h |3 +++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mmc-twl4030.c 
b/arch/arm/mach-omap2/mmc-twl4030.c
index 3c04c2f..30d0286 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -198,6 +198,18 @@ static int twl_mmc_resume(struct device *dev, int slot)
 #define twl_mmc_resume NULL
 #endif
 
+#if defined(CONFIG_ARCH_OMAP3)  defined(CONFIG_PM)
+
+static int twl4030_mmc_get_context_loss(struct device *dev)
+{
+   /* FIXME: PM DPS not implemented yet */
+   return 0;
+}
+
+#else
+#define twl4030_mmc_get_context_loss NULL
+#endif
+
 static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
int vdd)
 {
@@ -390,6 +402,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info 
*controllers)
} else
mmc-slots[0].switch_pin = -EINVAL;
 
+   mmc-get_context_loss_count =
+   twl4030_mmc_get_context_loss;
+
/* write protect normally uses an OMAP gpio */
if (gpio_is_valid(c-gpio_wp)) {
gpio_request(c-gpio_wp, mmc_wp);
diff --git a/arch/arm/plat-omap/include/mach/mmc.h 
b/arch/arm/plat-omap/include/mach/mmc.h
index 81d5b36..2f7cf31 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -59,6 +59,9 @@ struct omap_mmc_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);
+
u64 dma_mask;
 
struct omap_mmc_slot_data {
-- 
1.5.6.3

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


[PATCH V3 13/30] omap_hsmmc: set open drain bit correctly

2009-09-09 Thread Adrian Hunter
From ca1bda2fa518c0263af943ffd953ab59515c949d Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Thu, 23 Apr 2009 16:44:58 +0300
Subject: [PATCH] omap_hsmmc: set open drain bit correctly

The code could set the bit to 1 but not reset it to 0.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d5e4f08..e0b9c49 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -,9 +,11 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
if (do_send_init_stream)
send_init_stream(host);
 
+   con = OMAP_HSMMC_READ(host-base, CON);
if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
-   OMAP_HSMMC_WRITE(host-base, CON,
-   OMAP_HSMMC_READ(host-base, CON) | OD);
+   OMAP_HSMMC_WRITE(host-base, CON, con | OD);
+   else
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~OD);
 
mmc_host_lazy_disable(host-mmc);
 }
-- 
1.5.6.3

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


[PATCH V3 12/30] omap_hsmmc: context save/restore support

2009-09-09 Thread Adrian Hunter
From af66a8e899b8acf055fedd3a1fabf7ad9f0f2393 Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Wed, 22 Apr 2009 16:04:25 +0200
Subject: [PATCH] omap_hsmmc: context save/restore support

Keep the context over PM dynamic OFF states.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |  194 ++--
 1 files changed, 184 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8a41629..d5e4f08 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -37,6 +37,7 @@
 
 /* OMAP HSMMC Host Controller Registers */
 #define OMAP_HSMMC_SYSCONFIG   0x0010
+#define OMAP_HSMMC_SYSSTATUS   0x0014
 #define OMAP_HSMMC_CON 0x002C
 #define OMAP_HSMMC_BLK 0x0104
 #define OMAP_HSMMC_ARG 0x0108
@@ -94,6 +95,8 @@
 #define DUAL_VOLT_OCR_BIT  7
 #define SRC(1  25)
 #define SRD(1  26)
+#define SOFTRESET  (1  1)
+#define RESETDONE  (1  0)
 
 /*
  * FIXME: Most likely all the data using these _DEVID defines should come
@@ -152,6 +155,8 @@ struct mmc_omap_host {
int slot_id;
int dbclk_enabled;
int response_busy;
+   int context_loss;
+
struct  omap_mmc_platform_data  *pdata;
 };
 
@@ -166,6 +171,166 @@ static void omap_mmc_stop_clock(struct mmc_omap_host 
*host)
dev_dbg(mmc_dev(host-mmc), MMC Clock is not stoped\n);
 }
 
+#ifdef CONFIG_PM
+
+/*
+ * Restore the MMC host context, if it was lost as result of a
+ * power state change.
+ */
+static int omap_mmc_restore_ctx(struct mmc_omap_host *host)
+{
+   struct mmc_ios *ios = host-mmc-ios;
+   struct omap_mmc_platform_data *pdata = host-pdata;
+   int context_loss = 0;
+   u32 hctl, capa, con;
+   u16 dsor = 0;
+   unsigned long timeout;
+
+   if (pdata-get_context_loss_count) {
+   context_loss = pdata-get_context_loss_count(host-dev);
+   if (context_loss  0)
+   return 1;
+   }
+
+   dev_dbg(mmc_dev(host-mmc), context was %slost\n,
+   context_loss == host-context_loss ? not  : );
+   if (host-context_loss == context_loss)
+   return 1;
+
+   /* Wait for hardware reset */
+   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+   while ((OMAP_HSMMC_READ(host-base, SYSSTATUS)  RESETDONE) != RESETDONE
+time_before(jiffies, timeout))
+   ;
+
+   /* Do software reset */
+   OMAP_HSMMC_WRITE(host-base, SYSCONFIG, SOFTRESET);
+   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+   while ((OMAP_HSMMC_READ(host-base, SYSSTATUS)  RESETDONE) != RESETDONE
+time_before(jiffies, timeout))
+   ;
+
+   OMAP_HSMMC_WRITE(host-base, SYSCONFIG,
+   OMAP_HSMMC_READ(host-base, SYSCONFIG) | AUTOIDLE);
+
+   if (host-id == OMAP_MMC1_DEVID) {
+   if (host-power_mode != MMC_POWER_OFF 
+   (1  ios-vdd) = MMC_VDD_23_24)
+   hctl = SDVS18;
+   else
+   hctl = SDVS30;
+   capa = VS30 | VS18;
+   } else {
+   hctl = SDVS18;
+   capa = VS18;
+   }
+
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL) | hctl);
+
+   OMAP_HSMMC_WRITE(host-base, CAPA,
+   OMAP_HSMMC_READ(host-base, CAPA) | capa);
+
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL) | SDBP);
+
+   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+   while ((OMAP_HSMMC_READ(host-base, HCTL)  SDBP) != SDBP
+time_before(jiffies, timeout))
+   ;
+
+   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+   OMAP_HSMMC_WRITE(host-base, ISE, INT_EN_MASK);
+   OMAP_HSMMC_WRITE(host-base, IE, INT_EN_MASK);
+
+   /* Do not initialize card-specific things if the power is off */
+   if (host-power_mode == MMC_POWER_OFF)
+   goto out;
+
+   con = OMAP_HSMMC_READ(host-base, CON);
+   switch (ios-bus_width) {
+   case MMC_BUS_WIDTH_8:
+   OMAP_HSMMC_WRITE(host-base, CON, con | DW8);
+   break;
+   case MMC_BUS_WIDTH_4:
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL) | FOUR_BIT);
+   break;
+   case MMC_BUS_WIDTH_1:
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL)  ~FOUR_BIT);
+   

[PATCH V3 14/30] omap_hsmmc: ensure workqueues are empty before suspend

2009-09-09 Thread Adrian Hunter
From f97476c2395ae2a5003957caaf4897f43327e1dd Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Fri, 24 Apr 2009 13:13:20 +0300
Subject: [PATCH] omap_hsmmc: ensure workqueues are empty before suspend

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   50 +++-
 1 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e0b9c49..041af02 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -149,7 +149,6 @@ struct mmc_omap_host {
u32 bytesleft;
int suspended;
int irq;
-   int carddetect;
int use_dma, dma_ch;
int dma_line_tx, dma_line_rx;
int slot_id;
@@ -754,14 +753,19 @@ static void mmc_omap_detect(struct work_struct *work)
struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
mmc_carddetect_work);
struct omap_mmc_slot_data *slot = mmc_slot(host);
+   int carddetect;
+
+   if (host-suspended)
+   return;
+
+   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
if (mmc_slot(host).card_detect)
-   host-carddetect = slot-card_detect(slot-card_detect_irq);
+   carddetect = slot-card_detect(slot-card_detect_irq);
else
-   host-carddetect = -ENOSYS;
+   carddetect = -ENOSYS;
 
-   sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
-   if (host-carddetect) {
+   if (carddetect) {
mmc_detect_change(host-mmc, (HZ * 200) / 1000);
} else {
mmc_host_enable(host-mmc);
@@ -778,6 +782,8 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void 
*dev_id)
 {
struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;
 
+   if (host-suspended)
+   return IRQ_HANDLED;
schedule_work(host-mmc_carddetect_work);
 
return IRQ_HANDLED;
@@ -1517,30 +1523,42 @@ static int omap_mmc_suspend(struct platform_device 
*pdev, pm_message_t state)
return 0;
 
if (host) {
+   host-suspended = 1;
+   if (host-pdata-suspend) {
+   ret = host-pdata-suspend(pdev-dev,
+   host-slot_id);
+   if (ret) {
+   dev_dbg(mmc_dev(host-mmc),
+   Unable to handle MMC board
+level suspend\n);
+   host-suspended = 0;
+   return ret;
+   }
+   }
+   cancel_work_sync(host-mmc_carddetect_work);
mmc_host_enable(host-mmc);
ret = mmc_suspend_host(host-mmc, state);
if (ret == 0) {
-   host-suspended = 1;
-
OMAP_HSMMC_WRITE(host-base, ISE, 0);
OMAP_HSMMC_WRITE(host-base, IE, 0);
 
-   if (host-pdata-suspend) {
-   ret = host-pdata-suspend(pdev-dev,
-   host-slot_id);
-   if (ret)
-   dev_dbg(mmc_dev(host-mmc),
-   Unable to handle MMC board
-level suspend\n);
-   }
 
OMAP_HSMMC_WRITE(host-base, HCTL,
 OMAP_HSMMC_READ(host-base, HCTL)  
~SDBP);
mmc_host_disable(host-mmc);
clk_disable(host-iclk);
clk_disable(host-dbclk);
-   } else
+   } else {
+   host-suspended = 0;
+   if (host-pdata-resume) {
+   ret = host-pdata-resume(pdev-dev,
+ host-slot_id);
+   if (ret)
+   dev_dbg(mmc_dev(host-mmc),
+   Unmask interrupt failed\n);
+   }
mmc_host_disable(host-mmc);
+   }
 
}
return ret;
-- 
1.5.6.3

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


[PATCH V3 15/30] omap_hsmmc: fix scatter-gather list sanity checking

2009-09-09 Thread Adrian Hunter
From fff912de41b3c8b5036aaa4d8ac6762efac533f0 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen jarkko.lavi...@nokia.com
Date: Fri, 24 Apr 2009 14:20:43 +0300
Subject: [PATCH] omap_hsmmc: fix scatter-gather list sanity checking

Do not use host-dma_len when it is uninitialzed.
Finish the request with an error if the mmc_omap_prepare_data()
fails.

Signed-off-by: Jarkko Lavinen jarkko.lavi...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 041af02..df13a54 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -871,7 +871,7 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, 
struct mmc_request *req)
struct mmc_data *data = req-data;
 
/* Sanity check: all the SG entries must be aligned by block size. */
-   for (i = 0; i  host-dma_len; i++) {
+   for (i = 0; i  data-sg_len; i++) {
struct scatterlist *sgl;
 
sgl = data-sg + i;
@@ -1014,10 +1014,20 @@ static int omap_mmc_disable(struct mmc_host *mmc, int 
lazy)
 static void omap_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
 {
struct mmc_omap_host *host = mmc_priv(mmc);
+   int err;
 
WARN_ON(host-mrq != NULL);
host-mrq = req;
-   mmc_omap_prepare_data(host, req);
+   err = mmc_omap_prepare_data(host, req);
+   if (err) {
+   req-cmd-error = err;
+   if (req-data)
+   req-data-error = err;
+   host-mrq = NULL;
+   mmc_request_done(mmc, req);
+   return;
+   }
+
mmc_omap_start_command(host, req-cmd, req-data);
 }
 
-- 
1.5.6.3

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


[PATCH V3 16/30] omap_hsmmc: make use of new MMC_CAP_NONREMOVABLE host capability

2009-09-09 Thread Adrian Hunter
From 4344e2509599b187ff98b5ad8ea0f8dede2d9374 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Mon, 11 May 2009 10:06:38 +0300
Subject: [PATCH] omap_hsmmc: make use of new MMC_CAP_NONREMOVABLE host 
capability

Let the board specify that a card is nonremovable e.g. eMMC

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/mmc-twl4030.c |3 +++
 arch/arm/mach-omap2/mmc-twl4030.h |1 +
 arch/arm/plat-omap/include/mach/mmc.h |3 +++
 drivers/mmc/host/omap_hsmmc.c |3 +++
 4 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mmc-twl4030.c 
b/arch/arm/mach-omap2/mmc-twl4030.c
index 30d0286..56f07f2 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -415,6 +415,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info 
*controllers)
} else
mmc-slots[0].gpio_wp = -EINVAL;
 
+   if (c-nonremovable)
+   mmc-slots[0].nonremovable = 1;
+
/* NOTE:  MMC slots should have a Vcc regulator set up.
 * This may be from a TWL4030-family chip, another
 * controllable regulator, or a fixed supply.
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h 
b/arch/arm/mach-omap2/mmc-twl4030.h
index 3807c45..75b0c64 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.h
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -12,6 +12,7 @@ struct twl4030_hsmmc_info {
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 */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
char*name;  /* or NULL for default */
diff --git a/arch/arm/plat-omap/include/mach/mmc.h 
b/arch/arm/plat-omap/include/mach/mmc.h
index 2f7cf31..bab486c 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -83,6 +83,9 @@ struct omap_mmc_platform_data {
/* use the internal clock */
unsigned internal_clock:1;
 
+   /* nonremovable e.g. eMMC */
+   unsigned nonremovable:1;
+
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
 
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index df13a54..ed35b0d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1383,6 +1383,9 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
else if (pdata-slots[host-slot_id].wires = 4)
mmc-caps |= MMC_CAP_4_BIT_DATA;
 
+   if (pdata-slots[host-slot_id].nonremovable)
+   mmc-caps |= MMC_CAP_NONREMOVABLE;
+
omap_hsmmc_init(host);
 
/* Select DMA lines */
-- 
1.5.6.3

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


[PATCH V3 18/30] ARM: OMAP: mmc-twl4030: add regulator sleep / wake function

2009-09-09 Thread Adrian Hunter
From 1650c5568cd7e4f3bcc3e77ee3a6a3c098e9a23c Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Wed, 8 Jul 2009 13:20:30 +0300
Subject: [PATCH] ARM: OMAP: mmc-twl4030: add regulator sleep / wake function

Add the ability for the driver to put the card power
regulators to sleep and wake them up again.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/mmc-twl4030.c |   57 +
 arch/arm/plat-omap/include/mach/mmc.h |2 +
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mmc-twl4030.c 
b/arch/arm/mach-omap2/mmc-twl4030.c
index cb1cbd7..c9c59a2 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -340,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int 
slot, int power_on, int v
return ret;
 }
 
+static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
+ int cardsleep)
+{
+   struct twl_mmc_controller *c = hsmmc[0];
+   int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+   return regulator_set_mode(c-vcc, mode);
+}
+
+static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int 
vdd,
+  int cardsleep)
+{
+   struct twl_mmc_controller *c = NULL;
+   struct omap_mmc_platform_data *mmc = dev-platform_data;
+   int i, err, mode;
+
+   for (i = 1; i  ARRAY_SIZE(hsmmc); i++) {
+   if (mmc == hsmmc[i].mmc) {
+   c = hsmmc[i];
+   break;
+   }
+   }
+
+   if (c == NULL)
+   return -ENODEV;
+
+   /*
+* If we don't see a Vcc regulator, assume it's a fixed
+* voltage always-on regulator.
+*/
+   if (!c-vcc)
+   return 0;
+
+   mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+   if (!c-vcc_aux)
+   return regulator_set_mode(c-vcc, mode);
+
+   if (cardsleep) {
+   /* VCC can be turned off if card is asleep */
+   struct regulator *vcc_aux = c-vcc_aux;
+
+   c-vcc_aux = NULL;
+   if (sleep)
+   err = twl_mmc23_set_power(dev, slot, 0, 0);
+   else
+   err = twl_mmc23_set_power(dev, slot, 1, vdd);
+   c-vcc_aux = vcc_aux;
+   } else
+   err = regulator_set_mode(c-vcc, mode);
+   if (err)
+   return err;
+   return regulator_set_mode(c-vcc_aux, mode);
+}
+
 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
 
 void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -433,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info 
*controllers)
case 1:
/* on-chip level shifting via PBIAS0/PBIAS1 */
mmc-slots[0].set_power = twl_mmc1_set_power;
+   mmc-slots[0].set_sleep = twl_mmc1_set_sleep;
break;
case 2:
if (c-ext_clock)
@@ -443,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info 
*controllers)
case 3:
/* off-chip level shifting, or none */
mmc-slots[0].set_power = twl_mmc23_set_power;
+   mmc-slots[0].set_sleep = twl_mmc23_set_sleep;
break;
default:
pr_err(MMC%d configuration not supported!\n, c-mmc);
diff --git a/arch/arm/plat-omap/include/mach/mmc.h 
b/arch/arm/plat-omap/include/mach/mmc.h
index 82f1e29..9390297 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -95,6 +95,8 @@ struct omap_mmc_platform_data {
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);
+   int (*set_sleep)(struct device *dev, int slot, int sleep,
+int vdd, int cardsleep);
 
/* return MMC cover switch state, can be NULL if not supported.
 *
-- 
1.5.6.3

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


[PATCH V3 20/30] omap_hsmmc: add mmc card sleep and awake support

2009-09-09 Thread Adrian Hunter
From ea55481d3f16bcc2d7bda941972c722895afc7ee Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen jarkko.lavi...@nokia.com
Date: Tue, 12 May 2009 19:46:14 +0300
Subject: [PATCH] omap_hsmmc: add mmc card sleep and awake support

After 1 second of inactivity, put card and/or regulator
to sleep.  After 8 seconds of inactivity, turn off the
power.

Signed-off-by: Jarkko Lavinen jarkko.lavi...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |  162 ++---
 1 files changed, 88 insertions(+), 74 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index cf6023b..d6bf65b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -27,6 +27,7 @@
 #include linux/timer.h
 #include linux/clk.h
 #include linux/mmc/host.h
+#include linux/mmc/core.h
 #include linux/io.h
 #include linux/semaphore.h
 #include mach/dma.h
@@ -113,7 +114,8 @@
 
 /* Timeouts for entering power saving states on inactivity, msec */
 #define OMAP_MMC_DISABLED_TIMEOUT  100
-#define OMAP_MMC_OFF_TIMEOUT   1000
+#define OMAP_MMC_SLEEP_TIMEOUT 1000
+#define OMAP_MMC_OFF_TIMEOUT   8000
 
 /*
  * One controller can have multiple slots, like on some omap boards using
@@ -1175,20 +1177,21 @@ static void omap_hsmmc_init(struct mmc_omap_host *host)
 
 /*
  * Dynamic power saving handling, FSM:
- *   ENABLED - DISABLED - OFF / REGSLEEP
- * ^___|  |
- * |__|
+ *   ENABLED - DISABLED - CARDSLEEP / REGSLEEP - OFF
+ * ^___|  |  |
+ * |__|__|
  *
  * ENABLED:   mmc host is fully functional
  * DISABLED:  fclk is off
- * OFF:   fclk is off,voltage regulator is off
- * REGSLEEP:  fclk is off,voltage regulator is asleep
+ * CARDSLEEP: fclk is off, card is asleep, voltage regulator is asleep
+ * REGSLEEP:  fclk is off, voltage regulator is asleep
+ * OFF:   fclk is off, voltage regulator is off
  *
  * Transition handlers return the timeout for the next state transition
  * or negative error.
  */
 
-enum {ENABLED = 0, DISABLED, REGSLEEP, OFF};
+enum {ENABLED = 0, DISABLED, CARDSLEEP, REGSLEEP, OFF};
 
 /* Handler for [ENABLED - DISABLED] transition */
 static int omap_mmc_enabled_to_disabled(struct mmc_omap_host *host)
@@ -1202,46 +1205,72 @@ static int omap_mmc_enabled_to_disabled(struct 
mmc_omap_host *host)
if (host-power_mode == MMC_POWER_OFF)
return 0;
 
-   return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT);
+   return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT);
 }
 
-/* Handler for [DISABLED - OFF] transition */
-static int omap_mmc_disabled_to_off(struct mmc_omap_host *host)
+/* Handler for [DISABLED - REGSLEEP / CARDSLEEP] transition */
+static int omap_mmc_disabled_to_sleep(struct mmc_omap_host *host)
 {
-   int new_state;
-
-   dev_dbg(mmc_dev(host-mmc), DISABLED - OFF\n);
+   int err, new_state;
 
if (!mmc_try_claim_host(host-mmc))
return 0;
 
clk_enable(host-fclk);
-
omap_mmc_restore_ctx(host);
+   if (mmc_card_can_sleep(host-mmc)) {
+   err = mmc_card_sleep(host-mmc);
+   if (err  0) {
+   clk_disable(host-fclk);
+   mmc_release_host(host-mmc);
+   return err;
+   }
+   new_state = CARDSLEEP;
+   } else
+   new_state = REGSLEEP;
+   if (mmc_slot(host).set_sleep)
+   mmc_slot(host).set_sleep(host-dev, host-slot_id, 1, 0,
+new_state == CARDSLEEP);
+   /* FIXME: turn off bus power and perhaps interrupts too */
+   clk_disable(host-fclk);
+   host-dpm_state = new_state;
+
+   mmc_release_host(host-mmc);
+
+   dev_dbg(mmc_dev(host-mmc), DISABLED - %s\n,
+   host-dpm_state == CARDSLEEP ? CARDSLEEP : REGSLEEP);
 
if ((host-mmc-caps  MMC_CAP_NONREMOVABLE) ||
mmc_slot(host).card_detect ||
(mmc_slot(host).get_cover_state 
-mmc_slot(host).get_cover_state(host-dev, host-slot_id))) {
-   mmc_power_save_host(host-mmc);
-   new_state = OFF;
-   } else {
-   if (mmc_slot(host).set_sleep)
-   mmc_slot(host).set_sleep(host-dev, host-slot_id,
-1, 0, 0);
-   new_state = REGSLEEP;
+mmc_slot(host).get_cover_state(host-dev, host-slot_id)))
+   return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT);
+
+   return 0;
+}
+
+/* Handler for [REGSLEEP / CARDSLEEP - OFF] transition */
+static int omap_mmc_sleep_to_off(struct mmc_omap_host *host)
+{
+   if (!mmc_try_claim_host(host-mmc))
+   return 0;
+
+   if (!((host-mmc-caps  MMC_CAP_NONREMOVABLE) ||
+ mmc_slot(host).card_detect ||
+

[PATCH V3 21/30] omap_hsmmc: fix NULL pointer dereference

2009-09-09 Thread Adrian Hunter
From bd81dee10c08ae9290c9a6170584549c15bc43d0 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen jarkko.lavi...@nokia.com
Date: Tue, 12 May 2009 19:46:14 +0300
Subject: [PATCH] omap_hsmmc: fix NULL pointer dereference

Do not call 'mmc_omap_xfer_done()' if the request is
already done.

Signed-off-by: Jarkko Lavinen jarkko.lavi...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d6bf65b..243ad97 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -670,7 +670,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 
if (end_cmd || ((status  CC)  host-cmd))
mmc_omap_cmd_done(host, host-cmd);
-   if (end_trans || (status  TC))
+   if ((end_trans || (status  TC))  host-mrq)
mmc_omap_xfer_done(host, data);
 
return IRQ_HANDLED;
-- 
1.5.6.3

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


[PATCH V3 22/30] omap_hsmmc: cleanup macro usage

2009-09-09 Thread Adrian Hunter
From 5f9c3e4511904ff58ab1cf619f35a10cc528a94f Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Thu, 14 May 2009 09:11:38 +0200
Subject: [PATCH] omap_hsmmc: cleanup macro usage

Use macro mmc_slot() in omap_hsmmc.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   42 ++--
 1 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 243ad97..a669757 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -366,9 +366,8 @@ int mmc_omap_cover_is_closed(struct mmc_omap_host *host)
 {
int r = 1;
 
-   if (host-pdata-slots[host-slot_id].get_cover_state)
-   r = host-pdata-slots[host-slot_id].get_cover_state(host-dev,
-   host-slot_id);
+   if (mmc_slot(host).get_cover_state)
+   r = mmc_slot(host).get_cover_state(host-dev, host-slot_id);
return r;
 }
 
@@ -391,9 +390,8 @@ mmc_omap_show_slot_name(struct device *dev, struct 
device_attribute *attr,
 {
struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
struct mmc_omap_host *host = mmc_priv(mmc);
-   struct omap_mmc_slot_data slot = host-pdata-slots[host-slot_id];
 
-   return sprintf(buf, %s\n, slot.name);
+   return sprintf(buf, %s\n, mmc_slot(host).name);
 }
 
 static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -625,7 +623,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
(status  CMD_CRC)) {
if (host-cmd) {
if (status  CMD_TIMEOUT) {
-   mmc_omap_reset_controller_fsm(host, 
SRC);
+   mmc_omap_reset_controller_fsm(host,
+ SRC);
host-cmd-error = -ETIMEDOUT;
} else {
host-cmd-error = -EILSEQ;
@@ -768,7 +767,7 @@ static void mmc_omap_detect(struct work_struct *work)
 
sysfs_notify(host-mmc-class_dev.kobj, NULL, cover_switch);
 
-   if (mmc_slot(host).card_detect)
+   if (slot-card_detect)
carddetect = slot-card_detect(slot-card_detect_irq);
else
carddetect = -ENOSYS;
@@ -823,7 +822,7 @@ static void mmc_omap_config_dma_params(struct mmc_omap_host 
*host,
sg_dma_address(sgl), 0, 0);
} else {
omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-   (host-mapbase + OMAP_HSMMC_DATA), 0, 
0);
+   (host-mapbase + OMAP_HSMMC_DATA), 0, 0);
omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
sg_dma_address(sgl), 0, 0);
}
@@ -911,7 +910,7 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, 
struct mmc_request *req)
}
 
ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), MMC/SD,
-  mmc_omap_dma_cb,host, dma_ch);
+  mmc_omap_dma_cb, host, dma_ch);
if (ret != 0) {
dev_err(mmc_dev(host-mmc),
%s: omap_request_dma() failed with %d\n,
@@ -1131,21 +1130,19 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
 static int omap_hsmmc_get_cd(struct mmc_host *mmc)
 {
struct mmc_omap_host *host = mmc_priv(mmc);
-   struct omap_mmc_platform_data *pdata = host-pdata;
 
-   if (!pdata-slots[0].card_detect)
+   if (!mmc_slot(host).card_detect)
return -ENOSYS;
-   return pdata-slots[0].card_detect(pdata-slots[0].card_detect_irq);
+   return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq);
 }
 
 static int omap_hsmmc_get_ro(struct mmc_host *mmc)
 {
struct mmc_omap_host *host = mmc_priv(mmc);
-   struct omap_mmc_platform_data *pdata = host-pdata;
 
-   if (!pdata-slots[0].get_ro)
+   if (!mmc_slot(host).get_ro)
return -ENOSYS;
-   return pdata-slots[0].get_ro(host-dev, 0);
+   return mmc_slot(host).get_ro(host-dev, 0);
 }
 
 static void omap_hsmmc_init(struct mmc_omap_host *host)
@@ -1556,7 +1553,7 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
platform_set_drvdata(pdev, host);
INIT_WORK(host-mmc_carddetect_work, mmc_omap_detect);
 
-   if (pdata-slots[host-slot_id].power_saving)
+   if (mmc_slot(host).power_saving)
mmc-ops= mmc_omap_ps_ops;
else
mmc-ops= mmc_omap_ops;
@@ -1626,12 +1623,12 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
mmc-caps |= MMC_CAP_MMC_HIGHSPEED 

[PATCH V3 23/30] omap_hsmmc: clear interrupt status after init sequence

2009-09-09 Thread Adrian Hunter
From 8cd514349f0a383b8e59172067ac4a3a8829b907 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Sat, 16 May 2009 09:35:17 +0300
Subject: [PATCH] omap_hsmmc: clear interrupt status after init sequence

Clear the interrupt status after sending the initialization sequence,
as specified in the TRM.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a669757..42f3aad 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -358,6 +358,10 @@ static void send_init_stream(struct mmc_omap_host *host)
 
OMAP_HSMMC_WRITE(host-base, CON,
OMAP_HSMMC_READ(host-base, CON)  ~INIT_STREAM);
+
+   OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
+   OMAP_HSMMC_READ(host-base, STAT);
+
enable_irq(host-irq);
 }
 
-- 
1.5.6.3

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


[PATCH V3 17/30] omap_hsmmc: support for deeper power saving states

2009-09-09 Thread Adrian Hunter
From 2323c5463bab8e67ad3b6210eab91f2151fc72c0 Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Mon, 11 May 2009 14:41:30 +0300
Subject: [PATCH] omap_hsmmc: support for deeper power saving states

Support for multi-level dynamic power saving states in omap_hsmmc
(ENABLED-DISABLED-OFF).
In the deepest state (OFF) we switch off the voltage regulators.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/mmc-twl4030.c |3 +
 arch/arm/mach-omap2/mmc-twl4030.h |1 +
 arch/arm/plat-omap/include/mach/mmc.h |3 +
 drivers/mmc/host/omap_hsmmc.c |  245 +
 4 files changed, 222 insertions(+), 30 deletions(-)

diff --git a/arch/arm/mach-omap2/mmc-twl4030.c 
b/arch/arm/mach-omap2/mmc-twl4030.c
index 56f07f2..cb1cbd7 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -418,6 +418,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info 
*controllers)
if (c-nonremovable)
mmc-slots[0].nonremovable = 1;
 
+   if (c-power_saving)
+   mmc-slots[0].power_saving = 1;
+
/* NOTE:  MMC slots should have a Vcc regulator set up.
 * This may be from a TWL4030-family chip, another
 * controllable regulator, or a fixed supply.
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h 
b/arch/arm/mach-omap2/mmc-twl4030.h
index 75b0c64..a47e685 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.h
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -13,6 +13,7 @@ struct twl4030_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 */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
char*name;  /* or NULL for default */
diff --git a/arch/arm/plat-omap/include/mach/mmc.h 
b/arch/arm/plat-omap/include/mach/mmc.h
index bab486c..82f1e29 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -86,6 +86,9 @@ struct omap_mmc_platform_data {
/* nonremovable e.g. eMMC */
unsigned nonremovable:1;
 
+   /* Try to sleep or power off when possible */
+   unsigned power_saving:1;
+
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
 
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index ed35b0d..acb7a78 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -111,6 +111,10 @@
 #define OMAP_MMC_MASTER_CLOCK  9600
 #define DRIVER_NAMEmmci-omap-hs
 
+/* Timeouts for entering power saving states on inactivity, msec */
+#define OMAP_MMC_DISABLED_TIMEOUT  100
+#define OMAP_MMC_OFF_TIMEOUT   1000
+
 /*
  * 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
@@ -155,6 +159,7 @@ struct mmc_omap_host {
int dbclk_enabled;
int response_busy;
int context_loss;
+   int dpm_state;
 
struct  omap_mmc_platform_data  *pdata;
 };
@@ -985,29 +990,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct 
mmc_request *req)
return 0;
 }
 
-static int omap_mmc_enable(struct mmc_host *mmc)
-{
-   struct mmc_omap_host *host = mmc_priv(mmc);
-   int err;
-
-   err = clk_enable(host-fclk);
-   if (err)
-   return err;
-   dev_dbg(mmc_dev(host-mmc), mmc_fclk: enabled\n);
-   omap_mmc_restore_ctx(host);
-   return 0;
-}
-
-static int omap_mmc_disable(struct mmc_host *mmc, int lazy)
-{
-   struct mmc_omap_host *host = mmc_priv(mmc);
-
-   omap_mmc_save_ctx(host);
-   clk_disable(host-fclk);
-   dev_dbg(mmc_dev(host-mmc), mmc_fclk: disabled\n);
-   return 0;
-}
-
 /*
  * Request function. for read/write operation
  */
@@ -1061,6 +1043,8 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
host-power_mode = ios-power_mode;
}
 
+   /* FIXME: set registers based only on changes to ios */
+
con = OMAP_HSMMC_READ(host-base, CON);
switch (mmc-ios.bus_width) {
case MMC_BUS_WIDTH_8:
@@ -1133,7 +1117,10 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
else
OMAP_HSMMC_WRITE(host-base, CON, con  ~OD);
 
-   mmc_host_lazy_disable(host-mmc);
+   if (host-power_mode == MMC_POWER_OFF)
+   

[PATCH V3 24/30] omap_hsmmc: cater for weird CMD6 behaviour

2009-09-09 Thread Adrian Hunter
From 60731c064681d57c84ce563274f3f5869c598cce Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Sat, 16 May 2009 10:05:40 +0300
Subject: [PATCH] omap_hsmmc: cater for weird CMD6 behaviour

Sometimes the controller unexpectedly produces a TC (transfer
complete) interrupt before the CC (command complete) interrupt for
command 6 (SWITCH).  This is a problem because the CC interrupt
can get mixed up with the next request.  Add a hack for CMD6.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 42f3aad..205cc3a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -474,6 +474,13 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct 
mmc_data *data)
if (!data) {
struct mmc_request *mrq = host-mrq;
 
+   /* TC before CC from CMD6 - don't know why, but it happens */
+   if (host-cmd  host-cmd-opcode == 6 
+   host-response_busy) {
+   host-response_busy = 0;
+   return;
+   }
+
host-mrq = NULL;
mmc_request_done(host-mmc, mrq);
return;
-- 
1.5.6.3

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


[PATCH V3 28/30] omap_hsmmc: ensure all clock enables and disables are paired

2009-09-09 Thread Adrian Hunter
From baf6574a1b5e7c4fdc4a66d9e038efeee75ea1a0 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Sun, 31 May 2009 19:27:36 +0300
Subject: [PATCH] omap_hsmmc: ensure all clock enables and disables are paired

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   26 ++
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 047e656..64780da 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -735,22 +735,24 @@ static int omap_hsmmc_switch_opcond(struct 
omap_hsmmc_host *host, int vdd)
/* Disable the clocks */
clk_disable(host-fclk);
clk_disable(host-iclk);
-   clk_disable(host-dbclk);
+   if (host-dbclk_enabled)
+   clk_disable(host-dbclk);
 
/* Turn the power off */
ret = mmc_slot(host).set_power(host-dev, host-slot_id, 0, 0);
-   if (ret != 0)
-   goto err;
 
/* Turn the power ON with given VDD 1.8 or 3.0v */
-   ret = mmc_slot(host).set_power(host-dev, host-slot_id, 1, vdd);
+   if (!ret)
+   ret = mmc_slot(host).set_power(host-dev, host-slot_id, 1,
+  vdd);
+   clk_enable(host-iclk);
+   if (host-dbclk_enabled)
+   clk_enable(host-dbclk);
+   clk_enable(host-fclk);
+
if (ret != 0)
goto err;
 
-   clk_enable(host-fclk);
-   clk_enable(host-iclk);
-   clk_enable(host-dbclk);
-
OMAP_HSMMC_WRITE(host-base, HCTL,
OMAP_HSMMC_READ(host-base, HCTL)  SDVSCLR);
reg_val = OMAP_HSMMC_READ(host-base, HCTL);
@@ -1898,7 +1900,8 @@ static int omap_hsmmc_suspend(struct platform_device 
*pdev, pm_message_t state)
OMAP_HSMMC_READ(host-base, HCTL)  ~SDBP);
mmc_host_disable(host-mmc);
clk_disable(host-iclk);
-   clk_disable(host-dbclk);
+   if (host-dbclk_enabled)
+   clk_disable(host-dbclk);
} else {
host-suspended = 0;
if (host-pdata-resume) {
@@ -1929,9 +1932,8 @@ static int omap_hsmmc_resume(struct platform_device *pdev)
if (ret)
goto clk_en_err;
 
-   if (clk_enable(host-dbclk) != 0)
-   dev_dbg(mmc_dev(host-mmc),
-   Enabling debounce clk failed\n);
+   if (host-dbclk_enabled)
+   clk_enable(host-dbclk);
 
if (mmc_host_enable(host-mmc) != 0) {
clk_disable(host-iclk);
-- 
1.5.6.3

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


[PATCH V3 26/30] omap_hsmmc: code refactoring

2009-09-09 Thread Adrian Hunter
From 4bb38c80322897aba471fe50d0e6e9d774edbe96 Mon Sep 17 00:00:00 2001
From: Denis Karpov ext-denis.2.kar...@nokia.com
Date: Mon, 18 May 2009 13:29:18 +0300
Subject: [PATCH] omap_hsmmc: code refactoring

Functions', structures', variables' names are changed to start
with omap_hsmmc_ prefix.

Signed-off-by: Denis Karpov ext-denis.2.kar...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |  322 +
 1 files changed, 162 insertions(+), 160 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 50c7f94..4249723 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -133,7 +133,7 @@
 #define OMAP_HSMMC_WRITE(base, reg, val) \
__raw_writel((val), (base) + OMAP_HSMMC_##reg)
 
-struct mmc_omap_host {
+struct omap_hsmmc_host {
struct  device  *dev;
struct  mmc_host*mmc;
struct  mmc_request *mrq;
@@ -172,7 +172,7 @@ struct mmc_omap_host {
 /*
  * Stop clock to the card
  */
-static void omap_mmc_stop_clock(struct mmc_omap_host *host)
+static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
 {
OMAP_HSMMC_WRITE(host-base, SYSCTL,
OMAP_HSMMC_READ(host-base, SYSCTL)  ~CEN);
@@ -186,7 +186,7 @@ static void omap_mmc_stop_clock(struct mmc_omap_host *host)
  * Restore the MMC host context, if it was lost as result of a
  * power state change.
  */
-static int omap_mmc_restore_ctx(struct mmc_omap_host *host)
+static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
 {
struct mmc_ios *ios = host-mmc-ios;
struct omap_mmc_platform_data *pdata = host-pdata;
@@ -314,7 +314,7 @@ out:
 /*
  * Save the MMC host context (store the number of power state changes so far).
  */
-static void omap_mmc_save_ctx(struct mmc_omap_host *host)
+static void omap_hsmmc_context_save(struct omap_hsmmc_host *host)
 {
struct omap_mmc_platform_data *pdata = host-pdata;
int context_loss;
@@ -329,12 +329,12 @@ static void omap_mmc_save_ctx(struct mmc_omap_host *host)
 
 #else
 
-static int omap_mmc_restore_ctx(struct mmc_omap_host *host)
+static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
 {
return 0;
 }
 
-static void omap_mmc_save_ctx(struct mmc_omap_host *host)
+static void omap_hsmmc_context_save(struct omap_hsmmc_host *host)
 {
 }
 
@@ -344,7 +344,7 @@ static void omap_mmc_save_ctx(struct mmc_omap_host *host)
  * Send init stream sequence to card
  * before sending IDLE command
  */
-static void send_init_stream(struct mmc_omap_host *host)
+static void send_init_stream(struct omap_hsmmc_host *host)
 {
int reg = 0;
unsigned long timeout;
@@ -368,7 +368,7 @@ static void send_init_stream(struct mmc_omap_host *host)
 }
 
 static inline
-int mmc_omap_cover_is_closed(struct mmc_omap_host *host)
+int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host)
 {
int r = 1;
 
@@ -378,35 +378,35 @@ int mmc_omap_cover_is_closed(struct mmc_omap_host *host)
 }
 
 static ssize_t
-mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
+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 mmc_omap_host *host = mmc_priv(mmc);
+   struct omap_hsmmc_host *host = mmc_priv(mmc);
 
-   return sprintf(buf, %s\n, mmc_omap_cover_is_closed(host) ? closed :
-  open);
+   return sprintf(buf, %s\n,
+   omap_hsmmc_cover_is_closed(host) ? closed : open);
 }
 
-static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
+static DEVICE_ATTR(cover_switch, S_IRUGO, omap_hsmmc_show_cover_switch, NULL);
 
 static ssize_t
-mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
+omap_hsmmc_show_slot_name(struct device *dev, struct device_attribute *attr,
char *buf)
 {
struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
-   struct mmc_omap_host *host = mmc_priv(mmc);
+   struct omap_hsmmc_host *host = mmc_priv(mmc);
 
return sprintf(buf, %s\n, mmc_slot(host).name);
 }
 
-static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
+static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL);
 
 /*
  * Configure the response type and send the cmd.
  */
 static void
-mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
+omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
struct mmc_data *data)
 {
int cmdreg = 0, resptype = 0, cmdtype = 0;
@@ -467,7 +467,7 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct 
mmc_command *cmd,
 }
 
 static int
-mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)

[PATCH V3 27/30] omap_hsmmc: protect the card when the cover is open

2009-09-09 Thread Adrian Hunter
From bed30ea9b2f8c88199578df12faca269c0c5a91b Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Fri, 22 May 2009 16:53:49 +0300
Subject: [PATCH] omap_hsmmc: protect the card when the cover is open

Depending on the manufacturer, there is a small possibility that
removing a card while it is being written to, can render the
card permanently unusable.  To prevent that, the card is made
inaccessible when the cover is open.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   63 +++-
 1 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4249723..047e656 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -165,6 +165,8 @@ struct omap_hsmmc_host {
int context_loss;
int dpm_state;
int vdd;
+   int protect_card;
+   int reqs_blocked;
 
struct  omap_mmc_platform_data  *pdata;
 };
@@ -349,6 +351,9 @@ static void send_init_stream(struct omap_hsmmc_host *host)
int reg = 0;
unsigned long timeout;
 
+   if (host-protect_card)
+   return;
+
disable_irq(host-irq);
OMAP_HSMMC_WRITE(host-base, CON,
OMAP_HSMMC_READ(host-base, CON) | INIT_STREAM);
@@ -779,6 +784,30 @@ 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) {
+   printk(KERN_INFO %s: cover is closed, 
+card is now accessible\n,
+mmc_hostname(host-mmc));
+   host-protect_card = 0;
+   }
+   } else {
+   if (!host-protect_card) {
+   printk(KERN_INFO %s: cover is open, 
+card is now inaccessible\n,
+mmc_hostname(host-mmc));
+   host-protect_card = 1;
+   }
+   }
+}
+
 /*
  * Work Item to notify the core about card insertion/removal
  */
@@ -796,8 +825,10 @@ static void omap_hsmmc_detect(struct work_struct *work)
 
if (slot-card_detect)
carddetect = slot-card_detect(slot-card_detect_irq);
-   else
+   else {
+   omap_hsmmc_protect_card(host);
carddetect = -ENOSYS;
+   }
 
if (carddetect) {
mmc_detect_change(host-mmc, (HZ * 200) / 1000);
@@ -1033,8 +1064,32 @@ static void omap_hsmmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
 * interrupts, but not if we are already in interrupt context i.e.
 * retries.
 */
-   if (!in_interrupt())
+   if (!in_interrupt()) {
spin_lock_irqsave(host-irq_lock, host-flags);
+   /*
+* Protect the card from I/O if there is a possibility
+* it can be removed.
+*/
+   if (host-protect_card) {
+   if (host-reqs_blocked  3) {
+   /*
+* Ensure the controller is left in a consistent
+* state by resetting the command and data state
+* machines.
+*/
+   omap_hsmmc_reset_controller_fsm(host, SRD);
+   omap_hsmmc_reset_controller_fsm(host, SRC);
+   host-reqs_blocked += 1;
+   }
+   req-cmd-error = -EBADF;
+   if (req-data)
+   req-data-error = -EBADF;
+   spin_unlock_irqrestore(host-irq_lock, host-flags);
+   mmc_request_done(mmc, req);
+   return;
+   } else if (host-reqs_blocked)
+   host-reqs_blocked = 0;
+   }
WARN_ON(host-mrq != NULL);
host-mrq = req;
err = omap_hsmmc_prepare_data(host, req);
@@ -1725,6 +1780,8 @@ static int __init omap_hsmmc_probe(struct platform_device 
*pdev)
 
mmc_host_lazy_disable(host-mmc);
 
+   omap_hsmmc_protect_card(host);
+
mmc_add_host(mmc);
 
if (mmc_slot(host).name != NULL) {
@@ -1890,6 +1947,8 @@ static int omap_hsmmc_resume(struct platform_device *pdev)
Unmask interrupt failed\n);
}
 
+   omap_hsmmc_protect_card(host);
+
/* Notify the core to 

[PATCH V3 25/30] omap_hsmmc: prevent races with irq handler

2009-09-09 Thread Adrian Hunter
From 8dc8e911b67f5c77e95c203908ff2ad7ce728b13 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Sat, 16 May 2009 10:32:34 +0300
Subject: [PATCH] omap_hsmmc: prevent races with irq handler

If an unexpected interrupt occurs while preparing the
next request, an oops can occur.

For example, a new request is setting up DMA for data
transfer so host-data is not NULL.  An unexpected
transfer complete (TC) interrupt comes along and
the interrupt handler sets host-data to NULL.  Oops!

Prevent that by adding a spinlock.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   25 +
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 205cc3a..50c7f94 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -146,6 +146,8 @@ struct mmc_omap_host {
struct  work_struct mmc_carddetect_work;
void__iomem *base;
resource_size_t mapbase;
+   spinlock_t  irq_lock; /* Prevent races with irq handler */
+   unsigned long   flags;
unsigned intid;
unsigned intdma_len;
unsigned intdma_sg_idx;
@@ -452,6 +454,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct 
mmc_command *cmd,
if (host-use_dma)
cmdreg |= DMA_EN;
 
+   /*
+* In an interrupt context (i.e. STOP command), the spinlock is unlocked
+* by the interrupt handler, otherwise (i.e. for a new request) it is
+* unlocked here.
+*/
+   if (!in_interrupt())
+   spin_unlock_irqrestore(host-irq_lock, host-flags);
+
OMAP_HSMMC_WRITE(host-base, ARG, cmd-arg);
OMAP_HSMMC_WRITE(host-base, CMD, cmdreg);
 }
@@ -614,11 +624,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
struct mmc_data *data;
int end_cmd = 0, end_trans = 0, status;
 
+   spin_lock(host-irq_lock);
+
if (host-mrq == NULL) {
OMAP_HSMMC_WRITE(host-base, STAT,
OMAP_HSMMC_READ(host-base, STAT));
/* Flush posted write */
OMAP_HSMMC_READ(host-base, STAT);
+   spin_unlock(host-irq_lock);
return IRQ_HANDLED;
}
 
@@ -683,6 +696,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
if ((end_trans || (status  TC))  host-mrq)
mmc_omap_xfer_done(host, data);
 
+   spin_unlock(host-irq_lock);
+
return IRQ_HANDLED;
 }
 
@@ -1011,6 +1026,13 @@ static void omap_mmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
struct mmc_omap_host *host = mmc_priv(mmc);
int err;
 
+   /*
+* Prevent races with the interrupt handler because of unexpected
+* interrupts, but not if we are already in interrupt context i.e.
+* retries.
+*/
+   if (!in_interrupt())
+   spin_lock_irqsave(host-irq_lock, host-flags);
WARN_ON(host-mrq != NULL);
host-mrq = req;
err = mmc_omap_prepare_data(host, req);
@@ -1019,6 +1041,8 @@ static void omap_mmc_request(struct mmc_host *mmc, struct 
mmc_request *req)
if (req-data)
req-data-error = err;
host-mrq = NULL;
+   if (!in_interrupt())
+   spin_unlock_irqrestore(host-irq_lock, host-flags);
mmc_request_done(mmc, req);
return;
}
@@ -1573,6 +1597,7 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
mmc-f_max  = 5200;
 
sema_init(host-sem, 1);
+   spin_lock_init(host-irq_lock);
 
host-iclk = clk_get(pdev-dev, ick);
if (IS_ERR(host-iclk)) {
-- 
1.5.6.3

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


[PATCH V3 30/30] ARM: OMAP: RX51: set MMC capabilities and power-saving flag

2009-09-09 Thread Adrian Hunter
From 165355201788f4efc00c37774070d8b9960e9b70 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Fri, 10 Jul 2009 10:32:44 +0300
Subject: [PATCH] ARM: OMAP: RX51: set MMC capabilities and power-saving flag

Specify MMC capabilities and set the power-saving flag
for RX51.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/board-rx51-peripherals.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 56d931a..4ce5a76 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -19,6 +19,7 @@
 #include linux/delay.h
 #include linux/regulator/machine.h
 #include linux/gpio.h
+#include linux/mmc/host.h
 
 #include mach/mcspi.h
 #include mach/mux.h
@@ -102,6 +103,7 @@ static struct twl4030_hsmmc_info mmc[] = {
.cover_only = true,
.gpio_cd= 160,
.gpio_wp= -EINVAL,
+   .power_saving   = true,
},
{
.name   = internal,
@@ -109,6 +111,8 @@ static struct twl4030_hsmmc_info mmc[] = {
.wires  = 8,
.gpio_cd= -EINVAL,
.gpio_wp= -EINVAL,
+   .nonremovable   = true,
+   .power_saving   = true,
},
{}  /* Terminator */
 };
-- 
1.5.6.3

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


[PATCH V3 29/30] omap_hsmmc: set a large data timeout for commands with busy signal

2009-09-09 Thread Adrian Hunter
From c85a80da2efe181ff256074f7bcd9099428f2572 Mon Sep 17 00:00:00 2001
From: Adrian Hunter adrian.hun...@nokia.com
Date: Fri, 26 Jun 2009 11:29:20 +0300
Subject: [PATCH] omap_hsmmc: set a large data timeout for commands with busy 
signal

Commands like SWITCH (CMD6) send a response and then signal busy
while the operation is completed.  These commands are expected
to always succeed (otherwise the response would have indicated an
error).

Set an arbitrarily large data timeout value (100ms) for these commands
to ensure that premature timeouts do not occur.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   15 +++
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 64780da..b54f3e3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -990,7 +990,8 @@ static int omap_hsmmc_start_dma_transfer(struct 
omap_hsmmc_host *host,
 }
 
 static void set_data_timeout(struct omap_hsmmc_host *host,
-struct mmc_request *req)
+unsigned int timeout_ns,
+unsigned int timeout_clks)
 {
unsigned int timeout, cycle_ns;
uint32_t reg, clkd, dto = 0;
@@ -1001,8 +1002,8 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
clkd = 1;
 
cycle_ns = 10 / (clk_get_rate(host-fclk) / clkd);
-   timeout = req-data-timeout_ns / cycle_ns;
-   timeout += req-data-timeout_clks;
+   timeout = timeout_ns / cycle_ns;
+   timeout += timeout_clks;
if (timeout) {
while ((timeout  0x8000) == 0) {
dto += 1;
@@ -1036,12 +1037,18 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, 
struct mmc_request *req)
 
if (req-data == NULL) {
OMAP_HSMMC_WRITE(host-base, BLK, 0);
+   /*
+* Set an arbitrary 100ms data timeout for commands with
+* busy signal.
+*/
+   if (req-cmd-flags  MMC_RSP_BUSY)
+   set_data_timeout(host, 1U, 0);
return 0;
}
 
OMAP_HSMMC_WRITE(host-base, BLK, (req-data-blksz)
| (req-data-blocks  16));
-   set_data_timeout(host, req);
+   set_data_timeout(host, req-data-timeout_ns, req-data-timeout_clks);
 
if (host-use_dma) {
ret = omap_hsmmc_start_dma_transfer(host, req);
-- 
1.5.6.3

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


Re: [PATCH]PM: Initialization of SDRC params for DVFS on Zoom2

2009-09-09 Thread Jean Pihet
On Wednesday 09 September 2009 00:17:42 Kevin Hilman wrote:
 Reddy, Teerth tee...@ti.com writes:
  This patch initializes the SDRC params for DVFS on Zoom2.
 
  Signed-off-by: Teerth Reddy tee...@ti.com
  ---
   arch/arm/mach-omap2/board-zoom2.c |6 --
   1 files changed, 4 insertions(+), 2 deletions(-)
 
  Index: linux-omap-pm/arch/arm/mach-omap2/board-zoom2.c
  ===
  --- linux-omap-pm.orig/arch/arm/mach-omap2/board-zoom2.c
  +++ linux-omap-pm/arch/arm/mach-omap2/board-zoom2.c
  @@ -23,6 +23,7 @@
 
   #include mmc-twl4030.h
   #include omap3-opp.h
  +#include sdram-micron-mt46h32m32lf-6.h
 
   static struct omap_uart_config zoom2_uart_config __initdata = {
  .enabled_uarts  = ((1  0) | (1  1) | (1  2)),
  @@ -36,8 +37,9 @@ static void __init omap_zoom2_init_irq(v
   {
  omap_board_config = zoom2_config;
  omap_board_config_size = ARRAY_SIZE(zoom2_config);
  -   omap2_init_common_hw(NULL, NULL, omap3_mpu_rate_table,
  -omap3_dsp_rate_table, omap3_l3_rate_table);
  +   omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL,
  +   omap3_mpu_rate_table, omap3_dsp_rate_table,
  +   omap3_l3_rate_table);

 Not having looked at the Zoom2 schematics, are you sure this is only
 using a single chip select?  The other boards using the same part
 (beagle, overo) are interfacing to this part using both CSes.

 Have you tested DVFS on Zoom2 using the full 256Mb?
Good point!

DVFS works fine using the two chip selects:
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 mt46h32m32lf6_sdrc_params,
 omap3_mpu_rate_table,
 omap3_dsp_rate_table,
 omap3_l3_rate_table);

One remark though: since the memory chips are popped on top of the OMAP chip 
the schematics are not showing the chip selects connections. In any case 
U-Boot is configuring the SDRC module to use the 2 chip selects, so I think 
this change is needed.

We need confirmation. Anyone from TI knows?

Regards,
Jean


 Kevin

  omap_init_irq();
  omap_gpio_init();
   }

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


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


Re: several OMAP newbie questions

2009-09-09 Thread Mike Rapoport


Cliff Brake wrote:
 On Tue, Sep 1, 2009 at 6:34 AM, Mike Rapoportm...@compulab.co.il wrote:
 
 3) If I'm not much mistaken, board specific pin mux configuration has to deal
 with arch/arm/plat-omap/include/mach/mux.h and arch/arm/mach-omap2/mux.c. For
 instance, if my board uses ULPI pins that have not been defined already, I 
 need
 to patch those file with my pin mux definitions. Am I right here, or have I
 missed something?
 
 It seems to me there should be a global mux configuration per CPU, but
 should be configurable per board, group of boards, etc.  What I would
 like is a set of routines can be used to configure the mux that is
 then called by the board files (similar to PXA).

Yeah, I actually was missing pxa_mfp_config()...
The omap34xx_pins seems somewhat sparse...

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

-- 
Sincerely yours,
Mike.

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


Re: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Paul Walmsley
On Tue, 8 Sep 2009, Anand Gadiyar wrote:

 From: Rajendra Nayak rna...@ti.com
 
 OMAP3: Lock DPLL5 at boot
 
 Lock DPLL5 at 120MHz at boot. The USBHOST 120MHz f-clock and
 USBTLL f-clock are the only users of this DPLL, and 120MHz is
 is the only recommended rate for these clocks.
 
 With this patch, the 60 MHz ULPI clock is generated correctly.
 
 Tested on an OMAP3430 SDP.
 
 Signed-off-by: Rajendra Nayak rna...@ti.com
 Signed-off-by: Anand Gadiyar gadi...@ti.com
 ---
 Incorporated all 3 comments by Paul and Benoit. Updated
 $SUBJECT to reflect the change.

Thanks for the changes, I will queue this in a for-next branch for .33.


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


RE: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Pandita, Vikram

Paul

-Original Message-
From: linux-omap-ow...@vger.kernel.org 
[mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of Paul
Walmsley
Sent: Wednesday, September 09, 2009 10:43 AM
To: Gadiyar, Anand
Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; Cousson, Benoit
Subject: Re: [PATCH] OMAP3: Lock DPLL5 at boot

On Tue, 8 Sep 2009, Anand Gadiyar wrote:

 From: Rajendra Nayak rna...@ti.com

 OMAP3: Lock DPLL5 at boot

 Lock DPLL5 at 120MHz at boot. The USBHOST 120MHz f-clock and
 USBTLL f-clock are the only users of this DPLL, and 120MHz is
 is the only recommended rate for these clocks.

 With this patch, the 60 MHz ULPI clock is generated correctly.

 Tested on an OMAP3430 SDP.

 Signed-off-by: Rajendra Nayak rna...@ti.com
 Signed-off-by: Anand Gadiyar gadi...@ti.com
 ---
 Incorporated all 3 comments by Paul and Benoit. Updated
 $SUBJECT to reflect the change.

Thanks for the changes, I will queue this in a for-next branch for .33.

Is this for .33 or .32? 



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

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


RE: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Paul Walmsley
On Wed, 9 Sep 2009, Pandita, Vikram wrote:

 From: linux-omap-ow...@vger.kernel.org 
 [mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of Paul
 Walmsley
  $SUBJECT to reflect the change.
 
 Thanks for the changes, I will queue this in a for-next branch for .33.
 
 Is this for .33 or .32? 

I think it might be a little late for .32.  If there is some crash or 
instability that this fixes, we could queue it up for .32-fixes ?


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


RE: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Gadiyar, Anand
On Wed, 9 Sep 2009, Paul Walmsley wrote:
 On Wed, 9 Sep 2009, Pandita, Vikram wrote:
 
  From: linux-omap-ow...@vger.kernel.org 
  [mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of Paul
  Walmsley
   $SUBJECT to reflect the change.
  
  Thanks for the changes, I will queue this in a for-next branch for .33.
 
  Is this for .33 or .32?
 
 I think it might be a little late for .32.  If there is some crash or
 instability that this fixes, we could queue it up for .32-fixes ?
 

Well, without this, there's no way the child clocks can be enabled correctly.

Possibly it qualifies as a bug-fix in clock framework?

Rajendra had created this patch quite a while ago and it has received
sufficient testing on various codebases - I guess we just missed sending
it out to l-o early enough.

- Anand

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


RE: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Paul Walmsley
On Wed, 9 Sep 2009, Gadiyar, Anand wrote:

 On Wed, 9 Sep 2009, Paul Walmsley wrote:
  On Wed, 9 Sep 2009, Pandita, Vikram wrote:
  
   From: linux-omap-ow...@vger.kernel.org 
   [mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of Paul
   Walmsley
$SUBJECT to reflect the change.
   
   Thanks for the changes, I will queue this in a for-next branch for .33.
  
   Is this for .33 or .32?
  
  I think it might be a little late for .32.  If there is some crash or
  instability that this fixes, we could queue it up for .32-fixes ?
 
 Well, without this, there's no way the child clocks can be enabled correctly.

OK.  So is it the case that USBHOST/USBTLL/USIM won't work without this 
fix?  

If so then we'll queue it for .32-fixes.  Since .32 is already at -rc9, I 
think it is too late for .32.


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


RE: [PATCH] OMAP3: Lock DPLL5 at boot

2009-09-09 Thread Gadiyar, Anand
Thanks for the changes, I will queue this in a for-next branch for .33.
   
Is this for .33 or .32?
  
   I think it might be a little late for .32.  If there is some crash or
   instability that this fixes, we could queue it up for .32-fixes ?
 
  Well, without this, there's no way the child clocks can be enabled 
  correctly.
 
 OK.  So is it the case that USBHOST/USBTLL/USIM won't work without this
 fix?

Yup. Not sure about USIM - will check.

 
 If so then we'll queue it for .32-fixes.  Since .32 is already at -rc9, I
 think it is too late for .32.
 

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


Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8

2009-09-09 Thread Russell King - ARM Linux
On Wed, Sep 09, 2009 at 01:16:48PM +0530, Syed Mohammed, Khasim wrote:
 Hi Russell,
 
  -Original Message-
  From: Russell King - ARM Linux [mailto:li...@arm.linux.org.uk]
  Sent: Wednesday, September 09, 2009 12:47 PM
  To: Syed Mohammed, Khasim
  Cc: Aguirre Rodriguez, Sergio Alberto; Rabin Vincent; linux-arm-
  ker...@lists.arm.linux.org.uk; linux-omap@vger.kernel.org
  Subject: Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8
  
  And how about my revised version, which is the version which is going
  to be merged?
 
 Sorry for missing this out. This works, no issues reported.

And so can I add a:

Tested-by: Khasim Syed Mohammed kha...@ti.com

or is it a just a Reviewed-by: ?
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/07] pm: remove late/early platform driver pm callbacks V2

2009-09-09 Thread Rafael J. Wysocki
On Wednesday 09 September 2009, Dan Williams wrote:
 2009/7/4 Rafael J. Wysocki r...@sisk.pl:
  On Wednesday 24 June 2009, Magnus Damm wrote:
  pm: remove late/early platform driver pm callbacks V2
 
  [PATCH 01/07] arm: rework omap suspend_late()/resume_early()
  [PATCH 02/07] dma: rework dw_dmac suspend_late()/resume_early()
  [PATCH 03/07] dma: rework txx9dmac suspend_late()/resume_early()
  [PATCH 04/07] i2c: rework i2c-pxa suspend_late()/resume_early()
  [PATCH 05/07] i2c: rework i2c-s3c2410 suspend_late()/resume() V2
  [PATCH 06/07] usb: rework musb suspend()/resume_early()
  [PATCH 07/07] pm: remove platform device suspend_late()/resume_early() V2
 
  These patches simply remove -suspend_late() and -resume_early()
  from struct platform_driver. Drivers are converted to dev_pm_ops
  with CONFIG_SUSPEND in mind. Untested.
 
  All patches except [02/07] are known to compile.
 
  Signed-off-by: Magnus Damm d...@igel.co.jp
 [..]
 
  The series is now in the linux-next branch of the suspend-2.6 tree.  I'll 
  move
  it into the for-linus branch, which is not rebased, if the patches are not
  reported to cause any problems in the next few days.
 
 
 Hi,
 
 My linux-next test builds for drivers/dma/ caught a missed conversion
 of the at_hdmac driver.  Please check the attached fix (compile tested
 only) and include it in this series.

Applied to suspend-2.6/linux-next, thanks.

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


RE: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8

2009-09-09 Thread Syed Mohammed, Khasim


 -Original Message-
 From: Russell King - ARM Linux [mailto:li...@arm.linux.org.uk]
 Sent: Thursday, September 10, 2009 12:04 AM
 To: Syed Mohammed, Khasim
 Cc: Aguirre Rodriguez, Sergio Alberto; Rabin Vincent; linux-arm-
 ker...@lists.arm.linux.org.uk; linux-omap@vger.kernel.org
 Subject: Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8
 
 On Wed, Sep 09, 2009 at 01:16:48PM +0530, Syed Mohammed, Khasim wrote:
  Hi Russell,
 
   -Original Message-
   From: Russell King - ARM Linux [mailto:li...@arm.linux.org.uk]
   Sent: Wednesday, September 09, 2009 12:47 PM
   To: Syed Mohammed, Khasim
   Cc: Aguirre Rodriguez, Sergio Alberto; Rabin Vincent; linux-arm-
   ker...@lists.arm.linux.org.uk; linux-omap@vger.kernel.org
   Subject: Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8
  
   And how about my revised version, which is the version which is going
   to be merged?
 
  Sorry for missing this out. This works, no issues reported.
 
 And so can I add a:
 
 Tested-by: Khasim Syed Mohammed kha...@ti.com

I did test this, please add Tested-by.

Thanks,

Regards,
Khasim


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