RE: [SHDCI] Heavy (thousands) DMA leaks

2015-08-03 Thread Chen Bough
Hi Js,

I carefully review my patch, all the DMA memory mapped in sdhci_pre_req() is 
unmapped in sdhci_post_req.

Can you provide the method of your testing DMA leaks?  You said over 4000 
leaked mappings during one card transfer, if true, 
We can't map any dma memory after some sd transfer, do you meet this?


Best Regards
Haibo Chen



 -Original Message-
 From: Jiri Slaby [mailto:jsl...@suse.cz]
 Sent: Thursday, July 30, 2015 5:32 PM
 To: Chen Haibo-B51421
 Cc: Ulf Hansson; linux-mmc@vger.kernel.org; Linux kernel mailing list
 Subject: [SHDCI] Heavy (thousands) DMA leaks
 
 Hi,
 
 after
 commit 348487cb28e66b032bae1b38424d81bf5b08
 Author: Haibo Chen haibo.c...@freescale.com
 Date:   Tue Dec 9 17:04:05 2014 +0800
 
 mmc: sdhci: use pipeline mmc requests to improve performance
 
 I see heavy DMA leaks which result in warnings of the dma api debug code:
 WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:509 add_dma_entry+0x138/0x150()
 DMA-API: exceeded 7 overlapping mappings of cacheline 0x0b20ec00
 
 
 
 And mainly this one upon sdhci module removal. It is over 4000 leaked
 mappings during one card transfer.
 mmc0: card e624 removed
 [ cut here ]
 WARNING: CPU: 2 PID: 1263 at lib/dma-debug.c:974
 dma_debug_device_change+0x158/0x1c0()
 pci :02:00.0: DMA-API: device driver has pending DMA allocations
 while released from device [count=4041] One of leaked entries details:
 [device address=0xddff]
 [size=65536 bytes] [mapped with DMA_FROM_DEVICE] [mapped as scather-
 gather] Modules linked in:
 CPU: 2 PID: 1263 Comm: bash Tainted: GW   4.2.0-rc4 #12
 Hardware name: LENOVO 23252SG/23252SG, BIOS G2ET33WW (1.13 ) 07/24/2012
  81cc5e32 8800d03c3b68 81820938 
  8800d03c3bb8 8800d03c3ba8 810b827a 000100260021
  88030e50 0fc9 88030d95aeb8 88030e4ddd68 Call
 Trace:
  [81820938] dump_stack+0x4c/0x6e  [810b827a]
 warn_slowpath_common+0x8a/0xc0  [810b82f6]
 warn_slowpath_fmt+0x46/0x50  [813248c8]
 dma_debug_device_change+0x158/0x1c0
  [810d4e9d] notifier_call_chain+0x4d/0x80  [810d51fd]
 __blocking_notifier_call_chain+0x4d/0x70
  [810d5236] blocking_notifier_call_chain+0x16/0x20
  [814db395] __device_release_driver+0x105/0x130
  [814db3e3] device_release_driver+0x23/0x30
 [814d95ca] unbind_store+0xba/0xe0  [8123c638] ?
 kernfs_fop_write+0xe8/0x170  [814d8ac4]
 drv_attr_store+0x24/0x30  [8123ce4a] sysfs_kf_write+0x3a/0x50
 [8123c670] kernfs_fop_write+0x120/0x170  [811ce9e8]
 __vfs_write+0x28/0xe0  [811d1209] ? __sb_start_write+0x49/0xe0
 [810e3ba5] ? local_clock+0x25/0x30  [811cf041]
 vfs_write+0xa1/0x170  [810e43c4] ? vtime_account_user+0x54/0x60
 [811cfce6] SyS_write+0x46/0xa0  [81180f83] ?
 context_tracking_user_exit+0x13/0x20
  [8182a017] entry_SYSCALL_64_fastpath+0x12/0x6a
 ---[ end trace 398181ad32332b33 ]---
 Mapped at:
  [81324492] debug_dma_map_sg+0x122/0x140  [81616dd3]
 sdhci_pre_dma_transfer+0xc3/0x1b0  [81616f02]
 sdhci_pre_req+0x42/0x70  [81601492] mmc_pre_req+0x42/0x60
 [8160290e] mmc_start_req+0x3e/0x400
 
 I already fixed one symptom -- memory corruption. Could you revisit the
 commit once again, as there is surely at least one more bug?
 
 thanks,
 --
 js
 suse labs
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] mmc: dw_mmc: Fix coding style issues

2015-08-03 Thread Shawn Lin
This patch fixes the following issues reported by checkpatch.pl:
- use -EINVAL instead of -ENOSYS, to fix warning message:
   ENOSYS means 'invalid syscall nr' and nothing else
