public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch v4 00/17] S3C24XX SD/MMC maintainer
@ 2008-06-30 15:25 Ben Dooks
  2008-06-30 15:25 ` [patch v4 01/17] MMC: S3C24XX MMC/SD driver Ben Dooks
                   ` (16 more replies)
  0 siblings, 17 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge

This is an update series for the Samsung S3C24XX SoC
series SD/MMC controller, originally by Thomas Kleffel
and updated by Ben Dooks.

This patch set has multiple authours as it has been
gathered from various sources, including the OpenMoko
project.

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 01/17] MMC: S3C24XX MMC/SD driver.
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver Ben Dooks
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3c_mci.patch --]
[-- Type: text/plain, Size: 40005 bytes --]

From: Thomas Kleffel <tk@maintech.de>

This is the latest S3C MMC/SD driver by Thomas Kleffel

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc6-sdmmc/include/asm-arm/arch-s3c2410/regs-sdi.h
===================================================================
--- linux-2.6.26-rc6-sdmmc.orig/include/asm-arm/arch-s3c2410/regs-sdi.h	2008-06-17 10:10:07.000000000 +0100
+++ linux-2.6.26-rc6-sdmmc/include/asm-arm/arch-s3c2410/regs-sdi.h	2008-06-17 23:56:02.000000000 +0100
@@ -28,9 +28,15 @@
 #define S3C2410_SDIDCNT               (0x30)
 #define S3C2410_SDIDSTA               (0x34)
 #define S3C2410_SDIFSTA               (0x38)
+
 #define S3C2410_SDIDATA               (0x3C)
 #define S3C2410_SDIIMSK               (0x40)
 
+#define S3C2440_SDIDATA               (0x40)
+#define S3C2440_SDIIMSK               (0x3C)
+
+#define S3C2440_SDICON_SDRESET        (1<<8)
+#define S3C2440_SDICON_MMCCLOCK       (1<<5)
 #define S3C2410_SDICON_BYTEORDER      (1<<4)
 #define S3C2410_SDICON_SDIOIRQ        (1<<3)
 #define S3C2410_SDICON_RWAITEN        (1<<2)
@@ -42,7 +48,8 @@
 #define S3C2410_SDICMDCON_LONGRSP     (1<<10)
 #define S3C2410_SDICMDCON_WAITRSP     (1<<9)
 #define S3C2410_SDICMDCON_CMDSTART    (1<<8)
-#define S3C2410_SDICMDCON_INDEX       (0xff)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+#define S3C2410_SDICMDCON_INDEX       (0x3f)
 
 #define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
 #define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
@@ -51,6 +58,9 @@
 #define S3C2410_SDICMDSTAT_XFERING    (1<<8)
 #define S3C2410_SDICMDSTAT_INDEX      (0xff)
 
+#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
+#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
+#define S3C2440_SDIDCON_DS_WORD       (2<<22)
 #define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
 #define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
 #define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
@@ -59,6 +69,7 @@
 #define S3C2410_SDIDCON_WIDEBUS       (1<<16)
 #define S3C2410_SDIDCON_DMAEN         (1<<15)
 #define S3C2410_SDIDCON_STOP          (1<<14)
+#define S3C2440_SDIDCON_DATSTART      (1<<14)
 #define S3C2410_SDIDCON_DATMODE	      (3<<12)
 #define S3C2410_SDIDCON_BLKNUM        (0x7ff)
 
@@ -68,6 +79,7 @@
 #define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
 #define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
 
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
 #define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
 
 #define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
@@ -82,10 +94,12 @@
 #define S3C2410_SDIDSTA_TXDATAON      (1<<1)
 #define S3C2410_SDIDSTA_RXDATAON      (1<<0)
 
+#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
+#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)  /* 3 is correct (2 bits) */
 #define S3C2410_SDIFSTA_TFDET          (1<<13)
 #define S3C2410_SDIFSTA_RFDET          (1<<12)
-#define S3C2410_SDIFSTA_TXHALF         (1<<11)
-#define S3C2410_SDIFSTA_TXEMPTY        (1<<10)
+#define S3C2410_SDIFSTA_TFHALF         (1<<11)
+#define S3C2410_SDIFSTA_TFEMPTY        (1<<10)
 #define S3C2410_SDIFSTA_RFLAST         (1<<9)
 #define S3C2410_SDIFSTA_RFFULL         (1<<8)
 #define S3C2410_SDIFSTA_RFHALF         (1<<7)
