aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel
diff options
context:
space:
mode:
authorPaul Eggleton <bluelightning@bluelightning.org>2012-01-09 01:03:59 +0000
committerPaul Eggleton <paul.eggleton@linux.intel.com>2012-01-22 23:16:41 +0000
commit7469f0737aaefafd513f760b6847c29140027bc6 (patch)
treeae47db06d6c58d1c6aacc361d92f3ed32f9b0e54 /recipes-kernel
parentf14a97ee1ee05726ed8d4b2be0ad9fe3d6823b36 (diff)
downloadmeta-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')
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0001-s3c24xx-DMA-don-t-use-autoreload-feature.patch680
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0002-s3cmci-minor-fixups.patch40
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0003-ARM-s3c2410-drop-RFKILL-driver-for-H1940-bluetooth.patch237
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0004-mtd-nand-s3c2410-add-iPAQ-specific-layout.patch28
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0005-ARM-s3c2410-Add-nand-device-for-h1940.patch114
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0006-ARM-s3c2410-h1940-don-t-touch-UPLLCON.patch41
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0007-ARM-s3c2410-unlock-reset-button-on-H1940.patch49
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0008-ARM-h1940-add-bluetooth-RF-kill-switch.patch75
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0009-rfkill-add-IR-type.patch51
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0010-rfkill_gpio-add-support-for-inverted-GPIOs.patch59
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0011-ARM-h1940-add-IR-switch.patch61
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/0012-ARM-h1940-increase-oversampling-shift.patch29
-rw-r--r--recipes-kernel/linux/linux-3.1/h1940/defconfig17
-rw-r--r--recipes-kernel/linux/linux_3.1.bb17
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 \
+ "