Re: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu

2009-07-28 Thread Hiroshi DOYU
From: "ext Kanigeri, Hari" 
Subject: RE: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu
Date: Tue, 28 Jul 2009 17:42:21 +0200

> Hi Hiroshi,
> 
> > 
> > This "omap iommu" driver is used in OMAP4 IPC and its interface is a
> > character device node. IOW, the client of this device will be an
> > userland process and kernel won't know if it uses or not, but kernel
> > just provides "/dev/iommu?" for userland. So I don't think that we
> > have to care about the dependency of the existance of clients, at
> > least, for a moment.
> > 
> > >
> The first patch set that I sent is to provide support in IOMMU for OMAP4 just 
> like how it is done in OMAP3 today. The define "CONFIG_MPU_TESLA_IOMMU" is 
> used for now because in the first phase we are planning to use DSP-Bridge to 
> communicate with Tesla (until we move the new user-land IPC to replace 
> DSP-Bridge for OMAP4).
> IMHO, let's go ahead with these changes and any changes to support
> IOMMU from user-land we can address them in next set of patches.

Got it. Let's go for it;) I'll queue them up if you send the updated ones.
--
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] musb: cleanup the nop registration for OMAP3EVM

2009-07-28 Thread Gupta, Ajay Kumar
> On Friday 03 July 2009, Ajay Kumar Gupta wrote:
> > OMAP3EVM uses ISP1504 phy which doesn't require any
> > programming and thus has to use NOP otg transceiver.
> >
> > Cleanups being done:
> > - Remove unwanted code in usb-musb.c file
> > - Register nop in OMAP3EVM board file using
> >   usb_nop_xceiv_register().
> > - Select NOP_USB_XCEIV for OMAP3EVM boards.
> >
> > Signed-off-by: Ajay Kumar Gupta 
> 
> Acked-by: David Brownell 
> 
> ... another for-2.6.31 bugfix.

Greg,

Here is the refreshed version of this patch.

Thanks,
Ajay
 cut here =
OMAP3EVM uses ISP1504 phy which doesn't require any programming and
thus has to use NOP otg transceiver.

Cleanups being done:
- Remove unwanted code in usb-musb.c file
- Register NOP in OMAP3EVM board file using
  usb_nop_xceiv_register().
- Select NOP_USB_XCEIV for OMAP3EVM boards.
- Don't enable TWL4030_USB in omap3_evm_defconfig

Signed-off-by: Ajay Kumar Gupta 
Signed-off-by: Eino-Ville Talvala 
---
Resubmitting with below changes.
- Refreshed against linus tree
- Combining recent patch from Eino-Ville Talvala on
  "Removing TWL4030_USB from omap3_evm_defconfig"
- Register nop under #ifdef to avoid compilation warning when
  USB itself it not selected in OMAP3EVM build.

 arch/arm/configs/omap3_evm_defconfig |2 +-
 arch/arm/mach-omap2/board-omap3evm.c |5 +
 arch/arm/mach-omap2/usb-musb.c   |   21 -
 drivers/usb/musb/Kconfig |1 +
 4 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/arch/arm/configs/omap3_evm_defconfig 
b/arch/arm/configs/omap3_evm_defconfig
index 28be17f..d5ff477 100644
--- a/arch/arm/configs/omap3_evm_defconfig
+++ b/arch/arm/configs/omap3_evm_defconfig
@@ -1107,7 +1107,7 @@ CONFIG_USB_ZERO=m
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_ISP1301_OMAP is not set
-CONFIG_TWL4030_USB=y
+# CONFIG_TWL4030_USB is not set
 # CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
diff --git a/arch/arm/mach-omap2/board-omap3evm.c 
b/arch/arm/mach-omap2/board-omap3evm.c
index d3cc145..cf3dd77 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -307,6 +308,10 @@ static void __init omap3_evm_init(void)
ARRAY_SIZE(omap3evm_spi_board_info));
 
omap_serial_init();
+#ifdef CONFIG_NOP_USB_XCEIV
+   /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
+   usb_nop_xceiv_register();
+#endif
usb_musb_init();
ads7846_dev_init();
 }
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index d85296d..739e59e 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -155,20 +155,6 @@ static struct platform_device musb_device = {
.resource   = musb_resources,
 };
 
-#ifdef CONFIG_NOP_USB_XCEIV
-static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device nop_xceiv_device = {
-   .name   = "nop_usb_xceiv",
-   .id = -1,
-   .dev = {
-   .dma_mask   = &nop_xceiv_dmamask,
-   .coherent_dma_mask  = DMA_BIT_MASK(32),
-   .platform_data  = NULL,
-   },
-};
-#endif
-
 void __init usb_musb_init(void)
 {
if (cpu_is_omap243x())
@@ -183,13 +169,6 @@ void __init usb_musb_init(void)
 */
musb_plat.clock = "ick";
 
-#ifdef CONFIG_NOP_USB_XCEIV
-   if (platform_device_register(&nop_xceiv_device) < 0) {
-   printk(KERN_ERR "Unable to register NOP-XCEIV device\n");
-   return;
-   }
-#endif
-
if (platform_device_register(&musb_device) < 0) {
printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
return;
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 70073b1..803adcb 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -12,6 +12,7 @@ config USB_MUSB_HDRC
depends on !SUPERH
select NOP_USB_XCEIV if ARCH_DAVINCI
select TWL4030_USB if MACH_OMAP_3430SDP
+   select NOP_USB_XCEIV if MACH_OMAP3EVM
select USB_OTG_UTILS
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
help
-- 
1.6.2.4

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


RE: OMAP camera with BT-656 sensor

2009-07-28 Thread Hiremath, Vaibhav
Hi Thomas,

> -Original Message-
> From: Gary Thomas [mailto:g...@mlbassoc.com]
> Sent: Tuesday, July 28, 2009 6:15 PM
> To: Hiremath, Vaibhav
> Cc: Aguirre Rodriguez, Sergio Alberto; linux-omap@vger.kernel.org
> Subject: Re: OMAP camera with BT-656 sensor
> 
> Hiremath, Vaibhav wrote:
> >> -Original Message-
> >> From: linux-omap-ow...@vger.kernel.org [mailto:linux-omap-
> >> ow...@vger.kernel.org] On Behalf Of Aguirre Rodriguez, Sergio
> >> Alberto
> >> Sent: Tuesday, July 28, 2009 1:45 AM
> >> To: Gary Thomas
> >> Cc: linux-omap@vger.kernel.org
> >> Subject: RE: OMAP camera with BT-656 sensor
> >>
> >>
> >>
> >>> -Original Message-
> >>> From: Gary Thomas [mailto:g...@mlbassoc.com]
> >>> Sent: Monday, July 27, 2009 2:59 PM
> >>> To: Aguirre Rodriguez, Sergio Alberto
> >>> Cc: linux-omap@vger.kernel.org
> >>> Subject: Re: OMAP camera with BT-656 sensor
> >>>
> >>> Aguirre Rodriguez, Sergio Alberto wrote:
> > -Original Message-
> > From: Gary Thomas [mailto:g...@mlbassoc.com]
> > Sent: Monday, July 27, 2009 2:11 PM
> > To: Aguirre Rodriguez, Sergio Alberto
> > Cc: linux-omap@vger.kernel.org
> > Subject: OMAP camera with BT-656 sensor
> >>>... snip
> >>>
> > Bottom line, I'm confused as to how I should go about getting
> > my driver/system working.  Do I use your work, or just stick
> > with the PSP base (why?)??
>  What I do feel is that the PSP base will fulfill better your
> >> immediate
> >>> needs, but in the future, as I'm getting aware of Vaibhav
> changes,
> >> I'll be
> >>> interested in making them part of my tree aswell, so Vaibhav
> could
> >> avoid
> >>> rebasing the BT646 support internally everytime...
> >>>
> >>> Is there a GIT tree for this?
> >> AFAIK, this is the latest tree Vaibhav is exposing:
> >>
> >> http://arago-project.org/git/people/vaibhav/ti-psp-omap-video.git
> >>
> >> He maintains a camera and a DSS2 branch exactly to make both work
> on
> >> his 3530EVM.
> >>
> > [Hiremath, Vaibhav] Thanks Sergio for taking this up. Just to add
> on top of Sergio's comments, the current status of above tree is,
> DSS2 is already merged to latest kernel (Even on PM branch)
> baseline.
> >
> > http://arago-project.org/git/people/?p=vaibhav/ti-psp-omap-
> video.git;a=shortlog;h=refs/heads/ti_display
> >
> > http://arago-project.org/git/people/?p=vaibhav/ti-psp-omap-
> video.git;a=shortlog;h=refs/heads/pm
> >
> >
> > The next PSP release will contain 2.6.31(PM) + DSS2 + Camera +
> Resizer modules together in one release. I have started with Camera
> modules merging on top of 2.6.31 + DSS2; hopefully I should be able
> to complete this by next week (provided that I don't get any
> interrupts)
> >
> > You should be looking to Arago tree for all the developments which
> I do under Arago.
> >
> > Please let me know if you have any issues/doubts OR if you are
> looking for some quick solutions.
> 
> I'd like to use the latest tree with DSS2 (ti_display seems to be
> it), but
> the OMAP3 camera support is not present.
[Hiremath, Vaibhav] Yes you are correct.
>   * How hard would it be to merge the ti_omap3camera and ti_display
> branches?

[Hiremath, Vaibhav] Should not be that hard but I would suggest to go with 
latest Camera changes.

>   * Would this be a reasonable way forward?

 [Hiremath, Vaibhav] It would be really difficult to maintain the old code 
base, which in my opinion waste of efforts.

> 
> It would be nice if I could wait for your next release, but alas, my
> project is already weeks late and every hour counts...
> 
> >>> A [hopefully] minor complication is that I'm using Tomi's DSS2
> >>> tree for the base of my port.  How can I move/merge the PSP
> >>> based support into it?  Can I just pick up the whole
> drivers/media
> >>> subtree and put in in place of what I have?
> >> I recommend looking at the git tree above... I think that job is
> >> already done...
> >>
> >>> Thanks for your help - this myriad of trees and very disparate
> >>> support levels is really confusing to those of us on the
> >> outside...
> >>
> >> I know, and the lack of proper documentation is one of the first
> >> issues for me to look at...
> >>
> >> You're welcome.
> 
> 
> --
> 
> Gary Thomas |  Consulting for the
> MLB Associates  |Embedded world
> 

--
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


[RFC][PATCH v2 4/4] OMAP4: PMIC: Update TWL mfd driver to create twl6030 regulators

2009-07-28 Thread balajitk
From: Rajendra Nayak 

This version of patch series enables RUN TIME selection of TWL4030 or TWL6030.

This patch adds initial support for creating twl6030 PMIC
specific voltage regulators in the twl mfd driver.

Board specific regulator configurations will have to be passed from
respective board files.

Signed-off-by: Rajendra Nayak 
---
 drivers/mfd/twl-core.c  |   56 +-
 include/linux/i2c/twl.h |   18 +++
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index f505537..747289c 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -76,9 +76,9 @@
 #define twl_has_gpio() false
 #endif
 
-#if defined(CONFIG_REGULATOR_TWL4030) \
-   || defined(CONFIG_REGULATOR_TWL4030_MODULE)
-#define twl_has_regulator()true
+#if defined(CONFIG_REGULATOR_TWL) \
+   || defined(CONFIG_REGULATOR_TWL_MODULE)
+#define twl_has_regulator() true
 #else
 #define twl_has_regulator()false
 #endif
@@ -636,7 +636,7 @@ add_children(struct twl_platform_data *pdata, unsigned long 
features)
return PTR_ERR(child);
}
 
