Re: [PATCH v4] mmc: support HPI send command
Hi Chris. This feature is also used in eMMC4.41. So i want to know your opinion. (In eMMC4.5, i known this feature is important) If need more modification, i will do. if not, i want to merge this feature. Regards, Jaehoon Chung Jaehoon Chung wrote: This patch is added sending function for HPI command. HPI command is defined in eMMC4.41. We didn't use this feature..but maybe we need to use HPI command for eMMC4.5 feature. (If we use HPI command, it's useful for increasing performance and decreasing latency.) This patch is based on Chuanxiao's patch which one of many patches related with HPI sent to mailing.. Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Signed-off-by: Chuanxiao Dong chuanxiao.d...@intel.com CC: Hanumath Prasad hanumath.pra...@stericsson.com --- v4 : - change pr_info/pr_debug instead of printk() - remove unnecessary parameter. v3 : - Change response type R1 instead of R1b.(using STOP_TRANSMMISION) - Check card status with SEND_STATUS after sending HPI v2 : add error checking (when send hpi, card is out of prg-state) --- drivers/mmc/core/core.c| 58 drivers/mmc/core/mmc.c | 37 +++- drivers/mmc/core/mmc_ops.c | 31 +++ drivers/mmc/core/mmc_ops.h |1 + include/linux/mmc/card.h |4 +++ include/linux/mmc/core.h |1 + include/linux/mmc/mmc.h|3 ++ 7 files changed, 134 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index eb3069d..06fd77c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -360,6 +360,64 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) EXPORT_SYMBOL(mmc_wait_for_req); /** + * mmc_interrupt_hpi - Issue for High priority Interrupt + * @card: the MMC card associated with the HPI transfer + * + * Issued High Priority Interrupt, and check for card status + * util out-of prg-state. + */ +int mmc_interrupt_hpi(struct mmc_card *card) +{ + int err; + u32 status; + + BUG_ON(!card); + + if (!card-ext_csd.hpi_en) { + pr_info(Didn't set HPI enable bit!\n); + return 1; + } + + mmc_claim_host(card-host); + err = mmc_send_status(card, status); + if (err) { + pr_err(Didn't get card status!\n); + goto out; + } + + /* + * If Card status is prg-state, can send HPI command + */ + if (R1_CURRENT_STATE(status) == R1_STATE_PRG) { + do { + /* + * Actually, didn't be ensure that + * HPI command is running exactly. + * So, need to resend HPI until out of prg-state. + * then check the card status with SEND_STATUS. + * If timeout error is occured(when send hpi command), + * that means already out of prg-state. + */ + err = mmc_send_hpi_cmd(card, status); + if (err) + pr_debug(abort HPI (%d error), err); + else + pr_debug(HPI success!!!\n); + + err = mmc_send_status(card, status); + if (err) + break; + } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); + } else + pr_debug(Already out of prg-state!!\n); + +out: + mmc_release_host(card-host); + return err; +} +EXPORT_SYMBOL(mmc_interrupt_hpi); + +/** * mmc_wait_for_cmd - start a command and wait for completion * @host: MMC host to start command * @cmd: MMC command to start diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1c..ef312c9 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -402,8 +402,26 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) ext_csd[EXT_CSD_TRIM_MULT]; } - if (card-ext_csd.rev = 5) + if (card-ext_csd.rev = 5) { + /* check whether the eMMC card support HPI */ + if (ext_csd[EXT_CSD_HPI_FEATURES] 0x1) { + card-ext_csd.hpi = 1; + if (ext_csd[EXT_CSD_HPI_FEATURES] 0x2) + card-ext_csd.hpi_cmd = + MMC_STOP_TRANSMISSION; + else + card-ext_csd.hpi_cmd = + MMC_SEND_STATUS; + + /* + * Indicate the maximum timeout to close + * a command interrupted by HPI + */ + card-ext_csd.out_of_int_time = +
Re: [RFC PATCH v2] mmc: support background operation
Hi Chris. how about this feature..? didn't you have any comment? Regards, Jaehoon Chung Jaehoon Chung wrote: Hi mailing. This RFC patch is supported background operation(BKOPS). And if you want to test this patch, must apply [PATCH v3] mmc: support HPI send command This patch is based on Hanumath Prasad's patch mmc: enable background operations for emmc4.41 with HPI support Hanumath's patch is implemented before applied per forlin's patch use nonblock mmc request This patch is based on 3.1.0-rc1 in mmc-next. Background operations is run when set the URGENT_BKOPS in response. if set the URGENT_BKOPS in response, we can notify that card need the BKOPS. (URGENT_BKOPS is used in eMMC4.41 spec, but in eMMC4.5 changed to EXCEPTION_EVENT bit. maybe, we need to change this point). And all request is done, then run background operation. if request read/write operation when running BKOPS, issue HPI interrupt This patch is just RFC patch (not to merge). Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com CC: Hanumath Prasad hanumath.pra...@stericsson.com --- v2: - change pr_debug/pr_info instead of printk() - add check BKOPS_EN bit (if BKOPS support) --- drivers/mmc/card/block.c |4 drivers/mmc/card/queue.c | 10 ++ drivers/mmc/core/core.c| 38 ++ drivers/mmc/core/mmc.c | 34 ++ drivers/mmc/core/mmc_ops.c |3 +++ include/linux/mmc/card.h | 11 +++ include/linux/mmc/core.h |1 + include/linux/mmc/mmc.h|4 8 files changed, 105 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1ff5486..83379ff 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1078,6 +1078,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) switch (status) { case MMC_BLK_SUCCESS: case MMC_BLK_PARTIAL: + if (mmc_card_mmc(card) + (brq-cmd.resp[0] R1_URGENT_BKOPS)) + mmc_card_set_need_bkops(card); + /* * A block was successfully transferred. */ diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 45fb362..52b1293 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -46,6 +46,8 @@ static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq-queue; + struct mmc_card *card = mq-card; + unsigned long flags; current-flags |= PF_MEMALLOC; @@ -61,6 +63,13 @@ static int mmc_queue_thread(void *d) spin_unlock_irq(q-queue_lock); if (req || mq-mqrq_prev-req) { + if (mmc_card_doing_bkops(card)) { + mmc_interrupt_hpi(card); + spin_lock_irqsave(card-host-lock, flags); + mmc_card_clr_doing_bkops(card); + spin_unlock_irqrestore(card-host-lock, + flags); + } set_current_state(TASK_RUNNING); mq-issue_fn(mq, req); } else { @@ -68,6 +77,7 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_RUNNING); break; } + mmc_start_bkops(mq-card); up(mq-thread_sem); schedule(); down(mq-thread_sem); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 06fd77c..b5a92af 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -360,6 +360,44 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) EXPORT_SYMBOL(mmc_wait_for_req); /** + * mmc_start_bkops - start a background operation + * @card: the MMC card associated with the HPI transfer + * + * When need a background operation, card start a background operation. + */ +void mmc_start_bkops(struct mmc_card *card) +{ + int err; + unsigned long flags; + + BUG_ON(!card); + + if (!card-ext_csd.bkops_en) { + pr_info(Didn't set BKOPS enable bit!\n); + return; + } + + if (mmc_card_doing_bkops(card) || !mmc_card_need_bkops(card)) + return; + + mmc_claim_host(card-host); + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BKOPS_START, 1, 0); + if (err) { + mmc_card_clr_need_bkops(card); + goto out; + } + + spin_lock_irqsave(card-host-lock, flags); + mmc_card_clr_need_bkops(card); +
Re: [PATCH 1/3] arm/tegra: Move EN_VDD_1V05_GPIO to board-harmony.h
On Wed, Sep 21, 2011 at 01:16:49PM -0700, Olof Johansson wrote: Works for me. Or I could stage it in a topic branch that would be merged after Russell's GPIO tree. Holding stuff off from being merged doesn't work. If you have the following commit structure: A---...-M1-B-C-M2 +---A1-B1-C1' / +-A2-B2-C2---' Now, lets say A2 depends on C1. Merely delaying the stuff so that M2 happens after M1 is insufficient to ensure git state doesn't break. When bisecting, its entirely possible that the bisect algorithm may chose B2 as a potential test candidate. At that point you end up with A2, but without C1. The only way to solve this is to have A2 following on from C1 - which of course requires A1..C1 to be declared stable and either pulled into your local tree or for A2..C2 to be submitted to the same tree which A1..C1 are already in. -- 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 37/55] mmc: irq: Remove IRQF_DISABLED
Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled], We run all interrupt handlers with interrupts disabled and we even check and yell when an interrupt handler returns with interrupts enabled (see commit [b738a50a: genirq: Warn when handler enables interrupts]). So now this flag is a NOOP and can be removed. Signed-off-by: Yong Zhang yong.zha...@gmail.com Acked-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/mmc/host/omap_hsmmc.c |5 ++--- drivers/mmc/host/tmio_mmc.c |4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 21e4a79..75c6395 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2015,7 +2015,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } /* Request IRQ for MMC operations */ - ret = request_irq(host-irq, omap_hsmmc_irq, IRQF_DISABLED, + ret = request_irq(host-irq, omap_hsmmc_irq, 0, mmc_hostname(mmc), host); if (ret) { dev_dbg(mmc_dev(host-mmc), Unable to grab HSMMC IRQ\n); @@ -2043,8 +2043,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if ((mmc_slot(host).card_detect_irq)) { ret = request_irq(mmc_slot(host).card_detect_irq, omap_hsmmc_cd_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_DISABLED, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, mmc_hostname(mmc), host); if (ret) { dev_dbg(mmc_dev(host-mmc), diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 44a9668..a4ea102 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -88,8 +88,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *pdev) if (ret) goto cell_disable; - ret = request_irq(irq, tmio_mmc_irq, IRQF_DISABLED | - IRQF_TRIGGER_FALLING, dev_name(pdev-dev), host); + ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING, + dev_name(pdev-dev), host); if (ret) goto host_remove; -- 1.7.4.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] mmc: dw_mmc: modified the DMA threshold for SD card
This patch modified the DMA threshold. I didn't know exactly why need this threshold. But if this value is 16, we didn't read SCR register for SD card. Because in mmc_app_send_scr this values are used data.blocks=1 and data.blksz=8. (data.blocks * data.blksz = 8...so return -EINVAL) We didn't read the SCR register, then maybe should be set with wrong configuration. Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/mmc/host/dw_mmc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 0ed1d28..64e08e2 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -47,7 +47,7 @@ DW_MCI_CMD_ERROR_FLAGS | SDMMC_INT_HLE) #define DW_MCI_SEND_STATUS 1 #define DW_MCI_RECV_STATUS 2 -#define DW_MCI_DMA_THRESHOLD 16 +#define DW_MCI_DMA_THRESHOLD 8 #ifdef CONFIG_MMC_DW_IDMAC struct idmac_desc { -- 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] mmc: dw_mmc: modified the DMA threshold for SD card
On 09/22/2011 11:01 AM, Jaehoon Chung wrote: This patch modified the DMA threshold. I didn't know exactly why need this threshold. But if this value is 16, we didn't read SCR register for SD card. Because in mmc_app_send_scr this values are used data.blocks=1 and data.blksz=8. (data.blocks * data.blksz = 8...so return -EINVAL) The idea is that for a small transaction the time to set up the DMA is probably not worth the effort, therefore it does it using PIO mode (see dw_mci_submit_data, if dw_mci_submit_data_dma fails, it sets itself up for pio mode instead). So if it's using PIO mode and the SCR cannot be read, then PIO mode is broken. What's the value of the register HCON? dw_mci_probe reads it and decides which pio push and pull function to use based on the host data width. I've only tested one of them as we only have one configuration of hardware available, but you may have a different one. Cheers James We didn't read the SCR register, then maybe should be set with wrong configuration. Signed-off-by: Jaehoon Chung jh80.ch...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/mmc/host/dw_mmc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 0ed1d28..64e08e2 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -47,7 +47,7 @@ DW_MCI_CMD_ERROR_FLAGS | SDMMC_INT_HLE) #define DW_MCI_SEND_STATUS 1 #define DW_MCI_RECV_STATUS 2 -#define DW_MCI_DMA_THRESHOLD 16 +#define DW_MCI_DMA_THRESHOLD 8 #ifdef CONFIG_MMC_DW_IDMAC struct idmac_desc { -- 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
[no subject]
This patch adds the support for power off notify feature available in eMMC 4.5 devices. If the the host has support for this feature, then the mmc core will notify it to the device by setting the POWER_OFF_NOTIFICATION byte in the extended csd register with a value 1(POWER_ON). This patch should be applied after Seungwon Jeon's patch for cmd6 timeout. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v2: adds poweroff notification handling in suspend/normal v4: updated with review comments of Jeon v5: This patch version fixes the problem with power off notify function, when called for the first time and card is not yet initialised. v6: fixes checkpatch errors. The patches are generated after rebasing to chris's mmc-next branch. drivers/mmc/core/mmc.c | 17 + include/linux/mmc/card.h |1 + include/linux/mmc/host.h |1 + include/linux/mmc/mmc.h |6 ++ 4 files changed, 25 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 7adc30d..a547f49 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -412,6 +412,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) else card-erased_byte = 0x0; + if (card-ext_csd.rev = 6) { + card-ext_csd.power_off_longtime = 10 * + ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; + } out: return err; } @@ -713,6 +717,19 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } /* +* If the host supports the power_off_notify capability then +* set the notification byte in the ext_csd register of device +*/ + if (host-caps MMC_CAP_POWER_OFF_NOTIFY) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_OFF_NOTIFICATION, + EXT_CSD_POWER_ON, + card-ext_csd.generic_cmd6_time); + if (err err != -EBADMSG) + goto free_card; + } + + /* * Activate high speed (if supported) */ if ((card-ext_csd.hs_max_dtr != 0) diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 5294ddf..0f9dbd6 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -53,6 +53,7 @@ struct mmc_ext_csd { u8 rst_n_function; unsigned intpart_time; /* Units: ms */ unsigned intsa_timeout; /* Units: 100ns */ + unsigned intpower_off_longtime; /* Units: ms */ unsigned inths_max_dtr; unsigned intsectors; unsigned intcard_type; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index b2aefea..ed49e88 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -235,6 +235,7 @@ struct mmc_host { #define MMC_CAP_MAX_CURRENT_800(1 29) /* Host max current limit is 800mA */ #define MMC_CAP_CMD23 (1 30) /* CMD23 supported. */ #define MMC_CAP_HW_RESET (1 31) /* Hardware reset */ +#define MMC_CAP_POWER_OFF_NOTIFY(1 31)/*Notify poweroff supported */ mmc_pm_flag_t pm_caps;/* supported pm features */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index ed8fca8..95912da 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -270,6 +270,7 @@ struct _mmc_csd { * EXT_CSD fields */ +#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ #define EXT_CSD_PARTITION_ATTRIBUTE156 /* R/W */ #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ #define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ @@ -294,6 +295,7 @@ struct _mmc_csd { #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ #define EXT_CSD_SEC_FEATURE_SUPPORT231 /* RO */ #define EXT_CSD_TRIM_MULT 232 /* RO */ +#define EXT_CSD_POWER_OFF_LONG_TIME247 /*RO*/ /* * EXT_CSD field definitions @@ -331,6 +333,10 @@ struct _mmc_csd { #define EXT_CSD_RST_N_EN_MASK 0x3 #define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */ +#define EXT_CSD_NO_POWER_NOTIFICATION 0 +#define EXT_CSD_POWER_ON 1 +#define EXT_CSD_POWER_OFF_SHORT2 +#define EXT_CSD_POWER_OFF_LONG 3 /* * MMC_SWITCH access modes -- 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
[no subject]
This patch adds the power off notification handling during suspend and system poweroff. For suspend mode short timeout is used, whereas for the normal poweroff long timeout is used. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v2: adds poweroff notification handling in suspend/normal v4: updated with review comments of Jeon v5: This patch version fixes the problem with power off notify function, when called for the first time and card is not yet initialised. v6: fixes checkpatch errors. The patches are generated after rebasing to chris's mmc-next branch. drivers/mmc/core/core.c | 35 ++- drivers/mmc/core/mmc.c |5 - drivers/mmc/host/sdhci.c | 10 ++ include/linux/mmc/card.h | 19 +++ include/linux/mmc/host.h |4 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f22b774..17841a8 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1198,11 +1198,42 @@ static void mmc_power_up(struct mmc_host *host) void mmc_power_off(struct mmc_host *host) { - mmc_host_clk_hold(host); + struct mmc_card *card = host-card; + unsigned int notify_type; + unsigned int timeout; + int err; + mmc_host_clk_hold(host); host-ios.clock = 0; host-ios.vdd = 0; + if (card != NULL mmc_card_mmc(card) + (mmc_card_powernotify_on(card))) { + + if (host-power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { + notify_type = EXT_CSD_POWER_OFF_SHORT; + timeout = card-ext_csd.generic_cmd6_time; + mmc_card_set_powernotify_short(card); + } else { + notify_type = EXT_CSD_POWER_OFF_LONG; + timeout = card-ext_csd.power_off_longtime; + mmc_card_set_powernotify_long(card); + } + + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_OFF_NOTIFICATION, + notify_type, timeout); + + if (err err != -EBADMSG) + printk(KERN_ERR Device failed to respond + within %d poweroff time. + forcefully powering down + the device\n, timeout); + + /*Set the card state to no notification after the poweroff*/ + mmc_card_set_powernotify_off(card); + } + /* * Reset ocr mask to be the highest possible voltage supported for * this mmc host. This value will be used at next power up. @@ -2195,6 +2226,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(host-lock, flags); host-rescan_disable = 1; + host-power_notify_type = MMC_HOST_PW_NOTIFY_SHORT; spin_unlock_irqrestore(host-lock, flags); cancel_delayed_work_sync(host-detect); @@ -2218,6 +2250,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(host-lock, flags); host-rescan_disable = 0; + host-power_notify_type = MMC_HOST_PW_NOTIFY_LONG; spin_unlock_irqrestore(host-lock, flags); mmc_detect_change(host, 0); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a547f49..e3695a0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -720,7 +720,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * If the host supports the power_off_notify capability then * set the notification byte in the ext_csd register of device */ - if (host-caps MMC_CAP_POWER_OFF_NOTIFY) { + if ((host-caps MMC_CAP_POWER_OFF_NOTIFY) + (mmc_card_powernotify_off(card))) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_POWER_OFF_NOTIFICATION, EXT_CSD_POWER_ON, @@ -729,6 +730,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; } + if (!err) + mmc_card_set_powernotify_on(card); /* * Activate high speed (if supported) */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d66a7a1..04abd45 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2575,6 +2575,16 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[1] SDHCI_DRIVER_TYPE_D) mmc-caps |= MMC_CAP_DRIVER_TYPE_D; + /* +* If Notify capability is enabled and +* notify type is not initialised by host, set default to +* long power off notify timeout value +*/ + if (mmc-caps
[PATCH V3] mmc: core: eMMC 4.5 Power Class Selection Feature
This patch adds the power class selection feature available for mmc versions 4.0 and above. During the enumeration stage before switching to the lower data bus, check if the power class is supported for the current bus width. If the power class is available then switch to the power class and use the higher data bus. If power class is not supported then switch to the lower data bus in a worst case. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v1: This patch version modifies the power_class_select function prototype. During device enumeration, when the host tries to read the extended csd register after switching to higher bus width, the read fails at higher bus width. So the power_class_select function is modified to reuse the extended csd register values read with 1 bit bus width. v2: This patch version removes some checkpatch error v3: updated with review comments made by chris ball. patch generated by rebasing to chris balls mmc-next branch. drivers/mmc/core/mmc.c | 91 +++ include/linux/mmc/mmc.h | 13 +++ 2 files changed, 104 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e3695a0..9dd6c82 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -536,6 +536,81 @@ static struct device_type mmc_type = { }; /* + * Select the PowerClass for the current bus width + * If power class is defined for 4/8 bit bus in the + * extended CSD register, select it by executing the + * mmc_switch command. + */ +static int mmc_select_powerclass(struct mmc_card *card, + unsigned int bus_width, u8 *ext_csd) +{ + int err = 0; + unsigned int pwrclass_val; + unsigned int index = 0; + struct mmc_host *host = card-host; + + BUG_ON(!card); + BUG_ON(!host); + + if (ext_csd == NULL) + return 0; + /* Power class selection is supported for versions = 4.0 */ + if (card-csd.mmca_vsn CSD_SPEC_VER_4) + return 0; + /* Power class values are defined only for 4/8 bit bus */ + if (bus_width == EXT_CSD_BUS_WIDTH_1) + return 0; + + switch (1 host-ios.vdd) { + case MMC_VDD_165_195: + if (host-ios.clock = 2600) + index = EXT_CSD_PWR_CL_26_195; + else if (host-ios.clock = 5200) + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ? + EXT_CSD_PWR_CL_52_195 : + EXT_CSD_PWR_CL_DDR_52_195; + else if (host-ios.clock = 2) + index = EXT_CSD_PWR_CL_200_195; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + case MMC_VDD_34_35: + case MMC_VDD_35_36: + if (host-ios.clock = 2600) + index = EXT_CSD_PWR_CL_26_360; + else if (host-ios.clock = 5200) + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ? + EXT_CSD_PWR_CL_52_360 : + EXT_CSD_PWR_CL_DDR_52_360; + else if (host-ios.clock = 2) + index = EXT_CSD_PWR_CL_200_360; + break; + default: + printk(KERN_ERR votage range not supported\n); + break; + } + + pwrclass_val = ext_csd[index]; + + if (bus_width (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) + pwrclass_val = (pwrclass_val EXT_CSD_PWR_CL_8BIT_MASK) + EXT_CSD_PWR_CL_8BIT_SHIFT; + else + pwrclass_val = (pwrclass_val EXT_CSD_PWR_CL_4BIT_MASK) + EXT_CSD_PWR_CL_4BIT_SHIFT; + + /*If the power class is different from the default value*/ + if (pwrclass_val 0) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_CLASS, + pwrclass_val, + 0); + } + + return err; +} + +/* * Handle the detection and initialisation of a card. * * In the case of a resume, oldcard will contain the card @@ -807,6 +882,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ + err = mmc_select_powerclass(card, ext_csd_bits[idx][0], + ext_csd); + if (err) + printk(KERN_ERR %s: power class selection to + bus width %d failed\n, + mmc_hostname(card-host), +
[PATCH V1] mmc: core: HS200 mode support for eMMC 4.5
This patch adds the support of the HS200 bus speed for eMMC 4.5 devices. The eMMC 4.5 devices have support for 200MHz bus speed. The mmc core and host modules have been touched to add support for this module. It is necessary to know the card type in the sdhci.c file to add support for eMMC tuning function. So card.h file is included to import the card data structure. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v1: cases which produce same result have been combined to reduce repeated assignments. patch recreated after rebase to chris balls mmc-next branch. drivers/mmc/core/bus.c |3 +- drivers/mmc/core/mmc.c | 89 +- drivers/mmc/host/sdhci.c | 18 -- include/linux/mmc/card.h |3 ++ include/linux/mmc/host.h |8 include/linux/mmc/mmc.h |9 - 6 files changed, 116 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 393d817..a0aa7ab 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -301,10 +301,11 @@ int mmc_add_card(struct mmc_card *card) mmc_card_ddr_mode(card) ? DDR : , type); } else { - printk(KERN_INFO %s: new %s%s%s card at address %04x\n, + printk(KERN_INFO %s: new %s%s%s%s card at address %04x\n, mmc_hostname(card-host), mmc_sd_card_uhs(card) ? ultra high speed : (mmc_card_highspeed(card) ? high speed : ), + (mmc_card_hs200(card) ? HS200 : ), mmc_card_ddr_mode(card) ? DDR : , type, card-rca); } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 9dd6c82..2159ff6 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -283,6 +283,39 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) } card-ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; switch (ext_csd[EXT_CSD_CARD_TYPE] EXT_CSD_CARD_TYPE_MASK) { + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200; + break; + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V; + break; + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V; + break; case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card-ext_csd.hs_max_dtr = 5200; @@ -620,7 +653,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; - int err, ddr = 0; + int err, ddr = 0, hs_sdr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; @@ -810,10 +843,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * Activate high speed (if supported) */ - if ((card-ext_csd.hs_max_dtr != 0) - (host-caps MMC_CAP_MMC_HIGHSPEED)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_HS_TIMING, 1, 0); + if (card-ext_csd.hs_max_dtr != 0) { + if ((card-ext_csd.hs_max_dtr 5200) + (host-ext_caps MMC_CAP_MMC_HIGHSPEED_200))
Re:
Ignore this mail Sorry for no subject On 22 September 2011 16:40, Girish K S girish.shivananja...@linaro.org wrote: This patch adds the power off notification handling during suspend and system poweroff. For suspend mode short timeout is used, whereas for the normal poweroff long timeout is used. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v2: adds poweroff notification handling in suspend/normal v4: updated with review comments of Jeon v5: This patch version fixes the problem with power off notify function, when called for the first time and card is not yet initialised. v6: fixes checkpatch errors. The patches are generated after rebasing to chris's mmc-next branch. drivers/mmc/core/core.c | 35 ++- drivers/mmc/core/mmc.c | 5 - drivers/mmc/host/sdhci.c | 10 ++ include/linux/mmc/card.h | 19 +++ include/linux/mmc/host.h | 4 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f22b774..17841a8 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1198,11 +1198,42 @@ static void mmc_power_up(struct mmc_host *host) void mmc_power_off(struct mmc_host *host) { - mmc_host_clk_hold(host); + struct mmc_card *card = host-card; + unsigned int notify_type; + unsigned int timeout; + int err; + mmc_host_clk_hold(host); host-ios.clock = 0; host-ios.vdd = 0; + if (card != NULL mmc_card_mmc(card) + (mmc_card_powernotify_on(card))) { + + if (host-power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { + notify_type = EXT_CSD_POWER_OFF_SHORT; + timeout = card-ext_csd.generic_cmd6_time; + mmc_card_set_powernotify_short(card); + } else { + notify_type = EXT_CSD_POWER_OFF_LONG; + timeout = card-ext_csd.power_off_longtime; + mmc_card_set_powernotify_long(card); + } + + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_OFF_NOTIFICATION, + notify_type, timeout); + + if (err err != -EBADMSG) + printk(KERN_ERR Device failed to respond + within %d poweroff time. + forcefully powering down + the device\n, timeout); + + /*Set the card state to no notification after the poweroff*/ + mmc_card_set_powernotify_off(card); + } + /* * Reset ocr mask to be the highest possible voltage supported for * this mmc host. This value will be used at next power up. @@ -2195,6 +2226,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(host-lock, flags); host-rescan_disable = 1; + host-power_notify_type = MMC_HOST_PW_NOTIFY_SHORT; spin_unlock_irqrestore(host-lock, flags); cancel_delayed_work_sync(host-detect); @@ -2218,6 +2250,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(host-lock, flags); host-rescan_disable = 0; + host-power_notify_type = MMC_HOST_PW_NOTIFY_LONG; spin_unlock_irqrestore(host-lock, flags); mmc_detect_change(host, 0); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a547f49..e3695a0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -720,7 +720,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * If the host supports the power_off_notify capability then * set the notification byte in the ext_csd register of device */ - if (host-caps MMC_CAP_POWER_OFF_NOTIFY) { + if ((host-caps MMC_CAP_POWER_OFF_NOTIFY) + (mmc_card_powernotify_off(card))) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_POWER_OFF_NOTIFICATION, EXT_CSD_POWER_ON, @@ -729,6 +730,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; } + if (!err) + mmc_card_set_powernotify_on(card); /* * Activate high speed (if supported) */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d66a7a1..04abd45 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2575,6 +2575,16 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[1] SDHCI_DRIVER_TYPE_D) mmc-caps |= MMC_CAP_DRIVER_TYPE_D; + /* +
Re: [PATCH V3] mmc: core: eMMC 4.5 Power Class Selection Feature
Hi Girish, On Thu, Sep 22 2011, Girish K S wrote: This patch adds the power class selection feature available for mmc versions 4.0 and above. During the enumeration stage before switching to the lower data bus, check if the power class is supported for the current bus width. If the power class is available then switch to the power class and use the higher data bus. If power class is not supported then switch to the lower data bus in a worst case. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v1: This patch version modifies the power_class_select function prototype. During device enumeration, when the host tries to read the extended csd register after switching to higher bus width, the read fails at higher bus width. So the power_class_select function is modified to reuse the extended csd register values read with 1 bit bus width. v2: This patch version removes some checkpatch error v3: updated with review comments made by chris ball. patch generated by rebasing to chris balls mmc-next branch. The mmc.h patch doesn't apply against today's mmc-next branch -- maybe due to a patch I pushed yesterday, also make sure that you're on the mmc-next branch, not master. Mind rebasing once more, please? And: drivers/mmc/core/mmc.c | 91 +++ include/linux/mmc/mmc.h | 13 +++ 2 files changed, 104 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e3695a0..9dd6c82 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -536,6 +536,81 @@ static struct device_type mmc_type = { }; /* + * Select the PowerClass for the current bus width + * If power class is defined for 4/8 bit bus in the + * extended CSD register, select it by executing the + * mmc_switch command. + */ +static int mmc_select_powerclass(struct mmc_card *card, + unsigned int bus_width, u8 *ext_csd) +{ + int err = 0; + unsigned int pwrclass_val; + unsigned int index = 0; + struct mmc_host *host = card-host; + + BUG_ON(!card); If you're going to test the validity of card, do it before dereferencing card-host above. + BUG_ON(!host); + + if (ext_csd == NULL) + return 0; + /* Power class selection is supported for versions = 4.0 */ + if (card-csd.mmca_vsn CSD_SPEC_VER_4) + return 0; + /* Power class values are defined only for 4/8 bit bus */ + if (bus_width == EXT_CSD_BUS_WIDTH_1) + return 0; Let's add newlines before each comment line here. + + switch (1 host-ios.vdd) { + case MMC_VDD_165_195: + if (host-ios.clock = 2600) + index = EXT_CSD_PWR_CL_26_195; + else if (host-ios.clock = 5200) + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ? + EXT_CSD_PWR_CL_52_195 : + EXT_CSD_PWR_CL_DDR_52_195; + else if (host-ios.clock = 2) + index = EXT_CSD_PWR_CL_200_195; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + case MMC_VDD_34_35: + case MMC_VDD_35_36: + if (host-ios.clock = 2600) + index = EXT_CSD_PWR_CL_26_360; + else if (host-ios.clock = 5200) + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ? + EXT_CSD_PWR_CL_52_360 : + EXT_CSD_PWR_CL_DDR_52_360; + else if (host-ios.clock = 2) + index = EXT_CSD_PWR_CL_200_360; + break; + default: + printk(KERN_ERR votage range not supported\n); (voltage, not votage) This isn't good, because someone reading dmesg will have no idea that this message came from MMC, and even if they know that it came from MMC, they won't know which controller/card it came from. I suggest: pr_warning(%s: Voltage range not supported for power class.\n, mmc_hostname(host)); + break; + } + + pwrclass_val = ext_csd[index]; + + if (bus_width (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) + pwrclass_val = (pwrclass_val EXT_CSD_PWR_CL_8BIT_MASK) + EXT_CSD_PWR_CL_8BIT_SHIFT; + else + pwrclass_val = (pwrclass_val EXT_CSD_PWR_CL_4BIT_MASK) + EXT_CSD_PWR_CL_4BIT_SHIFT; + + /*If the power class is different from the default value*/ Same comment -- leave spaces before the comment text. (I meant for you to apply this comment to the whole patch.) + if (pwrclass_val 0) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_CLASS, +
[PATCH v4] mmc: core: Add default timeout value for CMD6.
EXT_CSD[248] includes the default maximum timeout for CMD6. This field is added at eMMC4.5 Spec. And it can be used for default timeout except for some operations which don't define the timeout(i.e. background operation, sanitize, flush cache) in eMMC4.5 Spec. Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/core/mmc.c | 16 include/linux/mmc/card.h |1 + include/linux/mmc/mmc.h |1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1c..b2ee14a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) else card-erased_byte = 0x0; + if (card-ext_csd.rev = 6) + card-ext_csd.generic_cmd6_time = 10 * + ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; + else + card-ext_csd.generic_cmd6_time = 0; + out: return err; } @@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (card-ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_ERASE_GROUP_DEF, 1, 0); +EXT_CSD_ERASE_GROUP_DEF, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if ((card-ext_csd.hs_max_dtr != 0) (host-caps MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_HS_TIMING, 1, 0); +EXT_CSD_HS_TIMING, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], -0); +card-ext_csd.generic_cmd6_time); if (!err) { mmc_set_bus_width(card-host, bus_width); @@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], -0); +card-ext_csd.generic_cmd6_time); } if (err) { printk(KERN_WARNING %s: switch to bus width %d ddr %d diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b460fc2..b713abf 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -52,6 +52,7 @@ struct mmc_ext_csd { u8 part_config; unsigned intpart_time; /* Units: ms */ unsigned intsa_timeout; /* Units: 100ns */ + unsigned intgeneric_cmd6_time; /* Units: 10ms */ unsigned inths_max_dtr; unsigned intsectors; unsigned intcard_type; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 5a794cb..e869f00 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -293,6 +293,7 @@ struct _mmc_csd { #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ #define EXT_CSD_SEC_FEATURE_SUPPORT231 /* RO */ #define EXT_CSD_TRIM_MULT 232 /* RO */ +#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ /* * EXT_CSD field definitions -- 1.7.0.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 REPOST 1/2] arm/dt: Tegra: Update SDHCI nodes to match bindings
On Tuesday 20 September 2011, Olof Johansson wrote: On Tue, Sep 20, 2011 at 2:01 PM, Arnd Bergmann a...@arndb.de wrote: Should I take the other one as well? It's probably better to let that go the proper way through the tegra tree for 3.2, right? Given that you have a public tree right now, and I don't (since kernel.org is down), please feel free to start a tegra/for-3.2 branch for me and apply it there. I'll base further work on top of that if needed. (There also aren't a whole lot of other patches queued for 3.2 right now). Ok, I've put it into the next/fixes branch now, so it will be in 3.2. Thanks, Arnd -- 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 37/57] mmc: irq: Remove IRQF_DISABLED
On Wed, Sep 21, 2011 at 2:58 PM, Yong Zhang yong.zha...@gmail.com wrote: Since commit [c58543c8: genirq: Run irq handlers with interrupts disabled], We run all interrupt handlers with interrupts disabled and we even check and yell when an interrupt handler returns with interrupts enabled (see commit [b738a50a: genirq: Warn when handler enables interrupts]). So now this flag is a NOOP and can be removed. Signed-off-by: Yong Zhang yong.zha...@gmail.com For omap_hsmmc.c Acked-by: Kishore Kadiyala kishore.kadiy...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 5 ++--- drivers/mmc/host/tmio_mmc.c | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 21e4a79..75c6395 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2015,7 +2015,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } /* Request IRQ for MMC operations */ - ret = request_irq(host-irq, omap_hsmmc_irq, IRQF_DISABLED, + ret = request_irq(host-irq, omap_hsmmc_irq, 0, mmc_hostname(mmc), host); if (ret) { dev_dbg(mmc_dev(host-mmc), Unable to grab HSMMC IRQ\n); @@ -2043,8 +2043,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if ((mmc_slot(host).card_detect_irq)) { ret = request_irq(mmc_slot(host).card_detect_irq, omap_hsmmc_cd_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_DISABLED, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, mmc_hostname(mmc), host); if (ret) { dev_dbg(mmc_dev(host-mmc), diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 44a9668..a4ea102 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -88,8 +88,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *pdev) if (ret) goto cell_disable; - ret = request_irq(irq, tmio_mmc_irq, IRQF_DISABLED | - IRQF_TRIGGER_FALLING, dev_name(pdev-dev), host); + ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING, + dev_name(pdev-dev), host); if (ret) goto host_remove; -- 1.7.4.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] mmc : general purpose partition support.
It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeon linkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h |4 include/linux/mmc/mmc.h |4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* +* General purpose partition Support +*/ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145] 16) + (ext_csd[144] 8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp1_size = 19; + + card-ext_csd.gp2_size = + (ext_csd[148] 16) + (ext_csd[147] 8) + + ext_csd[146]; + card-ext_csd.gp2_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp2_size = 19; + + card-ext_csd.gp3_size = + (ext_csd[151] 16) + (ext_csd[150] 8) + + ext_csd[149]; + card-ext_csd.gp3_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp3_size = 19; + + card-ext_csd.gp4_size = + (ext_csd[154] 16) + (ext_csd[153] 8) + + ext_csd[152]; + card-ext_csd.gp4_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp4_size = 19; + } card-ext_csd.sec_trim_mult = ext_csd[EXT_CSD_SEC_TRIM_MULT]; card-ext_csd.sec_erase_mult = diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b460fc2..96a98a7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -64,6 +64,10 @@ struct mmc_ext_csd {
Re: bounce_sg and sg in mmc_queue
On 09/21/2011 11:26 AM, J Freyensee wrote: Hello: Could anyone tell me in struct mmc_queue, what is the difference between 'struct scatterlist *bounce_sg' and 'struct scatterlist *sg' is? I see 'bounce_sg' get used to copy data from/to the buffer upon a host read/write operation so I assume 'bounce_sg' points to the most recent data from a host controller read/write operation. If someone actually knows this, I will send up a patch documenting this in the code. I think some of the mmc code could use a little documentation?? Thanks for the help. -- J (James/Jay) Freyensee Storage Technology Group Intel Corporation -- 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 1/3] arm/tegra: Move EN_VDD_1V05_GPIO to board-harmony.h
Russell King - ARM Linux wrote at Thursday, September 22, 2011 2:12 AM: On Wed, Sep 21, 2011 at 01:16:49PM -0700, Olof Johansson wrote: Works for me. Or I could stage it in a topic branch that would be merged after Russell's GPIO tree. Holding stuff off from being merged doesn't work. Russell, So I take it I should add the two ack'd patches to the ARM patch system, and have you pick them up? Thanks. If you have the following commit structure: A---...-M1-B-C-M2 +---A1-B1-C1' / +-A2-B2-C2---' Now, lets say A2 depends on C1. Merely delaying the stuff so that M2 happens after M1 is insufficient to ensure git state doesn't break. When bisecting, its entirely possible that the bisect algorithm may chose B2 as a potential test candidate. At that point you end up with A2, but without C1. The only way to solve this is to have A2 following on from C1 - which of course requires A1..C1 to be declared stable and either pulled into your local tree or for A2..C2 to be submitted to the same tree which A1..C1 are already in. -- nvpupblic -- 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 1/3] arm/tegra: Move EN_VDD_1V05_GPIO to board-harmony.h
On Thu, Sep 22, 2011 at 09:31:48AM -0700, Stephen Warren wrote: Russell King - ARM Linux wrote at Thursday, September 22, 2011 2:12 AM: On Wed, Sep 21, 2011 at 01:16:49PM -0700, Olof Johansson wrote: Works for me. Or I could stage it in a topic branch that would be merged after Russell's GPIO tree. Holding stuff off from being merged doesn't work. Russell, So I take it I should add the two ack'd patches to the ARM patch system, and have you pick them up? That's a workable solution, yes. I've done that with various other gpio patches from people, and Grant seems happy with that. -- 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 1/3] arm/tegra: Move EN_VDD_1V05_GPIO to board-harmony.h
On Thu, Sep 22, 2011 at 05:32:58PM +0100, Russell King - ARM Linux wrote: On Thu, Sep 22, 2011 at 09:31:48AM -0700, Stephen Warren wrote: Russell King - ARM Linux wrote at Thursday, September 22, 2011 2:12 AM: On Wed, Sep 21, 2011 at 01:16:49PM -0700, Olof Johansson wrote: Works for me. Or I could stage it in a topic branch that would be merged after Russell's GPIO tree. Holding stuff off from being merged doesn't work. Russell, So I take it I should add the two ack'd patches to the ARM patch system, and have you pick them up? That's a workable solution, yes. I've done that with various other gpio patches from people, and Grant seems happy with that. Yes, I'm comfortable with patches going in via other trees when there are dependencies. g. -- 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 2/3] arm/tegra: Replace mach/gpio.h with mach/gpio-tegra.h
On Wed, Sep 21, 2011 at 01:33:39PM -0600, Stephen Warren wrote: This will eventually allow mach/gpio.h to be deleted. This mirrors LinusW's recent equivalent work on various other ARM platforms. Signed-off-by: Stephen Warren swar...@nvidia.com Acked-by: Grant Likely grant.lik...@secretlab.ca --- arch/arm/mach-tegra/board-harmony.h |2 + arch/arm/mach-tegra/board-paz00.h |2 + arch/arm/mach-tegra/board-seaboard.h |2 + arch/arm/mach-tegra/board-trimslice.h |2 + arch/arm/mach-tegra/include/mach/gpio-tegra.h | 39 + arch/arm/mach-tegra/include/mach/gpio.h | 39 - arch/arm/mach-tegra/usb_phy.c |1 + drivers/gpio/gpio-tegra.c |1 + drivers/mmc/host/sdhci-tegra.c|2 + 9 files changed, 51 insertions(+), 39 deletions(-) create mode 100644 arch/arm/mach-tegra/include/mach/gpio-tegra.h diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h index 280d203..139d96c 100644 --- a/arch/arm/mach-tegra/board-harmony.h +++ b/arch/arm/mach-tegra/board-harmony.h @@ -17,6 +17,8 @@ #ifndef _MACH_TEGRA_BOARD_HARMONY_H #define _MACH_TEGRA_BOARD_HARMONY_H +#include mach/gpio-tegra.h + #define HARMONY_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_)) #define HARMONY_GPIO_WM8903(_x_) (HARMONY_GPIO_TPS6586X(4) + (_x_)) diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h index 86057c3..2dc1899 100644 --- a/arch/arm/mach-tegra/board-paz00.h +++ b/arch/arm/mach-tegra/board-paz00.h @@ -17,6 +17,8 @@ #ifndef _MACH_TEGRA_BOARD_PAZ00_H #define _MACH_TEGRA_BOARD_PAZ00_H +#include mach/gpio-tegra.h + /* SDCARD */ #define TEGRA_GPIO_SD1_CDTEGRA_GPIO_PV5 #define TEGRA_GPIO_SD1_WPTEGRA_GPIO_PH1 diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h index d06c334..4c45d4c 100644 --- a/arch/arm/mach-tegra/board-seaboard.h +++ b/arch/arm/mach-tegra/board-seaboard.h @@ -17,6 +17,8 @@ #ifndef _MACH_TEGRA_BOARD_SEABOARD_H #define _MACH_TEGRA_BOARD_SEABOARD_H +#include mach/gpio-tegra.h + #define SEABOARD_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_)) #define SEABOARD_GPIO_WM8903(_x_)(SEABOARD_GPIO_TPS6586X(4) + (_x_)) diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h index 7a7dee8..50f128d 100644 --- a/arch/arm/mach-tegra/board-trimslice.h +++ b/arch/arm/mach-tegra/board-trimslice.h @@ -17,6 +17,8 @@ #ifndef _MACH_TEGRA_BOARD_TRIMSLICE_H #define _MACH_TEGRA_BOARD_TRIMSLICE_H +#include mach/gpio-tegra.h + #define TRIMSLICE_GPIO_SD4_CDTEGRA_GPIO_PP1 /* mmc4 cd */ #define TRIMSLICE_GPIO_SD4_WPTEGRA_GPIO_PP2 /* mmc4 wp */ diff --git a/arch/arm/mach-tegra/include/mach/gpio-tegra.h b/arch/arm/mach-tegra/include/mach/gpio-tegra.h new file mode 100644 index 000..87d37fd --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/gpio-tegra.h @@ -0,0 +1,39 @@ +/* + * arch/arm/mach-tegra/include/mach/gpio.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Erik Gilling konk...@google.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MACH_TEGRA_GPIO_TEGRA_H +#define __MACH_TEGRA_GPIO_TEGRA_H + +#include linux/types.h +#include mach/irqs.h + +#define TEGRA_NR_GPIOS INT_GPIO_NR + +#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio)) + +struct tegra_gpio_table { + int gpio; /* GPIO number */ + boolenable; /* Enable for GPIO at init? */ +}; + +void tegra_gpio_config(struct tegra_gpio_table *table, int num); +void tegra_gpio_enable(int gpio); +void tegra_gpio_disable(int gpio); + +#endif diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h index 7910d26..e69de29 100644 --- a/arch/arm/mach-tegra/include/mach/gpio.h +++ b/arch/arm/mach-tegra/include/mach/gpio.h @@ -1,39 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/gpio.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling konk...@google.com - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY;
Re: [PATCH V1] mmc: core: HS200 mode support for eMMC 4.5
On 09/22/2011 04:13 AM, Girish K S wrote: This patch adds the support of the HS200 bus speed for eMMC 4.5 devices. The eMMC 4.5 devices have support for 200MHz bus speed. The mmc core and host modules have been touched to add support for this module. It is necessary to know the card type in the sdhci.c file to add support for eMMC tuning function. So card.h file is included to import the card data structure. Signed-off-by: Girish K Sgirish.shivananja...@linaro.org --- v1: cases which produce same result have been combined to reduce repeated assignments. patch recreated after rebase to chris balls mmc-next branch. drivers/mmc/core/bus.c |3 +- drivers/mmc/core/mmc.c | 89 +- drivers/mmc/host/sdhci.c | 18 -- include/linux/mmc/card.h |3 ++ include/linux/mmc/host.h |8 include/linux/mmc/mmc.h |9 - 6 files changed, 116 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 393d817..a0aa7ab 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -301,10 +301,11 @@ int mmc_add_card(struct mmc_card *card) mmc_card_ddr_mode(card) ? DDR : , type); } else { - printk(KERN_INFO %s: new %s%s%s card at address %04x\n, + printk(KERN_INFO %s: new %s%s%s%s card at address %04x\n, mmc_hostname(card-host), mmc_sd_card_uhs(card) ? ultra high speed : (mmc_card_highspeed(card) ? high speed : ), + (mmc_card_hs200(card) ? HS200 : ), mmc_card_ddr_mode(card) ? DDR : , type, card-rca); } when changing printk()'s in legacy code, how about changing the printk() itself to pr_info(), which is the standard now (at least if you ever want to get a new driver into the kernel)? diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 9dd6c82..2159ff6 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -283,6 +283,39 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) } card-ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; switch (ext_csd[EXT_CSD_CARD_TYPE] EXT_CSD_CARD_TYPE_MASK) { + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_200 | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200; + break; + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_2V | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V; + break; + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_52 | +EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_8V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + case EXT_CSD_CARD_TYPE_SDR_1_8V | EXT_CSD_CARD_TYPE_DDR_52 | +EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card-ext_csd.hs_max_dtr = 2; + card-ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V; + break; case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card-ext_csd.hs_max_dtr = 5200; @@ -620,7 +653,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; - int err, ddr = 0; + int err, ddr = 0, hs_sdr = 0; Don't mean to be picky, but this line could be cleaned up a bit (and I am wondering if a tool like 'sparse' or checkpatch.pl would complain?)? int err, ddr = 0; int hs_sdr = 0; or int err; int ddr= 0; int hs_sdr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; @@ -810,10 +843,15 @@ static int mmc_init_card(struct
Re: [PATCH] mmc : general purpose partition support.
On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h |4 include/linux/mmc/mmc.h |4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* +* General purpose partition Support +*/ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145] 16) + (ext_csd[144] 8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp1_size= 19; + + card-ext_csd.gp2_size = + (ext_csd[148] 16) + (ext_csd[147] 8) + + ext_csd[146]; + card-ext_csd.gp2_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp2_size= 19; + + card-ext_csd.gp3_size = + (ext_csd[151] 16) + (ext_csd[150] 8) + + ext_csd[149]; + card-ext_csd.gp3_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp3_size= 19; + + card-ext_csd.gp4_size = + (ext_csd[154] 16) + (ext_csd[153] 8) + + ext_csd[152]; + card-ext_csd.gp4_size *= +
Re: [PATCH v4] mmc: core: Add default timeout value for CMD6.
On 09/21/2011 07:12 PM, Seungwon Jeon wrote: EXT_CSD[248] includes the default maximum timeout for CMD6. This field is added at eMMC4.5 Spec. And it can be used for default timeout except for some operations which don't define the timeout(i.e. background operation, sanitize, flush cache) in eMMC4.5 Spec. Out of curiosity, what cache is being refered to in 'flush cache' comment? Signed-off-by: Seungwon Jeontgih@samsung.com --- drivers/mmc/core/mmc.c | 16 include/linux/mmc/card.h |1 + include/linux/mmc/mmc.h |1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1c..b2ee14a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) else card-erased_byte = 0x0; + if (card-ext_csd.rev= 6) + card-ext_csd.generic_cmd6_time = 10 * + ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; + else + card-ext_csd.generic_cmd6_time = 0; + out: return err; } @@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (card-ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_ERASE_GROUP_DEF, 1, 0); +EXT_CSD_ERASE_GROUP_DEF, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if ((card-ext_csd.hs_max_dtr != 0) (host-caps MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_HS_TIMING, 1, 0); +EXT_CSD_HS_TIMING, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], -0); +card-ext_csd.generic_cmd6_time); if (!err) { mmc_set_bus_width(card-host, bus_width); @@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], -0); +card-ext_csd.generic_cmd6_time); } if (err) { printk(KERN_WARNING %s: switch to bus width %d ddr %d diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b460fc2..b713abf 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -52,6 +52,7 @@ struct mmc_ext_csd { u8 part_config; unsigned intpart_time; /* Units: ms */ unsigned intsa_timeout; /* Units: 100ns */ + unsigned intgeneric_cmd6_time; /* Units: 10ms */ unsigned inths_max_dtr; unsigned intsectors; unsigned intcard_type; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 5a794cb..e869f00 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -293,6 +293,7 @@ struct _mmc_csd { #define EXT_CSD_SEC_ERASE_MULT230 /* RO */ #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ #define EXT_CSD_TRIM_MULT 232 /* RO */ +#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ /* * EXT_CSD field definitions -- 1.7.0.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 -- J (James/Jay) Freyensee Storage Technology Group Intel Corporation -- 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] mmc : general purpose partition support.
2011/9/23 J Freyensee james_p_freyen...@linux.intel.com: On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h | 4 include/linux/mmc/mmc.h | 4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). - if card-ext_csd.gp1_size is no zero, it means general purpose partition is enable. and it can set up to 4 partition in specification. so we should check it by next if(). + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* + * General purpose partition Support + */ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145] 16) + (ext_csd[144] 8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp1_size= 19; + + card-ext_csd.gp2_size = + (ext_csd[148] 16) + (ext_csd[147] 8) + + ext_csd[146]; + card-ext_csd.gp2_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp2_size= 19; + + card-ext_csd.gp3_size = + (ext_csd[151] 16) + (ext_csd[150] 8) + + ext_csd[149]; + card-ext_csd.gp3_size *= + (size_t)(hc_erase_grp_sz
Re: [PATCH] mmc : general purpose partition support.
On 09/22/2011 04:15 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h |4 include/linux/mmc/mmc.h |4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). - if card-ext_csd.gp1_size is no zero, it means general purpose partition is enable. and it can set up to 4 partition in specification. so we should check it by next if(). Please document that in your code. Please add a function header to this function. + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* +* General purpose partition Support +*/ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT]0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145]16) + (ext_csd[144]8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp1_size= 19; + + card-ext_csd.gp2_size = + (ext_csd[148]16) + (ext_csd[147]8) + + ext_csd[146]; + card-ext_csd.gp2_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp2_size= 19; + + card-ext_csd.gp3_size = + (ext_csd[151]16) + (ext_csd[150]8) + + ext_csd[149]; +
Re: [PATCH] mmc : general purpose partition support.
2011/9/23 J Freyensee james_p_freyen...@linux.intel.com: On 09/22/2011 04:15 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h | 4 include/linux/mmc/mmc.h | 4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). - if card-ext_csd.gp1_size is no zero, it means general purpose partition is enable. and it can set up to 4 partition in specification. so we should check it by next if(). Please document that in your code. Please add a function header to this function. I will add comments at this code. I don't understand why a function header should be added yet. + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* + * General purpose partition Support + */ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145] 16) + (ext_csd[144] 8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); + card-ext_csd.gp1_size= 19; + + card-ext_csd.gp2_size = + (ext_csd[148] 16) + (ext_csd[147] 8) + + ext_csd[146]; + card-ext_csd.gp2_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); +
Re: [PATCH] mmc : general purpose partition support.
On 09/22/2011 04:58 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 04:15 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h |4 include/linux/mmc/mmc.h |4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). -if card-ext_csd.gp1_size is no zero, it means general purpose partition is enable. and it can set up to 4 partition in specification. so we should check it by next if(). Please document that in your code. Please add a function header to this function. I will add comments at this code. I don't understand why a function header should be added yet. One or the other. but a function comment header should be added at some point. Yes, the mmc subsystem is pretty legacy, but any new work that gets added to the kernel is usually has higher standards for stuff like not just adding function header comments but putting them in a certain format...at least this is what I went through when I had things accepted upstream. + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* +* General purpose partition Support +*/ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = + (ext_csd[145] 16) + (ext_csd[144] 8) + + ext_csd[143]; + card-ext_csd.gp1_size *= + (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); +
Re: [PATCH] mmc : general purpose partition support.
2011/9/23 J Freyensee james_p_freyen...@linux.intel.com On 09/22/2011 04:58 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 04:15 PM, NamJae Jeon wrote: 2011/9/23 J Freyenseejames_p_freyen...@linux.intel.com: On 09/22/2011 08:34 AM, Namjae Jeon wrote: It allows general purpose parition in MMC Device. If it is enable, it will make mmcblk0gp1,gp2,gp3,gp4 partition like this. cat /proc/paritition 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp4 179 160 4096 mmcblk0gp3 179 128 4096 mmcblk0gp2 179 96 1052672 mmcblk0gp1 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeonlinkinj...@gmail.com --- drivers/mmc/card/block.c | 36 drivers/mmc/core/mmc.c | 42 ++ include/linux/mmc/card.h | 4 include/linux/mmc/mmc.h | 4 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9b90726..074ec55 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1402,6 +1402,42 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } + if (card-ext_csd.gp1_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP1, + card-ext_csd.gp1_size 9, + false, + gp1); + if (ret) + return ret; + } + if mmc_blk_alloc_part() fails for 'if (card-ext_csd.pt1_size)', why would you want to give this code the opportunity to call mmc_blk_alloc_part() again with the next if() below? If mmc_blk_alloc_part() fails, is it a big problem, like kzalloc() failing? If so, I would think you would want to immediately quit this function and report an error (either use errno value or pass the value of ret). - if card-ext_csd.gp1_size is no zero, it means general purpose partition is enable. and it can set up to 4 partition in specification. so we should check it by next if(). Please document that in your code. Please add a function header to this function. I will add comments at this code. I don't understand why a function header should be added yet. One or the other. but a function comment header should be added at some point. Yes, the mmc subsystem is pretty legacy, but any new work that gets added to the kernel is usually has higher standards for stuff like not just adding function header comments but putting them in a certain format...at least this is what I went through when I had things accepted upstream. Okay, I will release patch v2 after adding function header comments again. Thanks for your review. + if (card-ext_csd.gp2_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP2, + card-ext_csd.gp2_size 9, + false, + gp2); + if (ret) + return ret; + } + + if (card-ext_csd.gp3_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP3, + card-ext_csd.gp3_size 9, + false, + gp3); + if (ret) + return ret; + } + + if (card-ext_csd.gp4_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_GP4, + card-ext_csd.gp4_size 9, + false, + gp4); + if (ret) + return ret; + } + return ret; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 10f5a19..cc31511 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -393,6 +393,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.enhanced_area_offset = -EINVAL; card-ext_csd.enhanced_area_size = -EINVAL; } + + /* + * General purpose partition Support + */ + + if (ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x1) { + + u8 hc_erase_grp_sz = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + u8 hc_wp_grp_sz = + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + card-ext_csd.enhanced_area_en = 1; + + card-ext_csd.gp1_size = +
RE: [PATCH v4] mmc: core: Add default timeout value for CMD6.
Hi, J Freyensee wrote: On 09/21/2011 07:12 PM, Seungwon Jeon wrote: EXT_CSD[248] includes the default maximum timeout for CMD6. This field is added at eMMC4.5 Spec. And it can be used for default timeout except for some operations which don't define the timeout(i.e. background operation, sanitize, flush cache) in eMMC4.5 Spec. Out of curiosity, what cache is being refered to in 'flush cache' comment? It is described in eMMC4.5 Spec. Best regards, Seungwon Jeon. Signed-off-by: Seungwon Jeontgih@samsung.com --- drivers/mmc/core/mmc.c | 16 include/linux/mmc/card.h |1 + include/linux/mmc/mmc.h |1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1c..b2ee14a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) else card-erased_byte = 0x0; + if (card-ext_csd.rev= 6) + card-ext_csd.generic_cmd6_time = 10 * + ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; + else + card-ext_csd.generic_cmd6_time = 0; + out: return err; } @@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (card-ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_ERASE_GROUP_DEF, 1, 0); +EXT_CSD_ERASE_GROUP_DEF, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if ((card-ext_csd.hs_max_dtr != 0) (host-caps MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -EXT_CSD_HS_TIMING, 1, 0); +EXT_CSD_HS_TIMING, 1, +card-ext_csd.generic_cmd6_time); if (err err != -EBADMSG) goto free_card; @@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], -0); +card-ext_csd.generic_cmd6_time); if (!err) { mmc_set_bus_width(card-host, bus_width); @@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], -0); +card-ext_csd.generic_cmd6_time); } if (err) { printk(KERN_WARNING %s: switch to bus width %d ddr %d diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b460fc2..b713abf 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -52,6 +52,7 @@ struct mmc_ext_csd { u8 part_config; unsigned intpart_time; /* Units: ms */ unsigned intsa_timeout; /* Units: 100ns */ + unsigned intgeneric_cmd6_time; /* Units: 10ms */ unsigned inths_max_dtr; unsigned intsectors; unsigned intcard_type; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 5a794cb..e869f00 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -293,6 +293,7 @@ struct _mmc_csd { #define EXT_CSD_SEC_ERASE_MULT230 /* RO */ #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ #define EXT_CSD_TRIM_MULT 232 /* RO */ +#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ /* * EXT_CSD field definitions -- 1.7.0.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 -- J (James/Jay) Freyensee Storage Technology Group Intel Corporation -- 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 V1] mmc: core: HS200 mode support for eMMC 4.5
On Thu, Sep 22, 2011 at 04:43:40PM +0530, Girish K S wrote: This patch adds the support of the HS200 bus speed for eMMC 4.5 devices. The eMMC 4.5 devices have support for 200MHz bus speed. The mmc core and host modules have been touched to add support for this module. It is necessary to know the card type in the sdhci.c file to add support for eMMC tuning function. So card.h file is included to import the card data structure. Signed-off-by: Girish K S girish.shivananja...@linaro.org --- v1: cases which produce same result have been combined to reduce repeated assignments. patch recreated after rebase to chris balls mmc-next branch. Your patch does not apply to mmc-next tree... @@ -1661,7 +1663,10 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) if (!tuning_loop_counter !timeout) break; The sdhci_execute_tuning will not proceed here unless the ctrl register indicates the host is running at UHS_SDR104 or UHS_SDR50 with SDHCI_SDR50_NEEDS_TUNING flag set. Does your host also reflect this when running at 200Mhz bus speed? - cmd.opcode = MMC_SEND_TUNING_BLOCK; + if (mmc-card-type == MMC_TYPE_MMC) + cmd.opcode = MMC_SEND_TUNING_BLOCK_HS200; + else + cmd.opcode = MMC_SEND_TUNING_BLOCK; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; cmd.retries = 0; -- 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] mmc : general purpose partition support.
Hi Namjae, I scanned over your changes to enable GP partitions, and while I did not yet test your changes, they do appear to be ok. Please CC me on the next version of your patch so I can give it a spin and Ack on it. I do suggest at least thinking about ways to improve on this. Back when I added boot partition support, I already didn't like the fact that the block driver had to be aware of the eMMC partitions, with all the code duplication and such. By adding four more partitions, you've compounded the problem and now you have six pieces of code that really look the same. The core/mmc.c right now scans the size values and stores them in mmc_card, and the block driver is smart enough to know what to do with them. Why not make the block code generic at the expense of keeping an array of structures in mmc_card? The block driver would then just iterate over these and create the additional devices. The partition switch routine would then operate on these structures, and could then be pulled out of the block driver, making it simpler. Each physical partition could be described by something like - struct mmc_part { unsigned int size; unsigned int cookie;/* for mmc, idx used in mmc_switch, part_type from current mmc_blk_data */ char name[DISK_NAME_LEN]; bool force_ro; /* to make boot parts RO by default */ }; Just an idea. Clearly, if MMC grows by another 4-5 possible partitions, it's not realistic to be copy-pasting the same block of code, nor would it make sense if/when these types of devices support an arbitrary amount of physical partitions. Thanks, A -- 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] mmc : general purpose partition support.
2011/9/23 Andrei Warkentin awarken...@vmware.com: Hi Namjae, I scanned over your changes to enable GP partitions, and while I did not yet test your changes, they do appear to be ok. Please CC me on the next version of your patch so I can give it a spin and Ack on it. I do suggest at least thinking about ways to improve on this. Back when I added boot partition support, I already didn't like the fact that the block driver had to be aware of the eMMC partitions, with all the code duplication and such. By adding four more partitions, you've compounded the problem and now you have six pieces of code that really look the same. The core/mmc.c right now scans the size values and stores them in mmc_card, and the block driver is smart enough to know what to do with them. Why not make the block code generic at the expense of keeping an array of structures in mmc_card? The block driver would then just iterate over these and create the additional devices. The partition switch routine would then operate on these structures, and could then be pulled out of the block driver, making it simpler. Each physical partition could be described by something like - struct mmc_part { unsigned int size; unsigned int cookie; /* for mmc, idx used in mmc_switch, part_type from current mmc_blk_data */ char name[DISK_NAME_LEN]; bool force_ro; /* to make boot parts RO by default */ }; Just an idea. Clearly, if MMC grows by another 4-5 possible partitions, it's not realistic to be copy-pasting the same block of code, nor would it make sense if/when these types of devices support an arbitrary amount of physical partitions. Thanks, A Okay, I understand what you want. I will try to make patch included your suggestion again. Thanks for your review. -- 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: ext_csd.raw_* used in comparison but never set
f39b2dd9d065151a04f5996656d1f27a7eb32d45 added code to only compare read-only ext_csd fields in bus width testing code, yet it's comparing some fields that are never set. The affected fields are ext_csd.raw_erased_mem_count and ext_csd.raw_partition_support. Signed-off-by: Andrei Warkentin andrey.warken...@gmail.com --- drivers/mmc/core/mmc.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1c..bb33832 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -359,6 +359,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) * card has the Enhanced area enabled. If so, export enhanced * area offset and size to user by adding sysfs interface. */ + card-ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] 0x2) (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] 0x1)) { u8 hc_erase_grp_sz = @@ -405,6 +406,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) if (card-ext_csd.rev = 5) card-ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; + card-ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) card-erased_byte = 0xFF; else -- 1.7.6.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
slow eMMC write speed
Hello all, I am working on the block driver module of the eMMC driver (SDIO 3.0 controller). I am seeing very low write speed for eMMC transfers. On further debugging, I observed that every 63rd and 64th transfer takes a long time. I have tabulated this by noting the time interval between when CMD 25 (multi block write command) is sent and when DATA_END interrupt is received. In normal cases, to transfer 64k (128 blocks of data), it takes about 2.5ms. But, under the really slow transfer speed cases, it takes about 250-350ms to get the data_end interrupt after the multiblock write command is sent. In some cases, it takes a longer time. This radically reduces the throughput of the transfers. I have also enabled the bounce buffers. As a side question, can somebody please tell me why the bounce buffer is restricted to 64kB? Thanks in advance for any help that you can provide me on this issue. Also, please include my email id in the cc field when replying to this email since I am not subscribed to this mailing list. Thanks, Praveen Krishnan -- 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