r3793 - developers/sameo/patches/ar6k-ng
sameo at sita.openmoko.org
sameo at sita.openmoko.org
Wed Jan 9 12:48:18 CET 2008
Author: sameo
Date: 2008-01-09 12:48:17 +0100 (Wed, 09 Jan 2008)
New Revision: 3793
Added:
developers/sameo/patches/ar6k-ng/115-s3cmci_sdio.patch
Log:
ar6k-ng: Forgot to add the mci patch.
Added: developers/sameo/patches/ar6k-ng/115-s3cmci_sdio.patch
===================================================================
--- developers/sameo/patches/ar6k-ng/115-s3cmci_sdio.patch 2008-01-09 10:43:34 UTC (rev 3792)
+++ developers/sameo/patches/ar6k-ng/115-s3cmci_sdio.patch 2008-01-09 11:48:17 UTC (rev 3793)
@@ -0,0 +1,422 @@
+---
+ drivers/mmc/host/s3cmci.c | 156 +++++++++++++++++++++++++++++++---------------
+ drivers/mmc/host/s3cmci.h | 6 +
+ 2 files changed, 112 insertions(+), 50 deletions(-)
+
+Index: linux-2.6.22-atheros-ng/drivers/mmc/host/s3cmci.c
+===================================================================
+--- linux-2.6.22-atheros-ng.orig/drivers/mmc/host/s3cmci.c 2007-12-21 16:24:25.000000000 +0100
++++ linux-2.6.22-atheros-ng/drivers/mmc/host/s3cmci.c 2007-12-21 16:25:44.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <linux/mmc/host.h>
+ #include <linux/platform_device.h>
+ #include <linux/timer.h>
++#include <linux/delay.h>
+ #include <linux/irq.h>
+
+ #include <asm/dma.h>
+@@ -44,7 +45,7 @@
+
+ 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;
++static const int dbgmap_debug = dbg_debug | dbg_pio;
+
+ #define dbg(host, channels, args...) \
+ if (dbgmap_err & channels) \
+@@ -159,7 +160,7 @@
+ u32 newmask;
+
+ newmask = readl(host->base + host->sdiimsk);
+- newmask|= imask;
++ newmask |= imask;
+
+ writel(newmask, host->base + host->sdiimsk);
+
+@@ -180,11 +181,14 @@
+
+ static inline void clear_imask(struct s3cmci_host *host)
+ {
+- writel(0, host->base + host->sdiimsk);
++ if (host->sdio_int)
++ writel(S3C2410_SDIIMSK_SDIOIRQ, host->base + host->sdiimsk);
++ else
++ writel(0, host->base + host->sdiimsk);
+ }
+
+ static inline int get_data_buffer(struct s3cmci_host *host,
+- volatile u32 *words, volatile u32 **pointer)
++ volatile u32 *bytes, volatile u8 **pointer)
+ {
+ struct scatterlist *sg;
+
+@@ -201,7 +205,7 @@
+ }
+ sg = &host->mrq->data->sg[host->pio_sgptr];
+
+- *words = sg->length >> 2;
++ *bytes = sg->length;
+ *pointer= page_address(sg->page) + sg->offset;
+
+ host->pio_sgptr++;
+@@ -212,8 +216,8 @@
+ 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)
++#define FIFO_FILL(host) ((readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK))
++#define FIFO_FREE(host) ((63 - (readl(host->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK)))
+
+ static inline void do_pio_read(struct s3cmci_host *host)
+ {
+@@ -227,9 +231,9 @@
+ 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 (!host->pio_bytes) {
++ res = get_data_buffer(host, &host->pio_bytes,
++ &host->pio_ptr);
+ if (res) {
+ host->pio_active = XFER_NONE;
+ host->complete_what = COMPLETION_FINALIZE;
+@@ -240,27 +244,26 @@
+ }
+
+ dbg(host, dbg_pio, "pio_read(): new target: [%i]@[%p]\n",
+- host->pio_words, host->pio_ptr);
++ host->pio_bytes, host->pio_ptr);
+ }
+
+ dbg(host, dbg_pio, "pio_read(): fifo:[%02i] "
+ "buffer:[%03i] dcnt:[%08X]\n",
+- fifo, host->pio_words,
++ fifo, host->pio_bytes,
+ readl(host->base + S3C2410_SDIDCNT));
+
+- if (fifo > host->pio_words)
+- fifo = host->pio_words;
++ if (fifo > host->pio_bytes)
++ fifo = host->pio_bytes;
+
+- host->pio_words-= fifo;
+- host->pio_count+= fifo;
++ host->pio_bytes -= fifo;
++ host->pio_count += fifo;
+
+- while(fifo--) {
+- *(host->pio_ptr++) = readl(from_ptr);
+- }
++ while(fifo--)
++ *(host->pio_ptr++) = readb(from_ptr);
+ }
+
+- if (!host->pio_words) {
+- res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
++ if (!host->pio_bytes) {
++ res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);
+ if (res) {
+ dbg(host, dbg_pio, "pio_read(): "
+ "complete (no more buffers).\n");
+@@ -284,9 +287,9 @@
+ 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 (!host->pio_bytes) {
++ res = get_data_buffer(host, &host->pio_bytes,
++ &host->pio_ptr);
+ if (res) {
+ dbg(host, dbg_pio, "pio_write(): "
+ "complete (no more data).\n");
+@@ -297,18 +300,18 @@
+
+ dbg(host, dbg_pio, "pio_write(): "
+ "new source: [%i]@[%p]\n",
+- host->pio_words, host->pio_ptr);
++ host->pio_bytes, host->pio_ptr);
+
+ }
+
+- if (fifo > host->pio_words)
+- fifo = host->pio_words;
++ if (fifo > host->pio_bytes)
++ fifo = host->pio_bytes;
+
+- host->pio_words-= fifo;
+- host->pio_count+= fifo;
++ host->pio_bytes -= fifo;
++ host->pio_count += fifo;
+
+ while(fifo--) {
+- writel(*(host->pio_ptr++), to_ptr);
++ writeb(*(host->pio_ptr++), to_ptr);
+ }
+ }
+
+@@ -331,9 +334,9 @@
+ clear_imask(host);
+ if (host->pio_active != XFER_NONE) {
+ dbg(host, dbg_err, "unfinished %s "
+- "- pio_count:[%u] pio_words:[%u]\n",
++ "- pio_count:[%u] pio_bytes:[%u]\n",
+ (host->pio_active == XFER_READ)?"read":"write",
+- host->pio_count, host->pio_words);
++ host->pio_count, host->pio_bytes);
+
+ host->mrq->data->error = -EIO;
+ }
+@@ -376,6 +379,7 @@
+ struct mmc_command *cmd;
+ u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
+ u32 mci_cclear, mci_dclear;
++ int cardint = 0;
+ unsigned long iflags;
+
+ host = (struct s3cmci_host *)dev_id;
+@@ -390,8 +394,19 @@
+ mci_cclear = 0;
+ mci_dclear = 0;
+
++ if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
++ if (host->sdio_int) {
++ disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
++ cardint = 1;
++ host->sdio_pending_int = 0;
++ } else {
++ host->sdio_pending_int = 1;
++ }
++ mci_dclear |= S3C2410_SDIDSTA_SDIOIRQDETECT;
++ }
++
+ 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;
+@@ -413,7 +428,7 @@
+
+ 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);
+@@ -468,8 +483,10 @@
+ goto close_transfer;
+ }
+
+- if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
++ if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) {
+ host->complete_what = COMPLETION_XFERFINISH;
++ host->status = "ok: command response received, xfer to be done";
++ }
+
+ mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
+ }
+@@ -550,6 +567,10 @@
+ mci_dcnt, host->status);
+
+ spin_unlock_irqrestore(&host->complete_lock, iflags);
++
++ /* We have to delay this as it calls back into the driver */
++ if (cardint)
++ mmc_signal_sdio_irq(host->mmc);
+ return IRQ_HANDLED;
+
+ }
+@@ -671,7 +692,7 @@
+ writel(0, host->base + S3C2410_SDICMDARG);
+ writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
+ writel(0, host->base + S3C2410_SDICMDCON);
+- writel(0, host->base + host->sdiimsk);
++ clear_imask(host);
+
+ if (cmd->data && cmd->error)
+ cmd->data->error = cmd->error;
+@@ -711,7 +732,7 @@
+
+ //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);
+ }
+@@ -776,6 +797,9 @@
+ if (cmd->flags & MMC_RSP_136)
+ ccon|= S3C2410_SDICMDCON_LONGRSP;
+
++ if (cmd->data)
++ ccon |= S3C2410_SDICMDCON_WITHDATA;
++
+ writel(ccon, host->base + S3C2410_SDICMDCON);
+ }
+
+@@ -833,7 +857,8 @@
+ }
+
+ if (host->is2440) {
+- dcon |= S3C2440_SDIDCON_DS_WORD;
++ dcon |= S3C2440_SDIDCON_DS_BYTE;
++// dcon |= S3C2440_SDIDCON_DS_WORD;
+ dcon |= S3C2440_SDIDCON_DATSTART;
+ }
+
+@@ -858,12 +883,11 @@
+
+ //FIX: set slow clock to prevent timeouts on read
+ if (data->flags & MMC_DATA_READ) {
++ printk("######## FIX ########## \n");
+ writel(0xFF, host->base + S3C2410_SDIPRE);
+ }
+ }
+
+- //debug_dump_registers(host, "Data setup:");
+-
+ return 0;
+ }
+
+@@ -875,7 +899,7 @@
+ return -EINVAL;
+
+ host->pio_sgptr = 0;
+- host->pio_words = 0;
++ host->pio_bytes = 0;
+ host->pio_count = 0;
+ host->pio_active = rw?XFER_WRITE:XFER_READ;
+
+@@ -1019,7 +1043,7 @@
+ host->pdata->set_power(ios->power_mode, ios->vdd);
+
+ if (!host->is2440)
+- mci_con|=S3C2410_SDICON_FIFORESET;
++ mci_con |= S3C2410_SDICON_FIFORESET;
+
+ break;
+
+@@ -1032,7 +1056,7 @@
+ host->pdata->set_power(ios->power_mode, ios->vdd);
+
+ if (host->is2440)
+- mci_con|=S3C2440_SDICON_SDRESET;
++ mci_con |= S3C2440_SDICON_SDRESET;
+
+ break;
+ }
+@@ -1060,9 +1084,11 @@
+ else
+ mci_con &=~S3C2410_SDICON_CLOCKTYPE;
+
++ mci_con |= S3C2410_SDICON_SDIOIRQ;
++
+ writel(mci_con, host->base + S3C2410_SDICON);
+
+- if ((ios->power_mode==MMC_POWER_ON)
++ if ((ios->power_mode == MMC_POWER_ON)
+ || (ios->power_mode==MMC_POWER_UP)) {
+
+ dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",
+@@ -1094,10 +1120,39 @@
+ return s3c2410_gpio_getpin(host->pdata->gpio_wprotect);
+ }
+
++void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
++{
++ struct s3cmci_host *host = mmc_priv(mmc);
++ u32 con, imask;
++
++ con = readl(host->base + S3C2410_SDICON);
++ imask = readl(host->base + host->sdiimsk);
++
++ if (enable) {
++ host->sdio_int = 1;
++ con |= S3C2410_SDICON_SDIOIRQ;
++ imask |= S3C2410_SDIIMSK_SDIOIRQ;
++ if (host->sdio_pending_int) {
++ printk("We have a pending INT\n");
++ mmc_signal_sdio_irq(host->mmc);
++ host->sdio_pending_int = 0;
++ }
++ } else {
++
++ host->sdio_int = 0;
++ con &= ~S3C2410_SDICON_SDIOIRQ;
++ imask &= ~S3C2410_SDIIMSK_SDIOIRQ;
++ }
++
++ writel(imask, host->base + host->sdiimsk);
++ writel(con, host->base + S3C2410_SDICON);
++}
++
+ static struct mmc_host_ops s3cmci_ops = {
+- .request = s3cmci_request,
+- .set_ios = s3cmci_set_ios,
+- .get_ro = s3cmci_get_ro,
++ .request = s3cmci_request,
++ .set_ios = s3cmci_set_ios,
++ .get_ro = s3cmci_get_ro,
++ .enable_sdio_irq = s3cmci_enable_sdio_irq,
+ };
+
+ static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
+@@ -1143,6 +1198,7 @@
+ host->sdidata = S3C2410_SDIDATA;
+ host->clk_div = 2;
+ }
++ host->sdio_int = 0;
+ host->dodma = 0;
+ host->complete_what = COMPLETION_NONE;
+ host->pio_active = XFER_NONE;
+@@ -1229,7 +1285,7 @@
+
+ mmc->ops = &s3cmci_ops;
+ mmc->ocr_avail = host->pdata->ocr_avail;
+- mmc->caps = MMC_CAP_4_BIT_DATA;
++ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+ mmc->f_min = host->clk_rate / (host->clk_div * 256);
+ mmc->f_max = host->clk_rate / host->clk_div;
+
+@@ -1250,6 +1306,10 @@
+ goto free_dmabuf;
+ }
+
++
++// mdelay(1000);
++ mmc_detect_change(host->mmc, 500);
++
+ platform_set_drvdata(pdev, mmc);
+
+ dev_info(&pdev->dev,"initialisation done.\n");
+Index: linux-2.6.22-atheros-ng/drivers/mmc/host/s3cmci.h
+===================================================================
+--- linux-2.6.22-atheros-ng.orig/drivers/mmc/host/s3cmci.h 2007-12-21 16:24:29.000000000 +0100
++++ linux-2.6.22-atheros-ng/drivers/mmc/host/s3cmci.h 2007-12-21 16:24:32.000000000 +0100
+@@ -40,6 +40,8 @@
+ unsigned sdiimsk;
+ unsigned sdidata;
+ int dodma;
++ int sdio_int;
++ int sdio_pending_int;
+
+ volatile int dmatogo;
+
+@@ -53,9 +55,9 @@
+ volatile int dma_complete;
+
+ volatile u32 pio_sgptr;
+- volatile u32 pio_words;
++ volatile u32 pio_bytes;
+ volatile u32 pio_count;
+- volatile u32 *pio_ptr;
++ volatile u8 *pio_ptr;
+ #define XFER_NONE 0
+ #define XFER_READ 1
+ #define XFER_WRITE 2
More information about the commitlog
mailing list