-   if (twl_has_regulator()) {
+   if (twl_has_regulator() && is_class_twl4030()) {
/*
child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
if (IS_ERR(child))
@@ -659,7 +659,7 @@ add_children(struct twl_platform_data *pdata, unsigned long 
features)
return PTR_ERR(child);
}
 
-   if (twl_has_regulator() && usb_transceiver) {
+   if (twl_has_regulator() && is_class_twl4030() && usb_transceiver) {
static struct regulator_consumer_supply usb1v5 = {
.supply =   "usb1v5",
};
@@ -701,7 +701,8 @@ add_children(struct twl_platform_data *pdata, unsigned long 
features)
}
 
/* maybe add LDOs that are omitted on cost-reduced parts */
-   if (twl_has_regulator() && !(features & TPS_SUBSET)) {
+   if (twl_has_regulator() && is_class_twl4030()
+ && !(features & TPS_SUBSET)) {
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
if (IS_ERR(child))
return PTR_ERR(child);
@@ -727,6 +728,49 @@ add_children(struct twl_platform_data *pdata, unsigned 
long features)
return PTR_ERR(child);
}
 
+   /* twl6030 regulators */
+   if (twl_has_regulator() && is_class_twl4030()) {
+   child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VPP, pdata->vpp);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VANA, pdata->vana);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VDAC, pdata->vdac);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VUSB, pdata->vusb);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+
+   child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3);
+   if (IS_ERR(child))
+   return PTR_ERR(child);
+   }
+
return 0;
 }
 
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 53d9360..1f678ed 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -306,6 +306,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned 
num_bytes);
 #define TWL4030_INT_PWR_EDR2   0x6
 #define TWL4030_INT_PWR_SIH_CTRL   0x7
 
+
 /*--*/
 
 /* Power bus message definitions */
@@ -424,18 +425,25 @@ struct twl_platform_data {
struct twl_keypad_data  *keypad;
struct twl_usb_data *usb;
 
-   /* LDO regulators */
+   /* LDO regulators common to TWL4030/TWL6030 */
struct regulator_init_data  *vdac;
+   struct regulator_init_data  *vaux1;
+   struct regulator_init_data  *vaux2;
+   str

[RFC][PATCH v2 3/4] OMAP4: PMIC: Add support for twl6030 regulators

2009-07-28 Thread balajitk
From: Rajendra Nayak 

This version of patch series enables RUN TIME selection of TWL4030 or TWL6030.

This patch updates the regulator driver to add support
for TWL6030 PMIC specific LDO regulators.
SMPS resources are not yet supported for TWL6030 and
also .set_mode and .get_status for LDO's are yet to
be implemented for TWL6030.

Signed-off-by: Rajendra Nayak 
---
 drivers/mfd/twl-core.c|3 +-
 drivers/regulator/Kconfig |6 +-
 drivers/regulator/Makefile|2 +-
 drivers/regulator/twl-regulator.c |  134 +++--
 include/linux/i2c/twl.h   |   37 ++
 5 files changed, 155 insertions(+), 27 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 78109ca..f505537 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -126,7 +126,7 @@
 #define REG_SUB_CHIP_ID SUB_CHIP_ID3
 
 /* Last - for index max*/
-#define TWL4030_MODULE_LASTTWL4030_MODULE_SECURED_REG
+#define TWL4030_MODULE_LASTTWL_MODULE_PM_SLAVE_LDO
 #define TWL_MODULE_LAST TWL4030_MODULE_LAST
 
 /* Base Address defns for twl4030_map[] */
@@ -277,6 +277,7 @@ static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 
1] = {
{ 3, TWL4030_BASEADD_PM_RECEIVER },
{ 3, TWL4030_BASEADD_RTC },
{ 3, TWL4030_BASEADD_SECURED_REG },
+   { 3, TWL4030_BASEADD_PM_RECEIVER },
 };
 
 static struct twl_mapping twl6030_map[] = {
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index f431779..7f5987e 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -75,9 +75,9 @@ config REGULATOR_MAX1586
  regulator via I2C bus. The provided regulator is suitable
  for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
-config REGULATOR_TWL4030
-   bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
-   depends on TWL4030_CORE
+config REGULATOR_TWL
+   bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
+   depends on TWL_CORE
help
  This driver supports the voltage regulators provided by
  this family of companion chips.
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0653ce8..712f733 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += 
userspace-consumer.o
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
-obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
+obj-$(CONFIG_REGULATOR_TWL) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
diff --git a/drivers/regulator/twl-regulator.c 
b/drivers/regulator/twl-regulator.c
index d01aa4e..8182290 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -52,27 +52,38 @@ struct twlreg_info {
  * The first three registers of all power resource banks help hardware to
  * manage the various resource groups.
  */
+/* Common offset in TWL4030/6030 */
 #define VREG_GRP   0
+/* TWL4030 register offsets */
 #define VREG_TYPE  1
 #define VREG_REMAP 2
-#define VREG_DEDICATED 3   /* LDO control */
-
+#define VREG_DEDICATED 3
+/* TWL6030 register offsets */
+#define VREG_TRANS 1
+#define VREG_STATE 2
+#define VREG_VOLTAGE   3
+/* TWL6030 Misc register offsets */
+#define VREG_BC_ALL1
+#define VREG_BC_REF2
+#define VREG_BC_PROC   3
+#define VREG_BC_CLK_RST4
 
 static inline int
-twlreg_read(struct twlreg_info *info, unsigned offset)
+twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
 {
u8 value;
int status;
 
-   status = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER,
+   status = twl_i2c_read_u8(slave_subgp,
&value, info->base + offset);
return (status < 0) ? status : value;
 }
 
 static inline int
-twlreg_write(struct twlreg_info *info, unsigned offset, u8 value)
+twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset,
+u8 value)
 {
-   return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+   return twl_i2c_write_u8(slave_subgp,
value, info->base + offset);
 }
 
@@ -82,17 +93,22 @@ twlreg_write(struct twlreg_info *info, unsigned offset, u8 
value)
 
 static int twlreg_grp(struct regulator_dev *rdev)
 {
-   return twlreg_read(rdev_get_drvdata(rdev), VREG_GRP);
+   return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_SLAVE_LDO,
+VREG_GRP);
 }
 
 /*
  * Enable/disable regulators by joining/leaving the P1 (processor) group.
  * We assume nobody else is updating the DEV_GRP registers

[RFC][PATCH v2 2/4] OMAP4: PMIC: Add support for twl6030 RTC

2009-07-28 Thread balajitk
From: Balaji T K 

This version of patch series enables RUN TIME selection of TWL4030 or TWL6030.

This patch adds support for RTC in phoenix TWL6030.
Register offset addresses have changed in TWL6030
rtc-twl.c will hence forth support all twl RTC (4030, 5030, 6030 ..)

Signed-off-by: Balaji T K 
Signed-off-by: Santosh Shilimkar 
---
 drivers/mfd/twl-core.c |2 +-
 drivers/rtc/Kconfig|8 ++--
 drivers/rtc/Makefile   |2 +-
 drivers/rtc/rtc-twl.c  |  113 
 4 files changed, 91 insertions(+), 34 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 4066b2f..78109ca 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -89,7 +89,7 @@
 #define twl_has_madc() false
 #endif
 
-#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
+#if defined(CONFIG_RTC_DRV_TWL) || defined(CONFIG_RTC_DRV_TWL_MODULE)
 #define twl_has_rtc()  true
 #else
 #define twl_has_rtc()  false
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81adbdb..bb94924 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -257,15 +257,15 @@ config RTC_DRV_TWL92330
  platforms. The support is integrated with the rest of
  the Menelaus driver; it's not separate module.
 
-config RTC_DRV_TWL4030
-   tristate "TI TWL4030/TWL5030/TPS659x0"
-   depends on RTC_CLASS && TWL4030_CORE
+config RTC_DRV_TWL
+   tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
+   depends on RTC_CLASS && TWL_CORE
help
  If you say yes here you get support for the RTC on the
  TWL4030 family chips, used mostly with OMAP3 platforms.
 
  This driver can also be built as a module. If so, the module
- will be called rtc-twl4030.
+ will be called rtc-twl.
 
 config RTC_DRV_S35390A
tristate "Seiko Instruments S-35390A"
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e331b1c..c32e21d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -70,7 +70,7 @@ obj-$(CONFIG_RTC_DRV_SA1100)  += rtc-sa1100.o
 obj-$(CONFIG_RTC_DRV_SH)   += rtc-sh.o
 obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
-obj-$(CONFIG_RTC_DRV_TWL4030)  += rtc-twl.o
+obj-$(CONFIG_RTC_DRV_TWL)  += rtc-twl.o
 obj-$(CONFIG_RTC_DRV_TX4939)   += rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)   += rtc-vr41xx.o
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 630acb7..1e9f90d 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -34,27 +34,75 @@
 /*
  * RTC block register offsets (use TWL_MODULE_RTC)
  */
