[PATCH 4/5] glamo-mci: Make the read_worker work in its own thread

Thibaut Girka thib at sitedethib.com
Wed Jun 16 16:21:02 CEST 2010


---
 drivers/mfd/glamo/glamo-mci.c |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index 94ebec9..f49bdde 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -52,9 +52,8 @@ struct glamo_mci_host {
 
 	unsigned char request_counter;
 
+	struct workqueue_struct *workqueue;
 	struct work_struct read_work;
-
-	unsigned clk_enabled:1;
 };
 
 static void glamo_mci_send_request(struct mmc_host *mmc,
@@ -259,7 +258,7 @@ static irqreturn_t glamo_mci_irq(int irq, void *data)
 
 #if 0
 	if (cmd->data->flags & MMC_DATA_READ)
-		return;
+		return IRQ_HANDLED;
 #endif
 
 	status = glamo_reg_read(host, GLAMO_REG_MMC_RB_STAT1);
@@ -283,8 +282,10 @@ static irqreturn_t glamo_mci_irq(int irq, void *data)
 	if (mrq->stop)
 		glamo_mci_send_command(host, mrq->stop);
 
+#if 1
 	if (cmd->data->flags & MMC_DATA_READ)
 		do_pio_read(host, cmd->data);
+#endif
 
 	if (mrq->stop)
 		mrq->stop->error = glamo_mci_wait_idle(host, jiffies + HZ);
@@ -313,6 +314,7 @@ static void glamo_mci_read_worker(struct work_struct *work)
 	cmd = host->mrq->cmd;
 	sg = cmd->data->sg;
 	do {
+		/* TODO: How to get rid of that? */
 		status = glamo_reg_read(host, GLAMO_REG_MMC_RB_STAT1);
 
 		if (status & (GLAMO_STAT1_MMC_RTOUT | GLAMO_STAT1_MMC_DTOUT))
@@ -337,12 +339,15 @@ static void glamo_mci_read_worker(struct work_struct *work)
 			from_ptr += sg->length >> 1;
 
 			data_read += sg->length;
+
 			sg = sg_next(sg);
 		}
 
 	} while (sg);
 	cmd->data->bytes_xfered = data_read;
 
+	/* TODO: Delete everything from now on, and let the IRQ handler do it? */
+
 	do {
 		status = glamo_reg_read(host, GLAMO_REG_MMC_RB_STAT1);
 	} while (!(status & GLAMO_STAT1_MMC_IDLE));
@@ -350,6 +355,7 @@ static void glamo_mci_read_worker(struct work_struct *work)
 	if (host->mrq->stop)
 		glamo_mci_send_command(host, host->mrq->stop);
 
+	/* TODO: Replace by glamo_mci_wait_idle? */
 	do {
 		status = glamo_reg_read(host, GLAMO_REG_MMC_RB_STAT1);
 	} while (!(status & GLAMO_STAT1_MMC_IDLE));
@@ -543,7 +549,7 @@ static void glamo_mci_send_command(struct glamo_mci_host *host,
 	   By starting to copy data when it's avaiable we can increase
 	   throughput by up to 30%. */
 	if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
-		schedule_work(&host->read_work);
+		queue_work(host->workqueue, &host->read_work);
 #endif
 
 }
@@ -731,11 +737,11 @@ static int glamo_mci_probe(struct platform_device *pdev)
 	if (core->pdata)
 		host->pdata = core->pdata->mmc_data;
 	host->power_mode = MMC_POWER_OFF;
-	host->clk_enabled = 0;
 	host->core = core;
 	host->irq = platform_get_irq(pdev, 0);
 
 	INIT_WORK(&host->read_work, glamo_mci_read_worker);
+	host->workqueue = create_singlethread_workqueue("glamo-mci-read");
 
 	host->regulator = regulator_get(pdev->dev.parent, "SD_3V3");
 	if (IS_ERR(host->regulator)) {
@@ -852,7 +858,6 @@ static int glamo_mci_probe(struct platform_device *pdev)
 
 probe_mmc_host_disable:
 	mmc_host_disable(mmc);
-probe_freeirq:
 	free_irq(host->irq, host);
 probe_iounmap_data:
 	iounmap(host->data_base);
@@ -867,6 +872,7 @@ probe_free_mem_region_mmio:
 probe_regulator_put:
 	regulator_put(host->regulator);
 probe_free_host:
+	destroy_workqueue(host->workqueue);
 	mmc_free_host(mmc);
 probe_out:
 	return ret;
@@ -877,6 +883,9 @@ static int glamo_mci_remove(struct platform_device *pdev)
 	struct mmc_host	*mmc = platform_get_drvdata(pdev);
 	struct glamo_mci_host *host = mmc_priv(mmc);
 
+	flush_workqueue(host->workqueue);
+	destroy_workqueue(host->workqueue);
+
 	mmc_host_enable(mmc);
 	mmc_remove_host(mmc);
 	mmc_host_disable(mmc);
-- 
1.7.1




More information about the openmoko-kernel mailing list