Index: linux-2.6.26-rc6-sdmmc/drivers/mmc/host/s3cmci.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc6-sdmmc/drivers/mmc/host/s3cmci.c	2008-06-17 23:56:02.000000000 +0100
@@ -0,0 +1,1337 @@
+/*
+ *  linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver
+ *
+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#include <asm/dma.h>
+#include <asm/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "s3cmci.h"
+
+#define DRIVER_NAME "s3c-mci"
+
+enum dbg_channels {
+	dbg_err   = (1 << 0),
+	dbg_debug = (1 << 1),
+	dbg_info  = (1 << 2),
+	dbg_irq   = (1 << 3),
+	dbg_sg    = (1 << 4),
+	dbg_dma   = (1 << 5),
+	dbg_pio   = (1 << 6),
+	dbg_fail  = (1 << 7),
+	dbg_conf  = (1 << 8),
+};
+
+static const int dbgmap_err   = dbg_err | dbg_fail;
+static const int dbgmap_info  = dbg_info | dbg_conf;
+static const int dbgmap_debug = dbg_debug;
+
+#define dbg(host, channels, args...)		 \
+	if (dbgmap_err & channels) 		 \
+		dev_err(&host->pdev->dev, args); \
+	else if (dbgmap_info & channels)	 \
+		dev_info(&host->pdev->dev, args);\
+	else if (dbgmap_debug & channels)	 \
+		dev_dbg(&host->pdev->dev, args);
+
+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
+
+static struct s3c2410_dma_client s3cmci_dma_client = {
+	.name		= "s3c-mci",
+};
+
+static void finalize_request(struct s3cmci_host *host);
+static void s3cmci_send_request(struct mmc_host *mmc);
+static void s3cmci_reset(struct s3cmci_host *host);
+
+#ifdef CONFIG_MMC_DEBUG
+
+static inline void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
+{
+	u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
+	u32 datcon, datcnt, datsta, fsta, imask;
+
+	con 	= readl(host->base + S3C2410_SDICON);
+	pre 	= readl(host->base + S3C2410_SDIPRE);
+	cmdarg 	= readl(host->base + S3C2410_SDICMDARG);
+	cmdcon 	= readl(host->base + S3C2410_SDICMDCON);
+	cmdsta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	r0 	= readl(host->base + S3C2410_SDIRSP0);
+	r1 	= readl(host->base + S3C2410_SDIRSP1);
+	r2 	= readl(host->base + S3C2410_SDIRSP2);
+	r3 	= readl(host->base + S3C2410_SDIRSP3);
+	timer 	= readl(host->base + S3C2410_SDITIMER);
+	bsize 	= readl(host->base + S3C2410_SDIBSIZE);
+	datcon 	= readl(host->base + S3C2410_SDIDCON);
+	datcnt 	= readl(host->base + S3C2410_SDIDCNT);
+	datsta 	= readl(host->base + S3C2410_SDIDSTA);
+	fsta 	= readl(host->base + S3C2410_SDIFSTA);
+	imask   = readl(host->base + host->sdiimsk);
+
+	dbg(host, dbg_debug, "%s  CON:[%08x]  PRE:[%08x]  TMR:[%08x]\n",
+				prefix, con, pre, timer);
+
+	dbg(host, dbg_debug, "%s CCON:[%08x] CARG:[%08x] CSTA:[%08x]\n",
+				prefix, cmdcon, cmdarg, cmdsta);
+
+	dbg(host, dbg_debug, "%s DCON:[%08x] FSTA:[%08x]"
+			       " DSTA:[%08x] DCNT:[%08x]\n",
+				prefix, datcon, fsta, datsta, datcnt);
+
+	dbg(host, dbg_debug, "%s   R0:[%08x]   R1:[%08x]"
+			       "   R2:[%08x]   R3:[%08x]\n",
+				prefix, r0, r1, r2, r3);
+}
+
+static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
+								int stop)
+{
+ 	snprintf(host->dbgmsg_cmd, 300,
+		"#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
+		host->ccnt, (stop?" (STOP)":""),
+		cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
+
+	if (cmd->data) {
+		snprintf(host->dbgmsg_dat, 300,
+			"#%u bsize:%u blocks:%u bytes:%u",
+			host->dcnt, cmd->data->blksz,
+			cmd->data->blocks,
+			cmd->data->blocks * cmd->data->blksz);
+	} else {
+		host->dbgmsg_dat[0] = '\0';
+	}
+}
+
+static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd,
+								int fail)
+{
+	unsigned int dbglvl = fail?dbg_fail:dbg_debug;
+
+	if (!cmd)
+		return;
+
+	if (cmd->error == MMC_ERR_NONE) {
+		dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n",
+			host->dbgmsg_cmd, cmd->resp[0]);
+	} else {
+		dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n",
+			cmd->error, host->dbgmsg_cmd, host->status);
+	}
+
+	if (!cmd->data)
+		return;
+
+	if (cmd->data->error == MMC_ERR_NONE) {
+		dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat);
+	} else {
+		dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n",
+			cmd->data->error, host->dbgmsg_dat,
+			readl(host->base + S3C2410_SDIDCNT));
+	}
+}
+#endif
+
+static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
+{
+	u32 newmask;
+
+	newmask = readl(host->base + host->sdiimsk);
+	newmask|= imask;
+
+	writel(newmask, host->base + host->sdiimsk);
+
+	return newmask;
+}
+
+static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
+{
+	u32 newmask;
+
+	newmask = readl(host->base + host->sdiimsk);
+	newmask&= ~imask;
+
+	writel(newmask, host->base + host->sdiimsk);
+
+	return newmask;
+}
+
+static inline void clear_imask(struct s3cmci_host *host)
+{
+	writel(0, host->base + host->sdiimsk);
+}
+
+static inline int get_data_buffer(struct s3cmci_host *host,
+			volatile u32 *words, volatile u32 **pointer)
+{
+	struct scatterlist *sg;
+
+	if (host->pio_active == XFER_NONE)
+		return -EINVAL;
+
+	if ((!host->mrq) || (!host->mrq->data))
+		return -EINVAL;
+
+	if (host->pio_sgptr >= host->mrq->data->sg_len) {
+		dbg(host, dbg_debug, "no more buffers (%i/%i)\n",
+		      host->pio_sgptr, host->mrq->data->sg_len);
+		return -EBUSY;
+	}
+	sg = &host->mrq->data->sg[host->pio_sgptr];
+
+	*words	= sg->length >> 2;
+	*pointer= page_address(sg->page) + sg->offset;
+
+	host->pio_sgptr++;
+
+	dbg(host, dbg_sg, "new buffer (%i/%i)\n",
+	      host->pio_sgptr, host->mrq->data->sg_len);
+
+	return 0;
+}
+
+#define FIFO_FILL(host) ((readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK) >> 2)
+#define FIFO_FREE(host) ((63 - (readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK)) >> 2)
+
+static inline void do_pio_read(struct s3cmci_host *host)
+{
+	int res;
+	u32 fifo;
+	void __iomem *from_ptr;
+
+	//write real prescaler to host, it might be set slow to fix
+	writel(host->prescaler, host->base + S3C2410_SDIPRE);
+
+	from_ptr = host->base + host->sdidata;
+
+	while ((fifo = FIFO_FILL(host))) {
+		if (!host->pio_words) {
+			res = get_data_buffer(host, &host->pio_words,
+							&host->pio_ptr);
+			if (res) {
+				host->pio_active = XFER_NONE;
+				host->complete_what = COMPLETION_FINALIZE;
+
+				dbg(host, dbg_pio, "pio_read(): "
+					"complete (no more data).\n");
+				return;
+			}
+
+			dbg(host, dbg_pio, "pio_read(): new target: [%i]@[%p]\n",
+			       host->pio_words, host->pio_ptr);
+		}
+
+		dbg(host, dbg_pio, "pio_read(): fifo:[%02i] "
+				   "buffer:[%03i] dcnt:[%08X]\n",
+				   fifo, host->pio_words,
+				   readl(host->base + S3C2410_SDIDCNT));
+
+		if (fifo > host->pio_words)
+			fifo = host->pio_words;
+
+		host->pio_words-= fifo;
+		host->pio_count+= fifo;
+
+		while(fifo--) {
+			*(host->pio_ptr++) = readl(from_ptr);
+		}
+	}
+
+	if (!host->pio_words) {
+		res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
+		if (res) {
+			dbg(host, dbg_pio, "pio_read(): "
+				"complete (no more buffers).\n");
+			host->pio_active = XFER_NONE;
+			host->complete_what = COMPLETION_FINALIZE;
+
+			return;
+		}
+	}
+
+	enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
+}
+
+static inline void do_pio_write(struct s3cmci_host *host)
+{
+	int res;
+	u32 fifo;
+
+	void __iomem *to_ptr;
+
+	to_ptr = host->base + host->sdidata;
+
+	while ((fifo = FIFO_FREE(host))) {
+		if (!host->pio_words) {
+			res = get_data_buffer(host, &host->pio_words,
+							&host->pio_ptr);
+			if (res) {
+				dbg(host, dbg_pio, "pio_write(): "
+					"complete (no more data).\n");
+				host->pio_active = XFER_NONE;
+
+				return;
+			}
+
+			dbg(host, dbg_pio, "pio_write(): "
+				"new source: [%i]@[%p]\n",
+				host->pio_words, host->pio_ptr);
+
+		}
+
+		if (fifo > host->pio_words)
+			fifo = host->pio_words;
+
+		host->pio_words-= fifo;
+		host->pio_count+= fifo;
+
+		while(fifo--) {
+			writel(*(host->pio_ptr++), to_ptr);
+		}
+	}
+
+	enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
+}
+
+static void pio_tasklet(unsigned long data)
+{
+	struct s3cmci_host *host = (struct s3cmci_host *) data;
+
+
+	if (host->pio_active == XFER_WRITE)
+		do_pio_write(host);
+
+	if (host->pio_active == XFER_READ)
+		do_pio_read(host);
+
+	if (host->complete_what == COMPLETION_FINALIZE) {
+		clear_imask(host);
+		if (host->pio_active != XFER_NONE) {
+			dbg(host, dbg_err, "unfinished %s "
+				"- pio_count:[%u] pio_words:[%u]\n",
+				(host->pio_active == XFER_READ)?"read":"write",
+				host->pio_count, host->pio_words);
+
+			host->mrq->data->error = MMC_ERR_DMA;
+		}
+
+		disable_irq(host->irq);
+		finalize_request(host);
+	}
+}
+
+/*
+ * ISR for SDI Interface IRQ
+ * Communication between driver and ISR works as follows:
+ *   host->mrq 			points to current request
+ *   host->complete_what	tells the ISR when the request is considered done
+ *     COMPLETION_CMDSENT	  when the command was sent
+ *     COMPLETION_RSPFIN          when a response was received
+ *     COMPLETION_XFERFINISH	  when the data transfer is finished
+ *     COMPLETION_XFERFINISH_RSPFIN both of the above.
+ *   host->complete_request	is the completion-object the driver waits for
+ *
+ * 1) Driver sets up host->mrq and host->complete_what
+ * 2) Driver prepares the transfer
+ * 3) Driver enables interrupts
+ * 4) Driver starts transfer
+ * 5) Driver waits for host->complete_rquest
+ * 6) ISR checks for request status (errors and success)
+ * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error
+ * 7) ISR completes host->complete_request
+ * 8) ISR disables interrupts
+ * 9) Driver wakes up and takes care of the request
+ *
+ * Note: "->error"-fields are expected to be set to 0 before the request
+ *       was issued by mmc.c - therefore they are only set, when an error
+ *       contition comes up
+ */
+
+static irqreturn_t s3cmci_irq(int irq, void *dev_id)
+{
+	struct s3cmci_host *host;
+	struct mmc_command *cmd;
+	u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
+	u32 mci_cclear, mci_dclear;
+	unsigned long iflags;
+
+	host = (struct s3cmci_host *)dev_id;
+
+	spin_lock_irqsave(&host->complete_lock, iflags);
+
+	mci_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	mci_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	mci_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+	mci_fsta 	= readl(host->base + S3C2410_SDIFSTA);
+	mci_imsk	= readl(host->base + host->sdiimsk);
+	mci_cclear	= 0;
+	mci_dclear	= 0;
+
+	if ((host->complete_what == COMPLETION_NONE) ||
+			(host->complete_what == COMPLETION_FINALIZE)) {
+		host->status = "nothing to complete";
+		clear_imask(host);
+		goto irq_out;
+	}
+
+	if (!host->mrq) {
+		host->status = "no active mrq";
+		clear_imask(host);
+		goto irq_out;
+	}
+
+	cmd = host->cmd_is_stop?host->mrq->stop:host->mrq->cmd;
+
+	if (!cmd) {
+		host->status = "no active cmd";
+		clear_imask(host);
+		goto irq_out;
+	}
+
+	if (!host->dodma) {
+		if ((host->pio_active == XFER_WRITE) &&
+				(mci_fsta & S3C2410_SDIFSTA_TFDET)) {
+
+			disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
+			tasklet_schedule(&host->pio_tasklet);
+			host->status = "pio tx";
+		}
+
+		if ((host->pio_active == XFER_READ) &&
+				(mci_fsta & S3C2410_SDIFSTA_RFDET)) {
+
+			disable_imask(host,
+				S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
+
+			tasklet_schedule(&host->pio_tasklet);
+			host->status = "pio rx";
+		}
+	}
+
+	if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
+		cmd->error = MMC_ERR_TIMEOUT;
+		host->status = "error: command timeout";
+		goto fail_transfer;
+	}
+
+	if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) {
+		if (host->complete_what == COMPLETION_CMDSENT) {
+			host->status = "ok: command sent";
+			goto close_transfer;
+		}
+
+		mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT;
+	}
+
+	if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
+		if (cmd->flags & MMC_RSP_CRC) {
+			cmd->error = MMC_ERR_BADCRC;
+			host->status = "error: bad command crc";
+			goto fail_transfer;
+		}
+
+		mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;
+	}
+
+	if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) {
+		if (host->complete_what == COMPLETION_RSPFIN) {
+			host->status = "ok: command response received";
+			goto close_transfer;
+		}
+
+		if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
+			host->complete_what = COMPLETION_XFERFINISH;
+
+		mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
+	}
+
+	/* errors handled after this point are only relevant
+	   when a data transfer is in progress */
+
+	if (!cmd->data)
+		goto clear_status_bits;
+
+	/* Check for FIFO failure */
+	if (host->is2440) {
+		if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
+			host->mrq->data->error = MMC_ERR_FIFO;
+			host->status = "error: 2440 fifo failure";
+			goto fail_transfer;
+		}
+	} else {
+		if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
+			cmd->data->error = MMC_ERR_FIFO;
+			host->status = "error:  fifo failure";
+			goto fail_transfer;
+		}
+	}
+
+	if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
+		cmd->data->error = MMC_ERR_BADCRC;
+		host->status = "error: bad data crc (outgoing)";
+		goto fail_transfer;
+	}
+
+	if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {
+		cmd->data->error = MMC_ERR_BADCRC;
+		host->status = "error: bad data crc (incoming)";
+		goto fail_transfer;
+	}
+
+	if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
+		cmd->data->error = MMC_ERR_TIMEOUT;
+		host->status = "error: data timeout";
+		goto fail_transfer;
+	}
+
+	if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) {
+		if (host->complete_what == COMPLETION_XFERFINISH) {
+			host->status = "ok: data transfer completed";
+			goto close_transfer;
+		}
+
+		if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+			host->complete_what = COMPLETION_RSPFIN;
+		}
+
+		mci_dclear |= S3C2410_SDIDSTA_XFERFINISH;
+	}
+
+clear_status_bits:
+	writel(mci_cclear, host->base + S3C2410_SDICMDSTAT);
+	writel(mci_dclear, host->base + S3C2410_SDIDSTA);
+
+	goto irq_out;
+
+fail_transfer:
+	host->pio_active = XFER_NONE;
+
+close_transfer:
+	host->complete_what = COMPLETION_FINALIZE;
+
+	clear_imask(host);
+	tasklet_schedule(&host->pio_tasklet);
+
+	goto irq_out;
+
+irq_out:
+	dbg(host, dbg_irq, "csta:0x%08x dsta:0x%08x "
+			   "fsta:0x%08x dcnt:0x%08x status:%s.\n",
+				mci_csta, mci_dsta, mci_fsta,
+				mci_dcnt, host->status);
+
+	spin_unlock_irqrestore(&host->complete_lock, iflags);
+	return IRQ_HANDLED;
+
+}
+
+/*
+ * ISR for the CardDetect Pin
+*/
+
+static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
+{
+	struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
+
+	dbg(host, dbg_irq, "card detect\n");
+
+	mmc_detect_change(host->mmc, 500);
+
+	return IRQ_HANDLED;
+}
+
+void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id,
+	int size, enum s3c2410_dma_buffresult result)
+{
+	unsigned long iflags;
+	u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt;
+	struct s3cmci_host *host = (struct s3cmci_host *)buf_id;
+
+	mci_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
+	mci_dsta 	= readl(host->base + S3C2410_SDIDSTA);
+	mci_fsta 	= readl(host->base + S3C2410_SDIFSTA);
+	mci_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
+
+	if ((!host->mrq) || (!host->mrq) || (!host->mrq->data))
+		return;
+
+	if (!host->dmatogo)
+		return;
+
+	spin_lock_irqsave(&host->complete_lock, iflags);
+
+	if (result != S3C2410_RES_OK) {
+		dbg(host, dbg_fail, "DMA FAILED: csta=0x%08x dsta=0x%08x "
+			"fsta=0x%08x dcnt:0x%08x result:0x%08x toGo:%u\n",
+			mci_csta, mci_dsta, mci_fsta,
+			mci_dcnt, result, host->dmatogo);
+
+		goto fail_request;
+	}
+
+	host->dmatogo--;
+	if (host->dmatogo) {
+		dbg(host, dbg_dma, "DMA DONE  Size:%i DSTA:[%08x] "
+			"DCNT:[%08x] toGo:%u\n",
+			size, mci_dsta, mci_dcnt, host->dmatogo);
+
+		goto out;
+	}
+
+	dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",
+		size, mci_dsta, mci_dcnt);
+
+	host->complete_what = COMPLETION_FINALIZE;
+
+out:
+	tasklet_schedule(&host->pio_tasklet);
+	spin_unlock_irqrestore(&host->complete_lock, iflags);
+	return;
+
+
+fail_request:
+	host->mrq->data->error = MMC_ERR_DMA;
+	host->complete_what = COMPLETION_FINALIZE;
+	writel(0, host->base + host->sdiimsk);
+	goto out;
+
+}
+
+static void finalize_request(struct s3cmci_host *host)
+{
+	struct mmc_request *mrq = host->mrq;
+	struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;
+	int debug_as_failure = 0;
+
+	if (host->complete_what != COMPLETION_FINALIZE)
+		return;
+
+	if (!mrq)
+		return;
+
+	if (cmd->data && (cmd->error == MMC_ERR_NONE) &&
+		  (cmd->data->error == MMC_ERR_NONE)) {
+
+		if (host->dodma && (!host->dma_complete)) {
+			dbg(host, dbg_dma, "DMA Missing!\n");
+			return;
+		}
+	}
+
+	// Read response
+	cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
+	cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
+	cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
+	cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
+
+	// reset clock speed, as it could still be set low for
+	writel(host->prescaler, host->base + S3C2410_SDIPRE);
+
+	if (cmd->error)
+		debug_as_failure = 1;
+
+	if (cmd->data && cmd->data->error)
+		debug_as_failure = 1;
+
+	//if(cmd->flags & MMC_RSP_MAYFAIL) debug_as_failure = 0;
+
+#ifdef CONFIG_MMC_DEBUG
+	dbg_dumpcmd(host, cmd, debug_as_failure);
+#endif
+	//Cleanup controller
+	writel(0, host->base + S3C2410_SDICMDARG);
+	writel(0, host->base + S3C2410_SDIDCON);
+	writel(0, host->base + S3C2410_SDICMDCON);
+	writel(0, host->base + host->sdiimsk);
+
+	if (cmd->data && cmd->error)
+		cmd->data->error = cmd->error;
+
+	if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) {
+		host->cmd_is_stop = 1;
+		s3cmci_send_request(host->mmc);
+		return;
+	}
+
+	// If we have no data transfer we are finished here
+	if (!mrq->data)
+		goto request_done;
+
+	// Calulate the amout of bytes transfer, but only if there was
+	// no error
+	if (mrq->data->error == MMC_ERR_NONE) {
+		mrq->data->bytes_xfered =
+			(mrq->data->blocks * mrq->data->blksz);
+	} else {
+		mrq->data->bytes_xfered = 0;
+	}
+
+	// If we had an error while transfering data we flush the
+	// DMA channel and the fifo to clear out any garbage
+	if (mrq->data->error != MMC_ERR_NONE) {
+		if (host->dodma)
+			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+
+		if (host->is2440) {
+			//Clear failure register and reset fifo
+			writel(S3C2440_SDIFSTA_FIFORESET |
+			       S3C2440_SDIFSTA_FIFOFAIL,
+			       host->base + S3C2410_SDIFSTA);
+		} else {
+			u32 mci_con;
+
+			//reset fifo
+			mci_con = readl(host->base + S3C2410_SDICON);
+			mci_con|= S3C2410_SDICON_FIFORESET;
+
+			writel(mci_con, host->base + S3C2410_SDICON);
+		}
+	}
+
+request_done:
+	host->complete_what = COMPLETION_NONE;
+	host->mrq = NULL;
+	mmc_request_done(host->mmc, mrq);
+}
+
+
+void s3cmci_dma_setup(struct s3cmci_host *host, enum s3c2410_dmasrc source)
+{
+	static int setup_ok = 0;
+	static enum s3c2410_dmasrc last_source = -1;
+
+	if (last_source == source)
+		return;
+
+	last_source = source;
+
+	s3c2410_dma_devconfig(host->dma, source, 3,
+		host->mem->start + host->sdidata);
+
+	if (!setup_ok) {
+		s3c2410_dma_config(host->dma, 4,
+			(S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI));
+		s3c2410_dma_set_buffdone_fn(host->dma, s3cmci_dma_done_callback);
+		s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
+		setup_ok = 1;
+	}
+}
+
+static void s3cmci_send_command(struct s3cmci_host *host,
+					struct mmc_command *cmd)
+{
+	u32 ccon, imsk;
+
+	imsk  = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT |
+		S3C2410_SDIIMSK_RESPONSEND | S3C2410_SDIIMSK_CMDSENT |
+		S3C2410_SDIIMSK_RESPONSECRC;
+
+	enable_imask(host, imsk);
+
+	if (cmd->data) {
+		host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
+	} else if (cmd->flags & MMC_RSP_PRESENT) {
+		host->complete_what = COMPLETION_RSPFIN;
+	} else {
+		host->complete_what = COMPLETION_CMDSENT;
+	}
+
+	writel(cmd->arg, host->base + S3C2410_SDICMDARG);
+
+	ccon = cmd->opcode & S3C2410_SDICMDCON_INDEX;
+	ccon|= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
+
+	if (cmd->flags & MMC_RSP_PRESENT)
+		ccon |= S3C2410_SDICMDCON_WAITRSP;
+
+	if (cmd->flags & MMC_RSP_136)
+		ccon|= S3C2410_SDICMDCON_LONGRSP;
+
+	writel(ccon, host->base + S3C2410_SDICMDCON);
+}
+
+static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
+{
+	u32 dcon, imsk, stoptries=3;
+
+	/* write DCON register */
+
+	if (!data) {
+		writel(0, host->base + S3C2410_SDIDCON);
+		return 0;
+	}
+
+	while(readl(host->base + S3C2410_SDIDSTA) &
+		(S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
+
+		dbg(host, dbg_err,
+			"mci_setup_data() transfer stillin progress.\n");
+
+		writel(0, host->base + S3C2410_SDIDCON);
+		s3cmci_reset(host);
+
+		if (0 == (stoptries--)) {
+#ifdef CONFIG_MMC_DEBUG
+			dbg_dumpregs(host, "DRF");
+#endif
+
+			return -EINVAL;
+		}
+	}
+
+	dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
+
+	if (host->dodma) {
+		dcon |= S3C2410_SDIDCON_DMAEN;
+	}
+
+	if (host->bus_width == MMC_BUS_WIDTH_4) {
+		dcon |= S3C2410_SDIDCON_WIDEBUS;
+	}
+
+	if (!(data->flags & MMC_DATA_STREAM)) {
+		dcon |= S3C2410_SDIDCON_BLOCKMODE;
+	}
+
+	if (data->flags & MMC_DATA_WRITE) {
+		dcon |= S3C2410_SDIDCON_TXAFTERRESP;
+		dcon |= S3C2410_SDIDCON_XFER_TXSTART;
+	}
+
+	if (data->flags & MMC_DATA_READ) {
+		dcon |= S3C2410_SDIDCON_RXAFTERCMD;
+		dcon |= S3C2410_SDIDCON_XFER_RXSTART;
+	}
+
+	if (host->is2440) {
+		dcon |= S3C2440_SDIDCON_DS_WORD;
+		dcon |= S3C2440_SDIDCON_DATSTART;
+	}
+
+	writel(dcon, host->base + S3C2410_SDIDCON);
+
+	/* write BSIZE register */
+
+	writel(data->blksz, host->base + S3C2410_SDIBSIZE);
+
+	/* add to IMASK register */
+	imsk =	S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
+		S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
+
+	enable_imask(host, imsk);
+
+	/* write TIMER register */
+
+	if (host->is2440) {
+		writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
+	} else {
+		writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
+
+		//FIX: set slow clock to prevent timeouts on read
+		if (data->flags & MMC_DATA_READ) {
+			writel(0xFF, host->base + S3C2410_SDIPRE);
+		}
+	}
+
+	//debug_dump_registers(host, "Data setup:");
+
+	return 0;
+}
+
+static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
+{
+	int rw = (data->flags & MMC_DATA_WRITE)?1:0;
+
+	if (rw != ((data->flags & MMC_DATA_READ)?0:1))
+		return -EINVAL;
+
+	host->pio_sgptr = 0;
+	host->pio_words = 0;
+	host->pio_count = 0;
+	host->pio_active = rw?XFER_WRITE:XFER_READ;
+
+	if (rw) {
+		do_pio_write(host);
+		enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
+	} else {
+		enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF
+			| S3C2410_SDIIMSK_RXFIFOLAST);
+	}
+
+	return 0;
+}
+
+static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
+{
+	int dma_len, i;
+
+	int rw = (data->flags & MMC_DATA_WRITE)?1:0;
+
+	if (rw != ((data->flags & MMC_DATA_READ)?0:1))
+		return -EINVAL;
+
+	s3cmci_dma_setup(host, rw?S3C2410_DMASRC_MEM:S3C2410_DMASRC_HW);
+	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+
+	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+				(rw)?DMA_TO_DEVICE:DMA_FROM_DEVICE);
+
+
+	if (dma_len == 0)
+		return -ENOMEM;
+
+	host->dma_complete = 0;
+	host->dmatogo = dma_len;
+
+	for (i = 0; i < dma_len; i++) {
+		int res;
+
+		dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i,
+			sg_dma_address(&data->sg[i]),
+			sg_dma_len(&data->sg[i]));
+
+		res = s3c2410_dma_enqueue(host->dma, (void *) host,
+				sg_dma_address(&data->sg[i]),
+				sg_dma_len(&data->sg[i]));
+
+		if (res) {
+			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+			return -EBUSY;
+		}
+ 	}
+
+	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START);
+
+	return 0;
+}
+
+static void s3cmci_send_request(struct mmc_host *mmc)
+{
+	struct s3cmci_host *host = mmc_priv(mmc);
+	struct mmc_request *mrq = host->mrq;
+	struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;
+
+	host->ccnt++;
+#ifdef CONFIG_MMC_DEBUG
+	prepare_dbgmsg(host, cmd, host->cmd_is_stop);
+#endif
+	//Clear command, data and fifo status registers
+	//Fifo clear only necessary on 2440, but doesn't hurt on 2410
+	writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
+	writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
+	writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);
+
+	if (cmd->data) {
+		int res;
+		res = s3cmci_setup_data(host, cmd->data);
+
+		host->dcnt++;
+
+		if (res) {
+			cmd->error = MMC_ERR_DMA;
+			cmd->data->error = MMC_ERR_DMA;
+
+			mmc_request_done(mmc, mrq);
+			return;
+		}
+
+
+		if (host->dodma) {
+			res = s3cmci_prepare_dma(host, cmd->data);
+		} else {
+			res = s3cmci_prepare_pio(host, cmd->data);
+		}
+
+		if (res) {
+			cmd->error = MMC_ERR_DMA;
+			cmd->data->error = MMC_ERR_DMA;
+
+			mmc_request_done(mmc, mrq);
+			return;
+		}
+
+	}
+
+	// Send command
+	s3cmci_send_command(host, cmd);
+
+	// Enable Interrupt
+	enable_irq(host->irq);
+}
+
+static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ 	struct s3cmci_host *host = mmc_priv(mmc);
+
+	host->cmd_is_stop = 0;
+	host->mrq = mrq;
+
+	s3cmci_send_request(mmc);
+}
+
+static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct s3cmci_host *host = mmc_priv(mmc);
+	u32 mci_psc, mci_con;
+
+	//Set power
+	mci_con = readl(host->base + S3C2410_SDICON);
+	switch(ios->power_mode) {
+		case MMC_POWER_ON:
+		case MMC_POWER_UP:
+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
+			s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
+			s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
+			s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
+			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
+			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+
+			if (!host->is2440)
+				mci_con|=S3C2410_SDICON_FIFORESET;
+
+			break;
+
+		case MMC_POWER_OFF:
+		default:
+			s3c2410_gpio_setpin(S3C2410_GPE5, 0);
+			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
+
+			if (host->is2440)
+				mci_con|=S3C2440_SDICON_SDRESET;
+
+			break;
+	}
+
+	//Set clock
+	for (mci_psc=0; mci_psc<255; mci_psc++) {
+		host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
+
+		if (host->real_rate <= ios->clock)
+			break;
+	}
+
+	if(mci_psc > 255) mci_psc = 255;
+	host->prescaler = mci_psc;
+
+	writel(host->prescaler, host->base + S3C2410_SDIPRE);
+
+	//If requested clock is 0, real_rate will be 0, too
+	if (ios->clock == 0)
+		host->real_rate = 0;
+
+	//Set CLOCK_ENABLE
+	if (ios->clock)
+		mci_con |= S3C2410_SDICON_CLOCKTYPE;
+	else
+		mci_con &=~S3C2410_SDICON_CLOCKTYPE;
+
+	writel(mci_con, host->base + S3C2410_SDICON);
+
+	if ((ios->power_mode==MMC_POWER_ON)
+		|| (ios->power_mode==MMC_POWER_UP)) {
+
+		dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",
+			host->real_rate/1000, ios->clock/1000);
+	} else {
+		dbg(host, dbg_conf, "powered down.\n");
+	}
+
+	host->bus_width = ios->bus_width;
+
+}
+
+static void s3cmci_reset(struct s3cmci_host *host)
+{
+	u32 con = readl(host->base + S3C2410_SDICON);
+
+	con |= S3C2440_SDICON_SDRESET;
+
+	writel(con, host->base + S3C2410_SDICON);
+}
+
+static struct mmc_host_ops s3cmci_ops = {
+	.request	= s3cmci_request,
+	.set_ios	= s3cmci_set_ios,
+};
+
+static int s3cmci_probe(struct platform_device *pdev, int is2440)
+{
+	struct mmc_host 	*mmc;
+	struct s3cmci_host 	*host;
+
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto probe_out;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc 	= mmc;
+	host->pdev	= pdev;
+
+	spin_lock_init(&host->complete_lock);
+	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
+	if (is2440) {
+		host->is2440	= 1;
+		host->sdiimsk	= S3C2440_SDIIMSK;
+		host->sdidata	= S3C2440_SDIDATA;
+		host->clk_div	= 1;
+	} else {
+		host->is2440	= 0;
+		host->sdiimsk	= S3C2410_SDIIMSK;
+		host->sdidata	= S3C2410_SDIDATA;
+		host->clk_div	= 2;
+	}
+	host->dodma		= 0;
+	host->complete_what 	= COMPLETION_NONE;
+	host->pio_active 	= XFER_NONE;
+
+	host->dma		= S3CMCI_DMA;
+	host->irq_cd		= IRQ_EINT2;
+
+	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!host->mem) {
+		dev_err(&pdev->dev,
+			"failed to get io memory region resouce.\n");
+
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->mem = request_mem_region(host->mem->start,
+		RESSIZE(host->mem), pdev->name);
+
+	if (!host->mem) {
+		dev_err(&pdev->dev, "failed to request io memory region.\n");
+		ret = -ENOENT;
+		goto probe_free_host;
+	}
+
+	host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+	if (host->base == 0) {
+		dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
+		ret = -EINVAL;
+		goto probe_free_mem_region;
+	}
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq == 0) {
+		dev_err(&pdev->dev, "failed to get interrupt resouce.\n");
+		ret = -EINVAL;
+		goto probe_iounmap;
+	}
+
+	if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {
+		dev_err(&pdev->dev, "failed to request mci interrupt.\n");
+		ret = -ENOENT;
+		goto probe_iounmap;
+	}
+
+	disable_irq(host->irq);
+
+	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
+	set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
+
+	if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) {
+		dev_err(&pdev->dev,
+			"failed to request card detect interrupt.\n");
+
+		ret = -ENOENT;
+		goto probe_free_irq;
+	}
+
+	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) {
+		dev_err(&pdev->dev, "unable to get DMA channel.\n");
+		ret = -EBUSY;
+		goto probe_free_irq_cd;
+	}
+
+	host->clk = clk_get(&pdev->dev, "sdi");
+	if (IS_ERR(host->clk)) {
+		dev_err(&pdev->dev, "failed to find clock source.\n");
+		ret = PTR_ERR(host->clk);
+		host->clk = NULL;
+		goto probe_free_host;
+	}
+
+	if ((ret = clk_enable(host->clk))) {
+		dev_err(&pdev->dev, "failed to enable clock source.\n");
+		goto clk_free;
+	}
+
+	host->clk_rate = clk_get_rate(host->clk);
+
+	mmc->ops 	= &s3cmci_ops;
+	mmc->ocr_avail	= MMC_VDD_32_33;
+	mmc->caps	= MMC_CAP_4_BIT_DATA;
+	mmc->f_min 	= host->clk_rate / (host->clk_div * 256);
+	mmc->f_max 	= host->clk_rate / host->clk_div;
+
+	mmc->max_blk_count	= 4095;
+	mmc->max_blk_size	= 4095;
+	mmc->max_req_size	= 4095 * 512;
+	mmc->max_seg_size	= mmc->max_req_size;
+
+	mmc->max_phys_segs	= 128;
+	mmc->max_hw_segs	= 128;
+
+	dbg(host, dbg_debug, "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
+		(host->is2440?"2440":""),
+		host->base, host->irq, host->irq_cd, host->dma);
+
+	if ((ret = mmc_add_host(mmc))) {
+		dev_err(&pdev->dev, "failed to add mmc host.\n");
+		goto free_dmabuf;
+	}
+
+	platform_set_drvdata(pdev, mmc);
+
+	dev_info(&pdev->dev,"initialisation done.\n");
+	return 0;
+
+ free_dmabuf:
+	clk_disable(host->clk);
+
+ clk_free:
+	clk_put(host->clk);
+
+ probe_free_irq_cd:
+ 	free_irq(host->irq_cd, host);
+
+ probe_free_irq:
+ 	free_irq(host->irq, host);
+
+ probe_iounmap:
+	iounmap(host->base);
+
+ probe_free_mem_region:
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+
+ probe_free_host:
+	mmc_free_host(mmc);
+ probe_out:
+	return ret;
+}
+
+static int s3cmci_remove(struct platform_device *pdev)
+{
+	struct mmc_host 	*mmc  = platform_get_drvdata(pdev);
+	struct s3cmci_host 	*host = mmc_priv(mmc);
+
+	mmc_remove_host(mmc);
+	clk_disable(host->clk);
+	clk_put(host->clk);
+ 	free_irq(host->irq_cd, host);
+ 	free_irq(host->irq, host);
+	iounmap(host->base);
+	release_mem_region(host->mem->start, RESSIZE(host->mem));
+	mmc_free_host(mmc);
+
+	return 0;
+}
+
+static int s3cmci_probe_2410(struct platform_device *dev)
+{
+	return s3cmci_probe(dev, 0);
+}
+
+static int s3cmci_probe_2412(struct platform_device *dev)
+{
+	return s3cmci_probe(dev, 1);
+}
+
+static int s3cmci_probe_2440(struct platform_device *dev)
+{
+	return s3cmci_probe(dev, 1);
+}
+
+#ifdef CONFIG_PM
+
+static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+
+	return  mmc_suspend_host(mmc, state);
+}
+
+static int s3cmci_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+
+	return mmc_resume_host(mmc);
+}
+
+#else /* CONFIG_PM */
+#define s3cmci_suspend NULL
+#define s3cmci_resume NULL
+#endif /* CONFIG_PM */
+
+
+static struct platform_driver s3cmci_driver_2410 =
+{
+	.driver.name	= "s3c2410-sdi",
+	.probe		= s3cmci_probe_2410,
+	.remove		= s3cmci_remove,
+	.suspend	= s3cmci_suspend,
+	.resume		= s3cmci_resume,
+};
+
+static struct platform_driver s3cmci_driver_2412 =
+{
+	.driver.name	= "s3c2412-sdi",
+	.probe		= s3cmci_probe_2412,
+	.remove		= s3cmci_remove,
+	.suspend	= s3cmci_suspend,
+	.resume		= s3cmci_resume,
+};
+
+static struct platform_driver s3cmci_driver_2440 =
+{
+	.driver.name	= "s3c2440-sdi",
+	.probe		= s3cmci_probe_2440,
+	.remove		= s3cmci_remove,
+	.suspend	= s3cmci_suspend,
+	.resume		= s3cmci_resume,
+};
+
+
+static int __init s3cmci_init(void)
+{
+	platform_driver_register(&s3cmci_driver_2410);
+	platform_driver_register(&s3cmci_driver_2412);
+	platform_driver_register(&s3cmci_driver_2440);
+	return 0;
+}
+
+static void __exit s3cmci_exit(void)
+{
+	platform_driver_unregister(&s3cmci_driver_2410);
+	platform_driver_unregister(&s3cmci_driver_2412);
+	platform_driver_unregister(&s3cmci_driver_2440);
+}
+
+module_init(s3cmci_init);
+module_exit(s3cmci_exit);
+
+MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>");
+
Index: linux-2.6.26-rc6-sdmmc/drivers/mmc/host/s3cmci.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc6-sdmmc/drivers/mmc/host/s3cmci.h	2008-06-17 23:56:02.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ *  linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver
+ *
+ *  Copyright (C) 2004-2006 Thomas Kleffel, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+//FIXME: DMA Resource management ?!
+#define S3CMCI_DMA 0
+
+enum s3cmci_waitfor {
+	COMPLETION_NONE,
+	COMPLETION_FINALIZE,
+	COMPLETION_CMDSENT,
+	COMPLETION_RSPFIN,
+	COMPLETION_XFERFINISH,
+	COMPLETION_XFERFINISH_RSPFIN,
+};
+
+struct s3cmci_host {
+	struct platform_device	*pdev;
+	struct mmc_host		*mmc;
+	struct resource		*mem;
+	struct clk		*clk;
+	void __iomem		*base;
+	int			irq;
+	int			irq_cd;
+	int			dma;
+
+	unsigned long		clk_rate;
+	unsigned long		clk_div;
+	unsigned long		real_rate;
+	u8			prescaler;
+
+	int			is2440;
+	unsigned		sdiimsk;
+	unsigned		sdidata;
+	int			dodma;
+
+	volatile int		dmatogo;
+
+	struct mmc_request	*mrq;
+	int			cmd_is_stop;
+
+	spinlock_t		complete_lock;
+	volatile enum s3cmci_waitfor
+				complete_what;
+
+	volatile int		dma_complete;
+
+	volatile u32		pio_sgptr;
+	volatile u32		pio_words;
+	volatile u32		pio_count;
+	volatile u32		*pio_ptr;
+#define XFER_NONE 0
+#define XFER_READ 1
+#define XFER_WRITE 2
+	volatile u32		pio_active;
+
+	int			bus_width;
+
+	char 			dbgmsg_cmd[301];
+	char 			dbgmsg_dat[301];
+	volatile char		*status;
+
+	unsigned int		ccnt, dcnt;
+	struct tasklet_struct	pio_tasklet;
+};
Index: linux-2.6.26-rc6-sdmmc/drivers/mmc/host/Kconfig
===================================================================
--- linux-2.6.26-rc6-sdmmc.orig/drivers/mmc/host/Kconfig	2008-06-17 23:55:19.000000000 +0100
+++ linux-2.6.26-rc6-sdmmc/drivers/mmc/host/Kconfig	2008-06-17 23:56:02.000000000 +0100
@@ -142,3 +142,14 @@ config MMC_SPI
 
 	  If unsure, or if your system has no SPI master driver, say N.
 