-#define REG_SECONDS_REG  0x00
-#define REG_MINUTES_REG  0x01
-#define REG_HOURS_REG0x02
-#define REG_DAYS_REG 0x03
-#define REG_MONTHS_REG   0x04
-#define REG_YEARS_REG0x05
-#define REG_WEEKS_REG0x06
-
-#define REG_ALARM_SECONDS_REG0x07
-#define REG_ALARM_MINUTES_REG0x08
-#define REG_ALARM_HOURS_REG  0x09
-#define REG_ALARM_DAYS_REG   0x0A
-#define REG_ALARM_MONTHS_REG 0x0B
-#define REG_ALARM_YEARS_REG  0x0C
-
-#define REG_RTC_CTRL_REG 0x0D
-#define REG_RTC_STATUS_REG   0x0E
-#define REG_RTC_INTERRUPTS_REG   0x0F
-
-#define REG_RTC_COMP_LSB_REG 0x10
-#define REG_RTC_COMP_MSB_REG 0x11
+enum {
+   REG_SECONDS_REG = 0,
+   REG_MINUTES_REG,
+   REG_HOURS_REG,
+   REG_DAYS_REG,
+   REG_MONTHS_REG,
+   REG_YEARS_REG,
+   REG_WEEKS_REG,
+
+   REG_ALARM_SECONDS_REG,
+   REG_ALARM_MINUTES_REG,
+   REG_ALARM_HOURS_REG,
+   REG_ALARM_DAYS_REG,
+   REG_ALARM_MONTHS_REG,
+   REG_ALARM_YEARS_REG,
+
+   REG_RTC_CTRL_REG,
+   REG_RTC_STATUS_REG,
+   REG_RTC_INTERRUPTS_REG,
+
+   REG_RTC_COMP_LSB_REG,
+   REG_RTC_COMP_MSB_REG,
+};
+const static u8 twl4030_rtc_reg_map[] = {
+   [REG_SECONDS_REG] = 0x00,
+   [REG_MINUTES_REG] = 0x01,
+   [REG_HOURS_REG] = 0x02,
+   [REG_DAYS_REG] = 0x03,
+   [REG_MONTHS_REG] = 0x04,
+   [REG_YEARS_REG] = 0x05,
+   [REG_WEEKS_REG] = 0x06,
+
+   [REG_ALARM_SECONDS_REG] = 0x07,
+   [REG_ALARM_MINUTES_REG] = 0x08,
+   [REG_ALARM_HOURS_REG] = 0x09,
+   [REG_ALARM_DAYS_REG] = 0x0A,
+   [REG_ALARM_MONTHS_REG] = 0x0B,
+   [REG_ALARM_YEARS_REG] = 0x0C,
+
+   [REG_RTC_CTRL_REG] = 0x0D,
+   [REG_RTC_STATUS_REG] = 0x0E,
+   [REG_RTC_INTERRUPTS_REG] = 0x0F,
+
+   [REG_RTC_COMP_LSB_REG] = 0x10,
+   [REG_RTC_COMP_MSB_REG] = 0x11,
+};
+const static u8 twl6030_rtc_reg_map[] = {
+   [REG_SECONDS_REG] = 0x00,
+   [REG

[RFC][PATCH v2 1/4] OMAP4: PMIC: Add support for twl6030 irq framework

2009-07-28 Thread balajitk
From: Balaji T K 

This version of patch series enables RUN TIME selection of TWL4030 or TWL6030.
CONFIG_TWL4030_CORE and CONFIG_TWL6030_CORE is replaced by CONFIG_TWL_CORE

This patch adds support for phoenix interrupt framework. New Interrupt status
register A, B, C are introduced in Phoenix and are cleared on write.
Due to difference in interrupt handling with respect to TWL4030,
twl6030-irq.c is created for TWL6030 PMIC

Signed-off-by: Rajendra Nayak 
Signed-off-by: Balaji T K 
Signed-off-by: Santosh Shilimkar 
---
 arch/arm/plat-omap/include/mach/irqs.h |   18 ++-
 drivers/mfd/Kconfig|4 +-
 drivers/mfd/Makefile   |2 +-
 drivers/mfd/twl-core.c |  128 --
 drivers/mfd/twl4030-irq.c  |4 +-
 drivers/mfd/twl6030-irq.c  |  301 
 include/linux/i2c/twl.h|   64 +++-
 7 files changed, 498 insertions(+), 23 deletions(-)
 create mode 100644 drivers/mfd/twl6030-irq.c

diff --git a/arch/arm/plat-omap/include/mach/irqs.h 
b/arch/arm/plat-omap/include/mach/irqs.h
index fb7cb77..e9e0500 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -531,7 +531,7 @@
 
 /* External TWL4030 can handle interrupts on 2430 and 34xx boards */
 #defineTWL4030_IRQ_BASE(OMAP_FPGA_IRQ_END)
-#ifdef CONFIG_TWL4030_CORE
+#ifdef CONFIG_TWL_CORE
 #defineTWL4030_BASE_NR_IRQS8
 #defineTWL4030_PWR_NR_IRQS 8
 #else
@@ -551,8 +551,22 @@
 #endif
 #define TWL4030_GPIO_IRQ_END   (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
 
+#defineTWL6030_IRQ_BASE(OMAP_FPGA_IRQ_END)
+#ifdef CONFIG_TWL_CORE
+#defineTWL6030_BASE_NR_IRQS20
+#else
+#defineTWL6030_BASE_NR_IRQS0
+#endif
+#define TWL6030_IRQ_END(TWL6030_IRQ_BASE + 
TWL6030_BASE_NR_IRQS)
+
 /* Total number of interrupts depends on the enabled blocks above */
-#define NR_IRQSTWL4030_GPIO_IRQ_END
+#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#define TWL_IRQ_ENDTWL4030_GPIO_IRQ_END
+#else
+#define TWL_IRQ_ENDTWL6030_IRQ_END
+#endif
+
+#define NR_IRQSTWL_IRQ_END
 
 #define OMAP_IRQ_BIT(irq)  (1 << ((irq) % 32))
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 491ac0f..38ad70b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -94,11 +94,11 @@ config MENELAUS
  and other features that are often used in portable devices like
  cell phones and PDAs.
 
-config TWL4030_CORE
+config TWL_CORE
bool "Texas Instruments TWL4030/TPS659x0 Support"
depends on I2C=y && GENERIC_HARDIRQS
help
- Say yes here if you have TWL4030 family chip on your board.
+ Say yes here if you have TWL4030 / TWL6030 family chip on your board.
  This core driver provides register access and IRQ handling
  facilities, and registers devices for the various functions
  so that function-specific drivers can bind to them.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 4e9d513..c733440 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_MFD_WM8350_I2C)  += wm8350-i2c.o
 obj-$(CONFIG_TPS65010) += tps65010.o
 obj-$(CONFIG_MENELAUS) += menelaus.o
 
-obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o
+obj-$(CONFIG_TWL_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
 
 obj-$(CONFIG_MFD_CORE) += mfd-core.o
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 6122db2..4066b2f 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -163,6 +163,35 @@
 /* Triton Core internal information (END) */
 
 
+/* subchip/slave 0 0x48 - POWER */
+#define TWL6030_BASEADD_RTC0x
+#define TWL6030_BASEADD_MEM0x0017
+#define TWL6030_BASEADD_PM_MASTER  0x001F
+#define TWL6030_BASEADD_PM_SLAVE_MISC  0x0030
+#define TWL6030_BASEADD_PM_SLAVE_SMPS  0x0040
+#define TWL6030_BASEADD_PM_SLAVE_LDO   0x0080
+#define TWL6030_BASEADD_PM_SLAVE_RES   0x00AD
+#define TWL6030_BASEADD_PM_MISC0x00E3
+#define TWL6030_BASEADD_PM_PUPD0x00F0
+
+/* subchip/slave 1 0x49 - FEATURE */
+#define TWL6030_BASEADD_USB0x
+#define TWL6030_BASEADD_GPADC_CTRL 0x0030
+#define TWL6030_BASEADD_GPADC_RT   0x0035
+#define TWL6030_BASEADD_GPADC  0x005D
+#define TWL6030_BASEADD_AUX0x0090
+#define TWL6030_BASEADD_PWM0x00BA
+#define TWL6030_BASEADD_GASGAUGE   0x00C0
+#define TWL6030_BASEADD_PIH0x00D0
+#define TWL6030_BASEADD_CHARGER0x00E0
+
+/* subchip/slave 2 0x4A - DFT */
+#define TWL6030_BASEADD_DIEID  0x00C0
+
+/* subchip/slave 3 0x4B - AUDIO */
+#define TWL6030_BASEADD_AUDIO  0x
+#define TWL6030_BASEADD_RSV0x
+
 /* Few power values */
 #define

drivers that require headers in mach-omap

2009-07-28 Thread Mike Chan
Omap folks, how are drivers that require access to prm and cm
registers via cm_read_mod_reg() etc... suppose to access these?

For example if drivers/usb/host/ohci-omap.c wanted to call:
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_IDLEST);

It seems some of the headers in mach-omap2 should be in
plat-omap/include/mach, or is there a more elegant way? The other
alternatives are to register calls in all the board files, or #include
../../.. both do not seem very elegant to me.

-- 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: PM: Move the clk stabilization delay to the right place

2009-07-28 Thread Paul Walmsley
On Fri, 26 Jun 2009, Rajendra Nayak wrote:

> The clock stabilization delay post a M2 divider change is needed
> even before a SDRC interface clock re-enable and not only before
> jumping back to SDRAM.
> 
> Signed-off-by: Rajendra Nayak 