- split lines whose length is greater than 80 characters
- avoid quoted string split across lines
- use min_t instead of min, to fix warning message:
   min() should probably be min_t(int, cnt, host-part_buf_count)
- fix missing a blank line after declarations

Signed-off-by: Shawn Lin shawn@rock-chips.com

---

Changes in v2:
- Keep consistency of comments
- Rebase on https://patchwork.kernel.org/patch/6672581

 drivers/mmc/host/dw_mmc.c | 90 +--
 1 file changed, 56 insertions(+), 34 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index e41fb74..3f070d9 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -238,8 +238,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, 
struct mmc_command *cmd)
struct dw_mci *host = slot-host;
const struct dw_mci_drv_data *drv_data = slot-host-drv_data;
u32 cmdr;
-   cmd-error = -EINPROGRESS;
 
+   cmd-error = -EINPROGRESS;
cmdr = cmd-opcode;
 
if (cmd-opcode == MMC_STOP_TRANSMISSION ||
@@ -374,7 +374,7 @@ static void dw_mci_start_command(struct dw_mci *host,
 cmd-arg, cmd_flags);
 
mci_writel(host, CMDARG, cmd-arg);
-   wmb();
+   wmb(); /* drain writebuffer */
dw_mci_wait_while_busy(host, cmd_flags);
 
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
@@ -383,6 +383,7 @@ static void dw_mci_start_command(struct dw_mci *host,
 static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data)
 {
struct mmc_command *stop = data-stop ? data-stop : host-stop_abort;
+
dw_mci_start_command(host, stop, host-stop_cmdr);
 }
 
@@ -467,6 +468,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
 {
unsigned int desc_len;
int i;
+
if (host-dma_64bit_address == 1) {
struct idmac_desc_64addr *desc_first, *desc_last, *desc;
 
@@ -474,6 +476,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
 
for (i = 0; i  sg_len; i++) {
unsigned int length = sg_dma_len(data-sg[i]);
+
u64 mem_addr = sg_dma_address(data-sg[i]);
 
for ( ; length ; desc++) {
@@ -518,6 +521,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
 
for (i = 0; i  sg_len; i++) {
unsigned int length = sg_dma_len(data-sg[i]);
+
u32 mem_addr = sg_dma_address(data-sg[i]);
 
for ( ; length ; desc++) {
@@ -557,7 +561,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
desc_last-des0 |= cpu_to_le32(IDMAC_DES0_LD);
}
 
-   wmb();
+   wmb(); /* drain writebuffer */
 }
 
 static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
@@ -575,6 +579,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, 
unsigned int sg_len)
temp |= SDMMC_CTRL_USE_IDMAC;
mci_writel(host, CTRL, temp);
 
+   /* drain writebuffer */
wmb();
 
/* Enable the IDMAC */
@@ -622,7 +627,9 @@ static int dw_mci_idmac_init(struct dw_mci *host)
host-ring_size = PAGE_SIZE / sizeof(struct idmac_desc);
 
/* Forward link the descriptor list */
-   for (i = 0, p = host-sg_cpu; i  host-ring_size - 1; i++, 
p++) {
+   for (i = 0, p = host-sg_cpu;
+i  host-ring_size - 1;
+i++, p++) {
p-des3 = cpu_to_le32(host-sg_dma +
(sizeof(struct idmac_desc) * (i + 1)));
p-des1 = 0;
@@ -751,7 +758,7 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, 
struct mmc_data *data)
u32 fifo_width = 1  host-data_shift;
u32 blksz_depth = blksz / fifo_width, fifoth_val;
u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
-   int idx = (sizeof(mszs) / sizeof(mszs[0])) - 1;
+   int idx = ARRAY_SIZE(mszs) - 1;
 
tx_wmark = (host-fifo_depth) / 2;
tx_wmark_invers = host-fifo_depth - tx_wmark;
@@ -876,6 +883,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, 
struct mmc_data *data)
 static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
 {
unsigned long irqflags;
+   int flags = SG_MITER_ATOMIC;
u32 temp;
 
data-error = -EINPROGRESS;
@@ -892,7 +900,6 @@ static void dw_mci_submit_data(struct dw_mci *host, struct 
mmc_data *data)
}
 
if (dw_mci_submit_data_dma(host, data)) {
-   int flags = SG_MITER_ATOMIC;
if (host-data-flags  

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

2015-08-03 Thread Andreas Fenkart
Hi Kishon,

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

/Andi

2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I kis...@ti.com:
 This patch series does the following
 *) Uses devm_regulator_get_optional() for vmmc and then removes the
CONFIG_REGULATOR check altogether.
 *) return on -EPROBE_DEFER
 *) enable/disable vmmc_aux regulator based on prior state

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

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

 Kishon Vijay Abraham I (16):
   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
 -EPROBE_DEFER
   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
   mmc: host: omap_hsmmc: add separate functions for enable/disable
 supply
   mmc: host: omap_hsmmc: add separate function to set pbias
   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
   mmc: host: omap_hsmmc: don't use -set_power to set initial regulator
 state
   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
 prior state
   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
   mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage
   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

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

  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
  arch/arm/boot/dts/am57xx-beagle-x15.dts|1 -
  drivers/mmc/host/omap_hsmmc.c  |  333 
 +---
  3 files changed, 216 insertions(+), 120 deletions(-)

 --
 1.7.9.5

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


Re: [SHDCI] Heavy (thousands) DMA leaks

2015-08-03 Thread Jiri Slaby
Hi,

On 08/03/2015, 11:30 AM, Chen Bough wrote:
 I carefully review my patch, all the DMA memory mapped in sdhci_pre_req() is 
 unmapped in sdhci_post_req.

I suspect 'host_cookie' or 'next' handling is bad somewhere. But I don't
know...

 Can you provide the method of your testing DMA leaks?

boot kernel with CONFIG_DMA_API_DEBUG
insert the card
mount it
rsync from the card ~200 MB
umount it
unload the sdhci driver
the leak warning is reported

I am not sure whether suspend-resume is needed after the first step.

 You said over 4000 leaked mappings during one card transfer, if true, 
 We can't map any dma memory after some sd transfer, do you meet this?

Yes, I see:
sdhci-pci :02:00.0: swiotlb buffer is full (sz: 65536 bytes)
after some time. The driver falls back to non-DMA transfers after that.
It also generates a warning about that:
WARNING: CPU: 0 PID: 0 at drivers/mmc/host/sdhci.c:857
sdhci_prepare_data+0x8ec/0x900 [sdhci]()

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


Re: [RFC PATCH v1 1/1] mmc: sprd: add MMC host driver for Spreadtrum SoC

2015-08-03 Thread Shawn Lin

On 2015-7-31 21:02, wuh...@gmail.com wrote:

This patch adds MMC host driver for Spreadtrum SoC.
The following coding style may be not meet kernel coding style.
I am not sure this kind of coding style is better or worse.
1) A macro that represent some bits of a register is added a prefix __,
 for example:
 #define SDHOST_16_HOST_CTRL_2   0x3E
 #define __TIMING_MODE_SDR12 0x
 #define __TIMING_MODE_SDR25 0x0001
 #define __TIMING_MODE_SDR50 0x0002
 I think it is more useful to distinguish a register from a bit of this
 register.
2) A function in order to operate a register is also added a prefix _.
 If the functions(A) call other function(B), we added a prefix __ before 
B,
 for example:
 static inline void _sdhost_enable_int(struct sdhost_host *host, u32 mask)
 {
 __local_writel(mask, host, SDHOST_32_INT_ST_EN);
 __local_writel(mask, host, SDHOST_32_INT_SIG_EN);
 }
 I think this make the relationship of the function call more explicit.

Signed-off-by: Billows Wu(WuHongtao) wuh...@gmail.com
---
  drivers/mmc/host/Kconfig   |6 +
  drivers/mmc/host/Makefile  |1 +
  drivers/mmc/host/sprd_sdhost.c | 1183 
  drivers/mmc/host/sprd_sdhost.h |  592 
  drivers/mmc/host/sprd_sdhost_debugfs.c |  213 ++
  drivers/mmc/host/sprd_sdhost_debugfs.h |   27 +
  6 files changed, 2022 insertions(+)
  create mode 100644 drivers/mmc/host/sprd_sdhost.c
  create mode 100644 drivers/mmc/host/sprd_sdhost.h
  create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.c
  create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.h

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index fd9a58e..c43d938 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -264,6 +264,12 @@ config MMC_SDHCI_SPEAR

  If you have a controller with this interface, say Y or M here.

+config SPRD_MMC_SDHOST
+   tristate Spreadtrum SDIO host Controller support
+   help
+ This selects the SDIO Host Controller in spreadtrum platform
+
+ If you have a controller with this interface, say Y or M here.
  If unsure, say N.

  config MMC_SDHCI_S3C_DMA
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e928d61..e00227f 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835)   += 
sdhci-bcm2835.o
  obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o
  obj-$(CONFIG_MMC_SDHCI_MSM)   += sdhci-msm.o
  obj-$(CONFIG_MMC_SDHCI_ST)+= sdhci-st.o
