Loading Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt 0 → 100644 +18 −0 Original line number Diff line number Diff line Broadcom BCM2835 SDHCI controller This file documents differences between the core properties described by mmc.txt and the properties that represent the BCM2835 controller. Required properties: - compatible : Should be "brcm,bcm2835-sdhci". - clocks : The clock feeding the SDHCI controller. Example: sdhci: sdhci { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; interrupts = <2 30>; clocks = <&clk_mmc>; bus-width = <4>; }; Documentation/devicetree/bindings/mmc/orion-sdio.txt 0 → 100644 +17 −0 Original line number Diff line number Diff line * Marvell orion-sdio controller This file documents differences between the core properties in mmc.txt and the properties used by the orion-sdio driver. - compatible: Should be "marvell,orion-sdio" - clocks: reference to the clock of the SDIO interface Example: mvsdio@d00d4000 { compatible = "marvell,orion-sdio"; reg = <0xd00d4000 0x200>; interrupts = <54>; clocks = <&gateclk 17>; status = "disabled"; }; drivers/mmc/card/block.c +17 −13 Original line number Diff line number Diff line Loading @@ -113,17 +113,6 @@ struct mmc_blk_data { static DEFINE_MUTEX(open_lock); enum mmc_blk_status { MMC_BLK_SUCCESS = 0, MMC_BLK_PARTIAL, MMC_BLK_CMD_ERR, MMC_BLK_RETRY, MMC_BLK_ABORT, MMC_BLK_DATA_ERR, MMC_BLK_ECC_ERR, MMC_BLK_NOMEDIUM, }; module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); Loading Loading @@ -1364,8 +1353,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) } else areq = NULL; areq = mmc_start_req(card->host, areq, (int *) &status); if (!areq) if (!areq) { if (status == MMC_BLK_NEW_REQUEST) mq->flags |= MMC_QUEUE_NEW_REQUEST; return 0; } mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); brq = &mq_rq->brq; Loading Loading @@ -1438,6 +1430,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) break; case MMC_BLK_NOMEDIUM: goto cmd_abort; default: pr_err("%s: Unhandled return value (%d)", req->rq_disk->disk_name, status); goto cmd_abort; } if (ret) { Loading Loading @@ -1472,6 +1468,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) int ret; struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_host *host = card->host; unsigned long flags; if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ Loading @@ -1486,6 +1484,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) goto out; } mq->flags &= ~MMC_QUEUE_NEW_REQUEST; if (req && req->cmd_flags & REQ_DISCARD) { /* complete ongoing async transfer before issuing discard */ if (card->host->areq) Loading @@ -1501,11 +1500,16 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) mmc_blk_issue_rw_rq(mq, NULL); ret = mmc_blk_issue_flush(mq, req); } else { if (!req && host->areq) { spin_lock_irqsave(&host->context_info.lock, flags); host->context_info.is_waiting_last_req = true; spin_unlock_irqrestore(&host->context_info.lock, flags); } ret = mmc_blk_issue_rw_rq(mq, req); } out: if (!req) if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) /* release host only when there are no more requests */ mmc_release_host(card->host); return ret; Loading drivers/mmc/card/queue.c +30 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ #define MMC_QUEUE_BOUNCESZ 65536 #define MMC_QUEUE_SUSPENDED (1 << 0) #define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) /* * Prepare a MMC request. This just filters out odd stuff. Loading Loading @@ -58,6 +59,7 @@ static int mmc_queue_thread(void *d) do { struct request *req = NULL; struct mmc_queue_req *tmp; unsigned int cmd_flags = 0; spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); Loading @@ -67,12 +69,23 @@ static int mmc_queue_thread(void *d) if (req || mq->mqrq_prev->req) { set_current_state(TASK_RUNNING); cmd_flags = req ? req->cmd_flags : 0; mq->issue_fn(mq, req); if (mq->flags & MMC_QUEUE_NEW_REQUEST) { mq->flags &= ~MMC_QUEUE_NEW_REQUEST; continue; /* fetch again */ } /* * Current request becomes previous request * and vice versa. * In case of special requests, current request * has been finished. Do not assign it to previous * request. */ if (cmd_flags & MMC_REQ_SPECIAL_MASK) mq->mqrq_cur->req = NULL; mq->mqrq_prev->brq.mrq.data = NULL; mq->mqrq_prev->req = NULL; tmp = mq->mqrq_prev; Loading Loading @@ -103,6 +116,8 @@ static void mmc_request_fn(struct request_queue *q) { struct mmc_queue *mq = q->queuedata; struct request *req; unsigned long flags; struct mmc_context_info *cntx; if (!mq) { while ((req = blk_fetch_request(q)) != NULL) { Loading @@ -112,7 +127,20 @@ static void mmc_request_fn(struct request_queue *q) return; } if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) cntx = &mq->card->host->context_info; if (!mq->mqrq_cur->req && mq->mqrq_prev->req) { /* * New MMC request arrived when MMC thread may be * blocked on the previous request to be complete * with no current request fetched */ spin_lock_irqsave(&cntx->lock, flags); if (cntx->is_waiting_last_req) { cntx->is_new_req = true; wake_up_interruptible(&cntx->wait); } spin_unlock_irqrestore(&cntx->lock, flags); } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) wake_up_process(mq->thread); } Loading drivers/mmc/card/queue.h +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ struct mmc_queue { struct task_struct *thread; struct semaphore thread_sem; unsigned int flags; #define MMC_QUEUE_SUSPENDED (1 << 0) #define MMC_QUEUE_NEW_REQUEST (1 << 1) int (*issue_fn)(struct mmc_queue *, struct request *); void *data; struct request_queue *queue; Loading Loading
Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt 0 → 100644 +18 −0 Original line number Diff line number Diff line Broadcom BCM2835 SDHCI controller This file documents differences between the core properties described by mmc.txt and the properties that represent the BCM2835 controller. Required properties: - compatible : Should be "brcm,bcm2835-sdhci". - clocks : The clock feeding the SDHCI controller. Example: sdhci: sdhci { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; interrupts = <2 30>; clocks = <&clk_mmc>; bus-width = <4>; };
Documentation/devicetree/bindings/mmc/orion-sdio.txt 0 → 100644 +17 −0 Original line number Diff line number Diff line * Marvell orion-sdio controller This file documents differences between the core properties in mmc.txt and the properties used by the orion-sdio driver. - compatible: Should be "marvell,orion-sdio" - clocks: reference to the clock of the SDIO interface Example: mvsdio@d00d4000 { compatible = "marvell,orion-sdio"; reg = <0xd00d4000 0x200>; interrupts = <54>; clocks = <&gateclk 17>; status = "disabled"; };
drivers/mmc/card/block.c +17 −13 Original line number Diff line number Diff line Loading @@ -113,17 +113,6 @@ struct mmc_blk_data { static DEFINE_MUTEX(open_lock); enum mmc_blk_status { MMC_BLK_SUCCESS = 0, MMC_BLK_PARTIAL, MMC_BLK_CMD_ERR, MMC_BLK_RETRY, MMC_BLK_ABORT, MMC_BLK_DATA_ERR, MMC_BLK_ECC_ERR, MMC_BLK_NOMEDIUM, }; module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); Loading Loading @@ -1364,8 +1353,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) } else areq = NULL; areq = mmc_start_req(card->host, areq, (int *) &status); if (!areq) if (!areq) { if (status == MMC_BLK_NEW_REQUEST) mq->flags |= MMC_QUEUE_NEW_REQUEST; return 0; } mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); brq = &mq_rq->brq; Loading Loading @@ -1438,6 +1430,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) break; case MMC_BLK_NOMEDIUM: goto cmd_abort; default: pr_err("%s: Unhandled return value (%d)", req->rq_disk->disk_name, status); goto cmd_abort; } if (ret) { Loading Loading @@ -1472,6 +1468,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) int ret; struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_host *host = card->host; unsigned long flags; if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ Loading @@ -1486,6 +1484,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) goto out; } mq->flags &= ~MMC_QUEUE_NEW_REQUEST; if (req && req->cmd_flags & REQ_DISCARD) { /* complete ongoing async transfer before issuing discard */ if (card->host->areq) Loading @@ -1501,11 +1500,16 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) mmc_blk_issue_rw_rq(mq, NULL); ret = mmc_blk_issue_flush(mq, req); } else { if (!req && host->areq) { spin_lock_irqsave(&host->context_info.lock, flags); host->context_info.is_waiting_last_req = true; spin_unlock_irqrestore(&host->context_info.lock, flags); } ret = mmc_blk_issue_rw_rq(mq, req); } out: if (!req) if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) /* release host only when there are no more requests */ mmc_release_host(card->host); return ret; Loading
drivers/mmc/card/queue.c +30 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ #define MMC_QUEUE_BOUNCESZ 65536 #define MMC_QUEUE_SUSPENDED (1 << 0) #define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) /* * Prepare a MMC request. This just filters out odd stuff. Loading Loading @@ -58,6 +59,7 @@ static int mmc_queue_thread(void *d) do { struct request *req = NULL; struct mmc_queue_req *tmp; unsigned int cmd_flags = 0; spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); Loading @@ -67,12 +69,23 @@ static int mmc_queue_thread(void *d) if (req || mq->mqrq_prev->req) { set_current_state(TASK_RUNNING); cmd_flags = req ? req->cmd_flags : 0; mq->issue_fn(mq, req); if (mq->flags & MMC_QUEUE_NEW_REQUEST) { mq->flags &= ~MMC_QUEUE_NEW_REQUEST; continue; /* fetch again */ } /* * Current request becomes previous request * and vice versa. * In case of special requests, current request * has been finished. Do not assign it to previous * request. */ if (cmd_flags & MMC_REQ_SPECIAL_MASK) mq->mqrq_cur->req = NULL; mq->mqrq_prev->brq.mrq.data = NULL; mq->mqrq_prev->req = NULL; tmp = mq->mqrq_prev; Loading Loading @@ -103,6 +116,8 @@ static void mmc_request_fn(struct request_queue *q) { struct mmc_queue *mq = q->queuedata; struct request *req; unsigned long flags; struct mmc_context_info *cntx; if (!mq) { while ((req = blk_fetch_request(q)) != NULL) { Loading @@ -112,7 +127,20 @@ static void mmc_request_fn(struct request_queue *q) return; } if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) cntx = &mq->card->host->context_info; if (!mq->mqrq_cur->req && mq->mqrq_prev->req) { /* * New MMC request arrived when MMC thread may be * blocked on the previous request to be complete * with no current request fetched */ spin_lock_irqsave(&cntx->lock, flags); if (cntx->is_waiting_last_req) { cntx->is_new_req = true; wake_up_interruptible(&cntx->wait); } spin_unlock_irqrestore(&cntx->lock, flags); } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) wake_up_process(mq->thread); } Loading
drivers/mmc/card/queue.h +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ struct mmc_queue { struct task_struct *thread; struct semaphore thread_sem; unsigned int flags; #define MMC_QUEUE_SUSPENDED (1 << 0) #define MMC_QUEUE_NEW_REQUEST (1 << 1) int (*issue_fn)(struct mmc_queue *, struct request *); void *data; struct request_queue *queue; Loading