For the archives: this patch has been accepted and sent upstream for 
2.6.31-rc fixes.

- Paul

> ---
>  arch/arm/mach-omap2/sram34xx.S |4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
> index f41f8d9..481f912 100644
> --- a/arch/arm/mach-omap2/sram34xx.S
> +++ b/arch/arm/mach-omap2/sram34xx.S
> @@ -97,6 +97,8 @@ ENTRY(omap3_sram_configure_core_dpll)
>   blnelock_dll
>   bl  sdram_in_selfrefresh@ put SDRAM in self refresh, idle SDRC
>   bl  configure_core_dpll @ change the DPLL3 M2 divider
> + mov r12, r5
> + bl  wait_clk_stable @ wait for SDRC to stabilize
>   bl  enable_sdrc @ take SDRC out of idle
>   cmp r4, #SDRC_UNLOCK_DLL@ wait for DLL status to change
>   bleqwait_dll_unlock
> @@ -104,8 +106,6 @@ ENTRY(omap3_sram_configure_core_dpll)
>   cmp r7, #1  @ if increasing SDRC clk rate,
>   beq return_to_sdram @ return to SDRAM code, otherwise,
>   bl  configure_sdrc  @ reprogram SDRC regs now
> - mov r12, r5
> - bl  wait_clk_stable @ wait for SDRC to stabilize
>  return_to_sdram:
>   isb @ prevent speculative exec past here
>   mov r0, #0  @ return value
> -- 
> 1.5.4.7
> 
> --
> 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
> 


- 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: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Mark Brown
On Tue, Jul 28, 2009 at 06:36:01PM +0200, Janusz Krzysztofik wrote:
> Tuesday 28 July 2009 18:11:32 Mark Brown wrote:

> > Like I say, I'd suggest always keeping the controls registered and just
> > masking and unmasking from user space - the control indexes get used so
> > removing them will just confuse things.

> However, in order for the machine driver to unmask/mask a machine specific 
> control, the codec driver must drop the machine driver a message about the 
> line discipline being activeted/deactivated, right? The only such existing 
> feedback I can see the codec is able to use is via snd_soc_init_card() that 
> calls snd_soc_dai_link.init() in turn. Am I missing something?

Well, the machine driver can look up controls by name (this is going to
be required in order to find the controls anyway...).  Besides, given
that the machine driver is already entirely CODEC-specific there'd no
problem with it calling into CODEC-specific APIs to do things.
--
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: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Janusz Krzysztofik
Tuesday 28 July 2009 18:11:32 Mark Brown wrote:
> On Tue, Jul 28, 2009 at 06:07:29PM +0200, Janusz Krzysztofik wrote:
> > now. Activation of the line discipline would deregister the codec device
> > from the platform bus and reregister it again, now as the line discipline
> > provided device. Is this possible with current ASoC framework?
>
> No, not currently.  But why would you do that, anyway?
>
> Like I say, I'd suggest always keeping the controls registered and just
> masking and unmasking from user space - the control indexes get used so
> removing them will just confuse things.

However, in order for the machine driver to unmask/mask a machine specific 
control, the codec driver must drop the machine driver a message about the 
line discipline being activeted/deactivated, right? The only such existing 
feedback I can see the codec is able to use is via snd_soc_init_card() that 
calls snd_soc_dai_link.init() in turn. Am I missing something?

Janusz
--
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: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Mark Brown
On Tue, Jul 28, 2009 at 06:07:29PM +0200, Janusz Krzysztofik wrote:

> What I would like to retain from the current codec driver are those two modes 
> of operation: without and with the line discipline activated. Initially, the 
> codec would be registered as a platform device, as it is now. Activation of 
> the line discipline would deregister the codec device from the platform bus 
> and reregister it again, now as the line discipline provided device. Is this 
> possible with current ASoC framework?

No, not currently.  But why would you do that, anyway?

Like I say, I'd suggest always keeping the controls registered and just
masking and unmasking from user space - the control indexes get used so
removing them will just confuse things.
--
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: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Janusz Krzysztofik
Tuesday 28 July 2009 17:07:27 Mark Brown wrote:
> On Tue, Jul 28, 2009 at 04:59:33PM +0200, Janusz Krzysztofik wrote:
> > Following that model, the line discipline code didn't seam to belong to a
> > codec driver for me. If it could be recognized as a new bus dirver, it
> > should be pushed down probably into a separate module. However, if it was
> > rather some kind of a bus adapter driver, it seamed to belong to the
> > machine code.
>
> The way it looks with the current code the line discipline itself is
> going to apply equally well to any serial port that's used - I'm not
> clear what's system-specific about it.  The bit that connects the line
> discipline to the line is a different matter but the bit that interacts
> with the TTY layer after registration is working through a pluggable
> abstraction layer and shouldn't, I'd expect, be specific to the
> particular serial port.

Mark,
I think I can't tell anything more before I try to implement it in a way you 
suggest, so I will.

What I would like to retain from the current codec driver are those two modes 
of operation: without and with the line discipline activated. Initially, the 
codec would be registered as a platform device, as it is now. Activation of 
the line discipline would deregister the codec device from the platform bus 
and reregister it again, now as the line discipline provided device. Is this 
possible with current ASoC framework?

Thanks,
Janusz
--
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: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu

2009-07-28 Thread Kanigeri, Hari
Hi Hiroshi,

> 
> This "omap iommu" driver is used in OMAP4 IPC and its interface is a
> character device node. IOW, the client of this device will be an
> userland process and kernel won't know if it uses or not, but kernel
> just provides "/dev/iommu?" for userland. So I don't think that we
> have to care about the dependency of the existance of clients, at
> least, for a moment.
> 
> >
The first patch set that I sent is to provide support in IOMMU for OMAP4 just 
like how it is done in OMAP3 today. The define "CONFIG_MPU_TESLA_IOMMU" is used 
for now because in the first phase we are planning to use DSP-Bridge to 
communicate with Tesla (until we move the new user-land IPC to replace 
DSP-Bridge for OMAP4).
IMHO, let's go ahead with these changes and any changes to support IOMMU from 
user-land we can address them in next set of patches.

Thank you,
Best regards,
Hari

> -Original Message-
> From: Hiroshi DOYU [mailto:hiroshi.d...@nokia.com]
> Sent: Monday, July 27, 2009 1:48 AM
> To: Kanigeri, Hari
> Cc: t...@atomide.com; linux-omap@vger.kernel.org; Gupta, Ramesh;
> r...@arm.linux.org.uk; Pasam, Vijay
> Subject: Re: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu
> 
> From: "ext Kanigeri, Hari" 
> Subject: RE: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu
> Date: Mon, 27 Jul 2009 02:18:21 +0200
> 
> > Hi Hiroshi,
> >
> > > > +static const struct iommu_platform_data omap4_iommu_pdata[]
> __initconst
> > > = {
> > > > +   {
> > > > +   .name = "ducati",
> > > > +   .nr_tlb_entries = 32,
> > > > +   .clk_name = "ducati_ick",
> > > > +   },
> > > > +#if defined(CONFIG_MPU_TESLA_IOMMU)
> > > > +   {
> > > > +   .name = "tesla",
> > > > +   .nr_tlb_entries = 32,
> > > > +   .clk_name = "tesla_ick",
> > > > +   },
> > > > +#endif
> > > > +};
> > >
> > > If iommu is used as a character device driver, is the above config
> still
> > > necessary?
> >
> > -- My apologies, I am not sure what you mean by this. Can you please
> elaborate a bit more.
> 
> Well...I'm trying to explain;),
> 
> This "omap iommu" driver is used in OMAP4 IPC and its interface is a
> character device node. IOW, the client of this device will be an
> userland process and kernel won't know if it uses or not, but kernel
> just provides "/dev/iommu?" for userland. So I don't think that we
> have to care about the dependency of the existance of clients, at
> least, for a moment.
> 
> >
> > Thank you,
> > Best regards,
> > Hari
> >
> > > -Original Message-
> > > From: Hiroshi DOYU [mailto:hiroshi.d...@nokia.com]
> > > Sent: Friday, July 24, 2009 1:22 PM
> > > To: Kanigeri, Hari
> > > Cc: t...@atomide.com; linux-omap@vger.kernel.org; Gupta, Ramesh;
> > > r...@arm.linux.org.uk; Pasam, Vijay
> > > Subject: Re: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in
> iommu
> > >
> > > From: "ext Kanigeri, Hari" 
> > > Subject: [RFC][PATCH 2/3] ARM:OMAP4 iommu:add omap4 support in iommu
> > > Date: Fri, 24 Jul 2009 19:22:32 +0200
> > >
> > > > This patch adds omap4 support in iommu
> > > > module. This creates OMAP4 platform specific file
> > > > for iommu and defines the Ducati MMU fault interrupt.
> > > >
> > > > Signed-off-by: Hari Kanigeri 
> > > > ---
> > > >  arch/arm/mach-omap2/omap4-iommu.c  |  112
> > > 
> > > >  arch/arm/plat-omap/include/mach/irqs.h |2 +-
> > > >  2 files changed, 113 insertions(+), 1 deletions(-)
> > > >  create mode 100644 arch/arm/mach-omap2/omap4-iommu.c
> > > >
> > > > diff --git a/arch/arm/mach-omap2/omap4-iommu.c b/arch/arm/mach-
> > > omap2/omap4-iommu.c
> > > > new file mode 100644
> > > > index 000..5a782df
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-omap2/omap4-iommu.c
> > > > @@ -0,0 +1,112 @@
> > > > +/*
> > > > + * omap iommu: omap4 device registration
> > > > + *
> > > > + * Copyright (C) 2009-2010 Nokia Corporation
> > > > + *
> > > > + * Written by Hari Kanigeri 
> > > > + *
> > > > + * Added support for OMAP4. This is based on original file
> > > > + * omap3-iommu.c
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or
> modify
> > > > + * it under the terms of the GNU General Public License version 2
> as
> > > > + * published by the Free Software Foundation.
> > > > + */
> > > > +
> > > > +#include 
> > > > +
> > > > +#include 
> > > > +#include 
> > > > +
> > > > +#define OMAP4_MMU1_BASE0x55082000
> > > > +#define OMAP4_MMU2_BASE0x4A066000
> > > > +
> > > > +#define OMAP4_MMU1_IRQ INT_44XX_DUCATI_MMU_IRQ
> > > > +#define OMAP4_MMU2_IRQ INT_44XX_DSP_MMU
> > > > +
> > > > +
> > > > +
> > > > +static unsigned long iommu_base[] __initdata = {
> > > > +   OMAP4_MMU1_BASE,
> > > > +   OMAP4_MMU2_BASE,
> > > > +};
> > > > +
> > > > +static int iommu_irq[] __initdata = {
> > > > +   OMAP4_MMU1_IRQ,
> > > > +   OMAP4_MMU2_IRQ,
> > > > +};
> > > > +
> > > > +static const st