+config MMC_S3C
+	tristate "Samsung S3C SD/MMC Card Interface support"
+	depends on ARCH_S3C2410 && MMC
+	help
+	  This selects a driver for the MCI interface found in
+          Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
+	  If you have a board based on one of those and a MMC/SD
+	  slot, say Y or M here.
+
+	  If unsure, say N.
+
Index: linux-2.6.26-rc6-sdmmc/drivers/mmc/host/Makefile
===================================================================
--- linux-2.6.26-rc6-sdmmc.orig/drivers/mmc/host/Makefile	2008-06-17 23:55:19.000000000 +0100
+++ linux-2.6.26-rc6-sdmmc/drivers/mmc/host/Makefile	2008-06-17 23:56:02.000000000 +0100
@@ -18,4 +18,4 @@ obj-$(CONFIG_MMC_OMAP)		+= omap.o
 obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
-
+obj-$(CONFIG_MMC_S3C)   	+= s3cmci.o

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
  2008-06-30 15:25 ` [patch v4 01/17] MMC: S3C24XX MMC/SD driver Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:50   ` Pierre Ossman
  2008-06-30 15:25 ` [patch v4 03/17] MMC: S3C24XX MMC/SD driver write fixes Ben Dooks
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/simtec-fix-checkpatch-errors.patch --]
[-- Type: text/plain, Size: 37557 bytes --]

Fix the checkpatch and other problems pointed out by
akpm.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:18:49.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 15:31:29.000000000 +0100
@@ -11,15 +11,13 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
-#include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <asm/dma.h>
-#include <asm/dma-mapping.h>
 
-#include <asm/io.h>
 #include <asm/arch/regs-sdi.h>
 #include <asm/arch/regs-gpio.h>
 
@@ -43,13 +41,15 @@ static const int dbgmap_err   = dbg_err 
 static const int dbgmap_info  = dbg_info | dbg_conf;
 static const int dbgmap_debug = dbg_debug;
 
-#define dbg(host, channels, args...)		 \
-	if (dbgmap_err & channels) 		 \
-		dev_err(&host->pdev->dev, args); \
-	else if (dbgmap_info & channels)	 \
-		dev_info(&host->pdev->dev, args);\
-	else if (dbgmap_debug & channels)	 \
-		dev_dbg(&host->pdev->dev, args);
+#define dbg(host, channels, args...)		  \
+	do {					  \
+	if (dbgmap_err & channels) 		  \
+		dev_err(&host->pdev->dev, args);  \
+	else if (dbgmap_info & channels)	  \
+		dev_info(&host->pdev->dev, args); \
+	else if (dbgmap_debug & channels)	  \
+		dev_dbg(&host->pdev->dev, args);  \
+	} while (0)
 
 #define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
 
@@ -63,7 +63,7 @@ static void s3cmci_reset(struct s3cmci_h
 
 #ifdef CONFIG_MMC_DEBUG
 
-static inline void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
+static void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
 {
 	u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
 	u32 datcon, datcnt, datsta, fsta, imask;
@@ -101,33 +101,33 @@ static inline void dbg_dumpregs(struct s
 }
 
 static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
-								int stop)
+			   int stop)
 {
- 	snprintf(host->dbgmsg_cmd, 300,
-		"#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
-		host->ccnt, (stop?" (STOP)":""),
-		cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
+	snprintf(host->dbgmsg_cmd, 300,
+		 "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
+		 host->ccnt, (stop ? " (STOP)" : ""),
+		 cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
 
 	if (cmd->data) {
 		snprintf(host->dbgmsg_dat, 300,
-			"#%u bsize:%u blocks:%u bytes:%u",
-			host->dcnt, cmd->data->blksz,
-			cmd->data->blocks,
-			cmd->data->blocks * cmd->data->blksz);
+			 "#%u bsize:%u blocks:%u bytes:%u",
+			 host->dcnt, cmd->data->blksz,
+			 cmd->data->blocks,
+			 cmd->data->blocks * cmd->data->blksz);
 	} else {
 		host->dbgmsg_dat[0] = '\0';
 	}
 }
 
 static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd,
-								int fail)
+			int fail)
 {
-	unsigned int dbglvl = fail?dbg_fail:dbg_debug;
+	unsigned int dbglvl = fail ? dbg_fail : dbg_debug;
 
 	if (!cmd)
 		return;
 
-	if (cmd->error == MMC_ERR_NONE) {
+	if (cmd->error == 0) {
 		dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n",
 			host->dbgmsg_cmd, cmd->resp[0]);
 	} else {
@@ -138,7 +138,7 @@ static void dbg_dumpcmd(struct s3cmci_ho
 	if (!cmd->data)
 		return;
 
-	if (cmd->data->error == MMC_ERR_NONE) {
+	if (cmd->data->error == 0) {
 		dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat);
 	} else {
 		dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n",
@@ -146,14 +146,23 @@ static void dbg_dumpcmd(struct s3cmci_ho
 			readl(host->base + S3C2410_SDIDCNT));
 	}
 }
-#endif
+#else
+static void dbg_dumpcmd(struct s3cmci_host *host,
+			struct mmc_command *cmd, int fail) { }
+
+static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
+			   int stop) { }
+
+static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
+
+#endif /* CONFIG_MMC_DEBUG */
 
 static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
 {
 	u32 newmask;
 
 	newmask = readl(host->base + host->sdiimsk);
-	newmask|= imask;
+	newmask |= imask;
 
 	writel(newmask, host->base + host->sdiimsk);
 
@@ -165,7 +174,7 @@ static inline u32 disable_imask(struct s
 	u32 newmask;
 
 	newmask = readl(host->base + host->sdiimsk);
-	newmask&= ~imask;
+	newmask &= ~imask;
 
 	writel(newmask, host->base + host->sdiimsk);
 
@@ -178,7 +187,7 @@ static inline void clear_imask(struct s3
 }
 
 static inline int get_data_buffer(struct s3cmci_host *host,
-			volatile u32 *words, volatile u32 **pointer)
+				  u32 *words, u32 **pointer)
 {
 	struct scatterlist *sg;
 
@@ -195,69 +204,82 @@ static inline int get_data_buffer(struct
 	}
 	sg = &host->mrq->data->sg[host->pio_sgptr];
 
-	*words	= sg->length >> 2;
-	*pointer= page_address(sg->page) + sg->offset;
+	*words = sg->length >> 2;
+	*pointer = sg_virt(sg);
 
 	host->pio_sgptr++;
 
 	dbg(host, dbg_sg, "new buffer (%i/%i)\n",
-	      host->pio_sgptr, host->mrq->data->sg_len);
+	    host->pio_sgptr, host->mrq->data->sg_len);
 
 	return 0;
 }
 
-#define FIFO_FILL(host) ((readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK) >> 2)
-#define FIFO_FREE(host) ((63 - (readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK)) >> 2)
+static inline u32 fifo_count(struct s3cmci_host *host)
+{
+	u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
+
+	fifostat &= S3C2410_SDIFSTA_COUNTMASK;
+	return fifostat >> 2;
+}
+
+static inline u32 fifo_free(struct s3cmci_host *host)
+{
+	u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
+
+	fifostat &= S3C2410_SDIFSTA_COUNTMASK;
+	return (63 - fifostat) >> 2;
+}
 
-static inline void do_pio_read(struct s3cmci_host *host)
+static void do_pio_read(struct s3cmci_host *host)
 {
 	int res;
 	u32 fifo;
 	void __iomem *from_ptr;
 
-	//write real prescaler to host, it might be set slow to fix
+	/* write real prescaler to host, it might be set slow to fix */
 	writel(host->prescaler, host->base + S3C2410_SDIPRE);
 
 	from_ptr = host->base + host->sdidata;
 
-	while ((fifo = FIFO_FILL(host))) {
+	while ((fifo = fifo_count(host))) {
 		if (!host->pio_words) {
 			res = get_data_buffer(host, &host->pio_words,
-							&host->pio_ptr);
+					      &host->pio_ptr);
 			if (res) {
 				host->pio_active = XFER_NONE;
 				host->complete_what = COMPLETION_FINALIZE;
 
 				dbg(host, dbg_pio, "pio_read(): "
-					"complete (no more data).\n");
+				    "complete (no more data).\n");
 				return;
 			}
 
-			dbg(host, dbg_pio, "pio_read(): new target: [%i]@[%p]\n",
-			       host->pio_words, host->pio_ptr);
+			dbg(host, dbg_pio,
+			    "pio_read(): new target: [%i]@[%p]\n",
+			    host->pio_words, host->pio_ptr);
 		}
 
-		dbg(host, dbg_pio, "pio_read(): fifo:[%02i] "
-				   "buffer:[%03i] dcnt:[%08X]\n",
-				   fifo, host->pio_words,
-				   readl(host->base + S3C2410_SDIDCNT));
+		dbg(host, dbg_pio,
+		    "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
+		    fifo, host->pio_words,
+		    readl(host->base + S3C2410_SDIDCNT));
 
 		if (fifo > host->pio_words)
 			fifo = host->pio_words;
 
-		host->pio_words-= fifo;
-		host->pio_count+= fifo;
+		host->pio_words -= fifo;
+		host->pio_count += fifo;
 
-		while(fifo--) {
+		while (fifo--)
 			*(host->pio_ptr++) = readl(from_ptr);
-		}
 	}
 
 	if (!host->pio_words) {
 		res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
 		if (res) {
-			dbg(host, dbg_pio, "pio_read(): "
-				"complete (no more buffers).\n");
+			dbg(host, dbg_pio,
+			    "pio_read(): complete (no more buffers).\n");
 			host->pio_active = XFER_NONE;
 			host->complete_what = COMPLETION_FINALIZE;
 
@@ -265,45 +287,44 @@ static inline void do_pio_read(struct s3
 		}
 	}
 
-	enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
+	enable_imask(host,
+		     S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
 }
 
-static inline void do_pio_write(struct s3cmci_host *host)
+static void do_pio_write(struct s3cmci_host *host)
 {
+	void __iomem *to_ptr;
 	int res;
 	u32 fifo;
 
-	void __iomem *to_ptr;
-
 	to_ptr = host->base + host->sdidata;
 
-	while ((fifo = FIFO_FREE(host))) {
+	while ((fifo = fifo_free(host))) {
 		if (!host->pio_words) {
 			res = get_data_buffer(host, &host->pio_words,
 							&host->pio_ptr);
 			if (res) {
-				dbg(host, dbg_pio, "pio_write(): "
-					"complete (no more data).\n");
+				dbg(host, dbg_pio,
+				    "pio_write(): complete (no more data).\n");
 				host->pio_active = XFER_NONE;
 
 				return;
 			}
 
-			dbg(host, dbg_pio, "pio_write(): "
-				"new source: [%i]@[%p]\n",
-				host->pio_words, host->pio_ptr);
+			dbg(host, dbg_pio,
+			    "pio_write(): new source: [%i]@[%p]\n",
+			    host->pio_words, host->pio_ptr);
 
 		}
 
 		if (fifo > host->pio_words)
 			fifo = host->pio_words;
 
-		host->pio_words-= fifo;
-		host->pio_count+= fifo;
+		host->pio_words -= fifo;
+		host->pio_count += fifo;
 
-		while(fifo--) {
+		while (fifo--)
 			writel(*(host->pio_ptr++), to_ptr);
-		}
 	}
 
 	enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
@@ -324,11 +345,11 @@ static void pio_tasklet(unsigned long da
 		clear_imask(host);
 		if (host->pio_active != XFER_NONE) {
 			dbg(host, dbg_err, "unfinished %s "
-				"- pio_count:[%u] pio_words:[%u]\n",
-				(host->pio_active == XFER_READ)?"read":"write",
-				host->pio_count, host->pio_words);
+			    "- pio_count:[%u] pio_words:[%u]\n",
+			    (host->pio_active == XFER_READ) ? "read" : "write",
+			    host->pio_count, host->pio_words);
 
-			host->mrq->data->error = MMC_ERR_DMA;
+			host->mrq->data->error = -EINVAL;
 		}
 
 		disable_irq(host->irq);
@@ -340,7 +361,7 @@ static void pio_tasklet(unsigned long da
  * ISR for SDI Interface IRQ
  * Communication between driver and ISR works as follows:
  *   host->mrq 			points to current request
- *   host->complete_what	tells the ISR when the request is considered done
+ *   host->complete_what	Indicates when the request is considered done
  *     COMPLETION_CMDSENT	  when the command was sent
  *     COMPLETION_RSPFIN          when a response was received
  *     COMPLETION_XFERFINISH	  when the data transfer is finished
@@ -365,26 +386,24 @@ static void pio_tasklet(unsigned long da
 
 static irqreturn_t s3cmci_irq(int irq, void *dev_id)
 {
-	struct s3cmci_host *host;
+	struct s3cmci_host *host = dev_id;
 	struct mmc_command *cmd;
 	u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
 	u32 mci_cclear, mci_dclear;
 	unsigned long iflags;
 
-	host = (struct s3cmci_host *)dev_id;
-
 	spin_lock_irqsave(&host->complete_lock, iflags);
 
-	mci_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
-	mci_dsta 	= readl(host->base + S3C2410_SDIDSTA);
-	mci_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
-	mci_fsta 	= readl(host->base + S3C2410_SDIFSTA);
-	mci_imsk	= readl(host->base + host->sdiimsk);
-	mci_cclear	= 0;
-	mci_dclear	= 0;
+	mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
+	mci_dsta = readl(host->base + S3C2410_SDIDSTA);
+	mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
+	mci_fsta = readl(host->base + S3C2410_SDIFSTA);
+	mci_imsk = readl(host->base + host->sdiimsk);
+	mci_cclear = 0;
+	mci_dclear = 0;
 
 	if ((host->complete_what == COMPLETION_NONE) ||
-			(host->complete_what == COMPLETION_FINALIZE)) {
+	    (host->complete_what == COMPLETION_FINALIZE)) {
 		host->status = "nothing to complete";
 		clear_imask(host);
 		goto irq_out;
@@ -396,7 +415,7 @@ static irqreturn_t s3cmci_irq(int irq, v
 		goto irq_out;
 	}
 
-	cmd = host->cmd_is_stop?host->mrq->stop:host->mrq->cmd;
+	cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;
 
 	if (!cmd) {
 		host->status = "no active cmd";
@@ -406,7 +425,7 @@ static irqreturn_t s3cmci_irq(int irq, v
 
 	if (!host->dodma) {
 		if ((host->pio_active == XFER_WRITE) &&
-				(mci_fsta & S3C2410_SDIFSTA_TFDET)) {
+		    (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
 
 			disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
 			tasklet_schedule(&host->pio_tasklet);
@@ -414,10 +433,11 @@ static irqreturn_t s3cmci_irq(int irq, v
 		}
 
 		if ((host->pio_active == XFER_READ) &&
-				(mci_fsta & S3C2410_SDIFSTA_RFDET)) {
+		    (mci_fsta & S3C2410_SDIFSTA_RFDET)) {
 
 			disable_imask(host,
-				S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
+				      S3C2410_SDIIMSK_RXFIFOHALF |
+				      S3C2410_SDIIMSK_RXFIFOLAST);
 
 			tasklet_schedule(&host->pio_tasklet);
 			host->status = "pio rx";
@@ -425,7 +445,7 @@ static irqreturn_t s3cmci_irq(int irq, v
 	}
 
 	if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
-		cmd->error = MMC_ERR_TIMEOUT;
+		cmd->error = -ETIMEDOUT;
 		host->status = "error: command timeout";
 		goto fail_transfer;
 	}
@@ -441,7 +461,7 @@ static irqreturn_t s3cmci_irq(int irq, v
 
 	if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
 		if (cmd->flags & MMC_RSP_CRC) {
-			cmd->error = MMC_ERR_BADCRC;
+			cmd->error = -EILSEQ;
 			host->status = "error: bad command crc";
 			goto fail_transfer;
 		}
@@ -470,32 +490,32 @@ static irqreturn_t s3cmci_irq(int irq, v
 	/* Check for FIFO failure */
 	if (host->is2440) {
 		if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
-			host->mrq->data->error = MMC_ERR_FIFO;
+			host->mrq->data->error = -EILSEQ;
 			host->status = "error: 2440 fifo failure";
 			goto fail_transfer;
 		}
 	} else {
 		if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
-			cmd->data->error = MMC_ERR_FIFO;
+			cmd->data->error = -EILSEQ;
 			host->status = "error:  fifo failure";
 			goto fail_transfer;
 		}
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
-		cmd->data->error = MMC_ERR_BADCRC;
+		cmd->data->error = -EILSEQ;
 		host->status = "error: bad data crc (outgoing)";
 		goto fail_transfer;
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {
-		cmd->data->error = MMC_ERR_BADCRC;
+		cmd->data->error = -EILSEQ;
 		host->status = "error: bad data crc (incoming)";
 		goto fail_transfer;
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
-		cmd->data->error = MMC_ERR_TIMEOUT;
+		cmd->data->error = -ETIMEDOUT;
 		host->status = "error: data timeout";
 		goto fail_transfer;
 	}
@@ -506,9 +526,8 @@ static irqreturn_t s3cmci_irq(int irq, v
 			goto close_transfer;
 		}
 
-		if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+		if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
 			host->complete_what = COMPLETION_RSPFIN;
-		}
 
 		mci_dclear |= S3C2410_SDIDSTA_XFERFINISH;
 	}
@@ -531,10 +550,9 @@ close_transfer:
 	goto irq_out;
 
 irq_out:
-	dbg(host, dbg_irq, "csta:0x%08x dsta:0x%08x "
-			   "fsta:0x%08x dcnt:0x%08x status:%s.\n",
-				mci_csta, mci_dsta, mci_fsta,
-				mci_dcnt, host->status);
+	dbg(host, dbg_irq,
+	    "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n",
+	    mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status);
 
 	spin_unlock_irqrestore(&host->complete_lock, iflags);
 	return IRQ_HANDLED;
@@ -557,22 +575,20 @@ static irqreturn_t s3cmci_irq_cd(int irq
 }
 
 void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id,
-	int size, enum s3c2410_dma_buffresult result)
+			      int size, enum s3c2410_dma_buffresult result)
 {
+	struct s3cmci_host *host = buf_id;
 	unsigned long iflags;
 	u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt;
-	struct s3cmci_host *host = (struct s3cmci_host *)buf_id;
 
-	mci_csta 	= readl(host->base + S3C2410_SDICMDSTAT);
-	mci_dsta 	= readl(host->base + S3C2410_SDIDSTA);
-	mci_fsta 	= readl(host->base + S3C2410_SDIFSTA);
-	mci_dcnt 	= readl(host->base + S3C2410_SDIDCNT);
-
-	if ((!host->mrq) || (!host->mrq) || (!host->mrq->data))
-		return;
-
-	if (!host->dmatogo)
-		return;
+	mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
+	mci_dsta = readl(host->base + S3C2410_SDIDSTA);
+	mci_fsta = readl(host->base + S3C2410_SDIFSTA);
+	mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
+
+	BUG_ON(!host->mrq);
+	BUG_ON(!host->mrq->data);
+	BUG_ON(!host->dmatogo);
 
 	spin_lock_irqsave(&host->complete_lock, iflags);
 
@@ -606,7 +622,7 @@ out:
 
 
 fail_request:
-	host->mrq->data->error = MMC_ERR_DMA;
+	host->mrq->data->error = -EINVAL;
 	host->complete_what = COMPLETION_FINALIZE;
 	writel(0, host->base + host->sdiimsk);
 	goto out;
@@ -616,7 +632,7 @@ fail_request:
 static void finalize_request(struct s3cmci_host *host)
 {
 	struct mmc_request *mrq = host->mrq;
-	struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;
+	struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 	int debug_as_failure = 0;
 
 	if (host->complete_what != COMPLETION_FINALIZE)
@@ -625,22 +641,20 @@ static void finalize_request(struct s3cm
 	if (!mrq)
 		return;
 
-	if (cmd->data && (cmd->error == MMC_ERR_NONE) &&
-		  (cmd->data->error == MMC_ERR_NONE)) {
-
+	if (cmd->data && (cmd->error == 0) &&
+	    (cmd->data->error == 0)) {
 		if (host->dodma && (!host->dma_complete)) {
 			dbg(host, dbg_dma, "DMA Missing!\n");
 			return;
 		}
 	}
 
-	// Read response
+	/* Read response from controller. */
 	cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
 	cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
 	cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
 	cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
 
-	// reset clock speed, as it could still be set low for
 	writel(host->prescaler, host->base + S3C2410_SDIPRE);
 
 	if (cmd->error)
@@ -649,12 +663,9 @@ static void finalize_request(struct s3cm
 	if (cmd->data && cmd->data->error)
 		debug_as_failure = 1;
 
-	//if(cmd->flags & MMC_RSP_MAYFAIL) debug_as_failure = 0;
-
-#ifdef CONFIG_MMC_DEBUG
 	dbg_dumpcmd(host, cmd, debug_as_failure);
-#endif
-	//Cleanup controller
+
+	/* Cleanup controller */
 	writel(0, host->base + S3C2410_SDICMDARG);
 	writel(0, host->base + S3C2410_SDIDCON);
 	writel(0, host->base + S3C2410_SDICMDCON);
@@ -669,36 +680,35 @@ static void finalize_request(struct s3cm
 		return;
 	}
 
-	// If we have no data transfer we are finished here
+	/* If we have no data transfer we are finished here */
 	if (!mrq->data)
 		goto request_done;
 
-	// Calulate the amout of bytes transfer, but only if there was
-	// no error
-	if (mrq->data->error == MMC_ERR_NONE) {
+	/* Calulate the amout of bytes transfer if there was no error */
+	if (mrq->data->error == 0) {
 		mrq->data->bytes_xfered =
 			(mrq->data->blocks * mrq->data->blksz);
 	} else {
 		mrq->data->bytes_xfered = 0;
 	}
 
-	// If we had an error while transfering data we flush the
-	// DMA channel and the fifo to clear out any garbage
-	if (mrq->data->error != MMC_ERR_NONE) {
+	/* If we had an error while transfering data we flush the
+	 * DMA channel and the fifo to clear out any garbage. */
+	if (mrq->data->error != 0) {
 		if (host->dodma)
 			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 
 		if (host->is2440) {
-			//Clear failure register and reset fifo
+			/* Clear failure register and reset fifo. */
 			writel(S3C2440_SDIFSTA_FIFORESET |
 			       S3C2440_SDIFSTA_FIFOFAIL,
 			       host->base + S3C2410_SDIFSTA);
 		} else {
 			u32 mci_con;
 
-			//reset fifo
+			/* reset fifo */
 			mci_con = readl(host->base + S3C2410_SDICON);
-			mci_con|= S3C2410_SDICON_FIFORESET;
+			mci_con |= S3C2410_SDICON_FIFORESET;
 
 			writel(mci_con, host->base + S3C2410_SDICON);
 		}
@@ -713,8 +723,8 @@ request_done:
 
 void s3cmci_dma_setup(struct s3cmci_host *host, enum s3c2410_dmasrc source)
 {
-	static int setup_ok = 0;
 	static enum s3c2410_dmasrc last_source = -1;
+	static int setup_ok;
 
 	if (last_source == source)
 		return;
@@ -722,12 +732,13 @@ void s3cmci_dma_setup(struct s3cmci_host
 	last_source = source;
 
 	s3c2410_dma_devconfig(host->dma, source, 3,
-		host->mem->start + host->sdidata);
+			      host->mem->start + host->sdidata);
 
 	if (!setup_ok) {
 		s3c2410_dma_config(host->dma, 4,
 			(S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI));
-		s3c2410_dma_set_buffdone_fn(host->dma, s3cmci_dma_done_callback);
+		s3c2410_dma_set_buffdone_fn(host->dma,
+					    s3cmci_dma_done_callback);
 		s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
 		setup_ok = 1;
 	}
@@ -744,31 +755,30 @@ static void s3cmci_send_command(struct s
 
 	enable_imask(host, imsk);
 
-	if (cmd->data) {
+	if (cmd->data)
 		host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
-	} else if (cmd->flags & MMC_RSP_PRESENT) {
+	else if (cmd->flags & MMC_RSP_PRESENT)
 		host->complete_what = COMPLETION_RSPFIN;
-	} else {
+	else
 		host->complete_what = COMPLETION_CMDSENT;
-	}
 
 	writel(cmd->arg, host->base + S3C2410_SDICMDARG);
 
-	ccon = cmd->opcode & S3C2410_SDICMDCON_INDEX;
-	ccon|= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
+	ccon  = cmd->opcode & S3C2410_SDICMDCON_INDEX;
+	ccon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
 
 	if (cmd->flags & MMC_RSP_PRESENT)
 		ccon |= S3C2410_SDICMDCON_WAITRSP;
 
 	if (cmd->flags & MMC_RSP_136)
-		ccon|= S3C2410_SDICMDCON_LONGRSP;
+		ccon |= S3C2410_SDICMDCON_LONGRSP;
 
 	writel(ccon, host->base + S3C2410_SDICMDCON);
 }
 
 static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
 {
-	u32 dcon, imsk, stoptries=3;
+	u32 dcon, imsk, stoptries = 3;
 
 	/* write DCON register */
 
@@ -777,37 +787,31 @@ static int s3cmci_setup_data(struct s3cm
 		return 0;
 	}
 
-	while(readl(host->base + S3C2410_SDIDSTA) &
-		(S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
+	while (readl(host->base + S3C2410_SDIDSTA) &
+	       (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
 
 		dbg(host, dbg_err,
-			"mci_setup_data() transfer stillin progress.\n");
+		    "mci_setup_data() transfer stillin progress.\n");
 
 		writel(0, host->base + S3C2410_SDIDCON);
 		s3cmci_reset(host);
 
-		if (0 == (stoptries--)) {
-#ifdef CONFIG_MMC_DEBUG
+		if ((stoptries--) == 0) {
 			dbg_dumpregs(host, "DRF");
-#endif
-
 			return -EINVAL;
 		}
 	}
 
 	dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
 
-	if (host->dodma) {
+	if (host->dodma)
 		dcon |= S3C2410_SDIDCON_DMAEN;
-	}
 
-	if (host->bus_width == MMC_BUS_WIDTH_4) {
+	if (host->bus_width == MMC_BUS_WIDTH_4)
 		dcon |= S3C2410_SDIDCON_WIDEBUS;
-	}
 
-	if (!(data->flags & MMC_DATA_STREAM)) {
+	if (!(data->flags & MMC_DATA_STREAM))
 		dcon |= S3C2410_SDIDCON_BLOCKMODE;
-	}
 
 	if (data->flags & MMC_DATA_WRITE) {
 		dcon |= S3C2410_SDIDCON_TXAFTERRESP;
@@ -831,8 +835,8 @@ static int s3cmci_setup_data(struct s3cm
 	writel(data->blksz, host->base + S3C2410_SDIBSIZE);
 
 	/* add to IMASK register */
-	imsk =	S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
-		S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
+	imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
+	       S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
 
 	enable_imask(host, imsk);
 
@@ -843,35 +847,33 @@ static int s3cmci_setup_data(struct s3cm
 	} else {
 		writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
 
-		//FIX: set slow clock to prevent timeouts on read
-		if (data->flags & MMC_DATA_READ) {
+		/* FIX: set slow clock to prevent timeouts on read */
+		if (data->flags & MMC_DATA_READ)
 			writel(0xFF, host->base + S3C2410_SDIPRE);
-		}
 	}
 
-	//debug_dump_registers(host, "Data setup:");
-
 	return 0;
 }
 
+#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ)
+
 static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
 {
-	int rw = (data->flags & MMC_DATA_WRITE)?1:0;
+	int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
 
-	if (rw != ((data->flags & MMC_DATA_READ)?0:1))
-		return -EINVAL;
+	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
 	host->pio_sgptr = 0;
 	host->pio_words = 0;
 	host->pio_count = 0;
-	host->pio_active = rw?XFER_WRITE:XFER_READ;
+	host->pio_active = rw ? XFER_WRITE : XFER_READ;
 
 	if (rw) {
 		do_pio_write(host);
 		enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
 	} else {
 		enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF
-			| S3C2410_SDIIMSK_RXFIFOLAST);
+			     | S3C2410_SDIIMSK_RXFIFOLAST);
 	}
 
 	return 0;
@@ -880,18 +882,15 @@ static int s3cmci_prepare_pio(struct s3c
 static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
 {
 	int dma_len, i;
+	int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
 
-	int rw = (data->flags & MMC_DATA_WRITE)?1:0;
-
-	if (rw != ((data->flags & MMC_DATA_READ)?0:1))
-		return -EINVAL;
+	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
-	s3cmci_dma_setup(host, rw?S3C2410_DMASRC_MEM:S3C2410_DMASRC_HW);
+	s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW);
 	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 
 	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
-				(rw)?DMA_TO_DEVICE:DMA_FROM_DEVICE);
-
+			     (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
 	if (dma_len == 0)
 		return -ENOMEM;
@@ -907,14 +906,14 @@ static int s3cmci_prepare_dma(struct s3c
 			sg_dma_len(&data->sg[i]));
 
 		res = s3c2410_dma_enqueue(host->dma, (void *) host,
-				sg_dma_address(&data->sg[i]),
-				sg_dma_len(&data->sg[i]));
+					  sg_dma_address(&data->sg[i]),
+					  sg_dma_len(&data->sg[i]));
 
 		if (res) {
 			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 			return -EBUSY;
 		}
- 	}
+	}
 
 	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START);
 
@@ -925,60 +924,57 @@ static void s3cmci_send_request(struct m
 {
 	struct s3cmci_host *host = mmc_priv(mmc);
 	struct mmc_request *mrq = host->mrq;
-	struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;
+	struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 
 	host->ccnt++;
-#ifdef CONFIG_MMC_DEBUG
 	prepare_dbgmsg(host, cmd, host->cmd_is_stop);
-#endif
-	//Clear command, data and fifo status registers
-	//Fifo clear only necessary on 2440, but doesn't hurt on 2410
+
+	/* Clear command, data and fifo status registers
+	   Fifo clear only necessary on 2440, but doesn't hurt on 2410
+	*/
 	writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
 	writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
 	writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);
 
 	if (cmd->data) {
-		int res;
-		res = s3cmci_setup_data(host, cmd->data);
+		int res = s3cmci_setup_data(host, cmd->data);
 
 		host->dcnt++;
 
 		if (res) {
-			cmd->error = MMC_ERR_DMA;
-			cmd->data->error = MMC_ERR_DMA;
+			cmd->error = -EINVAL;
+			cmd->data->error = -EINVAL;
 
 			mmc_request_done(mmc, mrq);
 			return;
 		}
 
-
-		if (host->dodma) {
+		if (host->dodma)
 			res = s3cmci_prepare_dma(host, cmd->data);
-		} else {
+		else
 			res = s3cmci_prepare_pio(host, cmd->data);
-		}
 
 		if (res) {
-			cmd->error = MMC_ERR_DMA;
-			cmd->data->error = MMC_ERR_DMA;
+			cmd->error = res;
+			cmd->data->error = res;
 
 			mmc_request_done(mmc, mrq);
 			return;
 		}
-
 	}
 
-	// Send command
+	/* Send command */
 	s3cmci_send_command(host, cmd);
 
-	// Enable Interrupt
+	/* Enable Interrupt */
 	enable_irq(host->irq);
 }
 
 static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
- 	struct s3cmci_host *host = mmc_priv(mmc);
+	struct s3cmci_host *host = mmc_priv(mmc);
 
+	host->status = "mmc request";
 	host->cmd_is_stop = 0;
 	host->mrq = mrq;
 
@@ -990,62 +986,64 @@ static void s3cmci_set_ios(struct mmc_ho
 	struct s3cmci_host *host = mmc_priv(mmc);
 	u32 mci_psc, mci_con;
 
-	//Set power
-	mci_con = readl(host->base + S3C2410_SDICON);
-	switch(ios->power_mode) {
-		case MMC_POWER_ON:
-		case MMC_POWER_UP:
-			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
-			s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
-			s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
-			s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
-			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
-			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
-
-			if (!host->is2440)
-				mci_con|=S3C2410_SDICON_FIFORESET;
+	/* Set the power state */
 
-			break;
+	mci_con = readl(host->base + S3C2410_SDICON);
 
-		case MMC_POWER_OFF:
-		default:
-			s3c2410_gpio_setpin(S3C2410_GPE5, 0);
-			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
+	switch (ios->power_mode) {
+	case MMC_POWER_ON:
+	case MMC_POWER_UP:
+		s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
+		s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
+		s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
+		s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
+		s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
+		s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+
+		if (!host->is2440)
+			mci_con |= S3C2410_SDICON_FIFORESET;
+
+		break;
+
+	case MMC_POWER_OFF:
+	default:
+		s3c2410_gpio_setpin(S3C2410_GPE5, 0);
+		s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
 
-			if (host->is2440)
-				mci_con|=S3C2440_SDICON_SDRESET;
+		if (host->is2440)
+			mci_con |= S3C2440_SDICON_SDRESET;
 
-			break;
+		break;
 	}
 
-	//Set clock
-	for (mci_psc=0; mci_psc<255; mci_psc++) {
+	/* Set clock */
+	for (mci_psc = 0; mci_psc < 255; mci_psc++) {
 		host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
 
 		if (host->real_rate <= ios->clock)
 			break;
 	}
 
-	if(mci_psc > 255) mci_psc = 255;
-	host->prescaler = mci_psc;
+	if (mci_psc > 255)
+		mci_psc = 255;
 
+	host->prescaler = mci_psc;
 	writel(host->prescaler, host->base + S3C2410_SDIPRE);
 
-	//If requested clock is 0, real_rate will be 0, too
+	/* If requested clock is 0, real_rate will be 0, too */
 	if (ios->clock == 0)
 		host->real_rate = 0;
 
-	//Set CLOCK_ENABLE
+	/* Set CLOCK_ENABLE */
 	if (ios->clock)
 		mci_con |= S3C2410_SDICON_CLOCKTYPE;
 	else
-		mci_con &=~S3C2410_SDICON_CLOCKTYPE;
+		mci_con &= ~S3C2410_SDICON_CLOCKTYPE;
 
 	writel(mci_con, host->base + S3C2410_SDICON);
 
-	if ((ios->power_mode==MMC_POWER_ON)
-		|| (ios->power_mode==MMC_POWER_UP)) {
-
+	if ((ios->power_mode == MMC_POWER_ON) ||
+	    (ios->power_mode == MMC_POWER_UP)) {
 		dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",
 			host->real_rate/1000, ios->clock/1000);
 	} else {
@@ -1053,7 +1051,6 @@ static void s3cmci_set_ios(struct mmc_ho
 	}
 
 	host->bus_width = ios->bus_width;
-
 }
 
 static void s3cmci_reset(struct s3cmci_host *host)
@@ -1061,7 +1058,6 @@ static void s3cmci_reset(struct s3cmci_h
 	u32 con = readl(host->base + S3C2410_SDICON);
 
 	con |= S3C2440_SDICON_SDRESET;
-
 	writel(con, host->base + S3C2410_SDICON);
 }
 
@@ -1070,11 +1066,10 @@ static struct mmc_host_ops s3cmci_ops = 
 	.set_ios	= s3cmci_set_ios,
 };
 
-static int s3cmci_probe(struct platform_device *pdev, int is2440)
+static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
 {
-	struct mmc_host 	*mmc;
-	struct s3cmci_host 	*host;
-
+	struct s3cmci_host *host;
+	struct mmc_host	*mmc;
 	int ret;
 
 	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
@@ -1086,20 +1081,21 @@ static int s3cmci_probe(struct platform_
 	host = mmc_priv(mmc);
 	host->mmc 	= mmc;
 	host->pdev	= pdev;
+	host->is2440	= is2440;
 
 	spin_lock_init(&host->complete_lock);
 	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
+
 	if (is2440) {
-		host->is2440	= 1;
 		host->sdiimsk	= S3C2440_SDIIMSK;
 		host->sdidata	= S3C2440_SDIDATA;
 		host->clk_div	= 1;
 	} else {
-		host->is2440	= 0;
 		host->sdiimsk	= S3C2410_SDIIMSK;
 		host->sdidata	= S3C2410_SDIDATA;
 		host->clk_div	= 2;
 	}
+
 	host->dodma		= 0;
 	host->complete_what 	= COMPLETION_NONE;
 	host->pio_active 	= XFER_NONE;
@@ -1117,7 +1113,7 @@ static int s3cmci_probe(struct platform_
 	}
 
 	host->mem = request_mem_region(host->mem->start,
-		RESSIZE(host->mem), pdev->name);
+				       RESSIZE(host->mem), pdev->name);
 
 	if (!host->mem) {
 		dev_err(&pdev->dev, "failed to request io memory region.\n");
@@ -1145,6 +1141,10 @@ static int s3cmci_probe(struct platform_
 		goto probe_iounmap;
 	}
 
+	/* We get spurious interrupts even when we have set the IMSK
+	 * register to ignore everything, so use disable_irq() to make
+	 * ensure we don't lock the system with un-serviceable requests. */
+
 	disable_irq(host->irq);
 
 	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
@@ -1153,7 +1153,6 @@ static int s3cmci_probe(struct platform_
 	if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) {
 		dev_err(&pdev->dev,
 			"failed to request card detect interrupt.\n");
-
 		ret = -ENOENT;
 		goto probe_free_irq;
 	}
@@ -1172,7 +1171,8 @@ static int s3cmci_probe(struct platform_
 		goto probe_free_host;
 	}
 
-	if ((ret = clk_enable(host->clk))) {
+	ret = clk_enable(host->clk);
+	if (ret) {
 		dev_err(&pdev->dev, "failed to enable clock source.\n");
 		goto clk_free;
 	}
@@ -1193,18 +1193,20 @@ static int s3cmci_probe(struct platform_
 	mmc->max_phys_segs	= 128;
 	mmc->max_hw_segs	= 128;
 
-	dbg(host, dbg_debug, "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
-		(host->is2440?"2440":""),
-		host->base, host->irq, host->irq_cd, host->dma);
+	dbg(host, dbg_debug,
+	    "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
+	    (host->is2440?"2440":""),
+	    host->base, host->irq, host->irq_cd, host->dma);
 
-	if ((ret = mmc_add_host(mmc))) {
+	ret = mmc_add_host(mmc);
+	if (ret) {
 		dev_err(&pdev->dev, "failed to add mmc host.\n");
 		goto free_dmabuf;
 	}
 
 	platform_set_drvdata(pdev, mmc);
+	dev_info(&pdev->dev, "initialisation done.\n");
 
-	dev_info(&pdev->dev,"initialisation done.\n");
 	return 0;
 
  free_dmabuf:
@@ -1214,10 +1216,10 @@ static int s3cmci_probe(struct platform_
 	clk_put(host->clk);
 
  probe_free_irq_cd:
- 	free_irq(host->irq_cd, host);
+	free_irq(host->irq_cd, host);
 
  probe_free_irq:
- 	free_irq(host->irq, host);
+	free_irq(host->irq, host);
 
  probe_iounmap:
 	iounmap(host->base);
@@ -1231,34 +1233,39 @@ static int s3cmci_probe(struct platform_
 	return ret;
 }
 
-static int s3cmci_remove(struct platform_device *pdev)
+static int __devexit s3cmci_remove(struct platform_device *pdev)
 {
-	struct mmc_host 	*mmc  = platform_get_drvdata(pdev);
-	struct s3cmci_host 	*host = mmc_priv(mmc);
+	struct mmc_host		*mmc  = platform_get_drvdata(pdev);
+	struct s3cmci_host	*host = mmc_priv(mmc);
 
 	mmc_remove_host(mmc);
+
 	clk_disable(host->clk);
 	clk_put(host->clk);
- 	free_irq(host->irq_cd, host);
- 	free_irq(host->irq, host);
+
+	tasklet_disable(&host->pio_tasklet);
+
+	free_irq(host->irq_cd, host);
+	free_irq(host->irq, host);
+
 	iounmap(host->base);
 	release_mem_region(host->mem->start, RESSIZE(host->mem));
-	mmc_free_host(mmc);
 
+	mmc_free_host(mmc);
 	return 0;
 }
 
-static int s3cmci_probe_2410(struct platform_device *dev)
+static int __devinit s3cmci_probe_2410(struct platform_device *dev)
 {
 	return s3cmci_probe(dev, 0);
 }
 
-static int s3cmci_probe_2412(struct platform_device *dev)
+static int __devinit s3cmci_probe_2412(struct platform_device *dev)
 {
 	return s3cmci_probe(dev, 1);
 }
 
-static int s3cmci_probe_2440(struct platform_device *dev)
+static int __devinit s3cmci_probe_2440(struct platform_device *dev)
 {
 	return s3cmci_probe(dev, 1);
 }
@@ -1285,29 +1292,29 @@ static int s3cmci_resume(struct platform
 #endif /* CONFIG_PM */
 
 
-static struct platform_driver s3cmci_driver_2410 =
-{
+static struct platform_driver s3cmci_driver_2410 = {
 	.driver.name	= "s3c2410-sdi",
+	.driver.owner	= THIS_MODULE,
 	.probe		= s3cmci_probe_2410,
-	.remove		= s3cmci_remove,
+	.remove		= __devexit_p(s3cmci_remove),
 	.suspend	= s3cmci_suspend,
 	.resume		= s3cmci_resume,
 };
 
-static struct platform_driver s3cmci_driver_2412 =
-{
+static struct platform_driver s3cmci_driver_2412 = {
 	.driver.name	= "s3c2412-sdi",
+	.driver.owner	= THIS_MODULE,
 	.probe		= s3cmci_probe_2412,
-	.remove		= s3cmci_remove,
+	.remove		= __devexit_p(s3cmci_remove),
 	.suspend	= s3cmci_suspend,
 	.resume		= s3cmci_resume,
 };
 
-static struct platform_driver s3cmci_driver_2440 =
-{
+static struct platform_driver s3cmci_driver_2440 = {
 	.driver.name	= "s3c2440-sdi",
+	.driver.owner	= THIS_MODULE,
 	.probe		= s3cmci_probe_2440,
-	.remove		= s3cmci_remove,
+	.remove		= __devexit_p(s3cmci_remove),
 	.suspend	= s3cmci_suspend,
 	.resume		= s3cmci_resume,
 };
@@ -1332,6 +1339,5 @@ module_init(s3cmci_init);
 module_exit(s3cmci_exit);
 
 MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>");
-
Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.h
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.h	2008-06-30 12:18:49.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.h	2008-06-30 15:30:30.000000000 +0100
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  */
 
-//FIXME: DMA Resource management ?!
+/* FIXME: DMA Resource management ?! */
 #define S3CMCI_DMA 0
 
 enum s3cmci_waitfor {
@@ -39,32 +39,30 @@ struct s3cmci_host {
 	unsigned		sdiimsk;
 	unsigned		sdidata;
 	int			dodma;
-
-	volatile int		dmatogo;
+	int			dmatogo;
 
 	struct mmc_request	*mrq;
 	int			cmd_is_stop;
 
 	spinlock_t		complete_lock;
-	volatile enum s3cmci_waitfor
-				complete_what;
+	enum s3cmci_waitfor	complete_what;
 
-	volatile int		dma_complete;
+	int			dma_complete;
 
-	volatile u32		pio_sgptr;
-	volatile u32		pio_words;
-	volatile u32		pio_count;
-	volatile u32		*pio_ptr;
+	u32			pio_sgptr;
+	u32			pio_words;
+	u32			pio_count;
+	u32			*pio_ptr;
 #define XFER_NONE 0
 #define XFER_READ 1
 #define XFER_WRITE 2
-	volatile u32		pio_active;
+	u32			pio_active;
 
 	int			bus_width;
 
 	char 			dbgmsg_cmd[301];
 	char 			dbgmsg_dat[301];
-	volatile char		*status;
+	char			*status;
 
 	unsigned int		ccnt, dcnt;
 	struct tasklet_struct	pio_tasklet;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 03/17] MMC: S3C24XX MMC/SD driver write fixes
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
  2008-06-30 15:25 ` [patch v4 01/17] MMC: S3C24XX MMC/SD driver Ben Dooks
  2008-06-30 15:25 ` [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 04/17] MMC: DMA free fix for S3C24XX SD/MMC driver Ben Dooks
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3cmci_dbg.patch --]
[-- Type: text/plain, Size: 1242 bytes --]

From: Harald Welte <laforge@openmoko.org>

This patch is a workaround of some S3C2410 MMC chip bug

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:18:49.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:04.000000000 +0100
@@ -461,9 +461,19 @@ static irqreturn_t s3cmci_irq(int irq, v
 
 	if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
 		if (cmd->flags & MMC_RSP_CRC) {
-			cmd->error = -EILSEQ;
-			host->status = "error: bad command crc";
-			goto fail_transfer;
+			if (host->mrq->cmd->flags & MMC_RSP_136) {
+				dbg(host, dbg_irq,
+				    "fixup: ignore CRC fail with long rsp\n");
+			} else {
+				/* note, we used to fail the transfer
+				 * here, but it seems that this is just
+				 * the hardware getting it wrong.
+				 *
+				 * cmd->error = -EILSEQ;
+				 * host->status = "error: bad command crc";
+				 * goto fail_transfer;
+				*/
+			}
 		}
 
 		mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 04/17] MMC: DMA free fix for S3C24XX SD/MMC driver
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (2 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 03/17] MMC: S3C24XX MMC/SD driver write fixes Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 05/17] MMC: S3C24XX MMC/SD stop fix Ben Dooks
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3cmci-dma-free.patch --]
[-- Type: text/plain, Size: 799 bytes --]

From: Harald Welte <laforge@openmoko.org>

Bugfix to ensure DMA channel allocated is freed on exit.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:04.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:13.000000000 +0100
@@ -1254,6 +1254,7 @@ static int s3cmci_remove(struct platform
 	clk_put(host->clk);
 
 	tasklet_disable(&host->pio_tasklet);
+	s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client);
 
 	free_irq(host->irq_cd, host);
 	free_irq(host->irq, host);

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 05/17] MMC: S3C24XX MMC/SD stop fix
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (3 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 04/17] MMC: DMA free fix for S3C24XX SD/MMC driver Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 06/17] MMC: Fix S3C24XX IRQ enable during PIO transfers Ben Dooks
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3cmci-stop-fix.patch --]
[-- Type: text/plain, Size: 1247 bytes --]

From: Thomas Kleffel <tk@maintech.de>

Fix the request finalisation by ensuring the controller
is stopped.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Harald Welte <laforge@openmoko.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:13.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:15.000000000 +0100
@@ -677,7 +677,7 @@ static void finalize_request(struct s3cm
 
 	/* Cleanup controller */
 	writel(0, host->base + S3C2410_SDICMDARG);
-	writel(0, host->base + S3C2410_SDIDCON);
+	writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
 	writel(0, host->base + S3C2410_SDICMDCON);
 	writel(0, host->base + host->sdiimsk);
 
@@ -803,7 +803,7 @@ static int s3cmci_setup_data(struct s3cm
 		dbg(host, dbg_err,
 		    "mci_setup_data() transfer stillin progress.\n");
 
-		writel(0, host->base + S3C2410_SDIDCON);
+		writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
 		s3cmci_reset(host);
 
 		if ((stoptries--) == 0) {

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 06/17] MMC: Fix S3C24XX IRQ enable during PIO transfers
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (4 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 05/17] MMC: S3C24XX MMC/SD stop fix Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 07/17] MMC: S3C24XX: Add platform data for MMC/SD driver Ben Dooks
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3cmci-unfinished-write-fix.patch --]
[-- Type: text/plain, Size: 1184 bytes --]

From: Roman Moracik <roman.moravcik@gmail.com> 

Fix Bug #677 - I/O errors on heavy microSD writes for 2.6.22.x.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:15.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:19:16.000000000 +0100
@@ -335,6 +335,8 @@ static void pio_tasklet(unsigned long da
 	struct s3cmci_host *host = (struct s3cmci_host *) data;
 
 
+	disable_irq(host->irq);
+
 	if (host->pio_active == XFER_WRITE)
 		do_pio_write(host);
 
@@ -352,9 +354,9 @@ static void pio_tasklet(unsigned long da
 			host->mrq->data->error = -EINVAL;
 		}
 
-		disable_irq(host->irq);
 		finalize_request(host);
-	}
+	} else
+		enable_irq(host->irq);
 }
 
 /*
@@ -630,7 +632,6 @@ out:
 	spin_unlock_irqrestore(&host->complete_lock, iflags);
 	return;
 
-
 fail_request:
 	host->mrq->data->error = -EINVAL;
 	host->complete_what = COMPLETION_FINALIZE;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 07/17] MMC: S3C24XX: Add platform data for MMC/SD driver
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (5 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 06/17] MMC: Fix S3C24XX IRQ enable during PIO transfers Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 08/17] MMC: S3C24XX: Add support to invert write protect line Ben Dooks
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: thirdparty/openmoko-mci/s3c_mci_platform.patch --]
[-- Type: text/plain, Size: 5166 bytes --]

This patch adds platform data support to the s3mci driver.  This allows
flexible board-specific configuration of set_power, card detect and read only
pins.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:31:15.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:31:46.000000000 +0100
@@ -21,6 +21,8 @@
 #include <asm/arch/regs-sdi.h>
 #include <asm/arch/regs-gpio.h>
 
+#include <asm/plat-s3c24xx/mci.h>
+
 #include "s3cmci.h"
 
 #define DRIVER_NAME "s3c-mci"
@@ -1011,6 +1013,9 @@ static void s3cmci_set_ios(struct mmc_ho
 		s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
 		s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
 
+		if (host->pdata->set_power)
+			host->pdata->set_power(ios->power_mode, ios->vdd);
+
 		if (!host->is2440)
 			mci_con |= S3C2410_SDICON_FIFORESET;
 
@@ -1024,6 +1029,9 @@ static void s3cmci_set_ios(struct mmc_ho
 		if (host->is2440)
 			mci_con |= S3C2440_SDICON_SDRESET;
 
+		if (host->pdata->set_power)
+			host->pdata->set_power(ios->power_mode, ios->vdd);
+
 		break;
 	}
 
@@ -1072,9 +1080,25 @@ static void s3cmci_reset(struct s3cmci_h
 	writel(con, host->base + S3C2410_SDICON);
 }
 
+static int s3cmci_get_ro(struct mmc_host *mmc)
+{
+	struct s3cmci_host *host = mmc_priv(mmc);
+
+	if (host->pdata->gpio_wprotect == 0)
+		return 0;
+
+	return s3c2410_gpio_getpin(host->pdata->gpio_wprotect);
+}
+
 static struct mmc_host_ops s3cmci_ops = {
 	.request	= s3cmci_request,
 	.set_ios	= s3cmci_set_ios,
+	.get_ro		= s3cmci_get_ro,
+};
+
+static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
+	/* This is currently here to avoid a number of if (host->pdata)
+	 * checks. Any zero fields to ensure reaonable defaults are picked. */
 };
 
 static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
@@ -1094,6 +1118,12 @@ static int __devinit s3cmci_probe(struct
 	host->pdev	= pdev;
 	host->is2440	= is2440;
 
+	host->pdata = pdev->dev.platform_data;
+	if (!host->pdata) {
+		pdev->dev.platform_data = &s3cmci_def_pdata;
+		host->pdata = &s3cmci_def_pdata;
+	}
+
 	spin_lock_init(&host->complete_lock);
 	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
 
@@ -1112,7 +1142,8 @@ static int __devinit s3cmci_probe(struct
 	host->pio_active 	= XFER_NONE;
 
 	host->dma		= S3CMCI_DMA;
-	host->irq_cd		= IRQ_EINT2;
+	host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
+	s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ);
 
 	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!host->mem) {
@@ -1158,7 +1189,7 @@ static int __devinit s3cmci_probe(struct
 
 	disable_irq(host->irq);
 
-	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
+	s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ);
 	set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
 
 	if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) {
@@ -1168,6 +1199,10 @@ static int __devinit s3cmci_probe(struct
 		goto probe_free_irq;
 	}
 
+	if (host->pdata->gpio_wprotect)
+		s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
+				    S3C2410_GPIO_INPUT);
+
 	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) {
 		dev_err(&pdev->dev, "unable to get DMA channel.\n");
 		ret = -EBUSY;
@@ -1191,11 +1226,14 @@ static int __devinit s3cmci_probe(struct
 	host->clk_rate = clk_get_rate(host->clk);
 
 	mmc->ops 	= &s3cmci_ops;
-	mmc->ocr_avail	= MMC_VDD_32_33;
+	mmc->ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34;
 	mmc->caps	= MMC_CAP_4_BIT_DATA;
 	mmc->f_min 	= host->clk_rate / (host->clk_div * 256);
 	mmc->f_max 	= host->clk_rate / host->clk_div;
 
+	if (host->pdata->ocr_avail)
+		mmc->ocr_avail = host->pdata->ocr_avail;
+
 	mmc->max_blk_count	= 4095;
 	mmc->max_blk_size	= 4095;
 	mmc->max_req_size	= 4095 * 512;
Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.h
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.h	2008-06-30 12:31:15.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.h	2008-06-30 12:31:37.000000000 +0100
@@ -22,6 +22,7 @@ enum s3cmci_waitfor {
 
 struct s3cmci_host {
 	struct platform_device	*pdev;
+	struct s3c24xx_mci_pdata *pdata;
 	struct mmc_host		*mmc;
 	struct resource		*mem;
 	struct clk		*clk;
Index: linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h	2008-06-30 12:31:37.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ARCH_MCI_H
+#define _ARCH_MCI_H
+
+struct s3c24xx_mci_pdata {
+	unsigned int	gpio_detect;
+	unsigned int	gpio_wprotect;
+	unsigned long	ocr_avail;
+	void		(*set_power)(unsigned char power_mode,
+				     unsigned short vdd);
+};
+
+#endif /* _ARCH_NCI_H */

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 08/17] MMC: S3C24XX: Add support to invert write protect line
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (6 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 07/17] MMC: S3C24XX: Add platform data for MMC/SD driver Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 09/17] MMC: S3C24XX: Ensure host->mrq->data is valid Ben Dooks
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-roinvert.patch --]
[-- Type: text/plain, Size: 1614 bytes --]

Support for inverting the sense of the MMC driver's write
protect detection line.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:31:46.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:42.000000000 +0100
@@ -1083,11 +1083,18 @@ static void s3cmci_reset(struct s3cmci_h
 static int s3cmci_get_ro(struct mmc_host *mmc)
 {
 	struct s3cmci_host *host = mmc_priv(mmc);
+	struct s3c24xx_mci_pdata *pdata = host->pdata;
+	int ret;
 
-	if (host->pdata->gpio_wprotect == 0)
+	if (pdata->gpio_wprotect == 0)
 		return 0;
 
-	return s3c2410_gpio_getpin(host->pdata->gpio_wprotect);
+	ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);
+
+	if (pdata->wprotect_invert)
+		ret = !ret;
+
+	return ret;
 }
 
 static struct mmc_host_ops s3cmci_ops = {
Index: linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/include/asm-arm/plat-s3c24xx/mci.h	2008-06-30 12:31:37.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h	2008-06-30 12:36:42.000000000 +0100
@@ -2,6 +2,8 @@
 #define _ARCH_MCI_H
 
 struct s3c24xx_mci_pdata {
+	unsigned int	wprotect_invert : 1;
+
 	unsigned int	gpio_detect;
 	unsigned int	gpio_wprotect;
 	unsigned long	ocr_avail;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 09/17] MMC: S3C24XX: Ensure host->mrq->data is valid
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (7 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 08/17] MMC: S3C24XX: Add support to invert write protect line Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 10/17] MMC: S3C24XX: Allow card-detect on non-IRQ capable pin Ben Dooks
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-piotasklet-crashfix.patch --]
[-- Type: text/plain, Size: 821 bytes --]

Fix a crash if host->mrq->data is NULL on ending a transfer.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:42.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:49.000000000 +0100
@@ -353,7 +353,8 @@ static void pio_tasklet(unsigned long da
 			    (host->pio_active == XFER_READ) ? "read" : "write",
 			    host->pio_count, host->pio_words);
 
-			host->mrq->data->error = -EINVAL;
+			if (host->mrq->data)
+				host->mrq->data->error = -EINVAL;
 		}
 
 		finalize_request(host);

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 10/17] MMC: S3C24XX: Allow card-detect on non-IRQ capable pin
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (8 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 09/17] MMC: S3C24XX: Ensure host->mrq->data is valid Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 11/17] MMC: S3C24XX: Fix s3c2410_dma_request() return code check Ben Dooks
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-nocdirq.patch --]
[-- Type: text/plain, Size: 2355 bytes --]

Add support to the S3C24XX MMC driver to have the card detect be on
a pin that is not IRQ capable.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:49.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:51.000000000 +0100
@@ -1150,8 +1150,6 @@ static int __devinit s3cmci_probe(struct
 	host->pio_active 	= XFER_NONE;
 
 	host->dma		= S3CMCI_DMA;
-	host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
-	s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ);
 
 	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!host->mem) {
@@ -1197,14 +1195,20 @@ static int __devinit s3cmci_probe(struct
 
 	disable_irq(host->irq);
 
-	s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ);
-	set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
+	host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
 
-	if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) {
-		dev_err(&pdev->dev,
-			"failed to request card detect interrupt.\n");
-		ret = -ENOENT;
-		goto probe_free_irq;
+	if (host->irq_cd >= 0) {
+		if (request_irq(host->irq_cd, s3cmci_irq_cd,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				DRIVER_NAME, host)) {
+			dev_err(&pdev->dev, "can't get card detect irq.\n");
+			ret = -ENOENT;
+			goto probe_free_irq;
+		}
+	} else {
+		dev_warn(&pdev->dev, "host detect has no irq available\n");
+		s3c2410_gpio_cfgpin(host->pdata->gpio_detect,
+				    S3C2410_GPIO_INPUT);
 	}
 
 	if (host->pdata->gpio_wprotect)
@@ -1273,7 +1277,8 @@ static int __devinit s3cmci_probe(struct
 	clk_put(host->clk);
 
  probe_free_irq_cd:
-	free_irq(host->irq_cd, host);
+	if (host->irq_cd >= 0)
+		free_irq(host->irq_cd, host);
 
  probe_free_irq:
 	free_irq(host->irq, host);
@@ -1303,7 +1308,8 @@ static int s3cmci_remove(struct platform
 	tasklet_disable(&host->pio_tasklet);
 	s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client);
 
-	free_irq(host->irq_cd, host);
+	if (host->irq_cd >= 0)
+		free_irq(host->irq_cd, host);
 	free_irq(host->irq, host);
 
 	iounmap(host->base);

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 11/17] MMC: S3C24XX: Fix s3c2410_dma_request() return code check.
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (9 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 10/17] MMC: S3C24XX: Allow card-detect on non-IRQ capable pin Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:25 ` [patch v4 12/17] MMC: S3C24XX: Add MODULE_ALIAS() entries for the platform devices Ben Dooks
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-dma-retcode-fix.patch --]
[-- Type: text/plain, Size: 1023 bytes --]