+obj-$(CONFIG_SPRD_MMC_SDHOST)  += sprd_sdhost.o sprd_sdhost_debugfs.o

  ifeq ($(CONFIG_CB710_DEBUG),y)
CFLAGS-cb710-mmc+= -DDEBUG
diff --git a/drivers/mmc/host/sprd_sdhost.c b/drivers/mmc/host/sprd_sdhost.c
new file mode 100644
index 000..18c9449
--- /dev/null
+++ b/drivers/mmc/host/sprd_sdhost.c
@@ -0,0 +1,1183 @@
+/*
+ * linux/drivers/mmc/host/sprd_sdhost.c - Secure Digital Host Controller
+ * Interface driver
+ *
+ * Copyright (C) 2015 Spreadtrum corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ */
+
+#include linux/delay.h
+#include linux/dma-mapping.h
+#include linux/highmem.h
+#include linux/io.h
+#include linux/module.h
+#include linux/of.h
+#include linux/of_device.h
+#include linux/of_gpio.h
+#include linux/platform_device.h
+#include linux/pm_runtime.h
+#include linux/regulator/consumer.h
+#include linux/slab.h
+#include linux/scatterlist.h
+
+#include sprd_sdhost.h
+#include sprd_sdhost_debugfs.h
+
+#define DRIVER_NAME sdhost
+#define SDHOST_CAPS \
+   (MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | \
+   MMC_CAP_ERASE |  MMC_CAP_UHS_SDR50 | \
+   MMC_CAP_CMD23 | MMC_CAP_HW_RESET)
+
+struct sdhost_caps_data {
+   char *name;
+   u32 ocr_avail;
+   u32 caps;
+   u32 caps2;
+   u32 pm_caps;
+   u32 base_clk;
+   u32 signal_default_voltage;
+};
+
+struct sdhost_caps_data caps_info_map[] = {
+   {
+   .name = sd,
+   .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31,
+   .caps = SDHOST_CAPS,
+   .caps2 = MMC_CAP2_HC_ERASE_SZ,
+   .base_clk = 19200,
+   .signal_default_voltage = 300,
+   },
+   {
+   .name = wifi,
+   .ocr_avail = MMC_VDD_165_195 | MMC_VDD_29_30 |
+   MMC_VDD_30_31 | MMC_VDD_32_33 | MMC_VDD_33_34,
+   .caps = SDHOST_CAPS | MMC_CAP_POWER_OFF_CARD |
+   MMC_CAP_UHS_SDR12,
+   .base_clk = 7600,
+   },
+   {
+   .name = emmc,
+   

Re: [PATCH] mmc: dw_mmc: Fix coding style issues

2015-08-03 Thread Shawn Lin

On 2015-8-3 12:07, Jaehoon Chung wrote:

Hi, Shawn.

On 07/28/2015 12:06 PM, Shawn Lin wrote:

This patch fixes the following issues reported by checkpatch.pl:
- use -EINVAL instead of -ENOSYS, to fix warning message:
   ENOSYS means 'invalid syscall nr' and nothing else
- split lines whose length is greater than 80 characters
- avoid quoted string split across lines
- use min_t instead of min, to fix warning message:
   min() should probably be min_t(int, cnt, host-part_buf_count)


Thanks for fixing coding style.
But i will apply this patch(https://patchwork.kernel.org/patch/6672581/).
So if you can fix with this patch, then it's helpful to me.
If you can't, i will modify your patch before applying.
How about?



Okay, I will fix with this patch and resend it.



Signed-off-by: Shawn Lin shawn@rock-chips.com
---

  drivers/mmc/host/dw_mmc.c | 85 ++-
  1 file changed, 54 insertions(+), 31 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 40e9d8e..6aede38 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -235,8 +235,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, 
struct mmc_command *cmd)
struct dw_mci *host = slot-host;
const struct dw_mci_drv_data *drv_data = slot-host-drv_data;
u32 cmdr;
-   cmd-error = -EINPROGRESS;

+   cmd-error = -EINPROGRESS;
cmdr = cmd-opcode;

if (cmd-opcode == MMC_STOP_TRANSMISSION ||
@@ -371,6 +371,7 @@ static void dw_mci_start_command(struct dw_mci *host,
 cmd-arg, cmd_flags);

mci_writel(host, CMDARG, cmd-arg);
+   /* Make sure CMDARG is configured before CMD */
wmb();
dw_mci_wait_while_busy(host, cmd_flags);

@@ -380,6 +381,7 @@ static void dw_mci_start_command(struct dw_mci *host,
  static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data)
  {
struct mmc_command *stop = data-stop ? data-stop : host-stop_abort;
+
dw_mci_start_command(host, stop, host-stop_cmdr);
  }

@@ -463,6 +465,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
unsigned int sg_len)
  {
int i;
+
if (host-dma_64bit_address == 1) {
struct idmac_desc_64addr *desc = host-sg_cpu;

@@ -524,7 +527,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, 
struct mmc_data *data,
desc-des0 |= cpu_to_le32(IDMAC_DES0_LD);
}

-   wmb();
+   wmb(); /* drain writebuffer */
  }

  static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
@@ -542,7 +545,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, 
unsigned int sg_len)
temp |= SDMMC_CTRL_USE_IDMAC;
mci_writel(host, CTRL, temp);

-   wmb();
+   wmb(); /* drain writebuffer */

/* Enable the IDMAC */
temp = mci_readl(host, BMOD);
@@ -589,7 +592,9 @@ static int dw_mci_idmac_init(struct dw_mci *host)
host-ring_size = PAGE_SIZE / sizeof(struct idmac_desc);

/* Forward link the descriptor list */
-   for (i = 0, p = host-sg_cpu; i  host-ring_size - 1; i++, 
p++) {
+   for (i = 0, p = host-sg_cpu;
+i  host-ring_size - 1;
+i++, p++) {
p-des3 = cpu_to_le32(host-sg_dma +
(sizeof(struct idmac_desc) * (i + 1)));
p-des1 = 0;
@@ -718,7 +723,7 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, 
struct mmc_data *data)
u32 fifo_width = 1  host-data_shift;
u32 blksz_depth = blksz / fifo_width, fifoth_val;
u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
-   int idx = (sizeof(mszs) / sizeof(mszs[0])) - 1;
+   int idx = ARRAY_SIZE(mszs) - 1;

tx_wmark = (host-fifo_depth) / 2;
tx_wmark_invers = host-fifo_depth - tx_wmark;
@@ -843,6 +848,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, 
struct mmc_data *data)
  static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
  {
unsigned long irqflags;
+   int flags = SG_MITER_ATOMIC;
u32 temp;

data-error = -EINPROGRESS;
@@ -859,7 +865,6 @@ static void dw_mci_submit_data(struct dw_mci *host, struct 
mmc_data *data)
}

if (dw_mci_submit_data_dma(host, data)) {
-   int flags = SG_MITER_ATOMIC;
if (host-data-flags  MMC_DATA_READ)
flags |= SG_MITER_TO_SG;
else
@@ -906,6 +911,7 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, 
u32 arg)
unsigned int cmd_status = 0;

mci_writel(host, CMDARG, arg);
+   /* Make sure CMDARG is configured before CMD */
wmb();
dw_mci_wait_while_busy(host, cmd);
mci_writel(host, CMD, SDMMC_CMD_START | cmd);
@@ -1019,6 +1025,7 @@ static 

[PATCH] mmc: dw_mmc: fix pio mode when internal dmac is enabled

2015-08-03 Thread Heiko Stübner
The dw_mci_init_dma() may decide to not use dma, but pio instead, caused
by things like wrong dma settings in the system.

Till now the code dw_mci_init_slot() always assumed that dma is available
when CONFIG_MMC_DW_IDMAC was defined, ignoring the host-use_dma var
set during dma init.

So when now the dma init failed for whatever reason, the transfer sizes
would still be set for dma transfers, especially including the maximum
block-count calculated from host-ring_size and resulting in a

[4.991109] [ cut here ]
[4.99] kernel BUG at drivers/mmc/core/core.c:256!
[4.991113] Internal error: Oops - BUG: 0 [#1] SMP ARM

because host-ring_size is 0 in this case and the slot init code uses
the wrong code to calculate the values.

Fix this by selecting the correct calculations using the host-use_dma
variable instead of the CONFIG_MMC_DW_IDMAC config option.

Signed-off-by: Heiko Stuebner he...@sntech.de
---
 drivers/mmc/host/dw_mmc.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 40e9d8e..9ec3521 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2391,19 +2391,20 @@ static int dw_mci_init_slot(struct dw_mci *host, 
unsigned int id)
mmc-max_seg_size = host-pdata-blk_settings-max_seg_size;
} else {
/* Useful defaults if platform data is unset. */
-#ifdef CONFIG_MMC_DW_IDMAC
-   mmc-max_segs = host-ring_size;
-   mmc-max_blk_size = 65536;
-   mmc-max_seg_size = 0x1000;
-   mmc-max_req_size = mmc-max_seg_size * host-ring_size;
-   mmc-max_blk_count = mmc-max_req_size / 512;
-#else
-   mmc-max_segs = 64;
-   mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */
-   mmc-max_blk_count = 512;
-   mmc-max_req_size = mmc-max_blk_size * mmc-max_blk_count;
-   mmc-max_seg_size = mmc-max_req_size;
-#endif /* CONFIG_MMC_DW_IDMAC */
+   if (host-use_dma) {
+   mmc-max_segs = host-ring_size;
+   mmc-max_blk_size = 65536;
+   mmc-max_seg_size = 0x1000;
+   mmc-max_req_size = mmc-max_seg_size * host-ring_size;
+   mmc-max_blk_count = mmc-max_req_size / 512;
+   } else {
+   mmc-max_segs = 64;
+   mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */
+   mmc-max_blk_count = 512;
+   mmc-max_req_size = mmc-max_blk_size *
+   mmc-max_blk_count;
+   mmc-max_seg_size = mmc-max_req_size;
+   }
}
 
if (dw_mci_get_cd(mmc))
-- 
2.1.4


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


Re: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1

2015-08-03 Thread Dong Aisheng
On Mon, Aug 03, 2015 at 09:08:28AM +0800, Chen Haibo-B51421 wrote:
 
 
  -Original Message-
  From: Dong Aisheng [mailto:aisheng.d...@freescale.com]
  Sent: Friday, July 31, 2015 10:58 PM
  To: Chen Haibo-B51421
  Cc: robh...@kernel.org; pawel.m...@arm.com; mark.rutl...@arm.com;
  ijc+devicet...@hellion.org.uk; ga...@codeaurora.org; shawn...@kernel.org;
  ker...@pengutronix.de; li...@arm.linux.org.uk; ulf.hans...@linaro.org;
  johan.dery...@barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
  devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-arm-
  ker...@lists.infradead.org; linux-mmc@vger.kernel.org
  Subject: Re: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the
  burst_length_enable bit to 1
  
  On Wed, Jul 29, 2015 at 05:03:57PM +0800, Haibo Chen wrote:
   Currently we find that if a usdhc is choosed to boot system, then ROM
   code will set the burst length enable bit of this usdhc as 0.
  
   This will make performance drop a lot if this usdhc's burst length is
   16. So this patch set back the burst_length_enable bit as 1, which is
   the default value, and means burst length is enabled for INCR.
  
   Signed-off-by: Haibo Chen haibo.c...@freescale.com
   ---
drivers/mmc/host/sdhci-esdhc-imx.c | 11 +++
1 file changed, 11 insertions(+)
  
   diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
   b/drivers/mmc/host/sdhci-esdhc-imx.c
   index 37d0095..dd945e5 100644
   --- a/drivers/mmc/host/sdhci-esdhc-imx.c
   +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
   @@ -32,6 +32,7 @@
#include sdhci-esdhc.h
  
#define  ESDHC_CTRL_D3CD 0x08
   +#define ESDHC_BURST_LEN_EN_INCR  (1  27)
/* VENDOR SPEC register */
#define ESDHC_VENDOR_SPEC0xc0
#define  ESDHC_VENDOR_SPEC_SDIO_QUIRK(1  1)
   @@ -1158,6 +1159,16 @@ static int sdhci_esdhc_imx_probe(struct
  platform_device *pdev)
 host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 host-mmc-caps |= MMC_CAP_1_8V_DDR;
  
   + /*
   +  * ROM code will change the burst_length_enable setting to
   +  * zero if this usdhc is choosed to boot system. Change it
   +  * back here, otherwise it will impact the performance a
   +  * lot if the burst length is 16.
  
  Can you clarify a bit more on why performance drops a lot if burst length
  is 16?
  Caused by the burst length setting did not work due to ROM disabled it?
 
 
 [haibo] this bit is used to enable/disable the burst length for the external 
 AHB2AXI bridge, 
 It's useful especially for INCR transfer because without burst length 
 indicator, the AHB2AXI 
 bridge doesn't know the burst length in advance. And without burst length 
 indicator, AHB INCR 
 transfers can only be converted to singles on the AXI side.
 
 Seting this bit means burst length enabled for INCR.
 If this bit is not set, performance will drop a lot when burst length is 8 or 
 16. I will add 
 this in the commit log.
  

Thanks for clarify.
One question: with this patch, can we set the default watermark level to 64 by 
default for all
SoC types?

If yes, we may not need patch 5 anymore.
[PATCH v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length

Regards
Dong Aisheng

  
  Regards
  Dong Aisheng
  
   +  */
   + writel(readl(host-ioaddr + SDHCI_HOST_CONTROL)
   + | ESDHC_BURST_LEN_EN_INCR,
   + host-ioaddr + SDHCI_HOST_CONTROL);
   +
 if (!(imx_data-socdata-flags  ESDHC_FLAG_HS200))
 host-quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
  
   --
   1.9.1
  
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

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

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

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

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

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

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

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

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

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

-- 
1.7.9.5

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


Re: [PATCH v2] mmc: dw_mmc: Add external dma interface support

2015-08-03 Thread Heiko Stübner
Hi Shawn,

Am Montag, 3. August 2015, 11:27:19 schrieb Shawn Lin:
 DesignWare MMC Controller can support two types of DMA
 mode: external dma and internal dma. We get a RK312x platform
 integrated dw_mmc and ARM pl330 dma controller. This patch add
 edmac ops to suuport these platforms. I've tested it on RK312x
 platform with edmac mode and RK3288 platform with idmac mode.
 
 Patch is based on next of git://git.linaro.org/people/ulf.hansson/mmc
 
 Signed-off-by: Shawn Lin shawn@rock-chips.com
 
 ---
 
 Changes in v2:
 - Fix typo of dev_info msg
 - remove unused dmach from declaration of dw_mci_dma_slave
 
  drivers/mmc/host/Kconfig|  24 +-
  drivers/mmc/host/dw_mmc-pltfm.c |   4 +
  drivers/mmc/host/dw_mmc.c   | 169
 ++-- include/linux/mmc/dw_mmc.h  | 
 18 -
  4 files changed, 205 insertions(+), 10 deletions(-)
 
 diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
 index 6a0f9c7..2a66b08 100644
 --- a/drivers/mmc/host/Kconfig
 +++ b/drivers/mmc/host/Kconfig
 @@ -607,16 +607,36 @@ config MMC_DW
   help
 This selects support for the Synopsys DesignWare Mobile Storage IP
 block, this provides host support for SD and MMC interfaces, in both
 -   PIO and external DMA modes.
 +   PIO, internal DMA mode and external DMA modes.
 +
 +choice
 + prompt DesignWare MMC transfer mode
 + depends on MMC_DW
 +
 +config MMC_DW_PIO
 + bool Use PIO transfers only
 + help
 +   Use PIO to transfer data between memory and the hardware.
 +   PIO is slower than DMA as it requires CPU instructions to
 +   move the data. This has been the traditional default for
 +   the DW MCI driver.
 
  config MMC_DW_IDMAC
   bool Internal DMAC interface
 - depends on MMC_DW
   help
 This selects support for the internal DMAC block within the Synopsys
 Designware Mobile Storage IP block. This disables the external DMA
 interface.
 
 +config MMC_DW_EDMAC
 + bool External DMAC interface
 + help
 +   This selects support for the external DMAC block outside the Synopsys
 +   Designware Mobile Storage IP block. This disables the internal DMA
 +   interface.
 +
 +endchoice
 +

more a drive-by comment:

This should definitly not be a choice. We're in multiplatform times, where 
you can have support for a multitude of socs using dw_mmc in one kernel. And 
one might want to use pio, one might want to use the internal dma while 
another one might want to use the external dma.

So which dma to use should definitly be decided at runtime and not at compile-
time.


Heiko

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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


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

2015-08-03 Thread Kishon Vijay Abraham I
From: Roger Quadros rog...@ti.com

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

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

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

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


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

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

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

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

Thanks
Kishon

 
 /Andi
 
 2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I kis...@ti.com:
 This patch series does the following
 *) Uses devm_regulator_get_optional() for vmmc and then removes the