Re: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Mark Brown
On Tue, Jul 28, 2009 at 04:59:33PM +0200, Janusz Krzysztofik wrote:

> Following that model, the line discipline code didn't seam to belong to a 
> codec driver for me. If it could be recognized as a new bus dirver, it should 
> be pushed down probably into a separate module. However, if it was rather 
> some kind of a bus adapter driver, it seamed to belong to the machine code.

The way it looks with the current code the line discipline itself is
going to apply equally well to any serial port that's used - I'm not
clear what's system-specific about it.  The bit that connects the line
discipline to the line is a different matter but the bit that interacts
with the TTY layer after registration is working through a pluggable
abstraction layer and shouldn't, I'd expect, be specific to the
particular serial port.
--
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: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem codec

2009-07-28 Thread Janusz Krzysztofik
Wednesday 22 July 2009 12:10:28 Mark Brown wrote:
> On Wed, Jul 22, 2009 at 05:22:28AM +0200, Janusz Krzysztofik wrote:
> > This patch adds support for Conexant CX20442-11 voice modem codec,
> > suitable for use by the ASoC board driver for Amstrad E3 (Delta)
> > videophone. Related sound card driver will follow.
> >
> You'll want to run checkpatch over it and send a followup fixing the
> issues it identifies.  Looking at this I suspect that it may be possible
> to refactor things so that more of the line discipline interaction is
> pushed down into the CODEC driver but that can also be done as a
> followup.
>
> would also be nice to add some documentation somewhere explaining how
> the hw_write() function is expected to be set up since it's a little
> surprising (if the line discipline stuff were pushed down into the code
> that'd become a lot more obvious).

Mark,
I am ready with a followup that corrects those minor issues, as well as with a 
new, corrected version of the machine driver. However, before I submit them, 
I'd like to discuss again your idea of pushing down the line discipline code 
into the codec driver.

As you may have noticed, my codec driver was ready for adopting it to one or 
more additional buses of different types, in a way similiar to those 
implemented in other codec drivers. There was a room for a hypothetical 
cx20442_xxx_probe() function, invoked by a hypothetical xxx bus driver after 
the bus comes up or a device is detected on it. That function could then set 
up its own codec->control_data and codec->hw_write pointers for talking to 
the codec via a hypothetical xxx bus adapter using its write method. In 
particular, that could be a line discipline provided acceess to the codec 
assosociated modem.

Following that model, the line discipline code didn't seam to belong to a 
codec driver for me. If it could be recognized as a new bus dirver, it should 
be pushed down probably into a separate module. However, if it was rather 
some kind of a bus adapter driver, it seamed to belong to the machine code.

As I had got no positive feedback to my RFC on inventing a new bus (votes were 
rather neutral, and I agreed with them[1]), I decided to put the line 
discipline code into the machine driver.

If you see things somehow different, please let me know, I can try to follow 
your ideas and rearrange the code.

Cheers,
Janusz

[1] http://www.spinics.net/lists/linux-serial/msg01856.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: OMAP camera with BT-656 sensor

2009-07-28 Thread Gary Thomas
Hiremath, Vaibhav wrote:
>> -Original Message-
>> From: linux-omap-ow...@vger.kernel.org [mailto:linux-omap-
>> ow...@vger.kernel.org] On Behalf Of Aguirre Rodriguez, Sergio
>> Alberto
>> Sent: Tuesday, July 28, 2009 1:45 AM
>> To: Gary Thomas
>> Cc: linux-omap@vger.kernel.org
>> Subject: RE: OMAP camera with BT-656 sensor
>>
>>
>>
>>> -Original Message-
>>> From: Gary Thomas [mailto:g...@mlbassoc.com]
>>> Sent: Monday, July 27, 2009 2:59 PM
>>> To: Aguirre Rodriguez, Sergio Alberto
>>> Cc: linux-omap@vger.kernel.org
>>> Subject: Re: OMAP camera with BT-656 sensor
>>>
>>> Aguirre Rodriguez, Sergio Alberto wrote:
> -Original Message-
> From: Gary Thomas [mailto:g...@mlbassoc.com]
> Sent: Monday, July 27, 2009 2:11 PM
> To: Aguirre Rodriguez, Sergio Alberto
> Cc: linux-omap@vger.kernel.org
> Subject: OMAP camera with BT-656 sensor
>>>... snip
>>>
> Bottom line, I'm confused as to how I should go about getting
> my driver/system working.  Do I use your work, or just stick
> with the PSP base (why?)??
 What I do feel is that the PSP base will fulfill better your
>> immediate
>>> needs, but in the future, as I'm getting aware of Vaibhav changes,
>> I'll be
>>> interested in making them part of my tree aswell, so Vaibhav could
>> avoid
>>> rebasing the BT646 support internally everytime...
>>>
>>> Is there a GIT tree for this?
>> AFAIK, this is the latest tree Vaibhav is exposing:
>>
>> http://arago-project.org/git/people/vaibhav/ti-psp-omap-video.git
>>
>> He maintains a camera and a DSS2 branch exactly to make both work on
>> his 3530EVM.
>>
> [Hiremath, Vaibhav] Thanks Sergio for taking this up. Just to add on top of 
> Sergio's comments, the current status of above tree is, DSS2 is already 
> merged to latest kernel (Even on PM branch) baseline.
> 
> http://arago-project.org/git/people/?p=vaibhav/ti-psp-omap-video.git;a=shortlog;h=refs/heads/ti_display
> 
> http://arago-project.org/git/people/?p=vaibhav/ti-psp-omap-video.git;a=shortlog;h=refs/heads/pm
> 
> 
> The next PSP release will contain 2.6.31(PM) + DSS2 + Camera + Resizer 
> modules together in one release. I have started with Camera modules merging 
> on top of 2.6.31 + DSS2; hopefully I should be able to complete this by next 
> week (provided that I don't get any interrupts)
> 
> You should be looking to Arago tree for all the developments which I do under 
> Arago.
> 
> Please let me know if you have any issues/doubts OR if you are looking for 
> some quick solutions.

I'd like to use the latest tree with DSS2 (ti_display seems to be it), but
the OMAP3 camera support is not present.
  * How hard would it be to merge the ti_omap3camera and ti_display branches?
  * Would this be a reasonable way forward?

It would be nice if I could wait for your next release, but alas, my
project is already weeks late and every hour counts...

>>> A [hopefully] minor complication is that I'm using Tomi's DSS2
>>> tree for the base of my port.  How can I move/merge the PSP
>>> based support into it?  Can I just pick up the whole drivers/media
>>> subtree and put in in place of what I have?
>> I recommend looking at the git tree above... I think that job is
>> already done...
>>
>>> Thanks for your help - this myriad of trees and very disparate
>>> support levels is really confusing to those of us on the
>> outside...
>>
>> I know, and the lack of proper documentation is one of the first
>> issues for me to look at...
>>
>> You're welcome.


-- 

Gary Thomas |  Consulting for the
MLB Associates  |Embedded world

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


[PATCH V2 1/32] mmc: add 'enable' and 'disable' methods to mmc host

2009-07-28 Thread Adrian Hunter
>From 4610f1ede273078f99214c6284202998aa537a1d Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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);
+   mmc_do_release_ho

[PATCH V2 8/32] mmc: check status after MMC SWITCH command

2009-07-28 Thread Adrian Hunter
>From 98c0aabb4c04bcdf7d166c0fb7e2c859e33f8c70 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 V2 12/32] omap_hsmmc: keep track of power mode

2009-07-28 Thread Adrian Hunter
>From 3592682a0965d32d3498f7da11073ff4d88f1bf7 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
Date: Tue, 7 Jul 2009 16:44:11 +0300
Subject: [PATCH] omap_hsmmc: keep track of power mode

This patch is preparation for adding context save
and restore support.

Keep track of the current power mode so that the
context restore function can avoid restoring the
context for a card if the power has been switched
off.  If the power is off, the card must be
reinitialized anyway which will re-establish the
context.

Signed-off-by: Adrian Hunter 
---
 drivers/mmc/host/omap_hsmmc.c |   27 +++
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f9b7cfe..c28d055 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -141,6 +141,7 @@ struct mmc_omap_host {
unsigned intdma_len;
unsigned intdma_sg_idx;
unsigned char   bus_mode;
+   unsigned char   power_mode;
u32 *buffer;
u32 bytesleft;
int suspended;
@@ -856,16 +857,25 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
unsigned long regval;
unsigned long timeout;
u32 con;
+   int do_send_init_stream = 0;
 
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);
-   break;
-   case MMC_POWER_UP:
-   mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
-   break;
+   if (ios->power_mode != host->power_mode) {
+   switch (ios->power_mode) {
+   case MMC_POWER_OFF:
+   mmc_slot(host).set_power(host->dev, host->slot_id,
+0, 0);
+   break;
+   case MMC_POWER_UP:
+   mmc_slot(host).set_power(host->dev, host->slot_id,
+1, ios->vdd);
+   break;
+   case MMC_POWER_ON:
+   do_send_init_stream = 1;
+   break;
+   }
+   host->power_mode = ios->power_mode;
}
 
con = OMAP_HSMMC_READ(host->base, CON);
@@ -931,7 +941,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | CEN);
 
