diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/au1000/db1x00 | |
download | blackbird-op-linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz blackbird-op-linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/mips/au1000/db1x00')
-rw-r--r-- | arch/mips/au1000/db1x00/Makefile | 9 | ||||
-rw-r--r-- | arch/mips/au1000/db1x00/board_setup.c | 127 | ||||
-rw-r--r-- | arch/mips/au1000/db1x00/init.c | 74 | ||||
-rw-r--r-- | arch/mips/au1000/db1x00/irqmap.c | 72 | ||||
-rw-r--r-- | arch/mips/au1000/db1x00/mirage_ts.c | 261 |
5 files changed, 543 insertions, 0 deletions
diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile new file mode 100644 index 000000000000..4c7d763f2113 --- /dev/null +++ b/arch/mips/au1000/db1x00/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor Db1x00 board. + +lib-y := init.o board_setup.o irqmap.o +obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c new file mode 100644 index 000000000000..ac05ba0ff63f --- /dev/null +++ b/arch/mips/au1000/db1x00/board_setup.c @@ -0,0 +1,127 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Db1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/console.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> +#include <asm/mach-au1x00/au1000.h> +#include <asm/mach-db1x00/db1x00.h> + +/* not correct for db1550 */ +static BCSR * const bcsr = (BCSR *)0xAE000000; + +void board_reset (void) +{ + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ + au_writel(0x00000000, 0xAE00001C); +} + +void __init board_setup(void) +{ + u32 pin_func; + + pin_func = 0; + /* not valid for 1550 */ +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + +#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) + /* set IRFIRSEL instead of GPIO15 */ + pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); + au_writel(pin_func, SYS_PINFUNC); + /* power off until the driver is in use */ + bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; + au_sync(); +#endif + au_writel(0, 0xAE000010); /* turn off pcmcia power */ + +#ifdef CONFIG_MIPS_MIRAGE + /* enable GPIO[31:0] inputs */ + au_writel(0, SYS_PININPUTEN); + + /* GPIO[20] is output, tristate the other input primary GPIO's */ + au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR); + + /* set GPIO[210:208] instead of SSI_0 */ + pin_func = au_readl(SYS_PINFUNC) | (u32)(1); + + /* set GPIO[215:211] for LED's */ + pin_func |= (u32)((5<<2)); + + /* set GPIO[214:213] for more LED's */ + pin_func |= (u32)((5<<12)); + + /* set GPIO[207:200] instead of PCMCIA/LCD */ + pin_func |= (u32)((3<<17)); + au_writel(pin_func, SYS_PINFUNC); + + /* Enable speaker amplifier. This should + * be part of the audio driver. + */ + au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR); + au_writel(0x02000200, GPIO2_OUTPUT); +#endif + + au_sync(); + +#ifdef CONFIG_MIPS_DB1000 + printk("AMD Alchemy Au1000/Db1000 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1500 + printk("AMD Alchemy Au1500/Db1500 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1100 + printk("AMD Alchemy Au1100/Db1100 Board\n"); +#endif +#ifdef CONFIG_MIPS_BOSPORUS + printk("AMD Alchemy Bosporus Board\n"); +#endif +#ifdef CONFIG_MIPS_MIRAGE + printk("AMD Alchemy Mirage Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1550 + printk("AMD Alchemy Au1550/Db1550 Board\n"); +#endif +} diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c new file mode 100644 index 000000000000..51eee94a5e82 --- /dev/null +++ b/arch/mips/au1000/db1x00/init.c @@ -0,0 +1,74 @@ +/* + * BRIEF MODULE DESCRIPTION + * PB1000 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/config.h> +#include <linux/string.h> +#include <linux/kernel.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ +#ifdef CONFIG_MIPS_BOSPORUS + return "Alchemy Bosporus Gateway Reference"; +#else + return "Alchemy Db1x00"; +#endif +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_DB1000; /* set the platform # */ + + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) + memsize = 0x04000000; + else + memsize = simple_strtol(memsize_str, NULL, 0); + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c new file mode 100644 index 000000000000..8f6ef0dbe1f8 --- /dev/null +++ b/arch/mips/au1000/db1x00/irqmap.c @@ -0,0 +1,72 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/delay.h> +#include <linux/bitops.h> + +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/mach-au1x00/au1000.h> + +au1xxx_irq_map_t au1xxx_irq_map[] = { + +#ifndef CONFIG_MIPS_MIRAGE +#ifdef CONFIG_MIPS_DB1550 + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */ + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */ +#else + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 Fully_Interted# */ + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 STSCHG# */ + { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */ + + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 Fully_Interted# */ + { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 STSCHG# */ + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */ +#endif +#else + { AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pen down */ +#endif + +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c new file mode 100644 index 000000000000..ade35e432004 --- /dev/null +++ b/arch/mips/au1000/db1x00/mirage_ts.c @@ -0,0 +1,261 @@ +/* + * linux/arch/mips/au1000/db1x00/mirage_ts.c + * + * BRIEF MODULE DESCRIPTION + * Glue between Mirage board-specific touchscreen pieces + * and generic Wolfson Codec touchscreen support. + * + * Based on pb1100_ts.c used in Hydrogen II. + * + * Copyright (c) 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/poll.h> +#include <linux/proc_fs.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/wait.h> + +#include <asm/segment.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/delay.h> +#include <asm/au1000.h> + +/* + * Imported interface to Wolfson Codec driver. + */ +extern void *wm97xx_ts_get_handle(int which); +extern int wm97xx_ts_ready(void* ts_handle); +extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans); +extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg); +extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val); +extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure); +extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z); + +int wm97xx_comodule_present = 1; + + +#define TS_NAME "mirage_ts" + +#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) +#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg) + + +#define PEN_DOWN_IRQ AU1000_GPIO_7 + +static struct task_struct *ts_task = 0; +static DECLARE_COMPLETION(ts_complete); +static DECLARE_WAIT_QUEUE_HEAD(pendown_wait); + +#ifdef CONFIG_WM97XX_FIVEWIRETS +static int release_pressure = 1; +#else +static int release_pressure = 50; +#endif + +typedef struct { + long x; + long y; +} DOWN_EVENT; + +#define SAMPLE_RATE 50 /* samples per second */ +#define PEN_DEBOUNCE 5 /* samples for settling - fn of SAMPLE_RATE */ +#define PEN_UP_TIMEOUT 10 /* in seconds */ +#define PEN_UP_SETTLE 5 /* samples per second */ + +static struct { + int xscale; + int xtrans; + int yscale; + int ytrans; +} mirage_ts_cal = +{ +#if 0 + xscale: 84, + xtrans: -157, + yscale: 66, + ytrans: -150, +#else + xscale: 84, + xtrans: -150, + yscale: 66, + ytrans: -146, +#endif +}; + + +static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs) +{ +//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD)); + wake_up(&pendown_wait); +} + +static int ts_thread(void *id) +{ + static int pen_was_down = 0; + static DOWN_EVENT pen_xy; + long x, y, z; + void *ts; /* handle */ + struct task_struct *tsk = current; + int timeout = HZ / SAMPLE_RATE; + + ts_task = tsk; + + daemonize(); + tsk->tty = NULL; + tsk->policy = SCHED_FIFO; + tsk->rt_priority = 1; + strcpy(tsk->comm, "touchscreen"); + + /* only want to receive SIGKILL */ + spin_lock_irq(&tsk->sigmask_lock); + siginitsetinv(&tsk->blocked, sigmask(SIGKILL)); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + + /* get handle for codec */ + ts = wm97xx_ts_get_handle(0); + + /* proceed only after everybody is ready */ + wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4); + + /* board-specific calibration */ + wm97xx_ts_set_cal(ts, + mirage_ts_cal.xscale, + mirage_ts_cal.xtrans, + mirage_ts_cal.yscale, + mirage_ts_cal.ytrans); + + /* route Wolfson pendown interrupts to our GPIO */ + au_sync(); + wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008); + au_sync(); + + for (;;) { + interruptible_sleep_on_timeout(&pendown_wait, timeout); + disable_irq(PEN_DOWN_IRQ); + if (signal_pending(tsk)) { + break; + } + + /* read codec */ + if (!wm97xx_ts_read_data(ts, &x, &y, &z)) + z = 0; /* treat no-data and pen-up the same */ + + if (signal_pending(tsk)) { + break; + } + + if (z >= release_pressure) { + y = ~y; /* top to bottom */ + if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX + /* bounce ? */ + x = pen_xy.x; + y = pen_xy.y; + --pen_was_down; + } else if (pen_was_down <= 1) { + pen_xy.x = x; + pen_xy.y = y; + if (pen_was_down) + wm97xx_ts_send_data(ts, x, y, z); + pen_was_down = PEN_DEBOUNCE; + } + //wm97xx_ts_send_data(ts, x, y, z); + timeout = HZ / SAMPLE_RATE; + } else { + if (pen_was_down) { + if (--pen_was_down) + z = release_pressure; + else //THXXX + wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z); + } + /* The pendown signal takes some time to settle after + * reading the pen pressure so wait a little + * before enabling the pen. + */ + if (! pen_was_down) { +// interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE); + timeout = HZ * PEN_UP_TIMEOUT; + } + } + enable_irq(PEN_DOWN_IRQ); + } + enable_irq(PEN_DOWN_IRQ); + ts_task = NULL; + complete(&ts_complete); + return 0; +} + +static int __init ts_mirage_init(void) +{ + int ret; + + /* pen down signal is connected to GPIO 7 */ + + ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL); + if (ret) { + err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret); + return ret; + } + + lock_kernel(); + ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES); + if (ret < 0) { + unlock_kernel(); + return ret; + } + unlock_kernel(); + + info("Mirage touchscreen IRQ initialized."); + + return 0; +} + +static void __exit ts_mirage_exit(void) +{ + if (ts_task) { + send_sig(SIGKILL, ts_task, 1); + wait_for_completion(&ts_complete); + } + + free_irq(PEN_DOWN_IRQ, NULL); +} + +module_init(ts_mirage_init); +module_exit(ts_mirage_exit); + |