CONFIG_REGULATOR check altogether.
 *) return on -EPROBE_DEFER
 *) enable/disable vmmc_aux regulator based on prior state

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

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

 Kishon Vijay Abraham I (16):
   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
 -EPROBE_DEFER
   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
   mmc: host: omap_hsmmc: add separate functions for enable/disable
 supply
   mmc: host: omap_hsmmc: add separate function to set pbias
   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
   mmc: host: omap_hsmmc: don't use -set_power to set initial regulator
 state
   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
 prior state
   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
   mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage
   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

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

  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
  arch/arm/boot/dts/am57xx-beagle-x15.dts|1 -
  drivers/mmc/host/omap_hsmmc.c  |  333 
 +---
  3 files changed, 216 insertions(+), 120 deletions(-)

 --
 1.7.9.5

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


Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400

2015-08-03 Thread Dong Aisheng
On Sun, Aug 02, 2015 at 04:59:04PM +0800, Chen Haibo-B51421 wrote:
 
 
  -Original Message-
  From: Dong Aisheng [mailto:aisheng.d...@freescale.com]
  Sent: Friday, July 31, 2015 10:15 PM
  To: Chen Haibo-B51421
  Cc: robh...@kernel.org; pawel.m...@arm.com; mark.rutl...@arm.com;
  ijc+devicet...@hellion.org.uk; ga...@codeaurora.org; shawn...@kernel.org;
  ker...@pengutronix.de; li...@arm.linux.org.uk; ulf.hans...@linaro.org;
  johan.dery...@barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
  devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-arm-
  ker...@lists.infradead.org; linux-mmc@vger.kernel.org
  Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
  support HS400
  
  On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
   The imx7d usdhc is derived from imx6sx, the difference is that imx7d
   support HS400.
  
   So introduce a new compatible string for imx7d and add HS400 support
   for imx7d usdhc.
  
   Signed-off-by: Haibo Chen haibo.c...@freescale.com
   ---