-   if (ios->power_mode == MMC_POWER_ON)
+   if (do_send_init_stream)
send_init_stream(host);
 
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -1109,6 +1119,7 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
host->slot_id   = 0;
host->mapbase   = res->start;
host->base  = ioremap(host->mapbase, SZ_4K);
+   host->power_mode = -1;
 
platform_set_drvdata(pdev, host);
INIT_WORK(&host->mmc_carddetect_work, mmc_omap_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 V2 21/32] omap_hsmmc: add mmc card sleep and awake support

2009-07-28 Thread Adrian Hunter
>From 372d05a33f04d6a664ad1d3a80bed3d9ae80e495 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen 
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 
Signed-off-by: Adrian Hunter 
---
 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 7a17901..d5fb066 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -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 ||
+ (mmc_slot(host).get_cover_state &&
+  mmc_slot(host).get_cover_state(host->dev, host->slot_

[PATCH V2 23/32] omap_hsmmc: cleanup macro usage

2009-07-28 Thread Adrian Hunter
>From 6a8acf9de3b12869c76ff2819e61c54c81b2c753 Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 4309031..0373bdd 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 | MMC_CAP_SD_HIGHSPE

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

2009-07-28 Thread Adrian Hunter
>From 3f9b4e7c30012bbad4f5cf678f2e02e943000b67 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 arch/arm/mach-omap2/board-rx51-peripherals.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 9a0bf67..d2ce938 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -102,6 +103,8 @@ static struct twl4030_hsmmc_info mmc[] = {
.cover_only = true,
.gpio_cd= 160,
.gpio_wp= -EINVAL,
+   .power_saving   = true,
+   .caps   = MMC_CAP_SD,
},
{
.name   = "internal",
@@ -109,6 +112,8 @@ static struct twl4030_hsmmc_info mmc[] = {
.wires  = 8,
.gpio_cd= -EINVAL,
.gpio_wp= -EINVAL,
+   .power_saving   = true,
+   .caps   = MMC_CAP_MMC | MMC_CAP_NONREMOVABLE,
},
{}  /* 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 V2 29/32] omap_hsmmc: protect the card when the cover is open

2009-07-28 Thread Adrian Hunter
>From f1228758121aab11ba2265f2c6fe37f65b3aae03 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 c2b334d..32d5aef 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);
@@ -1728,6 +1783,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) {
@@ -1893,6 +1950,8 @@ static int omap_hsmmc_resume(struct platform_device *pdev)
"Unmask interrupt failed\n");
}
 
+   omap_hsmmc_protect_card(host);
+
/* Notify the core t

[PATCH V2 27/32] omap_hsmmc: pass host capabilities for SD only and MMC only

2009-07-28 Thread Adrian Hunter
>From 6ed0f09877e25af46579c1e7754600d31356e302 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
Date: Mon, 18 May 2009 11:33:26 +0300
Subject: [PATCH] omap_hsmmc: pass host capabilities for SD only and MMC only

Some hosts can accept only certain types of cards.
For example, an eMMC is MMC only and a uSD slot may
be SD only.  Pass host capabilities from the board
through to the driver.

Signed-off-by: Adrian Hunter 
---
 arch/arm/mach-omap2/mmc-twl4030.c |5 ++---
 arch/arm/mach-omap2/mmc-twl4030.h |2 +-
 arch/arm/plat-omap/include/mach/mmc.h |6 +++---
 drivers/mmc/host/omap_hsmmc.c |7 ---
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/mmc-twl4030.c 
b/arch/arm/mach-omap2/mmc-twl4030.c
index f95c702..48765bf 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -464,12 +464,11 @@ 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;
-
if (c->power_saving)
mmc->slots[0].power_saving = 1;
 
+   mmc->slots[0].caps = c->caps;
+
/* 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 a47e685..cb43f52 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.h
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -12,8 +12,8 @@ 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 */
boolpower_saving;   /* Try to sleep or power off when possible */
+   unsigned long caps; /* MMC host capabilities */
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 9390297..48cf2de 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -83,12 +83,12 @@ struct omap_mmc_platform_data {
/* use the internal clock */
unsigned internal_clock:1;
 
-   /* nonremovable e.g. eMMC */
-   unsigned nonremovable:1;
-
/* Try to sleep or power off when possible */
unsigned power_saving:1;
 
+   /* MMC host capabilities */
+   unsigned long caps;
+
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 5213d87..42dfc49 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1664,10 +1664,11 @@ static int __init omap_mmc_probe(struct platform_device 
*pdev)
else if (mmc_slot(host).wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-   if (mmc_slot(host).nonremovable)
-   mmc->caps |= MMC_CAP_NONREMOVABLE;
+   mmc->caps |= mmc_slot(host).caps;
 
-   mmc->caps |= MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
+   /* If no card caps specified then assume them all */
+   if (!(mmc->caps & (MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC)))
+   mmc->caps |= MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
 
omap_hsmmc_init(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 V2 22/32] omap_hsmmc: fix NULL pointer dereference

2009-07-28 Thread Adrian Hunter
>From 0f00e61d9f963d44771f655deaa8f5f4951606a8 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen 
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 
Signed-off-by: Adrian Hunter 
---
 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 d5fb066..4309031 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 V2 15/32] omap_hsmmc: ensure workqueues are empty before suspend

2009-07-28 Thread Adrian Hunter
>From 00dc421d613a159f9b3b9991e62e1c4f3866377f Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
Date: Fri, 24 Apr 2009 13:13:20 +0300
Subject: [PATCH] omap_hsmmc: ensure workqueues are empty before suspend

Signed-off-by: Adrian Hunter 
---
 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 2b242c2..a9f7b74 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;
@@ -1519,30 +1525,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 V2 14/32] omap_hsmmc: set open drain bit correctly

2009-07-28 Thread Adrian Hunter
>From 60dc8abdafb94824a5984f769a05c9b82f784e6b Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 ac1a3bf..2b242c2 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 V2 11/32] ARM: OMAP: mmc-twl4030: add context loss counter support

2009-07-28 Thread Adrian Hunter
>From 53270a4f00a21cdf90bc6d93fa4cfc229096cc15 Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 1541fd4..5be3111 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -192,6 +192,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)
 {
@@ -384,6 +396,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 V2 9/32] omap_hsmmc: add debugfs entry (host registers)

2009-07-28 Thread Adrian Hunter
>From 4ea575689bc8933cb7370871fb10696c3b226b2d Mon Sep 17 00:00:00 2001
From: Denis Karpov 
Date: Wed, 22 Apr 2009 14:21:34 +0200
Subject: [PATCH] omap_hsmmc: add debugfs entry (host registers)

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

Signed-off-by: Denis Karpov 
Signed-off-by: Adrian Hunter 
---
 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 056bcaf..0444de1 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -17,6 +17,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -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;
@@ -1152,6 +1207,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 V2 2/32] mmc: allow host claim / release nesting

2009-07-28 Thread Adrian Hunter
>From 93e60ec163a4ef242e88056c9c642c227f256628 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 V2 31/32] omap_hsmmc: set a large data timeout for commands with busy signal

2009-07-28 Thread Adrian Hunter
>From d9cb1021a2d64c89bbc5763dbbcece68bcc0147c Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 abe1fa1..f5f207d 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


[PATCH V2 30/32] omap_hsmmc: ensure all clock enables and disables are paired

2009-07-28 Thread Adrian Hunter
>From 946bac7ddcc387a15c1391e416b54c3041798883 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 32d5aef..abe1fa1 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);
@@ -1901,7 +1903,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) {
@@ -1932,9 +1935,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 V2 28/32] omap_hsmmc: code refactoring

2009-07-28 Thread Adrian Hunter
>From c3c78e273388f1b74be248ea1c3cb2964b6897a3 Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 42dfc49..c2b334d 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)
+omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data)
 {
   

[PATCH V2 26/32] omap_hsmmc: prevent races with irq handler

2009-07-28 Thread Adrian Hunter
>From 4252559187e96877a2a7ab5a5b0d0631aa51c7d2 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 5121277..5213d87 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 V2 25/32] omap_hsmmc: cater for weird CMD6 behaviour

2009-07-28 Thread Adrian Hunter
>From 8520f6fd74c073a76121619403808f1e3da0f587 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 c7a6d88..5121277 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 V2 24/32] omap_hsmmc: clear interrupt status after init sequence

2009-07-28 Thread Adrian Hunter
>From 1aa0e844f89f4349a6e940079343efbf9e8130d6 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 0373bdd..c7a6d88 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 V2 20/32] omap_hsmmc: put MMC regulator to sleep

2009-07-28 Thread Adrian Hunter
>From a5e206faac032a8e52721904dbdda0bd4ba01ecf Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
Date: Tue, 12 May 2009 20:54:51 +0300
Subject: [PATCH] omap_hsmmc: put MMC regulator to sleep

When a card is not in use, the voltage regulator can be put
to sleep.  This is an alternative to powering the card off,
when powering off is not safe because the card might be
replaced without the driver being aware of it.

That situation happens if:
- the card is removable i.e. not eMMC
- and there is no card detect
- and there is a cover switch but the cover is open

Signed-off-by: Adrian Hunter 
---
 drivers/mmc/host/omap_hsmmc.c |   59 +---
 1 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a3418b5..7a17901 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -160,6 +160,7 @@ struct mmc_omap_host {
int response_busy;
int context_loss;
int dpm_state;
+   int vdd;
 
struct  omap_mmc_platform_data  *pdata;
 };
@@ -1031,10 +1032,12 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
case MMC_POWER_OFF:
mmc_slot(host).set_power(host->dev, host->slot_id,
 0, 0);
+   host->vdd = 0;
break;
case MMC_POWER_UP:
mmc_slot(host).set_power(host->dev, host->slot_id,
 1, ios->vdd);
+   host->vdd = ios->vdd;
break;
case MMC_POWER_ON:
do_send_init_stream = 1;
@@ -1172,19 +1175,20 @@ static void omap_hsmmc_init(struct mmc_omap_host *host)
 
 /*
  * Dynamic power saving handling, FSM:
- *   ENABLED -> DISABLED -> OFF
+ *   ENABLED -> DISABLED -> OFF / REGSLEEP
  * ^___|  |
  * |__|
  *
  * 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
  *
  * Transition handlers return the timeout for the next state transition
  * or negative error.
  */
 