The driver should be checking for a negative error code from
s3c2410_dma_request(), not non-zero. Newer kernels now return
the DMA channel number that was allocated by the request.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:51.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:53.000000000 +0100
@@ -1215,7 +1215,7 @@ static int __devinit s3cmci_probe(struct
 		s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
 				    S3C2410_GPIO_INPUT);
 
-	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) {
+	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
 		dev_err(&pdev->dev, "unable to get DMA channel.\n");
 		ret = -EBUSY;
 		goto probe_free_irq_cd;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 12/17] MMC: S3C24XX: Add MODULE_ALIAS() entries for the platform devices
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (10 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 11/17] MMC: S3C24XX: Fix s3c2410_dma_request() return code check Ben Dooks
@ 2008-06-30 15:25 ` Ben Dooks
  2008-06-30 15:26 ` [patch v4 13/17] MMC: S3C24XX: Fix use of msecs where jiffies are needed Ben Dooks
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:25 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-modalias.patch --]
[-- Type: text/plain, Size: 854 bytes --]

Add MODULE_ALIAS() declerations for all the supported platform
devices for this driver.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:53.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:55.000000000 +0100
@@ -1405,3 +1405,6 @@ module_exit(s3cmci_exit);
 MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>");
+MODULE_ALIAS("platform:s3c2410-sdi");
+MODULE_ALIAS("platform:s3c2412-sdi");
+MODULE_ALIAS("platform:s3c2440-sdi");

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 13/17] MMC: S3C24XX: Fix use of msecs where jiffies are needed
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (11 preceding siblings ...)
  2008-06-30 15:25 ` [patch v4 12/17] MMC: S3C24XX: Add MODULE_ALIAS() entries for the platform devices Ben Dooks
@ 2008-06-30 15:26 ` Ben Dooks
  2008-06-30 15:26 ` [patch v4 14/17] MMC: S3C24XX: Add media presence test to request handling Ben Dooks
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:26 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-detectchangefix.patch --]
[-- Type: text/plain, Size: 792 bytes --]

mmc_detect_change() takes jiffies, not msecs. Convert the
previous value of msecs into jiffies before calling.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:55.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:57.000000000 +0100
@@ -584,7 +584,7 @@ static irqreturn_t s3cmci_irq_cd(int irq
 
 	dbg(host, dbg_irq, "card detect\n");
 
-	mmc_detect_change(host->mmc, 500);
+	mmc_detect_change(host->mmc, msecs_to_jiffies(500));
 
 	return IRQ_HANDLED;
 }

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 14/17] MMC: S3C24XX: Add media presence test to request handling.
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (12 preceding siblings ...)
  2008-06-30 15:26 ` [patch v4 13/17] MMC: S3C24XX: Fix use of msecs where jiffies are needed Ben Dooks