drivers/mmc/host/sdhci-esdhc-imx.c | 66
   ++
1 file changed, 66 insertions(+)
  
   diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
   b/drivers/mmc/host/sdhci-esdhc-imx.c
   index c6b9f64..b441eed 100644
   --- a/drivers/mmc/host/sdhci-esdhc-imx.c
   +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
   @@ -44,6 +44,7 @@
#define  ESDHC_MIX_CTRL_EXE_TUNE (1  22)
#define  ESDHC_MIX_CTRL_SMPCLK_SEL   (1  23)
#define  ESDHC_MIX_CTRL_FBCLK_SEL(1  25)
   +#define  ESDHC_MIX_CTRL_HS400_EN (1  26)
/* Bits 3 and 6 are not SDHCI standard definitions */
#define  ESDHC_MIX_CTRL_SDHCI_MASK   0xb7
/* Tuning bits */
   @@ -60,6 +61,16 @@
#define  ESDHC_TUNE_CTRL_MIN 0
#define  ESDHC_TUNE_CTRL_MAX ((1  7) - 1)
  
   +/* strobe dll register */
   +#define ESDHC_STROBE_DLL_CTRL0x70
   +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1  0)
   +#define ESDHC_STROBE_DLL_CTRL_RESET  (1  1)
   +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT   3
   +
   +#define ESDHC_STROBE_DLL_STATUS  0x74
   +#define ESDHC_STROBE_DLL_STS_REF_LOCK(1  1)
   +#define ESDHC_STROBE_DLL_STS_SLV_LOCK0x1
   +