-enum {ENABLED = 0, DISABLED, OFF};
+enum {ENABLED = 0, DISABLED, REGSLEEP, OFF};
 
 /* Handler for [ENABLED -> DISABLED] transition */
 static int omap_mmc_enabled_to_disabled(struct mmc_omap_host *host)
@@ -1221,8 +1225,12 @@ static int omap_mmc_disabled_to_off(struct mmc_omap_host 
*host)
 mmc_slot(host).get_cover_state(host->dev, host->slot_id))) {
mmc_power_save_host(host->mmc);
new_state = OFF;
-   } else
-   new_state = DISABLED;
+   } else {
+   if (mmc_slot(host).set_sleep)
+   mmc_slot(host).set_sleep(host->dev, host->slot_id,
+1, 0, 0);
+   new_state = REGSLEEP;
+   }
 
OMAP_HSMMC_WRITE(host->base, ISE, 0);
OMAP_HSMMC_WRITE(host->base, IE, 0);
@@ -1279,6 +1287,44 @@ static int omap_mmc_off_to_enabled(struct mmc_omap_host 
*host)
return 0;
 }
 
+/* Handler for [REGSLEEP -> ENABLED] transition */
+static int omap_mmc_regsleep_to_enabled(struct mmc_omap_host *host)
+{
+   unsigned long timeout;
+
+   dev_dbg(mmc_dev(host->mmc), "REGSLEEP -> ENABLED\n");
+
+   clk_enable(host->fclk);
+   clk_enable(host->iclk);
+
+   if (clk_enable(host->dbclk))
+   dev_dbg(mmc_dev(host->mmc),
+   "Enabling debounce clk failed\n");
+
+   omap_mmc_restore_ctx(host);
+
+   /*
+* We turned off interrupts and bus power.  Interrupts
+* are turned on by 'mmc_omap_start_command()' so we
+* just need to turn on the bus power here.
+*/
+   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))
+   ;
+
+   if (mmc_slot(host).set_sleep)
+   mmc_slot(host).set_sleep(host->dev, host->slot_id,
+0, host->vdd, 0);
+
+   host->dpm_state = ENABLED;
+
+   return 0;
+}
+
 /*
  * Bring MMC host to ENABLED from any other PM state.
  */
@@ -1289,6 +1335,8 @@ static int omap_mmc_enable(struct mmc_host *mmc)
switch (host->dpm_state) {
case DISABLED:
return omap_mmc_disabled_to_enabled(host);
+   case REGSLEEP:
+   return omap_mmc_regsleep_to_enabled(host);
case OFF:
return omap_mmc_off_to_enabled(host);
default:
@@ 

[PATCH V2 18/32] omap_hsmmc: support for deeper power saving states

2009-07-28 Thread Adrian Hunter
>From ad38a2788cc03924eebc353159561566dc4911e5 Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 67c22c6..3678f0e 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -412,6 +412,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 e618bc0..a3418b5 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_NAME"mmci-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)
+   mmc_host_disable(host->mmc);
+   else
+   mmc_host_l

[PATCH V2 19/32] ARM: OMAP: mmc-twl4030: add regulator sleep / wake function

2009-07-28 Thread Adrian Hunter
>From b5f863cd167b6e3a1fb06be4e51513964fa83cb4 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 3678f0e..f95c702 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -334,6 +334,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)
@@ -427,6 +482,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)
@@ -437,6 +493,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 V2 17/32] omap_hsmmc: make use of new MMC_CAP_NONREMOVABLE host capability

2009-07-28 Thread Adrian Hunter
>From a5af29d59b76a8c09c3d02e46ab25754c1bb2ec6 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 5be3111..67c22c6 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -409,6 +409,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 6222940..e618bc0 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;
+
mmc->caps |= MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
 
omap_hsmmc_init(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 V2 16/32] omap_hsmmc: fix scatter-gather list sanity checking

2009-07-28 Thread Adrian Hunter
>From e37dab1cd1f8ac4bf4e2050a744a842d3d7ffdc1 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen 
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 
Signed-off-by: Adrian Hunter 
---
 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 a9f7b74..6222940 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 V2 10/32] omap_hsmmc: make use of new enable/disable interface

2009-07-28 Thread Adrian Hunter
>From 4ce5c79ed1c42938ee1d42d7cf172e6d1265106d Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 0444de1..f9b7cfe 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;
@@ -1192,6 +1235,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) {
@@ -1220,7 +1265,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);
@@ -1245,6 +1290,7 @@ stati

[PATCH V2 13/32] omap_hsmmc: context save/restore support

2009-07-28 Thread Adrian Hunter
>From 43e9fa346d7e386328876a8535dc8619bd1f47ae Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 c28d055..ac1a3bf 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);
+   break;

[PATCH V2 7/32] mmc: add host capabilities for SD only and MMC only

2009-07-28 Thread Adrian Hunter
>From f22d0fb3d25771f4e380176e99d55068b78f0c17 Mon Sep 17 00:00:00 2001
From: Matt Fleming 
Date: Sat, 25 Jul 2009 23:52:37 +
Subject: [PATCH] mmc: add host capabilities for SD only and MMC only

Some hosts can accept only certain types of cards.  For example, an eMMC
is MMC only and a uSD slot may be SD only.  However the MMC card scanning
logic checks for all card types one by one.

Add host capabilities to specify which card types can be used, and amend
the card scanning logic to skip scanning for those types which cannot be
used.

Signed-off-by: Matt Fleming 
Cc: Adrian Hunter 
Cc: Ian Molton 
Cc: "Roberto A. Foglietta" 
Cc: Jarkko Lavinen 
Cc: Denis Karpov 
Cc: Pierre Ossman 
Cc: Andrew Morton 
---
 drivers/mmc/core/core.c   |   16 +++-
 drivers/mmc/host/at91_mci.c   |2 +-
 drivers/mmc/host/atmel-mci.c  |1 +
 drivers/mmc/host/au1xmmc.c|3 ++-
 drivers/mmc/host/cb710-mmc.c  |3 ++-
 drivers/mmc/host/imxmmc.c |3 ++-
 drivers/mmc/host/mmc_spi.c|2 +-
 drivers/mmc/host/mmci.c   |2 ++
 drivers/mmc/host/mvsdio.c |3 ++-
 drivers/mmc/host/mxcmmc.c |3 ++-
 drivers/mmc/host/omap.c   |2 +-
 drivers/mmc/host/omap_hsmmc.c |2 ++
 drivers/mmc/host/pxamci.c |2 +-
 drivers/mmc/host/s3cmci.c |3 ++-
 drivers/mmc/host/sdhci.c  |2 +-
 drivers/mmc/host/sdricoh_cs.c |3 ++-
 drivers/mmc/host/tifm_sd.c|3 ++-
 drivers/mmc/host/tmio_mmc.c   |3 ++-
 drivers/mmc/host/via-sdmmc.c  |3 ++-
 drivers/mmc/host/wbsd.c   |3 ++-
 include/linux/mmc/host.h  |3 +++
 21 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8d03da4..5fe51ff 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1069,7 +1069,11 @@ void mmc_rescan(struct work_struct *work)
mmc_power_up(host);
mmc_go_idle(host);
 
-   mmc_send_if_cond(host, host->ocr_avail);
+   if ((host->caps & MMC_CAP_SDIO) || (host->caps & MMC_CAP_SD))
+   mmc_send_if_cond(host, host->ocr_avail);
+
+   if (!(host->caps & MMC_CAP_SDIO))
+   goto not_sdio;
 
/*
 * First we search for SDIO...
@@ -1081,6 +1085,10 @@ void mmc_rescan(struct work_struct *work)
goto out;
}
 
+not_sdio:
+   if (!(host->caps & MMC_CAP_SD))
+   goto not_sd;
+
/*
 * ...then normal SD...
 */
@@ -1091,6 +1099,10 @@ void mmc_rescan(struct work_struct *work)
goto out;
}
 
+not_sd:
+   if (!(host->caps & MMC_CAP_MMC))
+   goto not_mmc;
+
/*
 * ...and finally MMC.
 */
@@ -1101,6 +1113,8 @@ void mmc_rescan(struct work_struct *work)
goto out;
}
 
+not_mmc:
+
mmc_release_host(host);
mmc_power_off(host);
 
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e556d42..aa541a5 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -1007,7 +1007,7 @@ static int __init at91_mci_probe(struct platform_device 
*pdev)
mmc->f_min = 375000;
mmc->f_max = 2500;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-   mmc->caps = MMC_CAP_SDIO_IRQ;
+   mmc->caps = MMC_CAP_SDIO_IRQ | MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
 
mmc->max_blk_size = 4095;
mmc->max_blk_count = mmc->max_req_size;
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 7b603e4..907841a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1467,6 +1467,7 @@ static int __init atmci_init_slot(struct atmel_mci *host,
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
mmc->f_max = host->bus_hz / 2;
mmc->ocr_avail  = MMC_VDD_32_33 | MMC_VDD_33_34;
+   mmc->caps = MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
if (slot_data->bus_width >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
 
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index d3f5561..4aae609 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -1003,7 +1003,8 @@ static int __devinit au1xmmc_probe(struct platform_device 
*pdev)
mmc->max_blk_count = 512;
 
mmc->ocr_avail = AU1XMMC_OCR;
-   mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+   mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+   MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
 
host->status = HOST_S_IDLE;
 
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 11efefb..622b420 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -721,7 +721,8 @@ static int __devinit cb710_mmc_init(struct platform_device 
*pdev)
mmc->f_max = val;
mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX];
mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
-   mmc->caps = M

[PATCH V2 6/32] mmc: power off once at removal

2009-07-28 Thread Adrian Hunter
>From cf9505241b8ac5da1a3ebd0b77c1e0f5a149e461 Mon Sep 17 00:00:00 2001
From: Denis Karpov 
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 
Signed-off-by: Adrian Hunter 
---
 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 V2 5/32] mmc: add mmc card sleep and awake support