@ 2008-06-30 15:26 ` Ben Dooks
  2008-06-30 15:26 ` [patch v4 15/17] MMC: S3C24XX: Update error debugging Ben Dooks
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:26 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-add-mediacheck.patch --]
[-- Type: text/plain, Size: 2127 bytes --]

Ensure that we have physical media present before attempting to
send a request to a card. This ensures that we do not get flooded
by errors from commands that can never be completed timing out.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:36:57.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 15:23:42.000000000 +0100
@@ -984,6 +984,18 @@ static void s3cmci_send_request(struct m
 	enable_irq(host->irq);
 }
 
+static int s3cmci_card_present(struct s3cmci_host *host)
+{
+	struct s3c24xx_mci_pdata *pdata = host->pdata;
+	int ret;
+
+	if (pdata->gpio_detect == 0)
+		return -ENOSYS;
+
+	ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1;
+	return ret ^ pdata->detect_invert;
+}
+
 static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct s3cmci_host *host = mmc_priv(mmc);
@@ -992,7 +1004,12 @@ static void s3cmci_request(struct mmc_ho
 	host->cmd_is_stop = 0;
 	host->mrq = mrq;
 
-	s3cmci_send_request(mmc);
+	if (s3cmci_card_present(host) == 0) {
+		dbg(host, dbg_err, "%s: no medium present\n", __func__);
+		host->mrq->cmd->error = -ENOMEDIUM;
+		mmc_request_done(mmc, mrq);
+	} else
+		s3cmci_send_request(mmc);
 }
 
 static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