#define ESDHC_TUNING_CTRL0xcc
#define ESDHC_STD_TUNING_EN  (1  24)
/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
   -120,6 +131,8 @@
#define ESDHC_FLAG_ERR004536 BIT(7)
/* The IP supports HS200 mode */
#define ESDHC_FLAG_HS200 BIT(8)
   +/* The IP supports HS400 mode */
   +#define ESDHC_FLAG_SUP_HS400 BIT(9)
  
struct esdhc_soc_data {
 u32 flags;
   @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
 | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
  
   +static struct esdhc_soc_data usdhc_imx7d_data = {
   + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
   + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
   + | ESDHC_FLAG_SUP_HS400,
   +};
   +
struct pltfm_imx_data {
 u32 scratchpad;
 struct pinctrl *pinctrl;
   @@ -199,6 +218,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
  = {
 { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, },
 { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, },
 { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, },
   + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, },
 { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@
   static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 | SDHCI_SUPPORT_SDR50
 | SDHCI_USE_SDR50_TUNING;
   +
   + /* imx7d does not have a support_hs400 register, fake
  one */
  
  You could remove this line.
  It's bit, not register and i think no need such comment.
  
   + if (imx_data-socdata-flags  ESDHC_FLAG_SUP_HS400)
   + val |= SDHCI_SUPPORT_HS400;
 }
 }
  
   @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct sdhci_host
  *host,
 break;
 case MMC_TIMING_UHS_SDR104:
 case MMC_TIMING_MMC_HS200:
   + case MMC_TIMING_MMC_HS400:
 pinctrl = imx_data-pins_200mhz;
 break;
 default:
   @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct sdhci_host
  *host,
 return pinctrl_select_state(imx_data-pinctrl, pinctrl);  }
  
   +static void esdhc_set_strobe_dll(struct sdhci_host *host)
  
  It would be good if we can add some comments for this function for better
  understand.
  
 
 [haibo] okay, I will add comments here. 
 
   +{
   + u32 v;
   +
   + /* force a reset on strobe dll */
   + writel(ESDHC_STROBE_DLL_CTRL_RESET, host-ioaddr +
  

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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


[PATCH] mmc: enable mmc host device to suspend/resume asynchronously

2015-08-03 Thread Fu, Zhonghui
Enable mmc host device to suspend/resume asynchronously.
This can improve system suspend/resume speed.

Signed-off-by: Zhonghui Fu zhonghui...@linux.intel.com
---
 drivers/mmc/core/host.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 99a9c90..85f2bbb 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -577,6 +577,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device 
*dev)
host-class_dev.parent = dev;
host-class_dev.class = mmc_host_class;
device_initialize(host-class_dev);
+   device_enable_async_suspend(host-class_dev);
 
if (mmc_gpio_alloc(host)) {
put_device(host-class_dev);
-- 1.7.1

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