2009-07-28 Thread Adrian Hunter
>From 44a818d58544b3f796e2e4a7e2331d4f1d14a3f1 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen 
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 
Signed-off-by: Adrian Hunter 
---
 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 struct

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

2009-07-28 Thread Adrian Hunter
>From e6355578d082d94707c8fda1e1342c478019b5c8 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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 = {
.detect = mmc_sd_detect

[PATCH V2 3/32] mmc: add MMC_CAP_NONREMOVABLE host capability

2009-07-28 Thread Adrian Hunter
>From 447937e379db91975b4e834f19dfb1805d813fc4 Mon Sep 17 00:00:00 2001
From: Adrian Hunter 
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 
---
 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  http://vger.kernel.org/m

[PATCH V2 0/32] mmc and omap_hsmmc patches

2009-07-28 Thread Adrian Hunter
Hi

Here is version 2 of our 32 patches for mmc and omap_hsmmc.

They include Matt Fleming's change for card caps, and 2 other fixes:
- use a spin lock rather than enable / diable irq
- make disable delay specified in milliseconds not jiffies because the
value is an int, and jiffies are unsigned long (also millisecs are
better anyway)

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

Adrian Hunter (19):
  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: pass host capabilities for SD only and MMC only
  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

Matt Fleming (1):
  mmc: add host capabilities for SD only and MMC only

 arch/arm/mach-omap2/board-rx51-peripherals.c |5 +
 arch/arm/mach-omap2/mmc-twl4030.c|   77 ++
 arch/arm/mach-omap2/mmc-twl4030.h|2 +
 arch/arm/plat-omap/include/mach/mmc.h|   11 +
 drivers/mmc/core/core.c  |  291 +++-
 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/at91_mci.c  |2 +-
 drivers/mmc/host/atmel-mci.c |1 +
 drivers/mmc/host/au1xmmc.c   |3 +-
 drivers/mmc/host/cb710-mmc.c |3 +-
 drivers/mmc/host/imxmmc.c|3 +-
 drivers/mmc/host/mmc_spi.c   |2 +-
 drivers/mmc/host/mmci.c  |2 +
 drivers/mmc/host/mvsdio.c|3 +-
 drivers/mmc/host/mxcmmc.c|3 +-
 drivers/mmc/host/omap.c  |2 +-
 drivers/mmc/host/omap_hsmmc.c| 1038 +-
 drivers/mmc/host/pxamci.c|2 +-
 drivers/mmc/host/s3cmci.c|3 +-
 drivers/mmc/host/sdhci.c |2 +-
 drivers/mmc/host/sdricoh_cs.c|3 +-
 drivers/mmc/host/tifm_sd.c   |3 +-
 drivers/mmc/host/tmio_mmc.c  |3 +-
 drivers/mmc/host/via-sdmmc.c |3 +-
 drivers/mmc/host/wbsd.c  |3 +-
 include/linux/mmc/card.h |2 +
 include/linux/mmc/core.h |1 +
 include/linux/mmc/host.h |   61 ++
 include/linux/mmc/mmc.h  |3 +
 35 files changed, 1554 insertions(+), 232 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


Re: Camera Interface VS/HS Issue

2009-07-28 Thread matthias schwarz
2009/7/27 matthias schwarz :
> -- Forwarded message --
> From: matthias schwarz 
> Date: 2009/7/27
> Subject: Re: Camera Interface VS/HS Issue
> To: "Aguirre Rodriguez, Sergio Alberto" 
>
>
> 2009/7/27 Aguirre Rodriguez, Sergio Alberto :
>>
>>
>>> -Original Message-
>>> From: matthias schwarz [mailto:matthias.s...@googlemail.com]
>>> Sent: Monday, July 27, 2009 12:37 PM
>>> To: Aguirre Rodriguez, Sergio Alberto
>>> Cc: linux-omap@vger.kernel.org
>>> Subject: Re: Camera Interface VS/HS Issue
>>>
>>> 2009/7/27 Aguirre Rodriguez, Sergio Alberto :
>>> >
>>> >
>>> >> -Original Message-
>>> >> From: matthias schwarz [mailto:matthias.s...@googlemail.com]
>>> >> Sent: Monday, July 27, 2009 11:12 AM
>>> >> To: Aguirre Rodriguez, Sergio Alberto
>>> >> Cc: linux-omap@vger.kernel.org
>>> >> Subject: Re: Camera Interface VS/HS Issue
>>> >>
>>> >> 2009/7/27 Aguirre Rodriguez, Sergio Alberto :
>>> >> >
>>> >> >
>>> >> >> -Original Message-
>>> >> >> From: matthias schwarz [mailto:matthias.s...@googlemail.com]
>>> >> >> Sent: Monday, July 27, 2009 10:59 AM
>>> >> >> To: Aguirre Rodriguez, Sergio Alberto
>>> >> >> Cc: linux-omap@vger.kernel.org
>>> >> >> Subject: Re: Camera Interface VS/HS Issue
>>> >> >>
>>> >> >> 2009/7/27 Aguirre Rodriguez, Sergio Alberto :
>>> >> >> > Matthias,
>>> >> >> >
>>> >> >> > Please avoid top-posting, because its prohibited by the mailing
>>> list
>>> >> >> rules. I'm readjusting it for you below
>>> >> >>
>>> >> >> Oh, i am sorry about that, it is not going to happen again, promise.
>>> >> >> And thank you for readjusting.
>>> >> >
>>> >> > Anytime :)
>>> >> >>
>>> >> >> >
>>> >> >> > From: matthias schwarz [mailto:matthias.s...@googlemail.com]
>>> >> >> >> 2009/7/27 matthias schwarz :
>>> >> >> >> > 2009/7/27 Aguirre Rodriguez, Sergio Alberto :
>>> >> >> >> >> (rearranging mail to avoid top posting..)
>>> >> >> >> >>
>>> >> >> >> >> From: matthias schwarz [mailto:matthias.s...@googlemail.com]
>>> >> >> >> >>> 2009/7/27 Aguirre Rodriguez, Sergio Alberto
>>> :
>>> >> >> >> >>> >
>>> >> >> >> >>> >
>>> >> >> >> >>> >> -Original Message-
>>> >> >> >> >>> >> From: linux-omap-ow...@vger.kernel.org [mailto:linux-omap-
>>> >> >> >> >>> >> ow...@vger.kernel.org] On Behalf Of matthias schwarz
>>> >> >> >> >>> >> Sent: Monday, July 27, 2009 7:47 AM
>>> >> >> >> >>> >> To: linux-omap@vger.kernel.org
>>> >> >> >> >>> >> Subject: Camera Interface VS/HS Issue
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> Hi there,
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> i just recently ran into a problem when trying to let the
>>> ISP
>>> >> >> >> >>> >> (OMAP3530) generate HS/VS signals in SYNC mode.
>>> >> >> >> >>> >> I am building a module to do so.
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> It basically enables the three clocks (cam_ick, cam_mclk
>>> and
>>> >> >> >> >>> >> csi2_96m_fck),
>>> >> >> >> >>> >> then sets
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> ISPCCDC_PIX_LINES_PPLN
>>> >> >> >> >>> >> ISPCCDC_PIX_LINES_HLPRF
>>> >> >> >> >>> >> ISPCCDC_HD_VD_WID_VDW
>>> >> >> >> >>> >> ISPCCDC_HD_VD_WID_HDW
>>> >> >> >> >>> >> ISPCCDC_SYN_MODE_VDHDEN
>>> >> >> >> >>> >> ISPCCDC_SYN_MODE_VDHDOUT
>>> >> >> >> >>> >> ISPCCDC_CFG_VDLC
>>> >> >> >> >>> >> ISPTCTRL_CTRL_DIVA
>>> >> >> >> >>> >> ISPTCTRL_CTRL_DIVB
>>> >> >> >> >>> >> ISPCCDC_PCR
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> via some calls to ioremap and ioread32/iowrite32.
>>> >> >> >> >>> >> My question now is the following:
>>> >> >> >> >>> >> when i hook an oscilloscope to the corresponding pins
>>> >> (CAM_VS,
>>> >> >> >> CAM_HS,
>>> >> >> >> >>> >> CAM_XCLKA) i can see that only the CAM_XCLKA is working
>>> >> >> correctly,
>>> >> >> >> >>> >> also at the configured frequency.
>>> >> >> >> >>> >> Both, CAM_VS and CAM_HS remain at low voltage all the
>>> time,
>>> >> even
>>> >> >> >> when
>>> >> >> >> >>> >> i switch their polarities (ISPCCDC_SYN_MODE_VDPOL,
>>> >> >> >> >>> >> ISPCCDC_SYN_MODE_HDPOL) that behavior does not change and
>>> >> >> signals
>>> >> >> >> >>> >> always remain at low voltage.
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> Could someone help me out, or give me a hint what i might
>>> be
>>> >> >> >> missing
>>> >> >> >> >>> >> to generate those output signals correctly?
>>> >> >> >> >>> >
>>> >> >> >> >>> > Matthias,
>>> >> >> >> >>> >
>>> >> >> >> >>> > Can you please provide a register dump of the above values?
>>> >> >> >> >>> >
>>> >> >> >> >>> > Looks like you're touching the adequate registers though...
>>> >> But I
>>> >> >> >> can
>>> >> >> >> >>> help you more looking at the values.
>>> >> >> >> >>> >
>>> >> >> >> >>> Sure i can,
>>> >> >> >> >>> register values are the following:
>>> >> >> >> >>>
>>> >> >> >> >>> ccdc_pix_lines: 0x050005a0
>>> >> >> >> >>>
>>> >> >> >> >>> ccdc_hd_vd_wid: 0x00320064
>>> >> >> >> >>>
>>> >> >> >> >>> ccdc_syn_mode: 0x00050c0c
>>> >> >> >> >>
>>> >> >> >> >> This is wrong, because:
>>> >> >> >> >>
>>> >> >> >> >> Bit0 sets directions of cam_hs and cam_vs signals