Index: linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/include/asm-arm/plat-s3c24xx/mci.h	2008-06-30 12:36:42.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/include/asm-arm/plat-s3c24xx/mci.h	2008-06-30 12:37:19.000000000 +0100
@@ -3,6 +3,7 @@
 
 struct s3c24xx_mci_pdata {
 	unsigned int	wprotect_invert : 1;
+	unsigned int	detect_invert : 1;   /* set => detect active high. */
 
 	unsigned int	gpio_detect;
 	unsigned int	gpio_wprotect;

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 15/17] MMC: S3C24XX: Update error debugging.
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (13 preceding siblings ...)
  2008-06-30 15:26 ` [patch v4 14/17] MMC: S3C24XX: Add media presence test to request handling Ben Dooks
@ 2008-06-30 15:26 ` Ben Dooks
  2008-06-30 15:26 ` [patch v4 16/17] MMC: S3C24XX: Add maintainer entry Ben Dooks
  2008-06-30 15:26 ` [patch v4 17/17] MMC: S3C24XX: Ben Dooks
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:26 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-debug-errors.patch --]
[-- Type: text/plain, Size: 2680 bytes --]

Add better debugging to show where errors are being
generated, as some error codes can come from several
different code paths.

Also fix the error return path from s3cmci_setup_data()
to return the error it returned to the request.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 16:08:38.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 16:08:52.000000000 +0100
@@ -451,6 +451,7 @@ static irqreturn_t s3cmci_irq(int irq, v
 	}
 
 	if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
