Re: [PATCH 07/12] mmci: pass power_mode to the translate_vdd callback
On Wed, Jun 23, 2010 at 00:03:47 +0200, Linus Walleij wrote: 2010/6/22 Rabin Vincent rabin.vinc...@stericsson.com: @@ -17,7 +17,8 @@ * mmc/host.h * @translate_vdd: a callback function to translate a MMC_VDD_* * mask into a value to be binary or:ed and written into the - * MMCIPWR register of the block + * MMCIPWR register of the block. May also control external power + * based on the power_mode. Actually this callback is named like that for a reason: it is to be used to translate the MMC_VDD_* into a u8:4 bitmask for the MMCIPWR register, 4 bits possibly routed out of the PL180 block on some designs (never seen in practice, but could be used in theory). So it translates a voltage into a 4-bit bitmask, hence the name. Now the semantics are altered to have other side-effects in the platform, so the function should be renamed, something like platform_vdd_handler() would be more appropriate. This is already inside platform data, so how about just -vdd_handler()? Or -set_power(), like some other drivers? Note that we'd also like to use this to do the board-specific settings for the *DIREN and FBCLK bits, which replace the Voltage bits on some ST variants, like so: +static u32 mop500_sdi0_translate_vdd(struct device *dev, unsigned int vdd, +unsigned char power_mode) +{ + if (power_mode == MMC_POWER_UP) + gpio_set_value(gpio_sdmmc_en, 1); + else if (power_mode == MMC_POWER_OFF) + gpio_set_value(gpio_sdmmc_en, 0); + + return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | + MCI_DATA2DIREN | MCI_DATA31DIREN; +} Rabin -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 1/5] mmc: Add erase, secure erase, trim and secure trim operations
From c7a9eb435367fd8ef16e79c053f0c5a630473830 Mon Sep 17 00:00:00 2001 From: Adrian Hunter adrian.hun...@nokia.com Date: Tue, 1 Jun 2010 13:20:22 +0300 Subject: [PATCH 1/5] mmc: Add erase, secure erase, trim and secure trim operations SD/MMC cards tend to support an erase operation. In addition, eMMC v4.4 cards can support secure erase, trim and secure trim operations that are all variants of the basic erase command. Signed-off-by: Adrian Hunter adrian.hun...@nokia.com --- drivers/mmc/core/core.c | 346 + drivers/mmc/core/core.h |2 + drivers/mmc/core/mmc.c| 47 ++- drivers/mmc/core/sd.c | 82 +++ drivers/mmc/core/sd_ops.c | 48 ++ drivers/mmc/core/sd_ops.h |1 + include/linux/mmc/card.h | 19 +++ include/linux/mmc/core.h | 19 +++ include/linux/mmc/host.h |1 + include/linux/mmc/mmc.h | 24 +++- include/linux/mmc/sd.h|5 + 11 files changed, 587 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 569e94d..3b8b1b7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1050,6 +1050,352 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) EXPORT_SYMBOL(mmc_detect_change); +void mmc_init_erase(struct mmc_card *card) +{ + unsigned int sz; + + if (is_power_of_2(card-erase_size)) + card-erase_shift = ffs(card-erase_size) - 1; + else + card-erase_shift = 0; + + /* +* It is possible to erase an arbitrarily large area of an SD or MMC +* card. That is not desirable because it can take a long time +* (minutes) potentially delaying more important I/O, and also the +* timeout calculations become increasingly hugely over-estimated. +* Consequently, 'pref_erase' is defined as a guide to limit erases +* to that size and alignment. +* +* For SD cards that define Allocation Unit size, limit erases to one +* Allocation Unit at a time. For MMC cards that define High Capacity +* Erase Size, whether it is switched on or not, limit to that size. +* Otherwise just have a stab at a good value. For modern cards it +* will end up being 4MiB. Note that if the value is too small, it +* can end up taking longer to erase. +*/ + if (mmc_card_sd(card) card-ssr.au) { + card-pref_erase = card-ssr.au; + card-erase_shift = ffs(card-ssr.au) - 1; + } else if (card-ext_csd.hc_erase_size) { + card-pref_erase = card-ext_csd.hc_erase_size; + } else { + sz = (card-csd.capacity (card-csd.read_blkbits - 9)) 11; + if (sz 128) + card-pref_erase = 512 * 1024 / 512; + else if (sz 512) + card-pref_erase = 1024 * 1024 / 512; + else if (sz 1024) + card-pref_erase = 2 * 1024 * 1024 / 512; + else + card-pref_erase = 4 * 1024 * 1024 / 512; + if (card-pref_erase card-erase_size) + card-pref_erase = card-erase_size; + else { + sz = card-pref_erase % card-erase_size; + if (sz) + card-pref_erase += card-erase_size - sz; + } + } +} + +static void mmc_set_mmc_erase_timeout(struct mmc_card *card, + struct mmc_command *cmd, + unsigned int arg, unsigned int qty) +{ + unsigned int erase_timeout; + + if (card-ext_csd.erase_group_def 1) { + /* High Capacity Erase Group Size uses HC timeouts */ + if (arg == MMC_TRIM_ARG) + erase_timeout = card-ext_csd.trim_timeout; + else + erase_timeout = card-ext_csd.hc_erase_timeout; + } else { + /* CSD Erase Group Size uses write timeout */ + unsigned int mult = (10 card-csd.r2w_factor); + unsigned int timeout_clks = card-csd.tacc_clks * mult; + unsigned int timeout_us; + + /* Avoid overflow: e.g. tacc_ns=8000 mult=1280 */ + if (card-csd.tacc_ns 100) + timeout_us = (card-csd.tacc_ns * mult) / 1000; + else + timeout_us = (card-csd.tacc_ns / 1000) * mult; + + /* +* ios.clock is only a target. The real clock rate might be +* less but not that much less, so fudge it by multiplying by 2. +*/ + timeout_clks = 1; + timeout_us += (timeout_clks * 1000) / + (card-host-ios.clock / 1000); + + erase_timeout = timeout_us / 1000; + + /* +*
[PATCH V3 3/5] omap_hsmmc: Add erase capability
From 20b7223c8a3c021a31a7b8079990ec103d89007e Mon Sep 17 00:00:00 2001 From: Adrian Hunter adrian.hun...@nokia.com Date: Tue, 18 May 2010 17:33:13 +0300 Subject: [PATCH 3/5] omap_hsmmc: Add erase capability Disable the data (busy) timeout for erases and set the MMC_CAP_ERASE capability. Signed-off-by: Adrian Hunter adrian.hun...@nokia.com --- drivers/mmc/host/omap_hsmmc.c | 13 ++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b032828..5cbbe09 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -28,6 +28,7 @@ #include linux/clk.h #include linux/mmc/host.h #include linux/mmc/core.h +#include linux/mmc/mmc.h #include linux/io.h #include linux/semaphore.h #include linux/gpio.h @@ -78,6 +79,7 @@ #define INT_EN_MASK0x307F0033 #define BWR_ENABLE (1 4) #define BRR_ENABLE (1 5) +#define DTO_ENABLE (1 20) #define INIT_STREAM(1 1) #define DP_SELECT (1 21) #define DDIR (1 4) @@ -523,7 +525,8 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host-mmc), MMC Clock is not stoped\n); } -static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) +static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, + struct mmc_command *cmd) { unsigned int irq_mask; @@ -532,6 +535,10 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) else irq_mask = INT_EN_MASK; + /* Disable timeout for erases */ + if (cmd-opcode == MMC_ERASE) + irq_mask = ~DTO_ENABLE; + OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR); OMAP_HSMMC_WRITE(host-base, ISE, irq_mask); OMAP_HSMMC_WRITE(host-base, IE, irq_mask); @@ -782,7 +789,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, mmc_hostname(host-mmc), cmd-opcode, cmd-arg); host-cmd = cmd; - omap_hsmmc_enable_irq(host); + omap_hsmmc_enable_irq(host, cmd); host-response_busy = 0; if (cmd-flags MMC_RSP_PRESENT) { @@ -2094,7 +2101,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) mmc-max_seg_size = mmc-max_req_size; mmc-caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | -MMC_CAP_WAIT_WHILE_BUSY; +MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; if (mmc_slot(host).wires = 8) mmc-caps |= MMC_CAP_8_BIT_DATA; -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 4/5] block: Add secure discard
From b25b9a499f255ee5999c219525d82ef40382318c Mon Sep 17 00:00:00 2001 From: Adrian Hunter adrian.hun...@nokia.com Date: Wed, 23 Jun 2010 15:41:38 +0300 Subject: [PATCH 4/5] block: Add secure discard Secure discard is the same as discard except that all copies of the discarded sectors (perhaps created by garbage collection) must also be erased. Signed-off-by: Adrian Hunter adrian.hun...@nokia.com --- block/blk-core.c|6 +- block/blk-lib.c |6 ++ block/compat_ioctl.c|1 + block/elevator.c|4 block/ioctl.c | 15 ++- include/linux/bio.h |7 ++- include/linux/blkdev.h | 10 +- include/linux/fs.h |2 ++ kernel/trace/blktrace.c |8 9 files changed, 51 insertions(+), 8 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index f84cce4..6f9c6df 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1153,6 +1153,8 @@ void init_request_from_bio(struct request *req, struct bio *bio) req-cmd_flags |= REQ_DISCARD; if (bio_rw_flagged(bio, BIO_RW_BARRIER)) req-cmd_flags |= REQ_SOFTBARRIER; + if (bio_rw_flagged(bio, BIO_RW_SECURE)) + req-cmd_flags |= REQ_SECURE; } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) req-cmd_flags |= REQ_HARDBARRIER; @@ -1501,7 +1503,9 @@ static inline void __generic_make_request(struct bio *bio) goto end_io; if (bio_rw_flagged(bio, BIO_RW_DISCARD) - !blk_queue_discard(q)) { + (!blk_queue_discard(q) || +(bio_rw_flagged(bio, BIO_RW_SECURE) + !blk_queue_secdiscard(q { err = -EOPNOTSUPP; goto end_io; } diff --git a/block/blk-lib.c b/block/blk-lib.c index d0216b9..dc56682 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -52,6 +52,12 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, if (!blk_queue_discard(q)) return -EOPNOTSUPP; + if (flags BLKDEV_IFL_SECURE) { + if (!blk_queue_secdiscard(q)) + return -EOPNOTSUPP; + type |= DISCARD_SECURE; + } + while (nr_sects !ret) { unsigned int sector_size = q-limits.logical_block_size; unsigned int max_discard_sectors = diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index f26051f..24a146d 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -753,6 +753,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) case BLKFLSBUF: case BLKROSET: case BLKDISCARD: + case BLKSECDISCARD: /* * the ones below are implemented in blkdev_locked_ioctl, * but we call blkdev_ioctl, which gets the lock for us diff --git a/block/elevator.c b/block/elevator.c index 923a913..23b5f3d 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -83,6 +83,10 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) bio_rw_flagged(rq-bio, BIO_RW_DISCARD)) return 0; + if (bio_rw_flagged(bio, BIO_RW_SECURE) != + bio_rw_flagged(rq-bio, BIO_RW_SECURE)) + return 0; + /* * different data direction or already started, don't merge */ diff --git a/block/ioctl.c b/block/ioctl.c index e8eb679..1fba55f 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -114,8 +114,10 @@ static int blkdev_reread_part(struct block_device *bdev) } static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, -uint64_t len) +uint64_t len, int secure) { + unsigned long flags = BLKDEV_IFL_WAIT; + if (start 511) return -EINVAL; if (len 511) @@ -125,8 +127,9 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, if (start + len (bdev-bd_inode-i_size 9)) return -EINVAL; - return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, - BLKDEV_IFL_WAIT); + if (secure) + flags |= BLKDEV_IFL_SECURE; + return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); } static int put_ushort(unsigned long arg, unsigned short val) @@ -226,7 +229,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unlock_kernel(); return 0; - case BLKDISCARD: { + case BLKDISCARD: + case BLKSECDISCARD: { uint64_t range[2]; if (!(mode FMODE_WRITE)) @@ -235,7 +239,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, if (copy_from_user(range, (void __user *)arg, sizeof(range)))
[PATCH V3 2/5] mmc_block: Add discard support
From 1c859151d2d8c76e503a24c6d3d472cc01a68b3a Mon Sep 17 00:00:00 2001 From: Adrian Hunter adrian.hun...@nokia.com Date: Thu, 3 Jun 2010 10:47:12 +0300 Subject: [PATCH 2/5] mmc_block: Add discard support Enable MMC to service discard requests. In the case of SD and MMC cards that do not support trim, discards become erases. In the case of cards (MMC) that only allow erases in multiples of erase group size, round to the nearest completely discarded erase group. Signed-off-by: Adrian Hunter adrian.hun...@nokia.com --- drivers/mmc/card/block.c | 42 +- drivers/mmc/card/queue.c | 16 ++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index cb9fbc8..af14ae1 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -242,7 +242,40 @@ static u32 get_card_status(struct mmc_card *card, struct request *req) return cmd.resp[0]; } -static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) +static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) +{ + struct mmc_blk_data *md = mq-data; + struct mmc_card *card = md-queue.card; + unsigned int from, nr, arg; + int err = 0; + + mmc_claim_host(card-host); + + if (!mmc_can_erase(card)) { + err = -EOPNOTSUPP; + goto out; + } + + from = blk_rq_pos(req); + nr = blk_rq_sectors(req); + + if (mmc_can_trim(card)) + arg = MMC_TRIM_ARG; + else + arg = MMC_ERASE_ARG; + + err = mmc_erase(card, from, nr, arg); +out: + spin_lock_irq(md-lock); + __blk_end_request(req, err, blk_rq_bytes(req)); + spin_unlock_irq(md-lock); + + mmc_release_host(card-host); + + return err ? 0 : 1; +} + +static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq-data; struct mmc_card *card = md-queue.card; @@ -470,6 +503,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) return 0; } +static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) +{ + if (blk_discard_rq(req)) + return mmc_blk_issue_discard_rq(mq, req); + else + return mmc_blk_issue_rw_rq(mq, req); +} static inline int mmc_blk_readonly(struct mmc_card *card) { diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index d6ded24..37f648f 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -30,9 +30,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) { /* -* We only like normal block requests. +* We only like normal block requests and discards. */ - if (!blk_fs_request(req)) { + if (!blk_fs_request(req) !blk_discard_rq(req)) { blk_dump_rq_flags(req, MMC bad request); return BLKPREP_KILL; } @@ -130,6 +130,18 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock blk_queue_prep_rq(mq-queue, mmc_prep_request); blk_queue_ordered(mq-queue, QUEUE_ORDERED_DRAIN, NULL); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq-queue); + if (mmc_can_erase(card)) { + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mq-queue); + mq-queue-limits.max_discard_sectors = UINT_MAX; + if (card-erased_byte == 0) + mq-queue-limits.discard_zeroes_data = 1; + if (!mmc_can_trim(card) is_power_of_2(card-erase_size)) { + mq-queue-limits.discard_granularity = + card-erase_size 9; + mq-queue-limits.discard_alignment = + card-erase_size 9; + } + } #ifdef CONFIG_MMC_BLOCK_BOUNCE if (host-max_hw_segs == 1) { -- 1.6.3.3 -- 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 07/12] mmci: pass power_mode to the translate_vdd callback
[Rabin] On Wed, Jun 23, 2010 at 00:03:47 +0200, Linus Walleij wrote: 2010/6/22 Rabin Vincent rabin.vinc...@stericsson.com: @@ -17,7 +17,8 @@ * mmc/host.h * @translate_vdd: a callback function to translate a MMC_VDD_* * mask into a value to be binary or:ed and written into the - * MMCIPWR register of the block + * MMCIPWR register of the block. May also control external power + * based on the power_mode. Actually this callback is named like that for a reason: it is to be used to translate the MMC_VDD_* into a u8:4 bitmask for the MMCIPWR register, 4 bits possibly routed out of the PL180 block on some designs (never seen in practice, but could be used in theory). So it translates a voltage into a 4-bit bitmask, hence the name. Now the semantics are altered to have other side-effects in the platform, so the function should be renamed, something like platform_vdd_handler() would be more appropriate. This is already inside platform data, so how about just - vdd_handler()? Or -set_power(), like some other drivers? Any of these look good to me atleast. But now another thing I came to think of (the fun never ends): Since the ux500 also have a regulator for this and since that mechanism is mutually exclusive in the code (since the semantics implied that it was only a voltage translation function) you should also remove the condition that this only gets called in case there is no regulator. Note that we'd also like to use this to do the board-specific settings for the *DIREN and FBCLK bits, which replace the Voltage bits on some ST variants, like so: +static u32 mop500_sdi0_translate_vdd(struct device *dev, unsigned int vdd, + unsigned char power_mode) +{ + if (power_mode == MMC_POWER_UP) + gpio_set_value(gpio_sdmmc_en, 1); + else if (power_mode == MMC_POWER_OFF) + gpio_set_value(gpio_sdmmc_en, 0); + + return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | +MCI_DATA2DIREN | MCI_DATA31DIREN; +} OK just update the kerneldoc to reflect the fact that the platform can OR on any *custom* bits it like to the PWR register in this function. Side notice: some of bits are for the ST version only, when you patch in the latter, can you take this opportunity to also rename MCI_FBCLKEN to MCI_ST_FBCLKEN and so on for all stuff that is ST-specific? I think I am the sinner here, we had no convention for how to do this naming when we first began modifying this driver. It should be crystal clear that all custom extensions are named MCI_VENDOR_FOO. As a consequence, anything that is OR:ed into from the vdd_handler() should typically be MCI_VENDOR_FOO, and it will be clear why it's there. Yours, Linus Walleij -- 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] Disable the non working eMMC on Zoom2/3
On Tue, Jun 22, 2010 at 7:43 PM, Ghorai, Sukumar s-gho...@ti.com wrote: -Original Message- From: zhangfei gao [mailto:zhangfei@gmail.com] Sent: Tuesday, June 22, 2010 4:51 PM To: Chikkature Rajashekar, Madhusudhan Cc: Tony Lindgren; Menon, Nishanth; Ghorai, Sukumar; linux- o...@vger.kernel.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH] Disable the non working eMMC on Zoom2/3 On Sat, May 8, 2010 at 5:25 AM, Madhusudhan madhu...@ti.com wrote: -Original Message- From: Tony Lindgren [mailto:t...@atomide.com] Sent: Thursday, May 06, 2010 10:31 AM To: Madhusudhan Cc: 'Nishanth Menon'; 'Ghorai, Sukumar'; linux-o...@vger.kernel.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH] Disable the non working eMMC on Zoom2/3 * Madhusudhan madhu...@ti.com [100505 18:31]: -Original Message- From: Tony Lindgren [mailto:t...@atomide.com] And what about this Simulate multi mmc card as one big patch? Did not get you, what patch are you referring to? Oops sorry forgot the link: https://patchwork.kernel.org/patch/87944/ This will not help. I don't know the history of the patch but what this is intended for is to support multiple MMC cards connected to a single controller. But on the Zoom the eMMC we are talking about is connected to MMC2. Regards, Madhu Tony -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Hi, Guys Just wander whether 16G Micron eMMC works on your platform. I also have such issue, 16G Micron emmc can not work with read and write, with data timeout. While 8G Micron eMMC workable. Do you have the same issue? [Ghorai] we have 16G eMMC in ZOOM3 and 3630-SDP and its working fine. Let me know what board you are using. mmc1: new high speed MMC card at address 0001 PM: Adding info for mmc:mmc1:0001 mmcblk0: mmc1:0001 STM16G 14.8 GiB PM: Adding info for No Bus:mmcblk0 mmcblk0: p1 p2 Thanks Hi, Ghorai Thanks for your valueable info. We also enabled Micron 16G eMMC, two issues stuck us before. 1. The bus_width should be inited otherwise read ext_csd would be fail. 2. The emmc may stay in boot partition and kernel should switch to user partition, where filesystem is located. Thanks -- 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] Disable the non working eMMC on Zoom2/3
-Original Message- From: zhangfei gao [mailto:zhangfei@gmail.com] Sent: Thursday, June 24, 2010 4:26 PM To: Ghorai, Sukumar Cc: Chikkature Rajashekar, Madhusudhan; Tony Lindgren; Menon, Nishanth; linux-o...@vger.kernel.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH] Disable the non working eMMC on Zoom2/3 On Tue, Jun 22, 2010 at 7:43 PM, Ghorai, Sukumar s-gho...@ti.com wrote: -Original Message- From: zhangfei gao [mailto:zhangfei@gmail.com] Sent: Tuesday, June 22, 2010 4:51 PM To: Chikkature Rajashekar, Madhusudhan Cc: Tony Lindgren; Menon, Nishanth; Ghorai, Sukumar; linux- o...@vger.kernel.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH] Disable the non working eMMC on Zoom2/3 On Sat, May 8, 2010 at 5:25 AM, Madhusudhan madhu...@ti.com wrote: -Original Message- From: Tony Lindgren [mailto:t...@atomide.com] Sent: Thursday, May 06, 2010 10:31 AM To: Madhusudhan Cc: 'Nishanth Menon'; 'Ghorai, Sukumar'; linux-o...@vger.kernel.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH] Disable the non working eMMC on Zoom2/3 * Madhusudhan madhu...@ti.com [100505 18:31]: -Original Message- From: Tony Lindgren [mailto:t...@atomide.com] And what about this Simulate multi mmc card as one big patch? Did not get you, what patch are you referring to? Oops sorry forgot the link: https://patchwork.kernel.org/patch/87944/ This will not help. I don't know the history of the patch but what this is intended for is to support multiple MMC cards connected to a single controller. But on the Zoom the eMMC we are talking about is connected to MMC2. Regards, Madhu Tony -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Hi, Guys Just wander whether 16G Micron eMMC works on your platform. I also have such issue, 16G Micron emmc can not work with read and write, with data timeout. While 8G Micron eMMC workable. Do you have the same issue? [Ghorai] we have 16G eMMC in ZOOM3 and 3630-SDP and its working fine. Let me know what board you are using. mmc1: new high speed MMC card at address 0001 PM: Adding info for mmc:mmc1:0001 mmcblk0: mmc1:0001 STM16G 14.8 GiB PM: Adding info for No Bus:mmcblk0 mmcblk0: p1 p2 Thanks Hi, Ghorai Thanks for your valueable info. We also enabled Micron 16G eMMC, two issues stuck us before. 1. The bus_width should be inited otherwise read ext_csd would be fail. 2. The emmc may stay in boot partition and kernel should switch to user partition, where filesystem is located. [Ghorai] 1. If my understanding is not wrong, then the same problem exists in external MMC card too. 2. So, can you share your eMMC log, just to check if I have any clue! Or let me know how I can reproduce the issue. Thanks -- 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: remove regulator refcount fiddling in mmc core
Currently the mmc_regulator_set_ocr() fiddles with the regulator refcount by selectively calling regulator_[enable|disable] depending on the state of the regulator. This will confuse the reference count if case the regulator is for example shared with other MMC slots or user for other stuff than the MMC card. Push regulator_[enable|disable] out into the MMC host drivers and remove this from the MMC core so the reference count can be trusted. Cc: Andrew Morton a...@linux-foundation.org Cc: Liam Girdwood l...@slimlogic.co.uk Cc: Mark Brown broo...@opensource.wolfsonmicro.com Cc: Tony Lindgren t...@atomide.com Cc: Adrian Hunter adrian.hun...@nokia.com Cc: Robert Jarzmik robert.jarz...@free.fr Cc: Sundar Iyer sundar.i...@stericsson.com Cc: Bengt Jonsson bengt.jons...@stericsson.com Signed-off-by: Linus Walleij linus.wall...@stericsson.com --- This has been regression compiled for U300, OMAP3, PXA3XX defconfigs, tested on U300. We're facing problems with our regulator reference counters if this is not fixed. --- drivers/mmc/core/core.c | 66 ++--- drivers/mmc/host/mmci.c | 10 -- drivers/mmc/host/omap_hsmmc.c | 40 ++-- drivers/mmc/host/pxamci.c | 17 -- 4 files changed, 78 insertions(+), 55 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 569e94d..904f245 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -784,47 +784,39 @@ int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit) { int result = 0; int min_uV, max_uV; - int enabled; + int tmp; + int voltage; - enabled = regulator_is_enabled(supply); - if (enabled 0) - return enabled; - - if (vdd_bit) { - int tmp; - int voltage; - - /* REVISIT mmc_vddrange_to_ocrmask() may have set some -* bits this regulator doesn't quite support ... don't -* be too picky, most cards and regulators are OK with -* a 0.1V range goof (it's a small error percentage). -*/ - tmp = vdd_bit - ilog2(MMC_VDD_165_195); - if (tmp == 0) { - min_uV = 1650 * 1000; - max_uV = 1950 * 1000; - } else { - min_uV = 1900 * 1000 + tmp * 100 * 1000; - max_uV = min_uV + 100 * 1000; - } - - /* avoid needless changes to this voltage; the regulator -* might not allow this operation -*/ - voltage = regulator_get_voltage(supply); - if (voltage 0) - result = voltage; - else if (voltage min_uV || voltage max_uV) - result = regulator_set_voltage(supply, min_uV, max_uV); - else - result = 0; + if (!vdd_bit) + return 0; - if (result == 0 !enabled) - result = regulator_enable(supply); - } else if (enabled) { - result = regulator_disable(supply); + /* +* REVISIT mmc_vddrange_to_ocrmask() may have set some +* bits this regulator doesn't quite support ... don't +* be too picky, most cards and regulators are OK with +* a 0.1V range goof (it's a small error percentage). +*/ + tmp = vdd_bit - ilog2(MMC_VDD_165_195); + if (tmp == 0) { + min_uV = 1650 * 1000; + max_uV = 1950 * 1000; + } else { + min_uV = 1900 * 1000 + tmp * 100 * 1000; + max_uV = min_uV + 100 * 1000; } + /* +* Avoid needless changes to this voltage; the regulator +* might not allow this operation +*/ + voltage = regulator_get_voltage(supply); + if (voltage 0) + result = voltage; + else if (voltage min_uV || voltage max_uV) + result = regulator_set_voltage(supply, min_uV, max_uV); + else + result = 0; + return result; } EXPORT_SYMBOL(mmc_regulator_set_ocr); diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4917af9..5f530b1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -467,15 +467,17 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) switch (ios-power_mode) { case MMC_POWER_OFF: - if(host-vcc - regulator_is_enabled(host-vcc)) + if (host-vcc) regulator_disable(host-vcc); break; case MMC_POWER_UP: #ifdef CONFIG_REGULATOR - if (host-vcc) - /* This implicitly enables