diff options
author | Paul Eggleton <bluelightning@bluelightning.org> | 2012-01-09 01:03:59 +0000 |
---|---|---|
committer | Paul Eggleton <paul.eggleton@linux.intel.com> | 2012-01-22 23:16:41 +0000 |
commit | 7469f0737aaefafd513f760b6847c29140027bc6 (patch) | |
tree | ae47db06d6c58d1c6aacc361d92f3ed32f9b0e54 /recipes-kernel | |
parent | f14a97ee1ee05726ed8d4b2be0ad9fe3d6823b36 (diff) | |
download | meta-handheld-7469f0737aaefafd513f760b6847c29140027bc6.tar.gz |
linux_3.1: add patches for h1940
Add kernel patches for h1940 by Vasily Koruzhick <anarsoul@gmail.com>
Signed-off-by: Paul Eggleton <bluelightning@bluelightning.org>
Diffstat (limited to 'recipes-kernel')
14 files changed, 1488 insertions, 10 deletions
diff --git a/recipes-kernel/linux/linux-3.1/h1940/0001-s3c24xx-DMA-don-t-use-autoreload-feature.patch b/recipes-kernel/linux/linux-3.1/h1940/0001-s3c24xx-DMA-don-t-use-autoreload-feature.patch new file mode 100644 index 0000000..6e277fe --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0001-s3c24xx-DMA-don-t-use-autoreload-feature.patch @@ -0,0 +1,680 @@ +From 5b11095906d31d6e362447e2368da874260b41db Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Mon, 28 Nov 2011 00:15:59 +0300 +Subject: [PATCH 01/12] s3c24xx: DMA: don't use autoreload feature + +Some integrated DMA-capable hardware doesn't like autoreload +feature of s3c24xx DMA-engine, that's why s3cmci driver +didn't work with DMA transfers enabled. + +I rewrote DMA driver not to use autoreload feature and removed +all pre-loading features. Buffer re-load is fast enought to perform +it in IRQ handler, and anyway I don't see any reason to waste CPU +cycles on waiting for buffer load. Driver is much simplier now, +it was tested with s3cmci and s3c24xx-i2s drivers on s3c2442 and +s3c2410 SoCs and works just nice. + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/include/mach/dma.h | 15 +- + arch/arm/plat-s3c24xx/dma.c | 440 +++++------------------------- + 2 files changed, 69 insertions(+), 386 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h +index b2b2a5b..2d1ab2f 100644 +--- a/arch/arm/mach-s3c2410/include/mach/dma.h ++++ b/arch/arm/mach-s3c2410/include/mach/dma.h +@@ -79,28 +79,15 @@ enum s3c2410_dma_state { + * + * There are no buffers loaded (the channel should be inactive) + * +- * S3C2410_DMA_1LOADED +- * +- * There is one buffer loaded, however it has not been confirmed to be +- * loaded by the DMA engine. This may be because the channel is not +- * yet running, or the DMA driver decided that it was too costly to +- * sit and wait for it to happen. +- * + * S3C2410_DMA_1RUNNING + * +- * The buffer has been confirmed running, and not finisged +- * +- * S3C2410_DMA_1LOADED_1RUNNING ++ * The buffer has been confirmed running, and not finished + * +- * There is a buffer waiting to be loaded by the DMA engine, and one +- * currently running. + */ + + enum s3c2410_dma_loadst { + S3C2410_DMALOAD_NONE, +- S3C2410_DMALOAD_1LOADED, + S3C2410_DMALOAD_1RUNNING, +- S3C2410_DMALOAD_1LOADED_1RUNNING, + }; + + +diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c +index 539bd0e..79b3d6dae 100644 +--- a/arch/arm/plat-s3c24xx/dma.c ++++ b/arch/arm/plat-s3c24xx/dma.c +@@ -133,70 +133,6 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) + #define dbg_showchan(chan) do { } while(0) + #endif /* CONFIG_S3C2410_DMA_DEBUG */ + +-/* s3c2410_dma_stats_timeout +- * +- * Update DMA stats from timeout info +-*/ +- +-static void +-s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val) +-{ +- if (stats == NULL) +- return; +- +- if (val > stats->timeout_longest) +- stats->timeout_longest = val; +- if (val < stats->timeout_shortest) +- stats->timeout_shortest = val; +- +- stats->timeout_avg += val; +-} +- +-/* s3c2410_dma_waitforload +- * +- * wait for the DMA engine to load a buffer, and update the state accordingly +-*/ +- +-static int +-s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line) +-{ +- int timeout = chan->load_timeout; +- int took; +- +- if (chan->load_state != S3C2410_DMALOAD_1LOADED) { +- printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line); +- return 0; +- } +- +- if (chan->stats != NULL) +- chan->stats->loads++; +- +- while (--timeout > 0) { +- if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) { +- took = chan->load_timeout - timeout; +- +- s3c2410_dma_stats_timeout(chan->stats, took); +- +- switch (chan->load_state) { +- case S3C2410_DMALOAD_1LOADED: +- chan->load_state = S3C2410_DMALOAD_1RUNNING; +- break; +- +- default: +- printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state); +- } +- +- return 1; +- } +- } +- +- if (chan->stats != NULL) { +- chan->stats->timeout_failed++; +- } +- +- return 0; +-} +- + /* s3c2410_dma_loadbuffer + * + * load a buffer, and update the channel state +@@ -206,66 +142,33 @@ static inline int + s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, + struct s3c2410_dma_buf *buf) + { +- unsigned long reload; +- + if (buf == NULL) { + dmawarn("buffer is NULL\n"); + return -EINVAL; + } + +- pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n", ++ pr_debug("%s: loading buff %p (0x%08lx,0x%06x)\n", __func__, + buf, (unsigned long)buf->data, buf->size); + + /* check the state of the channel before we do anything */ + +- if (chan->load_state == S3C2410_DMALOAD_1LOADED) { +- dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n"); +- } +- +- if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) { +- dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n"); +- } ++ if (chan->load_state != S3C2410_DMALOAD_NONE) ++ printk(KERN_ERR "dma%d: channel already has buffer loaded\n", ++ chan->number); + +- /* it would seem sensible if we are the last buffer to not bother +- * with the auto-reload bit, so that the DMA engine will not try +- * and load another transfer after this one has finished... +- */ +- if (chan->load_state == S3C2410_DMALOAD_NONE) { +- pr_debug("load_state is none, checking for noreload (next=%p)\n", +- buf->next); +- reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0; +- } else { +- //pr_debug("load_state is %d => autoreload\n", chan->load_state); +- reload = S3C2410_DCON_AUTORELOAD; +- } +- +- if ((buf->data & 0xf0000000) != 0x30000000) { ++ if ((buf->data & 0xf0000000) != 0x30000000) + dmawarn("dmaload: buffer is %p\n", (void *)buf->data); +- } + + writel(buf->data, chan->addr_reg); + + dma_wrreg(chan, S3C2410_DMA_DCON, +- chan->dcon | reload | (buf->size/chan->xfer_unit)); ++ chan->dcon | S3C2410_DCON_NORELOAD | ++ (buf->size/chan->xfer_unit)); + +- chan->next = buf->next; ++ chan->curr = buf; + + /* update the state of the channel */ +- +- switch (chan->load_state) { +- case S3C2410_DMALOAD_NONE: +- chan->load_state = S3C2410_DMALOAD_1LOADED; +- break; +- +- case S3C2410_DMALOAD_1RUNNING: +- chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING; +- break; +- +- default: +- dmawarn("dmaload: unknown state %d in loadbuffer\n", +- chan->load_state); +- break; +- } ++ chan->load_state = S3C2410_DMALOAD_1RUNNING; + + return 0; + } +@@ -345,7 +248,6 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) + dbg_showchan(chan); + + /* enable the channel */ +- + if (!chan->irq_enabled) { + enable_irq(chan->irq); + chan->irq_enabled = 1; +@@ -360,14 +262,6 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) + + pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp); + +-#if 0 +- /* the dma buffer loads should take care of clearing the AUTO +- * reloading feature */ +- tmp = dma_rdreg(chan, S3C2410_DMA_DCON); +- tmp &= ~S3C2410_DCON_NORELOAD; +- dma_wrreg(chan, S3C2410_DMA_DCON, tmp); +-#endif +- + s3c2410_dma_call_op(chan, S3C2410_DMAOP_START); + + dbg_showchan(chan); +@@ -377,43 +271,11 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) + * the first buffer is finished, the new one will be loaded onto + * the channel */ + +- if (chan->next != NULL) { +- if (chan->load_state == S3C2410_DMALOAD_1LOADED) { +- +- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { +- pr_debug("%s: buff not yet loaded, no more todo\n", +- __func__); +- } else { +- chan->load_state = S3C2410_DMALOAD_1RUNNING; +- s3c2410_dma_loadbuffer(chan, chan->next); +- } +- +- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) { +- s3c2410_dma_loadbuffer(chan, chan->next); +- } +- } +- +- + local_irq_restore(flags); + + return 0; + } + +-/* s3c2410_dma_canload +- * +- * work out if we can queue another buffer into the DMA engine +-*/ +- +-static int +-s3c2410_dma_canload(struct s3c2410_dma_chan *chan) +-{ +- if (chan->load_state == S3C2410_DMALOAD_NONE || +- chan->load_state == S3C2410_DMALOAD_1RUNNING) +- return 1; +- +- return 0; +-} +- + /* s3c2410_dma_enqueue + * + * queue an given buffer for dma transfer. +@@ -462,47 +324,19 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, + + local_irq_save(flags); + +- if (chan->curr == NULL) { +- /* we've got nothing loaded... */ +- pr_debug("%s: buffer %p queued onto empty channel\n", +- __func__, buf); +- +- chan->curr = buf; +- chan->end = buf; +- chan->next = NULL; ++ if (chan->end == NULL) { ++ pr_debug("dma%d: queued buffer onto empty channel\n", ++ chan->number); ++ chan->next = buf; ++ chan->end = buf; + } else { +- pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", +- chan->number, __func__, buf); +- +- if (chan->end == NULL) +- pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", +- chan->number, __func__, chan); +- ++ pr_debug("dma%d: queued buffer onto non-empty channel\n", ++ chan->number); + chan->end->next = buf; + chan->end = buf; + } + +- /* if necessary, update the next buffer field */ +- if (chan->next == NULL) +- chan->next = buf; +- +- /* check to see if we can load a buffer */ +- if (chan->state == S3C2410_DMA_RUNNING) { +- if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) { +- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { +- printk(KERN_ERR "dma%d: loadbuffer:" +- "timeout loading buffer\n", +- chan->number); +- dbg_showchan(chan); +- local_irq_restore(flags); +- return -EINVAL; +- } +- } +- +- while (s3c2410_dma_canload(chan) && chan->next != NULL) { +- s3c2410_dma_loadbuffer(chan, chan->next); +- } +- } else if (chan->state == S3C2410_DMA_IDLE) { ++ if (chan->state == S3C2410_DMA_IDLE) { + if (chan->flags & S3C2410_DMAF_AUTOSTART) { + s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, + S3C2410_DMAOP_START); +@@ -529,51 +363,6 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf) + } + } + +-/* s3c2410_dma_lastxfer +- * +- * called when the system is out of buffers, to ensure that the channel +- * is prepared for shutdown. +-*/ +- +-static inline void +-s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) +-{ +-#if 0 +- pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", +- chan->number, chan->load_state); +-#endif +- +- switch (chan->load_state) { +- case S3C2410_DMALOAD_NONE: +- break; +- +- case S3C2410_DMALOAD_1LOADED: +- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { +- /* flag error? */ +- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", +- chan->number, __func__); +- return; +- } +- break; +- +- case S3C2410_DMALOAD_1LOADED_1RUNNING: +- /* I believe in this case we do not have anything to do +- * until the next buffer comes along, and we turn off the +- * reload */ +- return; +- +- default: +- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n", +- chan->number, chan->load_state); +- return; +- +- } +- +- /* hopefully this'll shut the damned thing up after the transfer... */ +- dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD); +-} +- +- + #define dmadbg2(x...) + + static irqreturn_t +@@ -582,57 +371,25 @@ s3c2410_dma_irq(int irq, void *devpw) + struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw; + struct s3c2410_dma_buf *buf; + ++ /* Check for orphaned irq */ ++ if (chan->state == S3C2410_DMA_IDLE) ++ return IRQ_HANDLED; ++ + buf = chan->curr; + + dbg_showchan(chan); + + /* modify the channel state */ + +- switch (chan->load_state) { +- case S3C2410_DMALOAD_1RUNNING: +- /* TODO - if we are running only one buffer, we probably +- * want to reload here, and then worry about the buffer +- * callback */ +- +- chan->load_state = S3C2410_DMALOAD_NONE; +- break; +- +- case S3C2410_DMALOAD_1LOADED: +- /* iirc, we should go back to NONE loaded here, we +- * had a buffer, and it was never verified as being +- * loaded. +- */ +- ++ if (chan->load_state == S3C2410_DMALOAD_1RUNNING) + chan->load_state = S3C2410_DMALOAD_NONE; +- break; +- +- case S3C2410_DMALOAD_1LOADED_1RUNNING: +- /* we'll worry about checking to see if another buffer is +- * ready after we've called back the owner. This should +- * ensure we do not wait around too long for the DMA +- * engine to start the next transfer +- */ +- +- chan->load_state = S3C2410_DMALOAD_1LOADED; +- break; +- +- case S3C2410_DMALOAD_NONE: ++ else + printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n", +- chan->number); +- break; +- +- default: +- printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n", +- chan->number, chan->load_state); +- break; +- } ++ chan->number); + + if (buf != NULL) { +- /* update the chain to make sure that if we load any more +- * buffers when we call the callback function, things should +- * work properly */ +- +- chan->curr = buf->next; ++ chan->curr = NULL; ++ chan->next = buf->next; + buf->next = NULL; + + if (buf->magic != BUF_MAGIC) { +@@ -640,12 +397,10 @@ s3c2410_dma_irq(int irq, void *devpw) + chan->number, __func__, buf); + return IRQ_HANDLED; + } +- + s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK); + + /* free resouces */ + s3c2410_dma_freebuf(buf); +- } else { + } + + /* only reload if the channel is still running... our buffer done +@@ -655,53 +410,36 @@ s3c2410_dma_irq(int irq, void *devpw) + /* todo: check that when the channel is shut-down from inside this + * function, we cope with unsetting reload, etc */ + +- if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) { +- unsigned long flags; +- +- switch (chan->load_state) { +- case S3C2410_DMALOAD_1RUNNING: +- /* don't need to do anything for this state */ +- break; +- +- case S3C2410_DMALOAD_NONE: +- /* can load buffer immediately */ +- break; +- +- case S3C2410_DMALOAD_1LOADED: +- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { +- /* flag error? */ +- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", +- chan->number, __func__); +- return IRQ_HANDLED; +- } +- +- break; +- +- case S3C2410_DMALOAD_1LOADED_1RUNNING: +- goto no_load; +- +- default: +- printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n", +- chan->number, chan->load_state); +- return IRQ_HANDLED; +- } ++ if (chan->next != NULL) { ++ if (chan->state != S3C2410_DMA_IDLE) { ++ unsigned long flags; ++ unsigned long tmp; + +- local_irq_save(flags); +- s3c2410_dma_loadbuffer(chan, chan->next); +- local_irq_restore(flags); ++ pr_debug("%s: dma%d: continuing with next buffer\n", ++ __func__, chan->number); ++ local_irq_save(flags); ++ s3c2410_dma_loadbuffer(chan, chan->next); ++ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); ++ tmp &= ~S3C2410_DMASKTRIG_STOP; ++ tmp |= S3C2410_DMASKTRIG_ON; ++ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); ++ local_irq_restore(flags); ++ } else ++ pr_debug("dma%d: buffdone callback stopped dma...\n", ++ chan->number); + } else { +- s3c2410_dma_lastxfer(chan); ++ /* No more buffers? So no queue */ ++ chan->end = NULL; + + /* see if we can stop this channel.. */ +- if (chan->load_state == S3C2410_DMALOAD_NONE) { +- pr_debug("dma%d: end of transfer, stopping channel (%ld)\n", ++ if (chan->state != S3C2410_DMA_IDLE) { ++ pr_debug("dma%d: end of transfer, stopping channel (%lu)\n", + chan->number, jiffies); + s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, + S3C2410_DMAOP_STOP); + } + } + +- no_load: + return IRQ_HANDLED; + } + +@@ -840,9 +578,20 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) + s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP); + + tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); +- tmp |= S3C2410_DMASKTRIG_STOP; +- //tmp &= ~S3C2410_DMASKTRIG_ON; +- dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); ++ if (tmp & S3C2410_DMASKTRIG_ON) { ++ int retries = 1000; ++ tmp |= S3C2410_DMASKTRIG_STOP; ++ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); ++ ++ while (--retries) { ++ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); ++ if (!(tmp & S3C2410_DMASKTRIG_ON)) ++ break; ++ } ++ ++ if (!retries) ++ pr_debug("dma%d: failed to stop??\n", chan->number); ++ } + + #if 0 + /* should also clear interrupts, according to WinCE BSP */ +@@ -860,22 +609,6 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) + return 0; + } + +-static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) +-{ +- unsigned long tmp; +- unsigned int timeout = 0x10000; +- +- while (timeout-- > 0) { +- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); +- +- if (!(tmp & S3C2410_DMASKTRIG_ON)) +- return; +- } +- +- pr_debug("dma%d: failed to stop?\n", chan->number); +-} +- +- + /* s3c2410_dma_flush + * + * stop the channel, and remove all current and pending transfers +@@ -917,8 +650,6 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) + + dbg_showregs(chan); + +- s3c2410_dma_waitforstop(chan); +- + #if 0 + /* should also clear interrupts, according to WinCE BSP */ + { +@@ -939,38 +670,8 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) + + static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) + { +- unsigned long flags; +- +- local_irq_save(flags); +- +- dbg_showchan(chan); +- +- /* if we've only loaded one buffer onto the channel, then chec +- * to see if we have another, and if so, try and load it so when +- * the first buffer is finished, the new one will be loaded onto +- * the channel */ +- +- if (chan->next != NULL) { +- if (chan->load_state == S3C2410_DMALOAD_1LOADED) { +- +- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { +- pr_debug("%s: buff not yet loaded, no more todo\n", +- __func__); +- } else { +- chan->load_state = S3C2410_DMALOAD_1RUNNING; +- s3c2410_dma_loadbuffer(chan, chan->next); +- } +- +- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) { +- s3c2410_dma_loadbuffer(chan, chan->next); +- } +- } +- +- +- local_irq_restore(flags); +- ++ /* Do nothing */ + return 0; +- + } + + int +@@ -1041,16 +742,12 @@ int s3c2410_dma_config(enum dma_ch channel, + case DMACH_PCM_IN: + case DMACH_PCM_OUT: + case DMACH_MIC_IN: ++ case DMACH_SDI: + default: + dcon |= S3C2410_DCON_HANDSHAKE; + dcon |= S3C2410_DCON_SYNC_PCLK; + break; + +- case DMACH_SDI: +- /* note, ensure if need HANDSHAKE or not */ +- dcon |= S3C2410_DCON_SYNC_PCLK; +- break; +- + case DMACH_XD0: + case DMACH_XD1: + dcon |= S3C2410_DCON_HANDSHAKE; +@@ -1228,20 +925,19 @@ static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp) + { + unsigned int no = cp->number | DMACH_LOW_LEVEL; + +- /* restore channel's hardware configuration */ +- + if (!cp->in_use) + return; + +- printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); +- +- s3c2410_dma_config(no, cp->xfer_unit); +- s3c2410_dma_devconfig(no, cp->source, cp->dev_addr); +- + /* re-select the dma source for this channel */ + + if (cp->map != NULL) + dma_sel.select(cp, cp->map); ++ ++ /* restore channel's hardware configuration */ ++ printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); ++ s3c2410_dma_config(no, cp->xfer_unit); ++ s3c2410_dma_devconfig(no, cp->source, cp->dev_addr); ++ + } + + static void s3c2410_dma_resume(void) +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0002-s3cmci-minor-fixups.patch b/recipes-kernel/linux/linux-3.1/h1940/0002-s3cmci-minor-fixups.patch new file mode 100644 index 0000000..8703012 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0002-s3cmci-minor-fixups.patch @@ -0,0 +1,40 @@ +From 3275ee65bcfbb86aecb7c7c98512124c591bc5dc Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Fri, 13 Aug 2010 20:01:53 +0300 +Subject: [PATCH 02/12] s3cmci: minor fixups + +- It's not necessary to start DMA op manually, as we have +autostart feature enabled +- Restore prescaler before DMA operation, otherwise it +takes ages to complete DMA op. + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + drivers/mmc/host/s3cmci.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c +index a04f87d..f37fc35 100644 +--- a/drivers/mmc/host/s3cmci.c ++++ b/drivers/mmc/host/s3cmci.c +@@ -1106,6 +1106,8 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); + ++ /* Restore prescaler value */ ++ writel(host->prescaler, host->base + S3C2410_SDIPRE); + res = s3c2410_dma_enqueue(host->dma, host, + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); +@@ -1116,8 +1118,6 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) + } + } + +- s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START); +- + return 0; + } + +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0003-ARM-s3c2410-drop-RFKILL-driver-for-H1940-bluetooth.patch b/recipes-kernel/linux/linux-3.1/h1940/0003-ARM-s3c2410-drop-RFKILL-driver-for-H1940-bluetooth.patch new file mode 100644 index 0000000..dc43a66 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0003-ARM-s3c2410-drop-RFKILL-driver-for-H1940-bluetooth.patch @@ -0,0 +1,237 @@ +From 5e42d393f09ff0804f3c1c115eb11fc6b73d8944 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Thu, 1 Dec 2011 22:15:38 +0300 +Subject: [PATCH 03/12] ARM: s3c2410: drop RFKILL driver for H1940 bluetooth + +rfkill-gpio can do it's job easily. + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/Kconfig | 8 -- + arch/arm/mach-s3c2410/Makefile | 1 - + arch/arm/mach-s3c2410/h1940-bluetooth.c | 157 ------------------------------- + arch/arm/mach-s3c2410/mach-h1940.c | 6 - + 4 files changed, 0 insertions(+), 172 deletions(-) + delete mode 100644 arch/arm/mach-s3c2410/h1940-bluetooth.c + +diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig +index 7245a55..281dc03 100644 +--- a/arch/arm/mach-s3c2410/Kconfig ++++ b/arch/arm/mach-s3c2410/Kconfig +@@ -81,14 +81,6 @@ config ARCH_H1940 + help + Say Y here if you are using the HP IPAQ H1940 + +-config H1940BT +- tristate "Control the state of H1940 bluetooth chip" +- depends on ARCH_H1940 +- select RFKILL +- help +- This is a simple driver that is able to control +- the state of built in bluetooth chip on h1940. +- + config PM_H1940 + bool + help +diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile +index 8169535..c1e5ce6 100644 +--- a/arch/arm/mach-s3c2410/Makefile ++++ b/arch/arm/mach-s3c2410/Makefile +@@ -21,7 +21,6 @@ obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o + + obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o + obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +-obj-$(CONFIG_H1940BT) += h1940-bluetooth.o + obj-$(CONFIG_PM_H1940) += pm-h1940.o + obj-$(CONFIG_MACH_N30) += mach-n30.o + obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o +diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c +deleted file mode 100644 +index a5eeb62..0000000 +--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c ++++ /dev/null +@@ -1,157 +0,0 @@ +-/* +- * arch/arm/mach-s3c2410/h1940-bluetooth.c +- * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org> +- * +- * This file is subject to the terms and conditions of the GNU General Public +- * License. See the file COPYING in the main directory of this archive for +- * more details. +- * +- * S3C2410 bluetooth "driver" +- * +- */ +- +-#include <linux/module.h> +-#include <linux/platform_device.h> +-#include <linux/delay.h> +-#include <linux/string.h> +-#include <linux/ctype.h> +-#include <linux/leds.h> +-#include <linux/gpio.h> +-#include <linux/rfkill.h> +- +-#include <mach/regs-gpio.h> +-#include <mach/hardware.h> +-#include <mach/h1940-latch.h> +-#include <mach/h1940.h> +- +-#define DRV_NAME "h1940-bt" +- +-/* Bluetooth control */ +-static void h1940bt_enable(int on) +-{ +- if (on) { +- /* Power on the chip */ +- gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1); +- /* Reset the chip */ +- mdelay(10); +- +- gpio_set_value(S3C2410_GPH(1), 1); +- mdelay(10); +- gpio_set_value(S3C2410_GPH(1), 0); +- +- h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL); +- } +- else { +- gpio_set_value(S3C2410_GPH(1), 1); +- mdelay(10); +- gpio_set_value(S3C2410_GPH(1), 0); +- mdelay(10); +- gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0); +- +- h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL); +- } +-} +- +-static int h1940bt_set_block(void *data, bool blocked) +-{ +- h1940bt_enable(!blocked); +- return 0; +-} +- +-static const struct rfkill_ops h1940bt_rfkill_ops = { +- .set_block = h1940bt_set_block, +-}; +- +-static int __devinit h1940bt_probe(struct platform_device *pdev) +-{ +- struct rfkill *rfk; +- int ret = 0; +- +- ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev)); +- if (ret) { +- dev_err(&pdev->dev, "could not get GPH1\n"); +- return ret; +- } +- +- ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev)); +- if (ret) { +- gpio_free(S3C2410_GPH(1)); +- dev_err(&pdev->dev, "could not get BT_POWER\n"); +- return ret; +- } +- +- /* Configures BT serial port GPIOs */ +- s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); +- s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); +- s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); +- s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); +- s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); +- s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); +- s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); +- s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); +- +- rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, +- &h1940bt_rfkill_ops, NULL); +- if (!rfk) { +- ret = -ENOMEM; +- goto err_rfk_alloc; +- } +- +- ret = rfkill_register(rfk); +- if (ret) +- goto err_rfkill; +- +- platform_set_drvdata(pdev, rfk); +- +- return 0; +- +-err_rfkill: +- rfkill_destroy(rfk); +-err_rfk_alloc: +- return ret; +-} +- +-static int h1940bt_remove(struct platform_device *pdev) +-{ +- struct rfkill *rfk = platform_get_drvdata(pdev); +- +- platform_set_drvdata(pdev, NULL); +- gpio_free(S3C2410_GPH(1)); +- +- if (rfk) { +- rfkill_unregister(rfk); +- rfkill_destroy(rfk); +- } +- rfk = NULL; +- +- h1940bt_enable(0); +- +- return 0; +-} +- +- +-static struct platform_driver h1940bt_driver = { +- .driver = { +- .name = DRV_NAME, +- }, +- .probe = h1940bt_probe, +- .remove = h1940bt_remove, +-}; +- +- +-static int __init h1940bt_init(void) +-{ +- return platform_driver_register(&h1940bt_driver); +-} +- +-static void __exit h1940bt_exit(void) +-{ +- platform_driver_unregister(&h1940bt_driver); +-} +- +-module_init(h1940bt_init); +-module_exit(h1940bt_exit); +- +-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); +-MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip"); +-MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index 2a2fa06..3bb42dd 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -445,11 +445,6 @@ static struct platform_device h1940_device_leds = { + }, + }; + +-static struct platform_device h1940_device_bluetooth = { +- .name = "h1940-bt", +- .id = -1, +-}; +- + static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd) + { + switch (power_mode) { +@@ -637,7 +632,6 @@ static struct platform_device *h1940_devices[] __initdata = { + &samsung_asoc_dma, + &s3c_device_usbgadget, + &h1940_device_leds, +- &h1940_device_bluetooth, + &s3c_device_sdi, + &s3c_device_rtc, + &s3c_device_timer[0], +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0004-mtd-nand-s3c2410-add-iPAQ-specific-layout.patch b/recipes-kernel/linux/linux-3.1/h1940/0004-mtd-nand-s3c2410-add-iPAQ-specific-layout.patch new file mode 100644 index 0000000..dd9898c --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0004-mtd-nand-s3c2410-add-iPAQ-specific-layout.patch @@ -0,0 +1,28 @@ +From 0d5bfdca2afa65fc2125766ca6a7643edf0e7d72 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sun, 18 Dec 2011 11:48:46 +0300 +Subject: [PATCH 04/12] mtd: nand: s3c2410: add iPAQ specific layout + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + drivers/mtd/nand/s3c2410.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c +index 4405468..71eeb5b 100644 +--- a/drivers/mtd/nand/s3c2410.c ++++ b/drivers/mtd/nand/s3c2410.c +@@ -66,8 +66,8 @@ static const int clock_stop = 0; + + static struct nand_ecclayout nand_hw_eccoob = { + .eccbytes = 3, +- .eccpos = {0, 1, 2}, +- .oobfree = {{8, 8}} ++ .eccpos = {8, 9, 10}, ++ .oobfree = {{2, 6}, {11, 5}} + }; + + /* controller and mtd information */ +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0005-ARM-s3c2410-Add-nand-device-for-h1940.patch b/recipes-kernel/linux/linux-3.1/h1940/0005-ARM-s3c2410-Add-nand-device-for-h1940.patch new file mode 100644 index 0000000..fdab3a9 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0005-ARM-s3c2410-Add-nand-device-for-h1940.patch @@ -0,0 +1,114 @@ +From a28513d09d1400b4a1953216a8364577babe95af Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Thu, 1 Dec 2011 22:19:33 +0300 +Subject: [PATCH 05/12] ARM: s3c2410: Add nand device for h1940 + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 62 ++++++++++++++++++++++++++++++++++++ + 1 files changed, 62 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index 3bb42dd..7e3cea9 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -32,6 +32,9 @@ + #include <linux/s3c_adc_battery.h> + #include <linux/delay.h> + ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++ + #include <video/platform_lcd.h> + + #include <linux/mmc/host.h> +@@ -66,6 +69,7 @@ + #include <plat/pm.h> + #include <plat/mci.h> + #include <plat/ts.h> ++#include <plat/nand.h> + + #include <sound/uda1380.h> + +@@ -467,6 +471,62 @@ static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = { + .ocr_avail = MMC_VDD_32_33, + }; + ++static struct mtd_partition h1940_nand_part[] = { ++ [0] = { ++ .name = "Boot0", ++ .offset = 0, ++ .size = SZ_16K, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ [1] = { ++ .name = "Boot1", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_1K * 240, ++ .mask_flags = 0, ++ }, ++ [2] = { ++ .name = "Env", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_16K, ++ .mask_flags = 0, ++ }, ++ [3] = { ++ .name = "Opts", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_32K, ++ .mask_flags = 0, ++ }, ++ [4] = { ++ .name = "Kernel", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_1M * 3, ++ .mask_flags = 0, ++ }, ++ [5] = { ++ .name = "Filesystem", ++ .offset = MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL, ++ .mask_flags = 0, ++ }, ++}; ++ ++static struct s3c2410_nand_set h1940_nand_sets[] = { ++ [0] = { ++ .name = "Internal", ++ .nr_chips = 1, ++ .nr_partitions = ARRAY_SIZE(h1940_nand_part), ++ .partitions = h1940_nand_part, ++ }, ++}; ++ ++static struct s3c2410_platform_nand h1940_nand_info = { ++ .tacls = 14, ++ .twrph0 = 44, ++ .twrph1 = 20, ++ .nr_sets = ARRAY_SIZE(h1940_nand_sets), ++ .sets = h1940_nand_sets, ++}; ++ + static int h1940_backlight_init(struct device *dev) + { + gpio_request(S3C2410_GPB(0), "Backlight"); +@@ -634,6 +694,7 @@ static struct platform_device *h1940_devices[] __initdata = { + &h1940_device_leds, + &s3c_device_sdi, + &s3c_device_rtc, ++ &s3c_device_nand, + &s3c_device_timer[0], + &h1940_backlight, + &h1940_lcd_powerdev, +@@ -682,6 +743,7 @@ static void __init h1940_init(void) + s3c24xx_udc_set_platdata(&h1940_udc_cfg); + s3c24xx_ts_set_platdata(&h1940_ts_cfg); + s3c_i2c0_set_platdata(NULL); ++ s3c_nand_set_platdata(&h1940_nand_info); + + /* Turn off suspend on both USB ports, and switch the + * selectable USB port to USB device mode. */ +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0006-ARM-s3c2410-h1940-don-t-touch-UPLLCON.patch b/recipes-kernel/linux/linux-3.1/h1940/0006-ARM-s3c2410-h1940-don-t-touch-UPLLCON.patch new file mode 100644 index 0000000..5ff95ff --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0006-ARM-s3c2410-h1940-don-t-touch-UPLLCON.patch @@ -0,0 +1,41 @@ +From b74e51276ed2c69f7c4857dfd12256e0e8bfb532 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Thu, 1 Dec 2011 22:20:28 +0300 +Subject: [PATCH 06/12] ARM: s3c2410: h1940: don't touch UPLLCON + +It's a bit late to modify UPLLCON in board init, +anyway bootloader already puts correct value in it. + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 7 ------- + 1 files changed, 0 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index 7e3cea9..3d85e36 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -736,8 +736,6 @@ static void __init h1940_init_irq(void) + + static void __init h1940_init(void) + { +- u32 tmp; +- + s3c24xx_fb_set_platdata(&h1940_fb_info); + s3c24xx_mci_set_platdata(&h1940_mmc_cfg); + s3c24xx_udc_set_platdata(&h1940_udc_cfg); +@@ -752,11 +750,6 @@ static void __init h1940_init(void) + S3C2410_MISCCR_USBSUSPND0 | + S3C2410_MISCCR_USBSUSPND1, 0x0); + +- tmp = (0x78 << S3C24XX_PLLCON_MDIVSHIFT) +- | (0x02 << S3C24XX_PLLCON_PDIVSHIFT) +- | (0x03 << S3C24XX_PLLCON_SDIVSHIFT); +- writel(tmp, S3C2410_UPLLCON); +- + gpio_request(S3C2410_GPC(0), "LCD power"); + gpio_request(S3C2410_GPC(1), "LCD power"); + gpio_request(S3C2410_GPC(4), "LCD power"); +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0007-ARM-s3c2410-unlock-reset-button-on-H1940.patch b/recipes-kernel/linux/linux-3.1/h1940/0007-ARM-s3c2410-unlock-reset-button-on-H1940.patch new file mode 100644 index 0000000..05d0325 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0007-ARM-s3c2410-unlock-reset-button-on-H1940.patch @@ -0,0 +1,49 @@ +From 4b645096c91e62dceff9add8cfb85e3b96932077 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sat, 3 Dec 2011 12:12:21 +0300 +Subject: [PATCH 07/12] ARM: s3c2410: unlock reset button on H1940 + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 17 +++++++++++++++-- + 1 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index 3d85e36..f1764ff 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -220,9 +220,9 @@ static struct s3c2410fb_mach_info h1940_fb_info __initdata = { + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + .gpdcon = 0xaa84aaa0, +- .gpdcon_mask = 0xffffffff, ++ .gpdcon_mask = 0xfffffff3, + .gpdup = 0x0000faff, +- .gpdup_mask = 0xffffffff, ++ .gpdup_mask = 0xfffffffd, + }; + + static int power_supply_init(struct device *dev) +@@ -787,6 +787,19 @@ static void __init h1940_init(void) + gpio_direction_output(S3C2410_GPA(7), 0); + gpio_direction_output(H1940_LATCH_LED_FLASH, 0); + ++ gpio_request(S3C2410_GPD(1), "Reset sense"); ++ gpio_request(S3C2410_GPA(14), "Reset reset"); ++ gpio_request(S3C2410_GPB(6), "Reset lock"); ++ gpio_direction_input(S3C2410_GPD(1)); ++ gpio_direction_output(S3C2410_GPA(14), 0); ++ if (gpio_get_value(S3C2410_GPD(1))) ++ gpio_set_value(S3C2410_GPA(14), 0); ++ ++ gpio_direction_output(S3C2410_GPA(14), 1); ++ mdelay(100); ++ gpio_direction_output(S3C2410_GPB(6), 1); ++ gpio_direction_output(S3C2410_GPB(6), 0); ++ + i2c_register_board_info(0, h1940_i2c_devices, + ARRAY_SIZE(h1940_i2c_devices)); + } +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0008-ARM-h1940-add-bluetooth-RF-kill-switch.patch b/recipes-kernel/linux/linux-3.1/h1940/0008-ARM-h1940-add-bluetooth-RF-kill-switch.patch new file mode 100644 index 0000000..6ca5693 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0008-ARM-h1940-add-bluetooth-RF-kill-switch.patch @@ -0,0 +1,75 @@ +From 00e890820c8d50198da2de86361cc2da7df9b5aa Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sat, 17 Dec 2011 13:14:51 +0300 +Subject: [PATCH 08/12] ARM: h1940: add bluetooth RF kill switch + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 30 ++++++++++++++++++++++++++++++ + 1 files changed, 30 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index f1764ff..95f231f 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -31,6 +31,7 @@ + #include <linux/pda_power.h> + #include <linux/s3c_adc_battery.h> + #include <linux/delay.h> ++#include <linux/rfkill-gpio.h> + + #include <linux/mtd/mtd.h> + #include <linux/mtd/partitions.h> +@@ -682,6 +683,21 @@ static struct platform_device h1940_dev_buttons = { + } + }; + ++static struct rfkill_gpio_platform_data h1940_bt_rfkill_pdata = { ++ .name = "h1940-bt", ++ .reset_gpio = -EINVAL, ++ .shutdown_gpio = H1940_LATCH_BLUETOOTH_POWER, ++ .type = RFKILL_TYPE_BLUETOOTH, ++}; ++ ++static struct platform_device h1940_bluetooth = { ++ .name = "rfkill_gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &h1940_bt_rfkill_pdata, ++ }, ++}; ++ + static struct platform_device *h1940_devices[] __initdata = { + &h1940_dev_buttons, + &s3c_device_ohci, +@@ -702,6 +718,7 @@ static struct platform_device *h1940_devices[] __initdata = { + &s3c_device_ts, + &power_supply, + &h1940_battery, ++ &h1940_bluetooth, + }; + + static void __init h1940_map_io(void) +@@ -776,6 +793,19 @@ static void __init h1940_init(void) + gpio_request(H1940_LATCH_SD_POWER, "SD power"); + gpio_direction_output(H1940_LATCH_SD_POWER, 0); + ++ /* Configures BT serial port GPIOs */ ++ s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); ++ s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); ++ s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPH1_nRTS0); ++ s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); ++ s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); ++ s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); ++ s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); ++ s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); ++ ++ gpio_request(S3C2410_GPC(9), "BT reset"); ++ gpio_direction_output(S3C2410_GPC(9), 1); ++ + platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); + + gpio_request(S3C2410_GPA(1), "Red LED blink"); +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0009-rfkill-add-IR-type.patch b/recipes-kernel/linux/linux-3.1/h1940/0009-rfkill-add-IR-type.patch new file mode 100644 index 0000000..813a907 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0009-rfkill-add-IR-type.patch @@ -0,0 +1,51 @@ +From 3d9ad82e01b03f6eec431e45c3ad711d94c55d89 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sun, 18 Dec 2011 11:30:22 +0300 +Subject: [PATCH 09/12] rfkill: add IR type + +Infrared receivers/transmitters can also be disabled, +so add IR type to rfkill subsystem + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + include/linux/rfkill.h | 1 + + net/rfkill/core.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h +index c6c6084..f7b30c6 100644 +--- a/include/linux/rfkill.h ++++ b/include/linux/rfkill.h +@@ -48,6 +48,7 @@ enum rfkill_type { + RFKILL_TYPE_WWAN, + RFKILL_TYPE_GPS, + RFKILL_TYPE_FM, ++ RFKILL_TYPE_IR, + NUM_RFKILL_TYPES, + }; + +diff --git a/net/rfkill/core.c b/net/rfkill/core.c +index be90640..e13f756 100644 +--- a/net/rfkill/core.c ++++ b/net/rfkill/core.c +@@ -566,7 +566,7 @@ static ssize_t rfkill_name_show(struct device *dev, + + static const char *rfkill_get_type_str(enum rfkill_type type) + { +- BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_FM + 1); ++ BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_IR + 1); + + switch (type) { + case RFKILL_TYPE_WLAN: +@@ -583,6 +583,8 @@ static const char *rfkill_get_type_str(enum rfkill_type type) + return "gps"; + case RFKILL_TYPE_FM: + return "fm"; ++ case RFKILL_TYPE_IR: ++ return "ir"; + default: + BUG(); + } +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0010-rfkill_gpio-add-support-for-inverted-GPIOs.patch b/recipes-kernel/linux/linux-3.1/h1940/0010-rfkill_gpio-add-support-for-inverted-GPIOs.patch new file mode 100644 index 0000000..229f6c8 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0010-rfkill_gpio-add-support-for-inverted-GPIOs.patch @@ -0,0 +1,59 @@ +From f6be67ff7bf7c33aef1a43342fcf79da88867a7e Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sun, 18 Dec 2011 11:31:32 +0300 +Subject: [PATCH 10/12] rfkill_gpio: add support for inverted GPIOs + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + include/linux/rfkill-gpio.h | 2 ++ + net/rfkill/rfkill-gpio.c | 12 ++++++++---- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill-gpio.h +index a175d05..682e347 100644 +--- a/include/linux/rfkill-gpio.h ++++ b/include/linux/rfkill-gpio.h +@@ -35,7 +35,9 @@ + struct rfkill_gpio_platform_data { + char *name; + int reset_gpio; ++ int reset_gpio_inverted; + int shutdown_gpio; ++ int shutdown_gpio_inverted; + const char *power_clk_name; + enum rfkill_type type; + }; +diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c +index 256c5dd..e9940ad 100644 +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -53,18 +53,22 @@ static int rfkill_gpio_set_power(void *data, bool blocked) + + if (blocked) { + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) +- gpio_direction_output(rfkill->pdata->shutdown_gpio, 0); ++ gpio_direction_output(rfkill->pdata->shutdown_gpio, ++ rfkill->pdata->shutdown_gpio_inverted); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) +- gpio_direction_output(rfkill->pdata->reset_gpio, 0); ++ gpio_direction_output(rfkill->pdata->reset_gpio, ++ rfkill->pdata->reset_gpio_inverted); + if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) + clk_disable(rfkill->pwr_clk); + } else { + if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill)) + clk_enable(rfkill->pwr_clk); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) +- gpio_direction_output(rfkill->pdata->reset_gpio, 1); ++ gpio_direction_output(rfkill->pdata->reset_gpio, ++ !rfkill->pdata->reset_gpio_inverted); + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) +- gpio_direction_output(rfkill->pdata->shutdown_gpio, 1); ++ gpio_direction_output(rfkill->pdata->shutdown_gpio, ++ !rfkill->pdata->shutdown_gpio_inverted); + } + + if (rfkill->pwr_clk) +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0011-ARM-h1940-add-IR-switch.patch b/recipes-kernel/linux/linux-3.1/h1940/0011-ARM-h1940-add-IR-switch.patch new file mode 100644 index 0000000..9592171 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0011-ARM-h1940-add-IR-switch.patch @@ -0,0 +1,61 @@ +From 659b820f5825d3ee8e6ff9f143374e6d22ebfdaa Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sun, 18 Dec 2011 11:29:30 +0300 +Subject: [PATCH 11/12] ARM: h1940: add IR switch + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 23 +++++++++++++++++++++++ + 1 files changed, 23 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index 95f231f..e78944f 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -698,6 +698,22 @@ static struct platform_device h1940_bluetooth = { + }, + }; + ++static struct rfkill_gpio_platform_data h1940_ir_rfkill_pdata = { ++ .name = "h1940-ir", ++ .reset_gpio = -EINVAL, ++ .shutdown_gpio = S3C2410_GPB(9), ++ .shutdown_gpio_inverted = 1, ++ .type = RFKILL_TYPE_IR, ++}; ++ ++static struct platform_device h1940_irda = { ++ .name = "rfkill_gpio", ++ .id = 1, ++ .dev = { ++ .platform_data = &h1940_ir_rfkill_pdata, ++ }, ++}; ++ + static struct platform_device *h1940_devices[] __initdata = { + &h1940_dev_buttons, + &s3c_device_ohci, +@@ -719,6 +735,7 @@ static struct platform_device *h1940_devices[] __initdata = { + &power_supply, + &h1940_battery, + &h1940_bluetooth, ++ &h1940_irda, + }; + + static void __init h1940_map_io(void) +@@ -803,6 +820,12 @@ static void __init h1940_init(void) + s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); + s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); + ++ /* Configure IR serial port GPIOs */ ++ s3c_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2); ++ s3c_gpio_setpull(S3C2410_GPH(6), S3C_GPIO_PULL_NONE); ++ s3c_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2); ++ s3c_gpio_setpull(S3C2410_GPH(7), S3C_GPIO_PULL_NONE); ++ + gpio_request(S3C2410_GPC(9), "BT reset"); + gpio_direction_output(S3C2410_GPC(9), 1); + +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/0012-ARM-h1940-increase-oversampling-shift.patch b/recipes-kernel/linux/linux-3.1/h1940/0012-ARM-h1940-increase-oversampling-shift.patch new file mode 100644 index 0000000..a349e32 --- /dev/null +++ b/recipes-kernel/linux/linux-3.1/h1940/0012-ARM-h1940-increase-oversampling-shift.patch @@ -0,0 +1,29 @@ +From 5eca931becfbd3c045b603b2b69323b53ea1054a Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick <anarsoul@gmail.com> +Date: Sun, 18 Dec 2011 11:47:03 +0300 +Subject: [PATCH 12/12] ARM: h1940: increase oversampling shift + +4 samples seems to be not enough for touchscreen driver +to work accurately + +Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> +--- + arch/arm/mach-s3c2410/mach-h1940.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c +index e78944f..23067d1 100644 +--- a/arch/arm/mach-s3c2410/mach-h1940.c ++++ b/arch/arm/mach-s3c2410/mach-h1940.c +@@ -183,7 +183,7 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { + static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = { + .delay = 10000, + .presc = 49, +- .oversampling_shift = 2, ++ .oversampling_shift = 5, + .cfg_gpio = s3c24xx_ts_cfg_gpio, + }; + +-- +1.7.8 + diff --git a/recipes-kernel/linux/linux-3.1/h1940/defconfig b/recipes-kernel/linux/linux-3.1/h1940/defconfig index ad8b777..288e6d0 100644 --- a/recipes-kernel/linux/linux-3.1/h1940/defconfig +++ b/recipes-kernel/linux/linux-3.1/h1940/defconfig @@ -258,11 +258,11 @@ CONFIG_PLAT_SAMSUNG=y # CONFIG_S3C_BOOT_WATCHDOG is not set # CONFIG_S3C_BOOT_ERROR_RESET is not set CONFIG_S3C_BOOT_UART_FORCE_FIFO=y -CONFIG_S3C_LOWLEVEL_UART_PORT=0 +CONFIG_S3C_LOWLEVEL_UART_PORT=1 CONFIG_S3C_GPIO_CFG_S3C24XX=y CONFIG_S3C_GPIO_PULL_DOWN=y CONFIG_S3C_GPIO_PULL_UP=y -CONFIG_SAMSUNG_GPIO_EXTRA=0 +CONFIG_SAMSUNG_GPIO_EXTRA=16 CONFIG_S3C_GPIO_SPACE=0 CONFIG_S3C_ADC=y CONFIG_S3C_DEV_USB_HOST=y @@ -304,7 +304,6 @@ CONFIG_S3C2410_GPIO=y # # CONFIG_ARCH_SMDK2410 is not set CONFIG_ARCH_H1940=y -CONFIG_H1940BT=y CONFIG_PM_H1940=y # CONFIG_MACH_N30 is not set # CONFIG_ARCH_BAST is not set @@ -619,11 +618,11 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set # CONFIG_WIMAX is not set -CONFIG_RFKILL=y +CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y # CONFIG_RFKILL_REGULATOR is not set -# CONFIG_RFKILL_GPIO is not set +CONFIG_RFKILL_GPIO=m # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set @@ -1269,8 +1268,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_SDHCI_PXAV2 is not set CONFIG_MMC_S3C=y # CONFIG_MMC_S3C_HW_SDIO_IRQ is not set -CONFIG_MMC_S3C_PIO=y -# CONFIG_MMC_S3C_DMA is not set +# CONFIG_MMC_S3C_PIO is not set +CONFIG_MMC_S3C_DMA=y # CONFIG_MMC_S3C_PIODMA is not set # CONFIG_MMC_DW is not set # CONFIG_MEMSTICK is not set @@ -1611,7 +1610,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_ARM_UNWIND=y CONFIG_DEBUG_USER=y # CONFIG_OC_ETM is not set -CONFIG_DEBUG_S3C_UART=0 +CONFIG_DEBUG_S3C_UART=1 # # Security options @@ -1731,7 +1730,7 @@ CONFIG_CRYPTO_HW=y # CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y -CONFIG_CRC16=m +CONFIG_CRC16=y # CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y diff --git a/recipes-kernel/linux/linux_3.1.bb b/recipes-kernel/linux/linux_3.1.bb index 7f4049b..980be11 100644 --- a/recipes-kernel/linux/linux_3.1.bb +++ b/recipes-kernel/linux/linux_3.1.bb @@ -1,6 +1,21 @@ require linux.inc require linux-${PV}.inc -PR = "${INC_PR}.7" +PR = "${INC_PR}.8" COMPATIBLE_MACHINE = "(akita|c7x0|collie|poodle|tosa|spitz|h1940)" + +SRC_URI_append_h1940 = " \ + file://0001-s3c24xx-DMA-don-t-use-autoreload-feature.patch \ + file://0002-s3cmci-minor-fixups.patch \ + file://0003-ARM-s3c2410-drop-RFKILL-driver-for-H1940-bluetooth.patch \ + file://0004-mtd-nand-s3c2410-add-iPAQ-specific-layout.patch \ + file://0005-ARM-s3c2410-Add-nand-device-for-h1940.patch \ + file://0006-ARM-s3c2410-h1940-don-t-touch-UPLLCON.patch \ + file://0007-ARM-s3c2410-unlock-reset-button-on-H1940.patch \ + file://0008-ARM-h1940-add-bluetooth-RF-kill-switch.patch \ + file://0009-rfkill-add-IR-type.patch \ + file://0010-rfkill_gpio-add-support-for-inverted-GPIOs.patch \ + file://0011-ARM-h1940-add-IR-switch.patch \ + file://0012-ARM-h1940-increase-oversampling-shift.patch \ + " |