+		dbg(host, dbg_err, "CMDSTAT: error CMDTIMEOUT\n");
 		cmd->error = -ETIMEDOUT;
 		host->status = "error: command timeout";
 		goto fail_transfer;
@@ -506,12 +507,14 @@ static irqreturn_t s3cmci_irq(int irq, v
 	/* Check for FIFO failure */
 	if (host->is2440) {
 		if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
+			dbg(host, dbg_err, "FIFO failure\n");
 			host->mrq->data->error = -EILSEQ;
 			host->status = "error: 2440 fifo failure";
 			goto fail_transfer;
 		}
 	} else {
 		if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
+			dbg(host, dbg_err, "FIFO failure\n");
 			cmd->data->error = -EILSEQ;
 			host->status = "error:  fifo failure";
 			goto fail_transfer;
@@ -519,18 +522,21 @@ static irqreturn_t s3cmci_irq(int irq, v
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
+		dbg(host, dbg_err, "bad data crc (outgoing)\n");
 		cmd->data->error = -EILSEQ;
 		host->status = "error: bad data crc (outgoing)";
 		goto fail_transfer;
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {
+		dbg(host, dbg_err, "bad data crc (incoming)\n");
 		cmd->data->error = -EILSEQ;
 		host->status = "error: bad data crc (incoming)";
 		goto fail_transfer;
 	}
 
 	if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
+		dbg(host, dbg_err, "data timeout\n");
 		cmd->data->error = -ETIMEDOUT;
 		host->status = "error: data timeout";
 		goto fail_transfer;
@@ -957,8 +963,9 @@ static void s3cmci_send_request(struct m
 		host->dcnt++;
 
 		if (res) {
-			cmd->error = -EINVAL;
-			cmd->data->error = -EINVAL;
+			dbg(host, dbg_err, "setup data error %d\n", res);
+			cmd->error = res;
+			cmd->data->error = res;
 
 			mmc_request_done(mmc, mrq);
 			return;
@@ -970,6 +977,7 @@ static void s3cmci_send_request(struct m
 			res = s3cmci_prepare_pio(host, cmd->data);
 
 		if (res) {
+			dbg(host, dbg_err, "data prepare error %d\n", res);
 			cmd->error = res;
 			cmd->data->error = res;
 

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 16/17] MMC: S3C24XX: Add maintainer entry
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (14 preceding siblings ...)
  2008-06-30 15:26 ` [patch v4 15/17] MMC: S3C24XX: Update error debugging Ben Dooks
@ 2008-06-30 15:26 ` Ben Dooks
  2008-06-30 15:26 ` [patch v4 17/17] MMC: S3C24XX: Ben Dooks
  16 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:26 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-maintainer.patch --]
[-- Type: text/plain, Size: 832 bytes --]

Add Ben Dooks as S3C24XX SD/MMC driver maintainer.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/MAINTAINERS
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/MAINTAINERS	2008-06-30 12:14:40.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/MAINTAINERS	2008-06-30 12:37:25.000000000 +0100
@@ -3544,6 +3544,13 @@ L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
 
+S3C24XX SD/MMC Driver
+P:	Ben Dooks
+M:	ben-linux@fluff.org
+L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+
 SAA7146 VIDEO4LINUX-2 DRIVER
 P:	Michael Hunold
 M:	michael@mihu.de

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [patch v4 17/17] MMC: S3C24XX:
  2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
                   ` (15 preceding siblings ...)
  2008-06-30 15:26 ` [patch v4 16/17] MMC: S3C24XX: Add maintainer entry Ben Dooks
@ 2008-06-30 15:26 ` Ben Dooks
  2008-06-30 15:36   ` Ben Dooks
  16 siblings, 1 reply; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:26 UTC (permalink / raw)
  To: linux-kernel, drzeus-mmc; +Cc: tk, laforge, Ben Dooks

[-- Attachment #1: simtec/s3c24xx-sdmmc-check-unaligned.patch --]
[-- Type: text/plain, Size: 1175 bytes --]

The hardware does not support any multi-block transfers
with an block-size that is not aligned. Also the driver
itself does not support single block non-32bit transfers
either.

Ensure that the s3cmci_setup_data() returns the appropriate
error if we encounter this.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

Index: linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c
===================================================================
--- linux-2.6.26-rc8-next20080627.orig/drivers/mmc/host/s3cmci.c	2008-06-30 12:38:22.000000000 +0100
+++ linux-2.6.26-rc8-next20080627/drivers/mmc/host/s3cmci.c	2008-06-30 12:38:46.000000000 +0100
@@ -808,6 +808,17 @@ static int s3cmci_setup_data(struct s3cm
 		return 0;
 	}
 
+	if ((data->blksz & 3) != 0) {
+		/* We cannot deal with unaligned blocks with more than
+		 * one block being transfered. */
+
+		if (data->blocks > 1)
+			return -EINVAL;
+
+		/* No support yet for non-word block transfers. */
+		return -EINVAL;
+	}
+
 	while (readl(host->base + S3C2410_SDIDSTA) &
 	       (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
 

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 17/17] MMC: S3C24XX:
  2008-06-30 15:26 ` [patch v4 17/17] MMC: S3C24XX: Ben Dooks
@ 2008-06-30 15:36   ` Ben Dooks
  2008-06-30 15:50     ` Pierre Ossman
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 15:36 UTC (permalink / raw)
  To: Ben Dooks; +Cc: linux-kernel, drzeus-mmc, tk, laforge

On Mon, Jun 30, 2008 at 04:26:04PM +0100, Ben Dooks wrote:

Should I resend this one, or the entire series with the 
subject line of this patch corrected?

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 15:25 ` [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver Ben Dooks
@ 2008-06-30 15:50   ` Pierre Ossman
  2008-06-30 16:15     ` Ben Dooks
  0 siblings, 1 reply; 28+ messages in thread
From: Pierre Ossman @ 2008-06-30 15:50 UTC (permalink / raw)
  To: Ben Dooks; +Cc: linux-kernel, tk, laforge, Ben Dooks

On Mon, 30 Jun 2008 16:25:49 +0100
Ben Dooks <ben-linux@fluff.org> wrote:

> Fix the checkpatch and other problems pointed out by
> akpm.
> 
> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
> 

I prefer to have this one merged into 01 as you'll end up with a commit
that you cannot compile otherwise. Besides, running checkpatch is
something you do before submitting anyway, not as a separate cleanup. :)

-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  rdesktop, core developer          http://www.rdesktop.org

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 17/17] MMC: S3C24XX:
  2008-06-30 15:36   ` Ben Dooks
@ 2008-06-30 15:50     ` Pierre Ossman
  0 siblings, 0 replies; 28+ messages in thread
From: Pierre Ossman @ 2008-06-30 15:50 UTC (permalink / raw)
  To: Ben Dooks; +Cc: Ben Dooks, linux-kernel, tk, laforge

On Mon, 30 Jun 2008 16:36:11 +0100
Ben Dooks <ben-linux@fluff.org> wrote:

> On Mon, Jun 30, 2008 at 04:26:04PM +0100, Ben Dooks wrote:
> 
> Should I resend this one, or the entire series with the 
> subject line of this patch corrected?
> 

That's ok. I can fix it up manually.

-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  rdesktop, core developer          http://www.rdesktop.org

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 15:50   ` Pierre Ossman
@ 2008-06-30 16:15     ` Ben Dooks
  2008-06-30 16:36       ` Harald Welte
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 16:15 UTC (permalink / raw)
  To: Pierre Ossman; +Cc: Ben Dooks, linux-kernel, tk, laforge

On Mon, Jun 30, 2008 at 05:50:18PM +0200, Pierre Ossman wrote:
> On Mon, 30 Jun 2008 16:25:49 +0100
> Ben Dooks <ben-linux@fluff.org> wrote:
> 
> > Fix the checkpatch and other problems pointed out by
> > akpm.
> > 
> > Signed-off-by: Ben Dooks <ben-linux@fluff.org>
> > 
> 
> I prefer to have this one merged into 01 as you'll end up with a commit
> that you cannot compile otherwise. Besides, running checkpatch is
> something you do before submitting anyway, not as a separate cleanup. :)

In this case I kept it seperate as the cleanups where done by myself
as the original driver authour is not interested or too busy to do
these himself. Basically, I was trying to keep the driver and my own
cleanup work seperate.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 16:15     ` Ben Dooks
@ 2008-06-30 16:36       ` Harald Welte
  2008-06-30 17:02         ` Thomas Kleffel
  2008-06-30 17:04         ` Ben Dooks
  0 siblings, 2 replies; 28+ messages in thread
From: Harald Welte @ 2008-06-30 16:36 UTC (permalink / raw)
  To: Ben Dooks; +Cc: Pierre Ossman, linux-kernel, tk

On Mon, Jun 30, 2008 at 05:15:37PM +0100, Ben Dooks wrote:
> On Mon, Jun 30, 2008 at 05:50:18PM +0200, Pierre Ossman wrote:
> > On Mon, 30 Jun 2008 16:25:49 +0100
> > Ben Dooks <ben-linux@fluff.org> wrote:
> > 
> > > Fix the checkpatch and other problems pointed out by
> > > akpm.
> > > 
> > > Signed-off-by: Ben Dooks <ben-linux@fluff.org>
> > > 
> > 
> > I prefer to have this one merged into 01 as you'll end up with a commit
> > that you cannot compile otherwise. Besides, running checkpatch is
> > something you do before submitting anyway, not as a separate cleanup. :)
> 
> In this case I kept it seperate as the cleanups where done by myself
> as the original driver authour is not interested or too busy to do
> these himself. Basically, I was trying to keep the driver and my own
> cleanup work seperate.

don't worry about that.  Thomas Kleffel is unlikely to return to do any
active work on it (I know him personally), and the OpenMoko community
will inevitably rebase its patches based on whatever ends up in
mainline.  So nobody is worried if you merge all that stuff into one
patch.  It's probably polite to add the significant contributors (such
as yourself and myself) to the list of authors at the beginning of the
file though - given the amount of changes the driver has received
compared to Tomas' original.

Thanks for all your work,
-- 
- Harald Welte <laforge@openmoko.org>          	        http://openmoko.org/
============================================================================
Software for the world's first truly open Free Software mobile phone

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 16:36       ` Harald Welte
@ 2008-06-30 17:02         ` Thomas Kleffel
  2008-06-30 17:31           ` Ben Dooks
  2008-06-30 17:04         ` Ben Dooks
  1 sibling, 1 reply; 28+ messages in thread
From: Thomas Kleffel @ 2008-06-30 17:02 UTC (permalink / raw)
  To: Harald Welte; +Cc: Ben Dooks, Pierre Ossman, linux-kernel

Hi,
> don't worry about that.  Thomas Kleffel is unlikely to return to do any
> active work on it (I know him personally), and the OpenMoko community
> will inevitably rebase its patches based on whatever ends up in
> mainline.  So nobody is worried if you merge all that stuff into one
> patch.  It's probably polite to add the significant contributors (such
> as yourself and myself) to the list of authors at the beginning of the
> file though - given the amount of changes the driver has received
> compared to Tomas' original.
>   
Harald is 100% right. I have absolutely no time at all to maintain this 
driver and I haven't worked on it (or any other SD/MMC related stuff) 
for almost two years now.

I'd like to thank Harald, Ben, Pierre and all others who are working 
hard to get the driver merged.

See you,

Thomas Kleffel




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 16:36       ` Harald Welte
  2008-06-30 17:02         ` Thomas Kleffel
@ 2008-06-30 17:04         ` Ben Dooks
  2008-06-30 18:10           ` Pierre Ossman
  1 sibling, 1 reply; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 17:04 UTC (permalink / raw)
  To: Harald Welte; +Cc: Ben Dooks, Pierre Ossman, linux-kernel, tk

On Tue, Jul 01, 2008 at 12:36:01AM +0800, Harald Welte wrote:
> On Mon, Jun 30, 2008 at 05:15:37PM +0100, Ben Dooks wrote:
> > On Mon, Jun 30, 2008 at 05:50:18PM +0200, Pierre Ossman wrote:
> > > On Mon, 30 Jun 2008 16:25:49 +0100
> > > Ben Dooks <ben-linux@fluff.org> wrote:
> > > 
> > > > Fix the checkpatch and other problems pointed out by
> > > > akpm.
> > > > 
> > > > Signed-off-by: Ben Dooks <ben-linux@fluff.org>
> > > > 
> > > 
> > > I prefer to have this one merged into 01 as you'll end up with a commit
> > > that you cannot compile otherwise. Besides, running checkpatch is
> > > something you do before submitting anyway, not as a separate cleanup. :)
> > 
> > In this case I kept it seperate as the cleanups where done by myself
> > as the original driver authour is not interested or too busy to do
> > these himself. Basically, I was trying to keep the driver and my own
> > cleanup work seperate.
> 
> don't worry about that.  Thomas Kleffel is unlikely to return to do any
> active work on it (I know him personally), and the OpenMoko community
> will inevitably rebase its patches based on whatever ends up in
> mainline.  So nobody is worried if you merge all that stuff into one
> patch.  It's probably polite to add the significant contributors (such
> as yourself and myself) to the list of authors at the beginning of the
> file though - given the amount of changes the driver has received
> compared to Tomas' original.

Thanks, having an public discussion about the position of the original
authour is useful. I was intending on submitting a patch once this lot
is merged to add myself and select others to the driver after the fact
so that everyone can acknowledge it.

You have missed part of the point. My extra work is not a small
set of changes which won't get counted when profiling the Kernel
contributors. My employers have given me time to sort these
items out, and we do get work off the fact that we're shown to be in
the leading contributors (iirc, 18th last-year) so I was trying to
ensure that this wasn't lost.

If Pierre or Thomas has objections to either then the series can
be reposted with #1 and #2 merged together.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 17:02         ` Thomas Kleffel
@ 2008-06-30 17:31           ` Ben Dooks
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 17:31 UTC (permalink / raw)
  To: Thomas Kleffel; +Cc: Harald Welte, Ben Dooks, Pierre Ossman, linux-kernel

On Mon, Jun 30, 2008 at 07:02:42PM +0200, Thomas Kleffel wrote:
> Hi,
> >don't worry about that.  Thomas Kleffel is unlikely to return to do any
> >active work on it (I know him personally), and the OpenMoko community
> >will inevitably rebase its patches based on whatever ends up in
> >mainline.  So nobody is worried if you merge all that stuff into one
> >patch.  It's probably polite to add the significant contributors (such
> >as yourself and myself) to the list of authors at the beginning of the
> >file though - given the amount of changes the driver has received
> >compared to Tomas' original.
> >  
> Harald is 100% right. I have absolutely no time at all to maintain this 
> driver and I haven't worked on it (or any other SD/MMC related stuff) 
> for almost two years now.
> 
> I'd like to thank Harald, Ben, Pierre and all others who are working 
> hard to get the driver merged.

Thanks for your original work. I suppose I should add a signed-off-by:
line from you to the original driver.
 
> See you,
> 
> Thomas Kleffel

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 17:04         ` Ben Dooks
@ 2008-06-30 18:10           ` Pierre Ossman
  2008-06-30 19:07             ` Ben Dooks
  0 siblings, 1 reply; 28+ messages in thread
From: Pierre Ossman @ 2008-06-30 18:10 UTC (permalink / raw)
  To: Ben Dooks; +Cc: Harald Welte, Ben Dooks, linux-kernel, tk

On Mon, 30 Jun 2008 18:04:08 +0100
Ben Dooks <ben-linux@fluff.org> wrote:

> 
> You have missed part of the point. My extra work is not a small
> set of changes which won't get counted when profiling the Kernel
> contributors. My employers have given me time to sort these
> items out, and we do get work off the fact that we're shown to be in
> the leading contributors (iirc, 18th last-year) so I was trying to
> ensure that this wasn't lost.
> 

I can appreciate that, but I do not want a commit in the tree that
doesn't even compile. You don't have to merge in all the other ones
(which should give you a reasonable blip in the statistics), but at
least #1 and #2.

-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  rdesktop, core developer          http://www.rdesktop.org

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver
  2008-06-30 18:10           ` Pierre Ossman
@ 2008-06-30 19:07             ` Ben Dooks
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Dooks @ 2008-06-30 19:07 UTC (permalink / raw)
  To: Pierre Ossman; +Cc: Ben Dooks, Harald Welte, linux-kernel, tk

On Mon, Jun 30, 2008 at 08:10:19PM +0200, Pierre Ossman wrote:
> On Mon, 30 Jun 2008 18:04:08 +0100
> Ben Dooks <ben-linux@fluff.org> wrote:
> 
> > 
> > You have missed part of the point. My extra work is not a small
> > set of changes which won't get counted when profiling the Kernel
> > contributors. My employers have given me time to sort these
> > items out, and we do get work off the fact that we're shown to be in
> > the leading contributors (iirc, 18th last-year) so I was trying to
> > ensure that this wasn't lost.
> > 
> 
> I can appreciate that, but I do not want a commit in the tree that
> doesn't even compile. You don't have to merge in all the other ones
> (which should give you a reasonable blip in the statistics), but at
> least #1 and #2.

Ok, I'll sort out reposting this.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2008-06-30 19:07 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-30 15:25 [patch v4 00/17] S3C24XX SD/MMC maintainer Ben Dooks
2008-06-30 15:25 ` [patch v4 01/17] MMC: S3C24XX MMC/SD driver Ben Dooks
2008-06-30 15:25 ` [patch v4 02/17] MMC: S3C24XX: Fix the checkpatch.pl errors in the s3cmci driver Ben Dooks
2008-06-30 15:50   ` Pierre Ossman
2008-06-30 16:15     ` Ben Dooks
2008-06-30 16:36       ` Harald Welte
2008-06-30 17:02         ` Thomas Kleffel
2008-06-30 17:31           ` Ben Dooks
2008-06-30 17:04         ` Ben Dooks
2008-06-30 18:10           ` Pierre Ossman
2008-06-30 19:07             ` Ben Dooks
2008-06-30 15:25 ` [patch v4 03/17] MMC: S3C24XX MMC/SD driver write fixes Ben Dooks
2008-06-30 15:25 ` [patch v4 04/17] MMC: DMA free fix for S3C24XX SD/MMC driver Ben Dooks
2008-06-30 15:25 ` [patch v4 05/17] MMC: S3C24XX MMC/SD stop fix Ben Dooks
2008-06-30 15:25 ` [patch v4 06/17] MMC: Fix S3C24XX IRQ enable during PIO transfers Ben Dooks
2008-06-30 15:25 ` [patch v4 07/17] MMC: S3C24XX: Add platform data for MMC/SD driver Ben Dooks
2008-06-30 15:25 ` [patch v4 08/17] MMC: S3C24XX: Add support to invert write protect line Ben Dooks
2008-06-30 15:25 ` [patch v4 09/17] MMC: S3C24XX: Ensure host->mrq->data is valid Ben Dooks
2008-06-30 15:25 ` [patch v4 10/17] MMC: S3C24XX: Allow card-detect on non-IRQ capable pin Ben Dooks
2008-06-30 15:25 ` [patch v4 11/17] MMC: S3C24XX: Fix s3c2410_dma_request() return code check Ben Dooks
2008-06-30 15:25 ` [patch v4 12/17] MMC: S3C24XX: Add MODULE_ALIAS() entries for the platform devices Ben Dooks
2008-06-30 15:26 ` [patch v4 13/17] MMC: S3C24XX: Fix use of msecs where jiffies are needed Ben Dooks
2008-06-30 15:26 ` [patch v4 14/17] MMC: S3C24XX: Add media presence test to request handling Ben Dooks
2008-06-30 15:26 ` [patch v4 15/17] MMC: S3C24XX: Update error debugging Ben Dooks
2008-06-30 15:26 ` [patch v4 16/17] MMC: S3C24XX: Add maintainer entry Ben Dooks
2008-06-30 15:26 ` [patch v4 17/17] MMC: S3C24XX: Ben Dooks
2008-06-30 15:36   ` Ben Dooks
2008-06-30 15:50     ` Pierre Ossman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox