diff options
author | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
---|---|---|
committer | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
commit | 709c4d66e0b107ca606941b988bad717c0b45d9b (patch) | |
tree | 37ee08b1eb308f3b2b6426d5793545c38396b838 /packages/linux/linux-rp-2.6.24/tosa | |
parent | fa6cd5a3b993f16c27de4ff82b42684516d433ba (diff) |
rename packages/ to recipes/ per earlier agreement
See links below for more details:
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816
Signed-off-by: Denys Dmytriyenko <denis@denix.org>
Acked-by: Mike Westerhof <mwester@dls.net>
Acked-by: Philip Balister <philip@balister.org>
Acked-by: Khem Raj <raj.khem@gmail.com>
Acked-by: Marcin Juszkiewicz <hrw@openembedded.org>
Acked-by: Koen Kooi <koen@openembedded.org>
Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'packages/linux/linux-rp-2.6.24/tosa')
70 files changed, 0 insertions, 18471 deletions
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch b/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch deleted file mode 100644 index ba79b4a470..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch +++ /dev/null @@ -1,201 +0,0 @@ -From d48a09b301d9a460d5ce027433e8cb8872e7b5c3 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Fri, 4 Jan 2008 18:26:38 +0000 -Subject: [PATCH 01/64] Allow runtime registration of regions of memory that require dma bouncing. - ---- - arch/arm/common/Kconfig | 4 ++ - arch/arm/common/dmabounce.c | 82 ++++++++++++++++++++++++++++++++++++- - arch/arm/common/sa1111.c | 2 +- - arch/arm/mach-ixp4xx/Kconfig | 1 + - arch/arm/mach-ixp4xx/common-pci.c | 2 +- - 5 files changed, 87 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig -index 3e07346..5f357fb 100644 ---- a/arch/arm/common/Kconfig -+++ b/arch/arm/common/Kconfig -@@ -13,10 +13,14 @@ config ICST307 - config SA1111 - bool - select DMABOUNCE -+ select PLATFORM_DMABOUNCE - - config DMABOUNCE - bool - -+config PLATFORM_DMABOUNCE -+ bool -+ - config TIMER_ACORN - bool - -diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c -index 52fc6a8..ed80abe 100644 ---- a/arch/arm/common/dmabounce.c -+++ b/arch/arm/common/dmabounce.c -@@ -16,6 +16,7 @@ - * - * Copyright (C) 2002 Hewlett Packard Company. - * Copyright (C) 2004 MontaVista Software, Inc. -+ * Copyright (C) 2007 Dmitry Baryshkov <dbaryshkov@gmail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -24,6 +25,7 @@ - - #include <linux/module.h> - #include <linux/init.h> -+#include <linux/rwsem.h> - #include <linux/slab.h> - #include <linux/device.h> - #include <linux/dma-mapping.h> -@@ -80,6 +82,80 @@ struct dmabounce_device_info { - rwlock_t lock; - }; - -+struct dmabounce_check_entry { -+ struct list_head list; -+ dmabounce_check checker; -+ void *data; -+}; -+ -+static struct list_head checkers = LIST_HEAD_INIT(checkers); -+static rwlock_t checkers_lock = RW_LOCK_UNLOCKED; -+ -+int -+dmabounce_register_checker(dmabounce_check function, void *data) -+{ -+ unsigned long flags; -+ struct dmabounce_check_entry *entry = -+ kzalloc(sizeof(struct dmabounce_check_entry), GFP_ATOMIC); -+ -+ if (!entry) -+ return ENOMEM; -+ -+ INIT_LIST_HEAD(&entry->list); -+ entry->checker = function; -+ entry->data = data; -+ -+ write_lock_irqsave(&checkers_lock, flags); -+ list_add(&entry->list, &checkers); -+ write_unlock_irqrestore(&checkers_lock, flags); -+ -+ return 0; -+} -+ -+void -+dmabounce_remove_checker(dmabounce_check function, void *data) -+{ -+ unsigned long flags; -+ struct list_head *pos; -+ -+ write_lock_irqsave(&checkers_lock, flags); -+ __list_for_each(pos, &checkers) { -+ struct dmabounce_check_entry *entry = container_of(pos, -+ struct dmabounce_check_entry, list); -+ if (entry->checker == function && entry->data == data) { -+ list_del(pos); -+ write_unlock_irqrestore(&checkers_lock, flags); -+ kfree(entry); -+ return; -+ } -+ } -+ -+ write_unlock_irqrestore(&checkers_lock, flags); -+ printk(KERN_WARNING "dmabounce checker not found: %p\n", function); -+} -+ -+static int dma_needs_bounce(struct device *dev, dma_addr_t dma, size_t size) -+{ -+ unsigned long flags; -+ struct list_head *pos; -+ -+ read_lock_irqsave(&checkers_lock, flags); -+ __list_for_each(pos, &checkers) { -+ struct dmabounce_check_entry *entry = container_of(pos, -+ struct dmabounce_check_entry, list); -+ if (entry->checker(dev, dma, size, entry->data)) { -+ read_unlock_irqrestore(&checkers_lock, flags); -+ return 1; -+ } -+ } -+ -+ read_unlock_irqrestore(&checkers_lock, flags); -+#ifdef CONFIG_PLATFORM_DMABOUNCE -+ return platform_dma_needs_bounce(dev, dma, size); -+#else -+ return 0; -+#endif -+} - #ifdef STATS - static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr, - char *buf) -@@ -239,7 +315,7 @@ map_single(struct device *dev, void *ptr, size_t size, - struct safe_buffer *buf; - - buf = alloc_safe_buffer(device_info, ptr, size, dir); -- if (buf == 0) { -+ if (buf == NULL) { - dev_err(dev, "%s: unable to map unsafe buffer %p!\n", - __func__, ptr); - return 0; -@@ -643,7 +719,6 @@ dmabounce_unregister_dev(struct device *dev) - dev->bus_id, dev->bus->name); - } - -- - EXPORT_SYMBOL(dma_map_single); - EXPORT_SYMBOL(dma_unmap_single); - EXPORT_SYMBOL(dma_map_sg); -@@ -653,6 +728,9 @@ EXPORT_SYMBOL(dma_sync_single_for_device); - EXPORT_SYMBOL(dma_sync_sg); - EXPORT_SYMBOL(dmabounce_register_dev); - EXPORT_SYMBOL(dmabounce_unregister_dev); -+EXPORT_SYMBOL(dmabounce_register_checker); -+EXPORT_SYMBOL(dmabounce_remove_checker); -+ - - MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>"); - MODULE_DESCRIPTION("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows"); -diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c -index eb06d0b..3b8fbdd 100644 ---- a/arch/arm/common/sa1111.c -+++ b/arch/arm/common/sa1111.c -@@ -778,7 +778,7 @@ static void __sa1111_remove(struct sa1111 *sachip) - * This should only get called for sa1111_device types due to the - * way we configure our device dma_masks. - */ --int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) -+int platform_dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) - { - /* - * Section 4.6 of the "Intel StrongARM SA-1111 Development Module -diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig -index 61b2dfc..5870371 100644 ---- a/arch/arm/mach-ixp4xx/Kconfig -+++ b/arch/arm/mach-ixp4xx/Kconfig -@@ -161,6 +161,7 @@ comment "IXP4xx Options" - config DMABOUNCE - bool - default y -+ select PLATFORM_DMABOUNCE - depends on PCI - - config IXP4XX_INDIRECT_PCI -diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c -index bf04121..ac46492 100644 ---- a/arch/arm/mach-ixp4xx/common-pci.c -+++ b/arch/arm/mach-ixp4xx/common-pci.c -@@ -336,7 +336,7 @@ static int ixp4xx_pci_platform_notify_remove(struct device *dev) - return 0; - } - --int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) -+int platform_dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) - { - return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); - } --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0001-pxa2xx-ac97-switch-AC-unit-to-correct-state-before.patch b/packages/linux/linux-rp-2.6.24/tosa/0001-pxa2xx-ac97-switch-AC-unit-to-correct-state-before.patch deleted file mode 100644 index 09f0cb946c..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0001-pxa2xx-ac97-switch-AC-unit-to-correct-state-before.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 688df15bb534519e0698cc8e4a4d9234afd32105 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 7 Nov 2008 15:50:39 +0300 -Subject: [PATCH] pxa2xx-ac97: switch AC unit to correct state before probing - -If AC97 unit is in partially enabled state, early request_irq can trigger -IRQ storm or even full hang up. Workaround this by forcibly switching ACLINK off -at the start of the probe. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - sound/soc/pxa/pxa2xx-ac97.c | 30 +++++++++++++++++------------- - 1 files changed, 17 insertions(+), 13 deletions(-) - -Index: linux-2.6.24/sound/soc/pxa/pxa2xx-ac97.c -=================================================================== ---- linux-2.6.24.orig/sound/soc/pxa/pxa2xx-ac97.c 2008-01-25 01:58:37.000000000 +0300 -+++ linux-2.6.24/sound/soc/pxa/pxa2xx-ac97.c 2008-11-15 20:02:45.396976363 +0300 -@@ -284,10 +284,6 @@ static int pxa2xx_ac97_probe(struct plat - { - int ret; - -- ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); -- if (ret < 0) -- goto err; -- - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); -@@ -296,15 +292,23 @@ static int pxa2xx_ac97_probe(struct plat - /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); - #endif -+ GCR = GCR_ACLINK_OFF; -+ - pxa_set_cken(CKEN_AC97, 1); -+ -+ ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); -+ if (ret < 0) -+ goto err; -+ -+ - return 0; - -- err: -- if (CKEN & (1 << CKEN_AC97)) { -+err: -+/* if (CKEN & (1 << CKEN_AC97)) {*/ - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); -- } -+/* }*/ - return ret; - } - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch b/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch deleted file mode 100644 index a562ef921b..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 8e95f90487d2fb46fd862744ddb34f47c30b0c5a Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Fri, 4 Jan 2008 18:27:50 +0000 -Subject: [PATCH 02/64] Modify dma_alloc_coherent on ARM so that it supports device local DMA. - ---- - arch/arm/mm/consistent.c | 125 +++++++++++++++++++++++++++++++++++++++++ - include/asm-arm/dma-mapping.h | 37 +++++++------ - 2 files changed, 145 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c -index 333a82a..3da0f94 100644 ---- a/arch/arm/mm/consistent.c -+++ b/arch/arm/mm/consistent.c -@@ -3,6 +3,8 @@ - * - * Copyright (C) 2000-2004 Russell King - * -+ * Device local coherent memory support added by Ian Molton (spyro@f2s.com) -+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -@@ -20,6 +22,7 @@ - - #include <asm/memory.h> - #include <asm/cacheflush.h> -+#include <asm/io.h> - #include <asm/tlbflush.h> - #include <asm/sizes.h> - -@@ -35,6 +38,13 @@ - #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) - #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) - -+struct dma_coherent_mem { -+ void *virt_base; -+ u32 device_base; -+ int size; -+ int flags; -+ unsigned long *bitmap; -+}; - - /* - * These are the page tables (2MB each) covering uncached, DMA consistent allocations -@@ -153,6 +163,13 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, - unsigned long order; - u64 mask = ISA_DMA_THRESHOLD, limit; - -+ /* Following is a work-around (a.k.a. hack) to prevent pages -+ * with __GFP_COMP being passed to split_page() which cannot -+ * handle them. The real problem is that this flag probably -+ * should be 0 on ARM as it is not supported on this -+ * platform--see CONFIG_HUGETLB_PAGE. */ -+ gfp &= ~(__GFP_COMP); -+ - if (!consistent_pte[0]) { - printk(KERN_ERR "%s: not initialised\n", __func__); - dump_stack(); -@@ -160,6 +177,26 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, - } - - if (dev) { -+ -+ if (dev->dma_mem) { -+ unsigned long flags; -+ int pgnum; -+ void *ret; -+ -+ spin_lock_irqsave(&consistent_lock, flags); -+ pgnum = bitmap_find_free_region(dev->dma_mem->bitmap, -+ dev->dma_mem->size, -+ get_order(size)); -+ spin_unlock_irqrestore(&consistent_lock, flags); -+ -+ if (pgnum >= 0) { -+ *handle = dev->dma_mem->device_base + (pgnum << PAGE_SHIFT); -+ ret = dev->dma_mem->virt_base + (pgnum << PAGE_SHIFT); -+ memset(ret, 0, size); -+ return ret; -+ } -+ } -+ - mask = dev->coherent_dma_mask; - - /* -@@ -177,6 +214,9 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, - mask, (unsigned long long)ISA_DMA_THRESHOLD); - goto no_page; - } -+ -+ if (dev->dma_mem && dev->dma_mem->flags & DMA_MEMORY_EXCLUSIVE) -+ return NULL; - } - - /* -@@ -359,6 +399,8 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr - pte_t *ptep; - int idx; - u32 off; -+ struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; -+ unsigned long order; - - WARN_ON(irqs_disabled()); - -@@ -368,6 +410,15 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr - } - - size = PAGE_ALIGN(size); -+ order = get_order(size); -+ -+ /* What if mem is valid and the range is not? */ -+ if (mem && cpu_addr >= mem->virt_base && cpu_addr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { -+ int page = (cpu_addr - mem->virt_base) >> PAGE_SHIFT; -+ -+ bitmap_release_region(mem->bitmap, page, order); -+ return; -+ } - - spin_lock_irqsave(&consistent_lock, flags); - c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); -@@ -437,6 +488,80 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr - } - EXPORT_SYMBOL(dma_free_coherent); - -+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, -+ dma_addr_t device_addr, size_t size, int flags) -+{ -+ void __iomem *mem_base; -+ int pages = size >> PAGE_SHIFT; -+ int bitmap_size = (pages + 31)/32; -+ -+ if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) -+ goto out; -+ if (!size) -+ goto out; -+ if (dev->dma_mem) -+ goto out; -+ -+ /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ -+ mem_base = ioremap_nocache(bus_addr, size); -+ if (!mem_base) -+ goto out; -+ -+ dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); -+ if (!dev->dma_mem) -+ goto out; -+ memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); -+ dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); -+ if (!dev->dma_mem->bitmap) -+ goto free1_out; -+ -+ dev->dma_mem->virt_base = mem_base; -+ dev->dma_mem->device_base = device_addr; -+ dev->dma_mem->size = pages; -+ dev->dma_mem->flags = flags; -+ -+ if (flags & DMA_MEMORY_MAP) -+ return DMA_MEMORY_MAP; -+ -+ return DMA_MEMORY_IO; -+ -+ free1_out: -+ kfree(dev->dma_mem->bitmap); -+ out: -+ return 0; -+} -+EXPORT_SYMBOL(dma_declare_coherent_memory); -+ -+void dma_release_declared_memory(struct device *dev) -+{ -+ struct dma_coherent_mem *mem = dev->dma_mem; -+ -+ if (!mem) -+ return; -+ dev->dma_mem = NULL; -+ kfree(mem->bitmap); -+ kfree(mem); -+} -+EXPORT_SYMBOL(dma_release_declared_memory); -+ -+void *dma_mark_declared_memory_occupied(struct device *dev, -+ dma_addr_t device_addr, size_t size) -+{ -+ struct dma_coherent_mem *mem = dev->dma_mem; -+ int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ int pos, err; -+ -+ if (!mem) -+ return ERR_PTR(-EINVAL); -+ -+ pos = (device_addr - mem->device_base) >> PAGE_SHIFT; -+ err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); -+ if (err != 0) -+ return ERR_PTR(err); -+ return mem->virt_base + (pos << PAGE_SHIFT); -+} -+EXPORT_SYMBOL(dma_mark_declared_memory_occupied); -+ - /* - * Initialise the consistent memory allocation. - */ -diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h -index e99406a..f18ba05 100644 ---- a/include/asm-arm/dma-mapping.h -+++ b/include/asm-arm/dma-mapping.h -@@ -7,6 +7,19 @@ - - #include <linux/scatterlist.h> - -+#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY -+extern int -+dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, -+ dma_addr_t device_addr, size_t size, int flags); -+ -+extern void -+dma_release_declared_memory(struct device *dev); -+ -+extern void * -+dma_mark_declared_memory_occupied(struct device *dev, -+ dma_addr_t device_addr, size_t size); -+ -+ - /* - * DMA-consistent mapping functions. These allocate/free a region of - * uncached, unwrite-buffered mapped memory space for use with DMA -@@ -433,23 +446,13 @@ extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long) - */ - extern void dmabounce_unregister_dev(struct device *); - --/** -- * dma_needs_bounce -- * -- * @dev: valid struct device pointer -- * @dma_handle: dma_handle of unbounced buffer -- * @size: size of region being mapped -- * -- * Platforms that utilize the dmabounce mechanism must implement -- * this function. -- * -- * The dmabounce routines call this function whenever a dma-mapping -- * is requested to determine whether a given buffer needs to be bounced -- * or not. The function must return 0 if the buffer is OK for -- * DMA access and 1 if the buffer needs to be bounced. -- * -- */ --extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); -+typedef int (*dmabounce_check)(struct device *dev, dma_addr_t dma, size_t size, void *data); -+extern int dmabounce_register_checker(dmabounce_check, void *data); -+extern void dmabounce_remove_checker(dmabounce_check, void *data); -+#ifdef CONFIG_PLATFORM_DMABOUNCE -+extern int platform_dma_needs_bounce(struct device *dev, dma_addr_t dma, size_t size, void *data); -+#endif -+ - #endif /* CONFIG_DMABOUNCE */ - - #endif /* __KERNEL__ */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch deleted file mode 100644 index d84a4f7835..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch +++ /dev/null @@ -1,243 +0,0 @@ -From a07910753f9965842b6647f0561db125b538f5ed Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Fri, 4 Jan 2008 18:32:44 +0000 -Subject: [PATCH 03/64] Core MFD support - -This patch provides a common subdevice registration system for MFD type -chips, using platfrom device. - -It also provides a new resource type for IRQs such that a subdevices IRQ may -be computed based on the MFD cores IRQ handler, since many MFDs provide an IRQ -multiplex. ---- - drivers/mfd/Kconfig | 4 ++ - drivers/mfd/Makefile | 2 + - drivers/mfd/mfd-core.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ioport.h | 1 + - include/linux/mfd-core.h | 51 ++++++++++++++++++++ - 5 files changed, 174 insertions(+), 0 deletions(-) - create mode 100644 drivers/mfd/mfd-core.c - create mode 100644 include/linux/mfd-core.h - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 2571619..1205c89 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -5,6 +5,10 @@ - menu "Multifunction device drivers" - depends on HAS_IOMEM - -+config MFD_CORE -+ tristate -+ default n -+ - config MFD_SM501 - tristate "Support for Silicon Motion SM501" - ---help--- -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 5143209..6c20064 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -4,6 +4,8 @@ - - obj-$(CONFIG_MFD_SM501) += sm501.o - -+obj-$(CONFIG_MFD_CORE) += mfd-core.o -+ - obj-$(CONFIG_MCP) += mcp-core.o - obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o - obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o -diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c -new file mode 100644 -index 0000000..88874e1 ---- /dev/null -+++ b/drivers/mfd/mfd-core.c -@@ -0,0 +1,116 @@ -+/* -+ * drivers/mfd/mfd-core.c -+ * -+ * core MFD support -+ * Copyright (c) 2006 Ian Molton -+ * Copyright (c) 2007 Dmitry Baryshkov -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/platform_device.h> -+#include <linux/mfd-core.h> -+ -+#define SIGNED_SHIFT(val, shift) ((shift) >= 0 ? \ -+ ((val) << (shift)) : \ -+ ((val) >> -(shift))) -+ -+int mfd_add_devices( -+ struct platform_device *parent, -+ const struct mfd_cell *cells, int n_devs, -+ struct resource *mem, -+ int relative_addr_shift, -+ int irq_base) -+{ -+ int i; -+ -+ for (i = 0; i < n_devs; i++) { -+ struct resource *res = NULL; -+ const struct mfd_cell *cell = cells + i; -+ struct platform_device *pdev; -+ int ret = -ENOMEM; -+ int r; -+ -+ pdev = platform_device_alloc(cell->name, -1); -+ if (!pdev) -+ goto fail_alloc; -+ -+ pdev->dev.uevent_suppress = 0; -+ pdev->dev.parent = &parent->dev; -+ -+ ret = platform_device_add_data(pdev, &cell, sizeof(struct mfd_cell *)); -+ if (ret) -+ goto fail_device; -+ -+ res = kzalloc(cell->num_resources * sizeof(struct resource), -+ GFP_KERNEL); -+ if (!res) -+ goto fail_device; -+ -+ for (r = 0; r < cell->num_resources; r++) { -+ res[r].name = cell->resources[r].name; -+ -+ /* Find out base to use */ -+ if (cell->resources[r].flags & IORESOURCE_MEM) { -+ res[r].parent = mem; -+ res[r].start = mem->start + -+ SIGNED_SHIFT(cell->resources[r].start, -+ relative_addr_shift); -+ res[r].end = mem->start + -+ SIGNED_SHIFT(cell->resources[r].end, -+ relative_addr_shift); -+ } else if ((cell->resources[r].flags & IORESOURCE_IRQ) && -+ (cell->resources[r].flags & IORESOURCE_IRQ_MFD_SUBDEVICE)) { -+ res[r].start = irq_base + -+ cell->resources[r].start; -+ res[r].end = irq_base + -+ cell->resources[r].end; -+ } else { -+ res[r].start = cell->resources[r].start; -+ res[r].end = cell->resources[r].end; -+ } -+ -+ res[r].flags = cell->resources[r].flags; -+ } -+ -+ ret = platform_device_add_resources(pdev, -+ res, -+ cell->num_resources); -+ kfree(res); -+ -+ if (ret) -+ goto fail_device; -+ -+ ret = platform_device_add(pdev); -+ -+ if (ret) { -+ platform_device_del(pdev); -+fail_device: -+ platform_device_put(pdev); -+fail_alloc: -+ mfd_remove_devices(parent); -+ return ret; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(mfd_add_devices); -+ -+static int mfd_remove_devices_fn(struct device *dev, void *unused) -+{ -+ platform_device_unregister(container_of(dev, struct platform_device, dev)); -+ return 0; -+} -+ -+void mfd_remove_devices(struct platform_device *parent) -+{ -+ device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn); -+} -+EXPORT_SYMBOL(mfd_remove_devices); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); -diff --git a/include/linux/ioport.h b/include/linux/ioport.h -index 6187a85..0348c71 100644 ---- a/include/linux/ioport.h -+++ b/include/linux/ioport.h -@@ -56,6 +56,7 @@ struct resource_list { - #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) - #define IORESOURCE_IRQ_LOWLEVEL (1<<3) - #define IORESOURCE_IRQ_SHAREABLE (1<<4) -+#define IORESOURCE_IRQ_MFD_SUBDEVICE (1<<5) - - /* ISA PnP DMA specific bits (IORESOURCE_BITS) */ - #define IORESOURCE_DMA_TYPE_MASK (3<<0) -diff --git a/include/linux/mfd-core.h b/include/linux/mfd-core.h -new file mode 100644 -index 0000000..0e9de78 ---- /dev/null -+++ b/include/linux/mfd-core.h -@@ -0,0 +1,51 @@ -+#ifndef MFD_CORE_H -+#define MFD_CORE_H -+/* -+ * drivers/mfd/mfd-core.h -+ * -+ * core MFD support -+ * Copyright (c) 2006 Ian Molton -+ * Copyright (c) 2007 Dmitry Baryshkov -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/platform_device.h> -+ -+struct mfd_cell { -+ const char *name; -+ -+ int (*enable)(struct platform_device *dev); -+ int (*disable)(struct platform_device *dev); -+ int (*suspend)(struct platform_device *dev); -+ int (*resume)(struct platform_device *dev); -+ -+ void *driver_data; /* data passed to drivers */ -+ -+ /* -+ * This resources can be specified relatievly to the parent device. -+ * For accessing device you should use resources from device -+ */ -+ int num_resources; -+ const struct resource *resources; -+}; -+ -+static inline __maybe_unused struct mfd_cell * -+mfd_get_cell(struct platform_device *pdev) -+{ -+ return *((struct mfd_cell **)(pdev->dev.platform_data)); -+} -+ -+extern int mfd_add_devices( -+ struct platform_device *parent, -+ const struct mfd_cell *cells, int n_devs, -+ struct resource *mem, -+ int relative_addr_shift, -+ int irq_base); -+ -+extern void mfd_remove_devices(struct platform_device *parent); -+ -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch deleted file mode 100644 index a78c0f37f3..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch +++ /dev/null @@ -1,907 +0,0 @@ -From 3f56cac281fb407b7d8e574d18ee7d72aa7e7c28 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sat, 29 Dec 2007 15:02:30 +0000 -Subject: [PATCH 04/64] Add support for tc6393xb MFD core - ---- - drivers/mfd/Kconfig | 6 + - drivers/mfd/Makefile | 2 + - drivers/mfd/tc6393xb.c | 740 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/tc6393xb.h | 108 ++++++ - 4 files changed, 856 insertions(+), 0 deletions(-) - create mode 100644 drivers/mfd/tc6393xb.c - create mode 100644 include/linux/mfd/tc6393xb.h - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 1205c89..9903d0a 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -9,6 +9,12 @@ config MFD_CORE - tristate - default n - -+config MFD_TC6393XB -+ bool "Support Toshiba TC6393XB" -+ select MFD_CORE -+ help -+ Support for Toshiba Mobile IO Controller TC6393XB -+ - config MFD_SM501 - tristate "Support for Silicon Motion SM501" - ---help--- -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 6c20064..ffd342e 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -6,6 +6,8 @@ obj-$(CONFIG_MFD_SM501) += sm501.o - - obj-$(CONFIG_MFD_CORE) += mfd-core.o - -+obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o -+ - obj-$(CONFIG_MCP) += mcp-core.o - obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o - obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -new file mode 100644 -index 0000000..9439f39 ---- /dev/null -+++ b/drivers/mfd/tc6393xb.c -@@ -0,0 +1,740 @@ -+/* -+ * Toshiba TC6393XB SoC support -+ * -+ * Copyright(c) 2005-2006 Chris Humbert -+ * Copyright(c) 2005 Dirk Opfer -+ * Copyright(c) 2005 Ian Molton <spyro@f2s.com> -+ * Copyright(c) 2007 Dmitry Baryshkov -+ * -+ * Based on code written by Sharp/Lineo for 2.4 kernels -+ * Based on locomo.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/platform_device.h> -+#include <linux/fb.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+#include <linux/mfd/tc6393xb.h> -+ -+struct tc6393xb_scr { -+ u8 x00[8]; -+ u8 revid; /* 0x08 Revision ID */ -+ u8 x01[0x47]; -+ u8 isr; /* 0x50 Interrupt Status */ -+ u8 x02; -+ u8 imr; /* 0x52 Interrupt Mask */ -+ u8 x03; -+ u8 irr; /* 0x54 Interrupt Routing */ -+ u8 x04[0x0b]; -+ u16 gper; /* 0x60 GP Enable */ -+ u8 x05[2]; -+ u16 gpi_sr[2]; /* 0x64 GPI Status */ -+ u16 gpi_imr[2]; /* 0x68 GPI INT Mask */ -+ u16 gpi_eder[2]; /* 0x6c GPI Edge Detect Enable */ -+ u16 gpi_lir[4]; /* 0x70 GPI Level Invert */ -+ u16 gpo_dsr[2]; /* 0x78 GPO Data Set */ -+ u16 gpo_doecr[2]; /* 0x7c GPO Data OE Control */ -+ u16 gp_iarcr[2]; /* 0x80 GP Internal Active Reg Control */ -+ u16 gp_iarlcr[2]; /* 0x84 GP Internal Active Reg Level Con*/ -+ u8 gpi_bcr[4]; /* 0x88 GPI Buffer Control */ -+ u16 gpa_iarcr; /* 0x8c GPa Internal Active Reg Control */ -+ u8 x06[2]; -+ u16 gpa_iarlcr; /* 0x90 GPa Internal Active Reg Level Co*/ -+ u8 x07[2]; -+ u16 gpa_bcr; /* 0x94 GPa Buffer Control */ -+ u8 x08[2]; -+ u16 ccr; /* 0x98 Clock Control */ -+ u16 pll2cr; /* 0x9a PLL2 Control */ -+ u16 pll1cr[2]; /* 0x9c PLL1 Control */ -+ u8 diarcr; /* 0xa0 Device Internal Active Reg Contr*/ -+ u8 dbocr; /* 0xa1 Device Buffer Off Control */ -+ u8 x09[0x3e]; -+ u8 fer; /* 0xe0 Function Enable */ -+ u8 x10[3]; -+ u16 mcr; /* 0xe4 Mode Control */ -+ u8 x11[0x14]; -+ u8 config; /* 0xfc Configuration Control */ -+ u8 x12[2]; -+ u8 debug; /* 0xff Debug */ -+} __attribute__ ((packed)); -+ -+/*--------------------------------------------------------------------------*/ -+ -+struct tc6393xb { -+ struct tc6393xb_scr __iomem *scr; -+ -+ spinlock_t lock; /* protects RMW cycles */ -+ -+ struct { -+ union tc6393xb_scr_fer fer; -+ union tc6393xb_scr_ccr ccr; -+ u8 gpi_bcr[4]; -+ } suspend_state; -+ -+ struct resource rscr; -+ struct resource *iomem; -+ int irq; -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int tc6393xb_mmc_enable(struct platform_device *mmc) { -+ struct platform_device *dev = to_platform_device(mmc->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.ck32ken = 1; -+ iowrite16(ccr.raw, &scr->ccr); -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_mmc_disable(struct platform_device *mmc) { -+ struct platform_device *dev = to_platform_device(mmc->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.ck32ken = 0; -+ iowrite16(ccr.raw, &scr->ccr); -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int tc6393xb_nand_disable(struct platform_device *nand) -+{ -+ return 0; -+} -+ -+static int tc6393xb_nand_enable(struct platform_device *nand) -+{ -+ struct platform_device *dev = to_platform_device(nand->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ /* SMD buffer on */ -+ dev_dbg(&dev->dev, "SMD buffer on\n"); -+ iowrite8(0xff, scr->gpi_bcr + 1); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) -+{ -+ struct platform_device *dev = to_platform_device(fb->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_fer fer; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ fer.raw = ioread8(&scr->fer); -+ fer.bits.slcden = on ? 1 : 0; -+ iowrite8(fer.raw, &scr->fer); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+EXPORT_SYMBOL(tc6393xb_lcd_set_power); -+ -+int tc6393xb_lcd_mode(struct platform_device *fb_dev, -+ struct fb_videomode *mode) { -+ struct tc6393xb *tc6393xb = -+ platform_get_drvdata(to_platform_device(fb_dev->dev.parent)); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ -+ iowrite16(mode->pixclock, scr->pll1cr + 0); -+ iowrite16(mode->pixclock >> 16, scr->pll1cr + 1); -+ -+ return 0; -+} -+EXPORT_SYMBOL(tc6393xb_lcd_mode); -+ -+static int tc6393xb_ohci_disable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ union tc6393xb_scr_fer fer; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ fer.raw = ioread8(&scr->fer); -+ fer.bits.usben = 0; -+ iowrite8(fer.raw, &scr->fer); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 0; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_ohci_enable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ union tc6393xb_scr_fer fer; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 1; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ fer.raw = ioread8(&scr->fer); -+ fer.bits.usben = 1; -+ iowrite8(fer.raw, &scr->fer); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_fb_disable(struct platform_device *fb) -+{ -+ struct platform_device *dev = to_platform_device(fb->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ union tc6393xb_scr_fer fer; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ /* -+ * FIXME: is this correct or it should be moved to other _disable? -+ */ -+ fer.raw = ioread8(&scr->fer); -+ fer.bits.slcden = 0; -+/* fer.bits.lcdcven = 0; */ -+ iowrite8(fer.raw, &scr->fer); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.mclksel = disable; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_fb_enable(struct platform_device *fb) -+{ -+ struct platform_device *dev = to_platform_device(fb->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.mclksel = m48MHz; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_fb_suspend(struct platform_device *fb) -+{ -+ struct platform_device *dev = to_platform_device(fb->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.mclksel = disable; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_fb_resume(struct platform_device *fb) -+{ -+ struct platform_device *dev = to_platform_device(fb->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.mclksel = m48MHz; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static struct resource tc6393xb_mmc_resources[] = { -+ { -+ .name = TMIO_MMC_CONTROL, -+ .start = 0x800, -+ .end = 0x9ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_CONFIG, -+ .start = 0x200, -+ .end = 0x2ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_IRQ, -+ .start = IRQ_TC6393_MMC, -+ .end = IRQ_TC6393_MMC, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+const static struct resource tc6393xb_nand_resources[] = { -+ { -+ .name = TMIO_NAND_CONFIG, -+ .start = 0x0100, -+ .end = 0x01ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_NAND_CONTROL, -+ .start = 0x1000, -+ .end = 0x1007, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_NAND_IRQ, -+ .start = IRQ_TC6393_NAND, -+ .end = IRQ_TC6393_NAND, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+const static struct resource tc6393xb_ohci_resources[] = { -+ { -+ .name = TMIO_OHCI_CONFIG, -+ .start = 0x0300, -+ .end = 0x03ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_CONTROL, -+ .start = 0x3000, -+ .end = 0x31ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_SRAM, -+ .start = 0x010000, -+ .end = 0x017fff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_SRAM_ALIAS, -+ .start = 0x018000, -+ .end = 0x01ffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_IRQ, -+ .start = IRQ_TC6393_OHCI, -+ .end = IRQ_TC6393_OHCI, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+const static struct resource tc6393xb_fb_resources[] = { -+ { -+ .name = TMIO_FB_CONFIG, -+ .start = 0x0500, -+ .end = 0x05ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_FB_CONTROL, -+ .start = 0x5000, -+ .end = 0x51ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_FB_VRAM, -+ .start = 0x100000, -+ .end = 0x1fffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_FB_IRQ, -+ .start = IRQ_TC6393_FB, -+ .end = IRQ_TC6393_FB, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+static struct mfd_cell tc6393xb_cells[] = { -+ { -+ .name = "tmio-nand", -+ .enable = tc6393xb_nand_enable, -+ .disable = tc6393xb_nand_disable, -+ .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), -+ .resources = tc6393xb_nand_resources, -+ }, -+ { -+ .name = "tmio-ohci", -+ .enable = tc6393xb_ohci_enable, -+ .disable = tc6393xb_ohci_disable, -+ .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), -+ .resources = tc6393xb_ohci_resources, -+ }, -+ { -+ .name = "tmio-fb", -+ .enable = tc6393xb_fb_enable, -+ .disable = tc6393xb_fb_disable, -+ .suspend = tc6393xb_fb_suspend, -+ .resume = tc6393xb_fb_resume, -+ .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), -+ .resources = tc6393xb_fb_resources, -+ }, -+ { -+ .name = "tmio-mmc", -+ .enable = tc6393xb_mmc_enable, -+ .disable = tc6393xb_mmc_disable, -+ .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), -+ .resources = tc6393xb_mmc_resources, -+ }, -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static void -+tc6393xb_irq(unsigned int irq, struct irq_desc *desc) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned int isr; -+ unsigned int i; -+ -+ desc->chip->ack(irq); -+ -+ while ((isr = ioread8(&scr->isr) & ~ioread8(&scr->imr))) -+ for (i = 0; i < TC6393XB_NR_IRQS; i++) { -+ if (isr & (1 << i)) -+ desc_handle_irq(tcpd->irq_base + i, -+ irq_desc + tcpd->irq_base + i); -+ } -+} -+ -+static void tc6393xb_irq_ack(unsigned int irq) -+{ -+} -+ -+static void tc6393xb_irq_mask(unsigned int irq) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ iowrite8(ioread8(&scr->imr) | (1 << (irq - tcpd->irq_base)), -+ &scr->imr); -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+} -+ -+static void tc6393xb_irq_unmask(unsigned int irq) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ iowrite8(ioread8(&scr->imr) & ~(1 << (irq - tcpd->irq_base)), -+ &scr->imr); -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+} -+ -+static struct irq_chip tc6393xb_chip = { -+ .name = "tc6393xb", -+ .ack = tc6393xb_irq_ack, -+ .mask = tc6393xb_irq_mask, -+ .unmask = tc6393xb_irq_unmask, -+}; -+ -+static void tc6393xb_attach_irq(struct platform_device *dev) -+{ -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ unsigned int irq; -+ -+ for ( -+ irq = tcpd->irq_base; -+ irq <= tcpd->irq_base + TC6393XB_NR_IRQS; -+ irq++) { -+ set_irq_chip(irq, &tc6393xb_chip); -+ set_irq_chip_data(irq, dev); -+ set_irq_handler(irq, handle_edge_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ } -+ -+ set_irq_type(tc6393xb->irq, IRQT_FALLING); -+ set_irq_chip_data(tc6393xb->irq, dev); -+ set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); -+} -+ -+static void tc6393xb_detach_irq(struct platform_device *dev) -+{ -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ unsigned int irq; -+ -+ set_irq_chained_handler(tc6393xb->irq, NULL); -+ set_irq_chip_data(tc6393xb->irq, NULL); -+ -+ for ( -+ irq = tcpd->irq_base; -+ irq <= tcpd->irq_base + TC6393XB_NR_IRQS; -+ irq++) { -+ set_irq_flags(irq, 0); -+ set_irq_chip(irq, NULL); -+ set_irq_chip_data(irq, NULL); -+ } -+} -+ -+static int tc6393xb_hw_init(struct platform_device *dev, int resume) -+{ -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ int ret; -+ int i; -+ -+ if (resume) -+ ret = tcpd->resume(dev); -+ else -+ ret = tcpd->enable(dev); -+ if (ret) -+ return ret; -+ -+ iowrite8(resume ? -+ tc6393xb->suspend_state.fer.raw : -+ 0, &scr->fer); -+ iowrite16(tcpd->scr_pll2cr, &scr->pll2cr); -+ iowrite16(resume? -+ tc6393xb->suspend_state.ccr.raw : -+ tcpd->scr_ccr.raw, &scr->ccr); -+ iowrite16(tcpd->scr_mcr.raw, &scr->mcr); -+ iowrite16(tcpd->scr_gper, &scr->gper); -+ iowrite8(0, &scr->irr); -+ iowrite8(0xbf, &scr->imr); -+ iowrite16(tcpd->scr_gpo_dsr, scr->gpo_dsr + 0); -+ iowrite16(tcpd->scr_gpo_dsr >> 16, scr->gpo_dsr + 1); -+ iowrite16(tcpd->scr_gpo_doecr, scr->gpo_doecr + 0); -+ iowrite16(tcpd->scr_gpo_doecr >> 16, scr->gpo_doecr + 1); -+ -+ if (resume) -+ for (i = 0; i < 4; i++) -+ iowrite8(tc6393xb->suspend_state.gpi_bcr[i], -+ scr->gpi_bcr + i); -+ -+ return 0; -+} -+ -+static int __devinit tc6393xb_probe(struct platform_device *dev) -+{ -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb; -+ struct resource *iomem; -+ struct resource *rscr; -+ int retval; -+ -+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); -+ if (!iomem) -+ return -EINVAL; -+ -+ tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); -+ if (!tc6393xb) { -+ retval = -ENOMEM; -+ goto err_kzalloc; -+ } -+ -+ spin_lock_init(&tc6393xb->lock); -+ -+ platform_set_drvdata(dev, tc6393xb); -+ tc6393xb->iomem = iomem; -+ tc6393xb->irq = platform_get_irq(dev, 0); -+ -+ rscr = &tc6393xb->rscr; -+ rscr->name = "tc6393xb-core"; -+ rscr->start = iomem->start; -+ rscr->end = iomem->start + 0xff; -+ rscr->flags = IORESOURCE_MEM; -+ -+ retval = request_resource(iomem, rscr); -+ if (retval) -+ goto err_request_scr; -+ -+ tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); -+ if (!tc6393xb->scr) { -+ retval = -ENOMEM; -+ goto err_ioremap; -+ } -+ -+ retval = tc6393xb_hw_init(dev, 0); -+ if (retval) -+ goto err_hw_init; -+ -+ printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", -+ ioread8(&tc6393xb->scr->revid), -+ (unsigned long) iomem->start, tc6393xb->irq); -+ -+ if (tc6393xb->irq) -+ tc6393xb_attach_irq(dev); -+ -+ tc6393xb_cells[0].driver_data = tcpd->nand_data; -+ tc6393xb_cells[1].driver_data = NULL; /* tcpd->ohci_data; */ -+ tc6393xb_cells[2].driver_data = tcpd->fb_data; -+ -+ retval = mfd_add_devices(dev, -+ tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), -+ iomem, 0, tcpd->irq_base); -+ -+ if (retval == 0) -+ return 0; -+ -+ if (tc6393xb->irq) -+ tc6393xb_detach_irq(dev); -+ -+err_hw_init: -+ iounmap(tc6393xb->scr); -+err_ioremap: -+ release_resource(rscr); -+err_request_scr: -+ kfree(tc6393xb); -+err_kzalloc: -+ release_resource(iomem); -+ return retval; -+} -+ -+static int __devexit tc6393xb_remove(struct platform_device *dev) { -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ int ret; -+ -+ if (tc6393xb->irq) -+ tc6393xb_detach_irq(dev); -+ -+ ret = tcpd->disable(dev); -+ -+ iounmap(tc6393xb->scr); -+ release_resource(&tc6393xb->rscr); -+ release_resource(tc6393xb->iomem); -+ -+ mfd_remove_devices(dev); -+ -+ platform_set_drvdata(dev, NULL); -+ -+ kfree(tc6393xb); -+ -+ return ret; -+} -+ -+#ifdef CONFIG_PM -+static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ int i; -+ -+ -+ tc6393xb->suspend_state.ccr.raw = ioread16(&scr->ccr); -+ tc6393xb->suspend_state.fer.raw = ioread8(&scr->fer); -+ for (i = 0; i < 4; i++) -+ tc6393xb->suspend_state.gpi_bcr[i] = -+ ioread8(scr->gpi_bcr + i); -+ -+ return tcpd->suspend(dev); -+} -+ -+static int tc6393xb_resume(struct platform_device *dev) -+{ -+ return tc6393xb_hw_init(dev, 1); -+} -+#else -+#define tc6393xb_suspend NULL -+#define tc6393xb_resume NULL -+#endif -+ -+static struct platform_driver tc6393xb_driver = { -+ .probe = tc6393xb_probe, -+ .remove = __devexit_p(tc6393xb_remove), -+ .suspend = tc6393xb_suspend, -+ .resume = tc6393xb_resume, -+ -+ .driver = { -+ .name = "tc6393xb", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init tc6393xb_init(void) -+{ -+ return platform_driver_register(&tc6393xb_driver); -+} -+ -+static void __exit tc6393xb_exit(void) -+{ -+ platform_driver_unregister(&tc6393xb_driver); -+} -+ -+module_init(tc6393xb_init); -+module_exit(tc6393xb_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); -+MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); -diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h -new file mode 100644 -index 0000000..e699294 ---- /dev/null -+++ b/include/linux/mfd/tc6393xb.h -@@ -0,0 +1,108 @@ -+/* -+ * Toshiba TC6393XB SoC support -+ * -+ * Copyright(c) 2005-2006 Chris Humbert -+ * Copyright(c) 2005 Dirk Opfer -+ * Copyright(c) 2005 Ian Molton <spyro@f2s.com> -+ * Copyright(c) 2007 Dmitry Baryshkov -+ * -+ * Based on code written by Sharp/Lineo for 2.4 kernels -+ * Based on locomo.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef TC6393XB_H -+#define TC6393XB_H -+ -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+ -+union tc6393xb_scr_fer { -+ u8 raw; -+struct { -+ unsigned usben:1; /* D0 USB enable */ -+ unsigned lcdcven:1; /* D1 polysylicon TFT enable */ -+ unsigned slcden:1; /* D2 SLCD enable */ -+} __attribute__ ((packed)) bits; -+} __attribute__ ((packed)); -+ -+union tc6393xb_scr_ccr { -+ u16 raw; -+struct { -+ unsigned ck32ken:1; /* D0 SD host clock enable */ -+ unsigned usbcken:1; /* D1 USB host clock enable */ -+ unsigned x00:2; -+ unsigned sharp:1; /* D4 ??? set in Sharp's code */ -+ unsigned x01:3; -+ enum { disable = 0, -+ m12MHz = 1, -+ m24MHz = 2, -+ m48MHz = 3, -+ } mclksel:3; /* D10-D8 LCD controller clock */ -+ unsigned x02:1; -+ enum { h24MHz = 0, -+ h48MHz = 1, -+ } hclksel:2; /* D13-D12 host bus clock */ -+ unsigned x03:2; -+} __attribute__ ((packed)) bits; -+} __attribute__ ((packed)); -+ -+enum pincontrol { -+ opendrain = 0, -+ tristate = 1, -+ pushpull = 2, -+ /* reserved = 3, */ -+}; -+ -+union tc6393xb_scr_mcr { -+ u16 raw; -+struct { -+ enum pincontrol rdyst:2; /* D1-D0 HRDY control */ -+ unsigned x00:1; -+ unsigned aren:1; /* D3 HRDY pull up resistance cut off */ -+ enum pincontrol intst:2; /* D5-D4 #HINT control */ -+ unsigned x01:1; -+ unsigned aien:1; /* D7 #HINT pull up resitance cut off */ -+ unsigned x02:8; -+} __attribute__ ((packed)) bits; -+} __attribute__ ((packed)); -+ -+struct tc6393xb_platform_data { -+ u16 scr_pll2cr; /* PLL2 Control */ -+ union tc6393xb_scr_ccr scr_ccr; /* Clock Control */ -+ union tc6393xb_scr_mcr scr_mcr; /* Mode Control */ -+ u16 scr_gper; /* GP Enable */ -+ u32 scr_gpo_doecr; /* GPO Data OE Control */ -+ u32 scr_gpo_dsr; /* GPO Data Set */ -+ -+ int (*enable)(struct platform_device *dev); -+ int (*disable)(struct platform_device *dev); -+ int (*suspend)(struct platform_device *dev); -+ int (*resume)(struct platform_device *dev); -+ -+ int irq_base; /* a base for cascaded irq */ -+ -+ struct tmio_nand_data *nand_data; -+ struct tmio_fb_data *fb_data; -+}; -+ -+extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on); -+extern int tc6393xb_lcd_mode(struct platform_device *fb_dev, -+ struct fb_videomode *mode); -+ -+ -+/* -+ * Relative to irq_base -+ */ -+#define IRQ_TC6393_NAND 0 -+#define IRQ_TC6393_MMC 1 -+#define IRQ_TC6393_OHCI 2 -+#define IRQ_TC6393_SERIAL 3 -+#define IRQ_TC6393_FB 4 -+ -+#define TC6393XB_NR_IRQS 8 -+ -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch deleted file mode 100644 index 7183e3af6d..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch +++ /dev/null @@ -1,249 +0,0 @@ -From a6a6faf1dbb90c950fe55a1719720457bfb5830a Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sun, 16 Dec 2007 02:19:49 +0000 -Subject: [PATCH 05/64] Add support for tc6387xb MFD core - ---- - drivers/mfd/Kconfig | 6 ++ - drivers/mfd/Makefile | 1 + - drivers/mfd/tc6387xb.c | 163 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/tc6387xb.h | 28 +++++++ - 4 files changed, 198 insertions(+), 0 deletions(-) - create mode 100644 drivers/mfd/tc6387xb.c - create mode 100644 include/linux/mfd/tc6387xb.h - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 9903d0a..1575323 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -9,6 +9,12 @@ config MFD_CORE - tristate - default n - -+config MFD_TC6387XB -+ bool "Support Toshiba TC6387XB" -+ select MFD_CORE -+ help -+ Support for Toshiba Mobile IO Controller TC6387XB -+ - config MFD_TC6393XB - bool "Support Toshiba TC6393XB" - select MFD_CORE -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index ffd342e..41b2190 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -6,6 +6,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o - - obj-$(CONFIG_MFD_CORE) += mfd-core.o - -+obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o - obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o - - obj-$(CONFIG_MCP) += mcp-core.o -diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c -new file mode 100644 -index 0000000..c81fca2 ---- /dev/null -+++ b/drivers/mfd/tc6387xb.c -@@ -0,0 +1,163 @@ -+/* -+ * Toshiba TC6387XB support -+ * Copyright (c) 2005 Ian Molton -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This file contains TC6387XB base support. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/platform_device.h> -+ -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include <linux/mfd-core.h> -+#include <linux/mfd/tc6387xb.h> -+ -+#ifdef CONFIG_PM -+static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev); -+ -+ if (pdata && pdata->suspend) -+ pdata->suspend(dev); -+ -+ return 0; -+} -+ -+static int tc6387xb_resume(struct platform_device *dev) -+{ -+ struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev); -+ -+ if (pdata && pdata->resume) -+ pdata->resume(dev); -+ -+ return 0; -+} -+#else -+#define tc6387xb_suspend NULL -+#define tc6387xb_resume NULL -+#endif -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int tc6387xb_mmc_enable(struct platform_device *mmc) { -+ struct platform_device *dev = to_platform_device(mmc->dev.parent); -+ struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data; -+ -+ if(tc6387xb->enable_mmc_clock) -+ tc6387xb->enable_mmc_clock(dev); -+ -+ return 0; -+} -+ -+static int tc6387xb_mmc_disable(struct platform_device *mmc) { -+ struct platform_device *dev = to_platform_device(mmc->dev.parent); -+ struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data; -+ -+ if(tc6387xb->disable_mmc_clock) -+ tc6387xb->disable_mmc_clock(dev); -+ -+ return 0; -+} -+ -+ -+/*--------------------------------------------------------------------------*/ -+ -+static struct resource tc6387xb_mmc_resources[] = { -+ { -+ .name = TMIO_MMC_CONTROL, -+ .start = 0x800, -+ .end = 0x9ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_CONFIG, -+ .start = 0x200, -+ .end = 0x2ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_IRQ, -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+static struct mfd_cell tc6387xb_cells[] = { -+ { -+ .name = "tmio-mmc", -+ .enable = tc6387xb_mmc_enable, -+ .disable = tc6387xb_mmc_disable, -+ .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), -+ .resources = tc6387xb_mmc_resources, -+ }, -+}; -+ -+static int tc6387xb_probe(struct platform_device *dev) -+{ -+ struct tc6387xb_platform_data *data = platform_get_drvdata(dev); -+ struct resource *iomem; -+ int irq; -+ -+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); -+ if (!iomem) -+ return -EINVAL; -+ -+ irq = platform_get_irq(dev, 0); -+ -+ if(data && data->enable) -+ data->enable(dev); -+ -+ printk(KERN_INFO "Toshiba tc6393xb initialised\n"); -+ -+ return mfd_add_devices(dev, tc6387xb_cells, ARRAY_SIZE(tc6387xb_cells), -+ iomem, 0, irq); -+} -+ -+static int tc6387xb_remove(struct platform_device *dev) -+{ -+ struct tc6387xb_platform_data *data = platform_get_drvdata(dev); -+ -+ if(data && data->disable) -+ data->disable(dev); -+ -+ return 0; -+} -+ -+ -+static struct platform_driver tc6387xb_platform_driver = { -+ .driver = { -+ .name = "tc6387xb", -+ }, -+ .probe = tc6387xb_probe, -+ .remove = tc6387xb_remove, -+ .suspend = tc6387xb_suspend, -+ .resume = tc6387xb_resume, -+}; -+ -+ -+static int __init tc6387xb_init(void) -+{ -+ return platform_driver_register (&tc6387xb_platform_driver); -+} -+ -+static void __exit tc6387xb_exit(void) -+{ -+ platform_driver_unregister(&tc6387xb_platform_driver); -+} -+ -+module_init(tc6387xb_init); -+module_exit(tc6387xb_exit); -+ -+MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); -+MODULE_LICENSE("GPLv2"); -+MODULE_AUTHOR("Ian Molton"); -diff --git a/include/linux/mfd/tc6387xb.h b/include/linux/mfd/tc6387xb.h -new file mode 100644 -index 0000000..496770b ---- /dev/null -+++ b/include/linux/mfd/tc6387xb.h -@@ -0,0 +1,28 @@ -+/* -+ * linux/include/asm-arm/hardware/tc6387xb.h -+ * -+ * This file contains the definitions for the TC6393XB -+ * -+ * (C) Copyright 2005 Ian Molton <spyro@f2s.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public -+ * License. See linux/COPYING for more information. -+ * -+ */ -+#ifndef MFD_T7L66XB_H -+#define MFD_T7L66XB_H -+ -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+ -+struct tc6387xb_platform_data -+{ -+ int (*enable_mmc_clock)(struct platform_device *dev); -+ int (*disable_mmc_clock)(struct platform_device *dev); -+ int (*enable)(struct platform_device *dev); -+ int (*disable)(struct platform_device *dev); -+ int (*suspend)(struct platform_device *dev); -+ int (*resume)(struct platform_device *dev); -+}; -+ -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch deleted file mode 100644 index e7aff2455b..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch +++ /dev/null @@ -1,653 +0,0 @@ -From 2e31fea352ca97988452f1f2c94809de2977ce40 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sat, 29 Dec 2007 15:08:52 +0000 -Subject: [PATCH 06/64] Add support for t7l66xb MFD core - ---- - drivers/mfd/Kconfig | 6 + - drivers/mfd/Makefile | 1 + - drivers/mfd/t7l66xb.c | 550 +++++++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/t7l66xb.h | 45 ++++ - 4 files changed, 602 insertions(+), 0 deletions(-) - create mode 100644 drivers/mfd/t7l66xb.c - create mode 100644 include/linux/mfd/t7l66xb.h - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 1575323..f79a969 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -9,6 +9,12 @@ config MFD_CORE - tristate - default n - -+config MFD_T7L66XB -+ bool "Support Toshiba T7L66XB" -+ select MFD_CORE -+ help -+ Support for Toshiba Mobile IO Controller T7L66XB -+ - config MFD_TC6387XB - bool "Support Toshiba TC6387XB" - select MFD_CORE -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 41b2190..b2037ae 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -6,6 +6,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o - - obj-$(CONFIG_MFD_CORE) += mfd-core.o - -+obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o - obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o - obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o - -diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c -new file mode 100644 -index 0000000..308776a ---- /dev/null -+++ b/drivers/mfd/t7l66xb.c -@@ -0,0 +1,550 @@ -+/* -+ * -+ * Toshiba T7L66XB core mfd support -+ * -+ * Copyright (c) 2005 Ian Molton -+ * Copyright (c) 2007 Ian Molton -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * T7L66 features: -+ * -+ * Supported in this driver: -+ * SD/MMC -+ * SM/NAND flash controller -+ * OHCI controller -+ * -+ * As yet not supported -+ * GPIO interface (on NAND pins) -+ * Serial interface -+ * TFT 'interface converter' -+ * PCMCIA interface logic -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/platform_device.h> -+#include <linux/fb.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+#include <linux/mfd/t7l66xb.h> -+ -+union t7l66xb_dev_ctl { -+ u8 raw; -+struct { -+ unsigned usb_en:1; /* D0 USB enable */ -+ unsigned mmc_en:1; /* D1 MMC enable */ -+} __attribute__ ((packed)); -+} __attribute__ ((packed)); -+ -+ -+struct t7l66xb_scr { -+ u8 x00[8]; -+ u8 revid; /* 0x08 Revision ID */ -+ u8 x01[57]; -+ u8 imr; /* 0x42 Interrupt Mask */ -+ u8 x03[157]; -+ union t7l66xb_dev_ctl dev_ctl; /* 0xe0 Device control */ -+ u8 isr; /* 0xe1 Interrupt Status */ -+ u8 x04[14]; -+ u8 gpio_output_ctl; /* 0xf0 */ -+ u8 gpio_output_status; /* 0xf1 */ -+ u16 gpio_input_status; /* 0xf2 */ -+ u8 x05[4]; -+ u8 active_pullup_down_ctl; /* 0xf8 */ -+ u8 x06[7]; -+} __attribute__ ((packed)); -+ -+ -+/*--------------------------------------------------------------------------*/ -+ -+struct t7l66xb -+{ -+ struct t7l66xb_scr __iomem *scr; -+ spinlock_t lock; -+ -+ struct resource rscr; -+ struct resource *iomem; -+ int irq; -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int t7l66xb_ohci_enable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ dev_ctl.raw = readb(&scr->dev_ctl); -+ dev_ctl.usb_en = 1; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+static int t7l66xb_ohci_disable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ dev_ctl.raw = readb(&scr->dev_ctl); -+ dev_ctl.usb_en = 0; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int t7l66xb_mmc_enable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ if(pdata->enable_clk32k) -+ pdata->enable_clk32k(dev); -+ dev_ctl.raw = readb(&scr->dev_ctl); -+ dev_ctl.mmc_en = 1; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+static int t7l66xb_mmc_disable(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ dev_ctl.raw = readb(&scr->dev_ctl); -+ dev_ctl.mmc_en = 0; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ if(pdata->disable_clk32k) -+ pdata->disable_clk32k(dev); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int t7l66xb_nand_disable(struct platform_device *nand) -+{ -+ struct platform_device *dev = to_platform_device(nand->dev.parent); -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ dev_ctl.raw = readb(&scr->dev_ctl); -+// dev_ctl.nand_en = 0; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+static int t7l66xb_nand_enable(struct platform_device *nand) -+{ -+ struct platform_device *dev = to_platform_device(nand->dev.parent); -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ union t7l66xb_dev_ctl dev_ctl; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ -+ dev_ctl.raw = readb(&scr->dev_ctl); -+ // dev_ctl.nand_en = 1; -+ writeb(dev_ctl.raw, &scr->dev_ctl); -+ -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+ -+ return 0; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+const static struct resource t7l66xb_mmc_resources[] = { -+ { -+ .name = TMIO_MMC_CONTROL, -+ .start = 0x800, -+ .end = 0x9ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_CONFIG, -+ .start = 0x200, -+ .end = 0x2ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_MMC_IRQ, -+ .start = IRQ_T7L66XB_MMC, -+ .end = IRQ_T7L66XB_MMC, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+const static struct resource t7l66xb_ohci_resources[] = { -+ { -+ .name = TMIO_OHCI_CONFIG, -+ .start = 0x0300, -+ .end = 0x03ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_CONTROL, -+ .start = 0xa00, -+ .end = 0xbff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_SRAM, -+ .start = 0x01000, -+ .end = 0x02fff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_OHCI_IRQ, -+ .start = IRQ_T7L66XB_OHCI, -+ .end = IRQ_T7L66XB_OHCI, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+const static struct resource t7l66xb_nand_resources[] = { -+ { -+ .name = TMIO_NAND_CONFIG, -+ .start = 0x0100, -+ .end = 0x01ff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_NAND_CONTROL, -+ .start = 0xc00, -+ .end = 0xc07, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = TMIO_NAND_IRQ, -+ .start = IRQ_T7L66XB_NAND, -+ .end = IRQ_T7L66XB_NAND, -+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE, -+ }, -+}; -+ -+static struct mfd_cell t7l66xb_cells[] = { -+ { -+ .name = "tmio-mmc", -+ .enable = t7l66xb_mmc_enable, -+ .disable = t7l66xb_mmc_disable, -+ .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), -+ .resources = t7l66xb_mmc_resources, -+ }, -+ { -+ .name = "tmio-ohci", -+ .enable = t7l66xb_ohci_enable, -+ .disable = t7l66xb_ohci_disable, -+ .num_resources = ARRAY_SIZE(t7l66xb_ohci_resources), -+ .resources = t7l66xb_ohci_resources, -+ }, -+ { -+ .name = "tmio-nand", -+ .enable = t7l66xb_nand_enable, -+ .disable = t7l66xb_nand_disable, -+ .num_resources = ARRAY_SIZE(t7l66xb_nand_resources), -+ .resources = t7l66xb_nand_resources, -+ }, -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+/* Handle the T7L66XB interrupt mux */ -+static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned int isr; -+ unsigned int i; -+ -+ desc->chip->ack(irq); -+ while ((isr = readb(&scr->isr) & ~readb(&scr->imr))) -+ for (i = 0; i < T7L66XB_NR_IRQS; i++) -+ if (isr & (1 << i)) -+ desc_handle_irq(tcpd->irq_base + i, -+ irq_desc + tcpd->irq_base + i); -+} -+ -+static void t7l66xb_irq_mask(unsigned int irq) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ iowrite8(ioread8(&scr->imr) | (1 << (irq - tcpd->irq_base)), -+ &scr->imr); -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+} -+ -+static void t7l66xb_irq_unmask(unsigned int irq) -+{ -+ struct platform_device *dev = get_irq_chip_data(irq); -+ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ struct t7l66xb_scr __iomem *scr = t7l66xb->scr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&t7l66xb->lock, flags); -+ iowrite8(ioread8(&scr->imr) & ~(1 << (irq - tcpd->irq_base)), -+ &scr->imr); -+ spin_unlock_irqrestore(&t7l66xb->lock, flags); -+} -+ -+static struct irq_chip t7l66xb_chip = { -+ .name = "t7l66xb", -+ .ack = t7l66xb_irq_mask, -+ .mask = t7l66xb_irq_mask, -+ .unmask = t7l66xb_irq_unmask, -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+/* Install the IRQ handler */ -+static void t7l66xb_attach_irq(struct platform_device *dev) -+{ -+ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ unsigned int irq; -+ -+ for ( -+ irq = tcpd->irq_base; -+ irq <= tcpd->irq_base + T7L66XB_NR_IRQS; -+ irq++) { -+ set_irq_chip (irq, &t7l66xb_chip); -+ set_irq_chip_data (irq, dev); -+ set_irq_handler(irq, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ } -+ -+ set_irq_type (t7l66xb->irq, IRQT_FALLING); -+ set_irq_chip_data (t7l66xb->irq, dev); -+ set_irq_chained_handler (t7l66xb->irq, t7l66xb_irq); -+} -+ -+static void t7l66xb_detach_irq(struct platform_device *dev) -+{ -+ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ unsigned int irq; -+ -+ set_irq_chained_handler(t7l66xb->irq, NULL); -+ set_irq_chip_data(t7l66xb->irq, NULL); -+ -+ for ( -+ irq = tcpd->irq_base; -+ irq <= tcpd->irq_base + T7L66XB_NR_IRQS; -+ irq++) { -+ set_irq_flags(irq, 0); -+ set_irq_chip(irq, NULL); -+ set_irq_chip_data(irq, NULL); -+ } -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+#ifdef CONFIG_PM -+static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ -+ -+ if (pdata && pdata->suspend) -+ pdata->suspend(dev); -+ -+ return 0; -+} -+ -+static int t7l66xb_resume(struct platform_device *dev) -+{ -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ -+ if (pdata && pdata->resume) -+ pdata->resume(dev); -+ -+ return 0; -+} -+#else -+#define t7l66xb_suspend NULL -+#define t7l66xb_resume NULL -+#endif -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int t7l66xb_probe(struct platform_device *dev) -+{ -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb; -+ struct resource *iomem; -+ struct resource *rscr; -+ int retval = -ENOMEM; -+ -+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); -+ if (!iomem) -+ return -EINVAL; -+ -+ t7l66xb = kzalloc (sizeof *t7l66xb, GFP_KERNEL); -+ if (!t7l66xb) -+ goto err_kzalloc; -+ -+ spin_lock_init(&t7l66xb->lock); -+ -+ platform_set_drvdata(dev, t7l66xb); -+ t7l66xb->iomem = iomem; -+ t7l66xb->irq = platform_get_irq(dev, 0); -+ -+ rscr = &t7l66xb->rscr; -+ rscr->name = "t7l66xb-core"; -+ rscr->start = iomem->start; -+ rscr->end = iomem->start + 0xff; -+ rscr->flags = IORESOURCE_MEM; -+ -+ if((retval = request_resource(iomem, rscr))) -+ goto err_request_scr; -+ -+ t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); -+ if (!t7l66xb->scr) { -+ retval = -ENOMEM; -+ goto err_ioremap; -+ } -+ -+ if (pdata && pdata->enable) -+ pdata->enable(dev); -+ -+ writeb(0xbf, &t7l66xb->scr->imr); /* Mask all interrupts */ -+ -+ printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n", -+ dev->name, readb(&t7l66xb->scr->revid), -+ (unsigned long)t7l66xb->scr, t7l66xb->irq); -+ -+ if(t7l66xb->irq) -+ t7l66xb_attach_irq(dev); -+ -+ t7l66xb_cells[2].driver_data = pdata->nand_data; -+ -+ if(!(retval = mfd_add_devices(dev, t7l66xb_cells, -+ ARRAY_SIZE(t7l66xb_cells), -+ iomem, 0, pdata->irq_base))) -+ return 0; -+ -+ if(t7l66xb->irq) -+ t7l66xb_detach_irq(dev); -+ -+ iounmap(t7l66xb->scr); -+err_ioremap: -+ release_resource(rscr); -+err_request_scr: -+ kfree(t7l66xb); -+err_kzalloc: -+ release_resource(iomem); -+ return retval; -+} -+ -+static int t7l66xb_remove(struct platform_device *dev) -+{ -+ struct t7l66xb_platform_data *pdata = dev->dev.platform_data; -+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev); -+ int ret; -+ -+ if (t7l66xb->irq) -+ t7l66xb_detach_irq(dev); -+ -+ ret = pdata->disable(dev); -+ -+ iounmap(t7l66xb->scr); -+ release_resource(&t7l66xb->rscr); -+ release_resource(t7l66xb->iomem); -+ -+ mfd_remove_devices(dev); -+ -+ platform_set_drvdata(dev, NULL); -+ -+ kfree(t7l66xb); -+ -+ return ret; -+ -+} -+ -+static struct platform_driver t7l66xb_platform_driver = { -+ .driver = { -+ .name = "t7l66xb", -+ .owner = THIS_MODULE, -+ }, -+ .suspend = t7l66xb_suspend, -+ .resume = t7l66xb_resume, -+ .probe = t7l66xb_probe, -+ .remove = t7l66xb_remove, -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static int __init t7l66xb_init(void) -+{ -+ int retval = 0; -+ -+ retval = platform_driver_register (&t7l66xb_platform_driver); -+ return retval; -+} -+ -+static void __exit t7l66xb_exit(void) -+{ -+ platform_driver_unregister(&t7l66xb_platform_driver); -+} -+ -+module_init(t7l66xb_init); -+module_exit(t7l66xb_exit); -+ -+MODULE_DESCRIPTION("Toshiba T7L66XB core driver"); -+MODULE_LICENSE("GPLv2"); -+MODULE_AUTHOR("Ian Molton"); -+ -diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h -new file mode 100644 -index 0000000..06b8de5 ---- /dev/null -+++ b/include/linux/mfd/t7l66xb.h -@@ -0,0 +1,45 @@ -+/* -+ * linux/include/asm-arm/hardware/t7l66xb.h -+ * -+ * This file contains the definitions for the T7L66XB -+ * -+ * (C) Copyright 2005 Ian Molton <spyro@f2s.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#ifndef _ASM_ARCH_T7L66XB_SOC -+#define _ASM_ARCH_T7L66XB_SOC -+ -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+ -+ -+struct t7l66xb_platform_data -+{ -+ int (*enable_clk32k)(struct platform_device *dev); -+ int (*disable_clk32k)(struct platform_device *dev); -+ -+ int (*enable)(struct platform_device *dev); -+ int (*disable)(struct platform_device *dev); -+ int (*suspend)(struct platform_device *dev); -+ int (*resume)(struct platform_device *dev); -+ -+ int irq_base; /* a base for cascaded irq */ -+ -+ struct tmio_nand_data *nand_data; -+}; -+ -+ -+#define T7L66XB_NAND_CNF_BASE (0x000100) -+#define T7L66XB_NAND_CTL_BASE (0x001000) -+ -+#define IRQ_T7L66XB_NAND (3) -+#define IRQ_T7L66XB_MMC (1) -+#define IRQ_T7L66XB_OHCI (2) -+ -+#define T7L66XB_NR_IRQS 8 -+ -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch b/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch deleted file mode 100644 index 2f5f11400c..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch +++ /dev/null @@ -1,81 +0,0 @@ -From d6e8b347dbcce9e0e8d2204b774c1c33cfcb483e Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sat, 29 Dec 2007 15:27:43 +0000 -Subject: [PATCH 07/64] Common headers for TMIO MFD subdevices - ---- - include/linux/mfd/tmio.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 62 insertions(+), 0 deletions(-) - create mode 100644 include/linux/mfd/tmio.h - -diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h -new file mode 100644 -index 0000000..b42a4c3 ---- /dev/null -+++ b/include/linux/mfd/tmio.h -@@ -0,0 +1,62 @@ -+#ifndef MFD_TMIO_H -+#define MFD_TMIO_H -+ -+#include <linux/io.h> -+#include <linux/platform_device.h> -+ -+struct fb_videomode; -+ -+/* -+ * data for the NAND controller -+ */ -+struct tmio_nand_data { -+ struct nand_bbt_descr *badblock_pattern; -+ struct mtd_partition *partition; -+ unsigned int num_partitions; -+}; -+ -+struct tmio_fb_data { -+ int (*lcd_set_power)(struct platform_device *fb_dev, -+ bool on); -+ int (*lcd_mode)(struct platform_device *fb_dev, -+ struct fb_videomode *mode); -+ int num_modes; -+ struct fb_videomode *modes; -+}; -+ -+static u32 __maybe_unused tmio_ioread32(const void __iomem *addr) -+{ -+ return ((u32) ioread16(addr)) | (((u32) ioread16(addr + 2)) << 16); -+} -+ -+static u32 __maybe_unused tmio_iowrite32(u32 val, const void __iomem *addr) -+{ -+ iowrite16(val, addr); -+ iowrite16(val >> 16, addr + 2); -+ return val; -+} -+ -+#define FBIO_TMIO_ACC_WRITE 0x7C639300 -+#define FBIO_TMIO_ACC_SYNC 0x7C639301 -+ -+#define TMIO_MMC_CONFIG "tmio-mmc-config" -+#define TMIO_MMC_CONTROL "tmio-mmc-control" -+#define TMIO_MMC_IRQ "tmio-mmc" -+ -+#define TMIO_NAND_CONFIG "tmio-nand-config" -+#define TMIO_NAND_CONTROL "tmio-nand-control" -+#define TMIO_NAND_IRQ "tmio-nand" -+ -+#define TMIO_FB_CONFIG "tmio-fb-config" -+#define TMIO_FB_CONTROL "tmio-fb-control" -+#define TMIO_FB_VRAM "tmio-fb-vram" -+#define TMIO_FB_IRQ "tmio-fb" -+ -+#define TMIO_OHCI_CONFIG "tmio-ohci-config" -+#define TMIO_OHCI_CONTROL "tmio-ohci-control" -+#define TMIO_OHCI_SRAM "tmio-ohci-sram" -+#define TMIO_OHCI_SRAM_ALIAS "tmio-ohci-sram-alias" -+#define TMIO_OHCI_IRQ "tmio-ohci" -+ -+#endif -+ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch deleted file mode 100644 index 48b8000ab7..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch +++ /dev/null @@ -1,608 +0,0 @@ -From 917b3997a39396f5f51418930de7b933ad053bad Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sat, 29 Dec 2007 15:14:23 +0000 -Subject: [PATCH 08/64] Nand driver for TMIO devices - ---- - drivers/mtd/nand/Kconfig | 7 + - drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/tmio_nand.c | 557 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 565 insertions(+), 0 deletions(-) - create mode 100644 drivers/mtd/nand/tmio_nand.c - -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 246d451..43e489a 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -284,6 +284,13 @@ config MTD_NAND_CM_X270 - depends on MTD_NAND && MACH_ARMCORE - - -+config MTD_NAND_TMIO -+ tristate "NAND Flash device on Toshiba Mobile IO Controller" -+ depends on MTD_NAND && MFD_CORE -+ help -+ Support for NAND flash connected to a Toshiba Mobile IO -+ Controller in some PDAs, including the Sharp SL6000x. -+ - config MTD_NAND_NANDSIM - tristate "Support for NAND Flash Simulator" - depends on MTD_PARTITIONS -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 3ad6c01..d839ebd 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o - obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o - obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o - obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o -+obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o - obj-$(CONFIG_MTD_ALAUDA) += alauda.o - -diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c -new file mode 100644 -index 0000000..450b4ec ---- /dev/null -+++ b/drivers/mtd/nand/tmio_nand.c -@@ -0,0 +1,557 @@ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/ioport.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/nand_ecc.h> -+#include <linux/mtd/partitions.h> -+ -+/*--------------------------------------------------------------------------*/ -+ -+/* tmio_nfcr.mode Register Command List */ -+#define FCR_MODE_DATA 0x94 /* Data Data_Mode */ -+#define FCR_MODE_COMMAND 0x95 /* Data Command_Mode */ -+#define FCR_MODE_ADDRESS 0x96 /* Data Address_Mode */ -+ -+#define FCR_MODE_HWECC_CALC 0xB4 /* HW-ECC Data */ -+#define FCR_MODE_HWECC_RESULT 0xD4 /* HW-ECC Calculation Result Read_Mode */ -+#define FCR_MODE_HWECC_RESET 0xF4 /* HW-ECC Reset */ -+ -+#define FCR_MODE_POWER_ON 0x0C /* Power Supply ON to SSFDC card */ -+#define FCR_MODE_POWER_OFF 0x08 /* Power Supply OFF to SSFDC card */ -+ -+#define FCR_MODE_LED_OFF 0x00 /* LED OFF */ -+#define FCR_MODE_LED_ON 0x04 /* LED ON */ -+ -+#define FCR_MODE_EJECT_ON 0x68 /* Ejection Demand from Penguin is Advanced */ -+#define FCR_MODE_EJECT_OFF 0x08 /* Ejection Demand from Penguin is Not Advanced */ -+ -+#define FCR_MODE_LOCK 0x6C /* Operates By Lock_Mode. Ejection Switch is Invalid */ -+#define FCR_MODE_UNLOCK 0x0C /* Operates By UnLock_Mode.Ejection Switch is Effective */ -+ -+#define FCR_MODE_CONTROLLER_ID 0x40 /* Controller ID Read */ -+#define FCR_MODE_STANDBY 0x00 /* SSFDC card Changes Standby State */ -+ -+#define FCR_MODE_WE 0x80 -+#define FCR_MODE_ECC1 0x40 -+#define FCR_MODE_ECC0 0x20 -+#define FCR_MODE_CE 0x10 -+#define FCR_MODE_PCNT1 0x08 -+#define FCR_MODE_PCNT0 0x04 -+#define FCR_MODE_ALE 0x02 -+#define FCR_MODE_CLE 0x01 -+ -+#define FCR_STATUS_BUSY 0x80 -+ -+/* -+ *NAND Flash Host Controller Configuration Register -+ */ -+struct tmio_nfhccr { -+ u8 x00[4]; -+ u16 command; /* 0x04 Command */ -+ u8 x01[0x0a]; -+ u16 base[2]; /* 0x10 NAND Flash Control Reg Base Addr*/ -+ u8 x02[0x29]; -+ u8 intp; /* 0x3d Interrupt Pin */ -+ u8 x03[0x0a]; -+ u8 inte; /* 0x48 Interrupt Enable */ -+ u8 x04; -+ u8 ec; /* 0x4a Event Control */ -+ u8 x05; -+ u8 icc; /* 0x4c Internal Clock Control */ -+ u8 x06[0x0e]; -+ u8 eccc; /* 0x5b ECC Control */ -+ u8 x07[4]; -+ u8 nftc; /* 0x60 NAND Flash Transaction Control */ -+ u8 nfm; /* 0x61 NAND Flash Monitor */ -+ u8 nfpsc; /* 0x62 NAND Flash Power Supply Control */ -+ u8 nfdc; /* 0x63 NAND Flash Detect Control */ -+ u8 x08[0x9c]; -+} __attribute__ ((packed)); -+ -+/* -+ *NAND Flash Control Register -+ */ -+struct tmio_nfcr { -+union { -+ u8 u8; /* 0x00 Data Register */ -+ u16 u16; -+ u32 u32; -+} __attribute__ ((packed)); -+ u8 mode; /* 0x04 Mode Register */ -+ u8 status; /* 0x05 Status Register */ -+ u8 isr; /* 0x06 Interrupt Status Register */ -+ u8 imr; /* 0x07 Interrupt Mask Register */ -+} __attribute__ ((packed)); -+ -+struct tmio_nand { -+ struct mtd_info mtd; -+ struct nand_chip chip; -+ -+ struct platform_device *dev; -+ -+ struct tmio_nfhccr __iomem *ccr; -+ struct tmio_nfcr __iomem *fcr; -+ -+ unsigned int irq; -+ -+ /* for tmio_nand_read_byte */ -+ u8 read; -+ unsigned read_good:1; -+}; -+ -+#define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd) -+ -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+static const char *part_probes[] = { "cmdlinepart", NULL }; -+#endif -+ -+/*--------------------------------------------------------------------------*/ -+ -+static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ struct nand_chip *chip = mtd->priv; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ u8 mode; -+ -+ if (ctrl & NAND_NCE) { -+ mode = FCR_MODE_DATA; -+ -+ if (ctrl & NAND_CLE) -+ mode |= FCR_MODE_CLE; -+ else -+ mode &= ~FCR_MODE_CLE; -+ -+ if (ctrl & NAND_ALE) -+ mode |= FCR_MODE_ALE; -+ else -+ mode &= ~FCR_MODE_ALE; -+ } else { -+ mode = FCR_MODE_STANDBY; -+ } -+ -+ iowrite8(mode, &fcr->mode); -+ tmio->read_good = 0; -+ } -+ -+ if (cmd != NAND_CMD_NONE) -+ writeb(cmd, chip->IO_ADDR_W); -+} -+ -+static int tmio_nand_dev_ready(struct mtd_info *mtd) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ return !(ioread8(&fcr->status) & FCR_STATUS_BUSY); -+} -+ -+static irqreturn_t tmio_irq(int irq, void *__dev) -+{ -+ struct platform_device *dev = __dev; -+ struct tmio_nand *tmio = platform_get_drvdata(dev); -+ struct nand_chip *nand_chip = &tmio->chip; -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ /* disable RDYREQ interrupt */ -+ iowrite8(0x00, &fcr->imr); -+ -+ if (unlikely(!waitqueue_active(&nand_chip->controller->wq))) -+ dev_warn(&dev->dev, "spurious interrupt\n"); -+ -+ wake_up(&nand_chip->controller->wq); -+ return IRQ_HANDLED; -+} -+ -+/* -+ *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB. -+ *This interrupt is normally disabled, but for long operations like -+ *erase and write, we enable it to wake us up. The irq handler -+ *disables the interrupt. -+ */ -+static int -+tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ long timeout; -+ -+ /* enable RDYREQ interrupt */ -+ iowrite8(0x0f, &fcr->isr); -+ iowrite8(0x81, &fcr->imr); -+ -+ timeout = wait_event_timeout(nand_chip->controller->wq, tmio_nand_dev_ready(mtd), -+ msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20)); -+ -+ if (unlikely(!tmio_nand_dev_ready(mtd))) { -+ iowrite8(0x00, &fcr->imr); -+ dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n", -+ nand_chip->state == FL_ERASING ? "erase" : "program", -+ nand_chip->state == FL_ERASING ? 400 : 20); -+ -+ } else if (unlikely(!timeout)) { -+ iowrite8(0x00, &fcr->imr); -+ dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n"); -+ } -+ -+ nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); -+ return nand_chip->read_byte(mtd); -+} -+ -+/* -+ *The TMIO controller combines two 8-bit data bytes into one 16-bit -+ *word. This function separates them so nand_base.c works as expected, -+ *especially its NAND_CMD_READID routines. -+ * -+ *To prevent stale data from being read, tmio_nand_hwcontrol() clears -+ *tmio->read_good. -+ */ -+static u_char tmio_nand_read_byte(struct mtd_info *mtd) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ unsigned int data; -+ -+ if (tmio->read_good--) -+ return tmio->read; -+ -+ data = ioread16(&fcr->u16); -+ tmio->read = data >> 8; -+ return data; -+} -+ -+/* -+ *The TMIO controller converts an 8-bit NAND interface to a 16-bit -+ *bus interface, so all data reads and writes must be 16-bit wide. -+ *Thus, we implement 16-bit versions of the read, write, and verify -+ *buffer functions. -+ */ -+static void -+tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ iowrite16_rep(&fcr->u16, buf, len >> 1); -+} -+ -+static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ ioread16_rep(&fcr->u16, buf, len >> 1); -+} -+ -+static int -+tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ u16 *p = (u16 *) buf; -+ -+ for (len >>= 1; len; len--) -+ if (*(p++) != ioread16(&fcr->u16)) -+ return -EFAULT; -+ return 0; -+} -+ -+static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ iowrite8(FCR_MODE_HWECC_RESET, &fcr->mode); -+ ioread8(&fcr->u8); /* dummy read */ -+ iowrite8(FCR_MODE_HWECC_CALC, &fcr->mode); -+} -+ -+static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, -+ u_char *ecc_code) -+{ -+ struct tmio_nand *tmio = mtd_to_tmio(mtd); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ unsigned int ecc; -+ -+ iowrite8(FCR_MODE_HWECC_RESULT, &fcr->mode); -+ -+ ecc = ioread16(&fcr->u16); -+ ecc_code[1] = ecc; /* 000-255 LP7-0 */ -+ ecc_code[0] = ecc >> 8; /* 000-255 LP15-8 */ -+ ecc = ioread16(&fcr->u16); -+ ecc_code[2] = ecc; /* 000-255 CP5-0,11b */ -+ ecc_code[4] = ecc >> 8; /* 256-511 LP7-0 */ -+ ecc = ioread16(&fcr->u16); -+ ecc_code[3] = ecc; /* 256-511 LP15-8 */ -+ ecc_code[5] = ecc >> 8; /* 256-511 CP5-0,11b */ -+ -+ iowrite8(FCR_MODE_DATA, &fcr->mode); -+ return 0; -+} -+ -+static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ const struct resource *nfcr = NULL; -+ struct tmio_nfhccr __iomem *ccr = tmio->ccr; -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ unsigned long base; -+ int i; -+ -+ for (i = 0; i < cell->num_resources; i++) -+ if (!strcmp((cell->resources+i)->name, TMIO_NAND_CONTROL)) -+ nfcr = &cell->resources[i]; -+ -+ if (nfcr == NULL) -+ return -ENOMEM; -+ -+ if (!cell->enable) { -+ printk(KERN_ERR "null cell enable!"); -+ return -EINVAL; -+ } -+ -+ cell->enable(dev); -+ -+ /* (4Ch) CLKRUN Enable 1st spcrunc */ -+ iowrite8(0x81, &ccr->icc); -+ -+ /* (10h)BaseAddress 0x1000 spba.spba2 */ -+ base = nfcr->start; -+ iowrite16(base, ccr->base + 0); -+ iowrite16(base >> 16, ccr->base + 1); -+ -+ /* (04h)Command Register I/O spcmd */ -+ iowrite8(0x02, &ccr->command); -+ -+ /* (62h) Power Supply Control ssmpwc */ -+ /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */ -+ iowrite8(0x02, &ccr->nfpsc); -+ -+ /* (63h) Detect Control ssmdtc */ -+ iowrite8(0x02, &ccr->nfdc); -+ -+ /* Interrupt status register clear sintst */ -+ iowrite8(0x0f, &fcr->isr); -+ -+ /* After power supply, Media are reset smode */ -+ iowrite8(FCR_MODE_POWER_ON, &fcr->mode); -+ iowrite8(FCR_MODE_COMMAND, &fcr->mode); -+ iowrite8(NAND_CMD_RESET, &fcr->u8); -+ -+ /* Standby Mode smode */ -+ iowrite8(FCR_MODE_STANDBY, &fcr->mode); -+ -+ mdelay(5); -+ -+ return 0; -+} -+ -+static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_nfcr __iomem *fcr = tmio->fcr; -+ -+ iowrite8(FCR_MODE_POWER_OFF, &fcr->mode); -+ cell->disable(dev); -+} -+ -+static int tmio_probe(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_nand_data *data = cell->driver_data; -+ struct resource *ccr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONFIG); -+ struct resource *fcr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONTROL); -+ int irq = platform_get_irq(dev, 0); -+ struct tmio_nand *tmio; -+ struct mtd_info *mtd; -+ struct nand_chip *nand_chip; -+ struct mtd_partition *parts; -+ int nbparts = 0; -+ int retval; -+ -+ if (data == NULL) { -+ dev_err(&dev->dev, "NULL platform data!\n"); -+ return -EINVAL; -+ } -+ -+ tmio = kzalloc(sizeof *tmio, GFP_KERNEL); -+ if (!tmio) { -+ retval = -ENOMEM; -+ goto err_kzalloc; -+ } -+ -+ tmio->dev = dev; -+ -+ platform_set_drvdata(dev, tmio); -+ mtd = &tmio->mtd; -+ nand_chip = &tmio->chip; -+ mtd->priv = nand_chip; -+ mtd->name = "tmio-nand"; -+ -+ tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1); -+ if (!tmio->ccr) { -+ retval = -EIO; -+ goto err_iomap_ccr; -+ } -+ -+ tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1); -+ if (!tmio->fcr) { -+ retval = -EIO; -+ goto err_iomap_fcr; -+ } -+ -+ retval = tmio_hw_init(dev, tmio); -+ if (retval) -+ goto err_hwinit; -+ -+ /* Set address of NAND IO lines */ -+ nand_chip->IO_ADDR_R = tmio->fcr; -+ nand_chip->IO_ADDR_W = tmio->fcr; -+ -+ /* Set address of hardware control function */ -+ nand_chip->cmd_ctrl = tmio_nand_hwcontrol; -+ nand_chip->dev_ready = tmio_nand_dev_ready; -+ nand_chip->read_byte = tmio_nand_read_byte; -+ nand_chip->write_buf = tmio_nand_write_buf; -+ nand_chip->read_buf = tmio_nand_read_buf; -+ nand_chip->verify_buf = tmio_nand_verify_buf; -+ -+ /* set eccmode using hardware ECC */ -+ nand_chip->ecc.mode = NAND_ECC_HW; -+ nand_chip->ecc.size = 512; -+ nand_chip->ecc.bytes = 6; -+ nand_chip->ecc.hwctl = tmio_nand_enable_hwecc; -+ nand_chip->ecc.calculate = tmio_nand_calculate_ecc; -+ nand_chip->ecc.correct = nand_correct_data; -+ nand_chip->badblock_pattern = data->badblock_pattern; -+ -+ /* 15 us command delay time */ -+ nand_chip->chip_delay = 15; -+ -+ retval = request_irq(irq, &tmio_irq, -+ IRQF_DISABLED, dev->dev.bus_id, dev); -+ if (retval) { -+ dev_err(&dev->dev, "request_irq error %d\n", retval); -+ goto err_irq; -+ } -+ -+ tmio->irq = irq; -+ nand_chip->waitfunc = tmio_nand_wait; -+ -+ /* Scan to find existence of the device */ -+ if (nand_scan(mtd, 1)) { -+ retval = -ENODEV; -+ goto err_scan; -+ } -+ /* Register the partitions */ -+#ifdef CONFIG_MTD_PARTITIONS -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+ nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0); -+#endif -+ if (nbparts <= 0) { -+ parts = data->partition; -+ nbparts = data->num_partitions; -+ } -+ -+ retval = add_mtd_partitions(mtd, parts, nbparts); -+#else -+ retval = add_mtd_device(mtd); -+#endif -+ -+ if (!retval) -+ return retval; -+ -+ nand_release(mtd); -+ -+err_scan: -+ if (tmio->irq) -+ free_irq(tmio->irq, dev); -+err_irq: -+ tmio_hw_stop(dev, tmio); -+err_hwinit: -+ iounmap(tmio->fcr); -+err_iomap_fcr: -+ iounmap(tmio->ccr); -+err_iomap_ccr: -+ kfree(tmio); -+err_kzalloc: -+ return retval; -+} -+ -+static int tmio_remove(struct platform_device *dev) -+{ -+ struct tmio_nand *tmio = platform_get_drvdata(dev); -+ -+ nand_release(&tmio->mtd); -+ if (tmio->irq) -+ free_irq(tmio->irq, tmio); -+ tmio_hw_stop(dev, tmio); -+ iounmap(tmio->fcr); -+ iounmap(tmio->ccr); -+ kfree(tmio); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int tmio_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ -+ if (cell->suspend) -+ cell->suspend(dev); -+ -+ tmio_hw_stop(dev, platform_get_drvdata(dev)); -+ return 0; -+} -+ -+static int tmio_resume(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ -+ tmio_hw_init(dev, platform_get_drvdata(dev)); -+ -+ if (cell->resume) -+ cell->resume(dev); -+ -+ return 0; -+} -+#endif -+ -+static struct platform_driver tmio_driver = { -+ .driver.name = "tmio-nand", -+ .driver.owner = THIS_MODULE, -+ .probe = tmio_probe, -+ .remove = tmio_remove, -+#ifdef CONFIG_PM -+ .suspend = tmio_suspend, -+ .resume = tmio_resume, -+#endif -+}; -+ -+static int __init tmio_init(void) -+{ -+ return platform_driver_register(&tmio_driver); -+} -+ -+static void __exit tmio_exit(void) -+{ -+ platform_driver_unregister(&tmio_driver); -+} -+ -+module_init(tmio_init); -+module_exit(tmio_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dirk Opfer, Chris Humbert, Dmitry Baryshkov"); -+MODULE_DESCRIPTION("NAND flash driver on Toshiba Mobile IO controller"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch deleted file mode 100644 index 5fc96f8973..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch +++ /dev/null @@ -1,1128 +0,0 @@ -From 519d015892ab0a7cad1f6b26fcd38117171384ce Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Tue, 1 Jan 2008 21:22:23 +0000 -Subject: [PATCH 09/64] FB driver for TMIO devices - ---- - drivers/video/Kconfig | 22 + - drivers/video/Makefile | 1 + - drivers/video/tmiofb.c | 1062 ++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1085 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/tmiofb.c - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 5b3dbcf..6d0df58 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -1782,6 +1782,28 @@ config FB_W100 - - If unsure, say N. - -+config FB_TMIO -+ tristate "Toshiba Mobice IO FrameBuffer support" -+ depends on FB && MFD_CORE -+ select FB_CFB_FILLRECT -+ select FB_CFB_COPYAREA -+ select FB_CFB_IMAGEBLIT -+ ---help--- -+ Frame buffer driver for the Toshiba Mobile IO integrated as found -+ on the Sharp SL-6000 series -+ -+ This driver is also available as a module ( = code which can be -+ inserted and removed from the running kernel whenever you want). The -+ module will be called tmiofb. If you want to compile it as a module, -+ say M here and read <file:Documentation/kbuild/modules.txt>. -+ -+ If unsure, say N. -+ -+config FB_TMIO_ACCELL -+ bool "tmiofb acceleration" -+ depends on FB_TMIO -+ default y -+ - config FB_S3C2410 - tristate "S3C2410 LCD framebuffer support" - depends on FB && ARCH_S3C2410 -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index 83e02b3..74e9384 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -97,6 +97,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o - obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o - obj-$(CONFIG_FB_PXA) += pxafb.o - obj-$(CONFIG_FB_W100) += w100fb.o -+obj-$(CONFIG_FB_TMIO) += tmiofb.o - obj-$(CONFIG_FB_AU1100) += au1100fb.o - obj-$(CONFIG_FB_AU1200) += au1200fb.o - obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o -diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c -new file mode 100644 -index 0000000..6b963a1 ---- /dev/null -+++ b/drivers/video/tmiofb.c -@@ -0,0 +1,1062 @@ -+/* -+ * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller -+ * -+ * Copyright(C) 2005-2006 Chris Humbert -+ * Copyright(C) 2005 Dirk Opfer -+ * -+ * Based on: -+ * drivers/video/w100fb.c -+ * code written by Sharp/Lineo for 2.4 kernels -+ * -+ * 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 program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+#include <linux/fb.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+/* Why should fb driver call console functions? because acquire_console_sem() */ -+#include <linux/console.h> -+#include <linux/uaccess.h> -+#include <linux/vmalloc.h> -+ -+/* -+ * accelerator commands -+ */ -+#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe)) -+#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe)) -+#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe)) -+#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff)) -+#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe)) -+#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe)) -+#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff)) -+#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff)) -+#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff)) -+ -+#define TMIOFB_ACC_CMGO 0x20000000 -+#define TMIOFB_ACC_CMGO_CEND 0x00000001 -+#define TMIOFB_ACC_CMGO_INT 0x00000002 -+#define TMIOFB_ACC_CMGO_CMOD 0x00000010 -+#define TMIOFB_ACC_CMGO_CDVRV 0x00000020 -+#define TMIOFB_ACC_CMGO_CDHRV 0x00000040 -+#define TMIOFB_ACC_CMGO_RUND 0x00008000 -+#define TMIOFB_ACC_SCGO 0x21000000 -+#define TMIOFB_ACC_SCGO_CEND 0x00000001 -+#define TMIOFB_ACC_SCGO_INT 0x00000002 -+#define TMIOFB_ACC_SCGO_ROP3 0x00000004 -+#define TMIOFB_ACC_SCGO_TRNS 0x00000008 -+#define TMIOFB_ACC_SCGO_DVRV 0x00000010 -+#define TMIOFB_ACC_SCGO_DHRV 0x00000020 -+#define TMIOFB_ACC_SCGO_SVRV 0x00000040 -+#define TMIOFB_ACC_SCGO_SHRV 0x00000080 -+#define TMIOFB_ACC_SCGO_DSTXY 0x00008000 -+#define TMIOFB_ACC_SBGO 0x22000000 -+#define TMIOFB_ACC_SBGO_CEND 0x00000001 -+#define TMIOFB_ACC_SBGO_INT 0x00000002 -+#define TMIOFB_ACC_SBGO_DVRV 0x00000010 -+#define TMIOFB_ACC_SBGO_DHRV 0x00000020 -+#define TMIOFB_ACC_SBGO_SVRV 0x00000040 -+#define TMIOFB_ACC_SBGO_SHRV 0x00000080 -+#define TMIOFB_ACC_SBGO_SBMD 0x00000100 -+#define TMIOFB_ACC_FLGO 0x23000000 -+#define TMIOFB_ACC_FLGO_CEND 0x00000001 -+#define TMIOFB_ACC_FLGO_INT 0x00000002 -+#define TMIOFB_ACC_FLGO_ROP3 0x00000004 -+#define TMIOFB_ACC_LDGO 0x24000000 -+#define TMIOFB_ACC_LDGO_CEND 0x00000001 -+#define TMIOFB_ACC_LDGO_INT 0x00000002 -+#define TMIOFB_ACC_LDGO_ROP3 0x00000004 -+#define TMIOFB_ACC_LDGO_ENDPX 0x00000008 -+#define TMIOFB_ACC_LDGO_LVRV 0x00000010 -+#define TMIOFB_ACC_LDGO_LHRV 0x00000020 -+#define TMIOFB_ACC_LDGO_LDMOD 0x00000040 -+ -+/* a FIFO is always allocated, even if acceleration is not used */ -+#define TMIOFB_FIFO_SIZE 512 -+ -+/* -+ * LCD Host Controller Configuration Register -+ * -+ * This iomem area supports only 16-bit IO. -+ */ -+struct tmio_lhccr { -+ u16 x00[2]; -+ u16 cmd; /* 0x04 Command */ -+ u16 x01; -+ u16 revid; /* 0x08 Revision ID */ -+ u16 x02[3]; -+ u16 basel; /* 0x10 LCD Control Reg Base Addr Low */ -+ u16 baseh; /* 0x12 LCD Control Reg Base Addr High */ -+ u16 x03[0x16]; -+ u16 ugcc; /* 0x40 Unified Gated Clock Control */ -+ u16 gcc; /* 0x42 Gated Clock Control */ -+ u16 x04[6]; -+ u16 usc; /* 0x50 Unified Software Clear */ -+ u16 x05[7]; -+ u16 vramrtc; /* 0x60 VRAM Timing Control */ -+ /* 0x61 VRAM Refresh Control */ -+ u16 vramsac; /* 0x62 VRAM Access Control */ -+ /* 0x63 VRAM Status */ -+ u16 vrambc; /* 0x64 VRAM Block Control */ -+ u16 x06[0x4d]; -+}; -+ -+/* -+ * LCD Control Register -+ * -+ * This iomem area supports only 16-bit IO. -+ */ -+struct tmio_lcr { -+ u16 uis; /* 0x000 Unified Interrupt Status */ -+ u16 x00[3]; -+ u16 vhpn; /* 0x008 VRAM Horizontal Pixel Number */ -+ u16 cfsal; /* 0x00a Command FIFO Start Address Low */ -+ u16 cfsah; /* 0x00c Command FIFO Start Address High */ -+ u16 cfs; /* 0x00e Command FIFO Size */ -+ u16 cfws; /* 0x010 Command FIFO Writeable Size */ -+ u16 bbie; /* 0x012 BitBLT Interrupt Enable */ -+ u16 bbisc; /* 0x014 BitBLT Interrupt Status and Clear */ -+ u16 ccs; /* 0x016 Command Count Status */ -+ u16 bbes; /* 0x018 BitBLT Execution Status */ -+ u16 x01; -+ u16 cmdl; /* 0x01c Command Low */ -+ u16 cmdh; /* 0x01e Command High */ -+ u16 x02; -+ u16 cfc; /* 0x022 Command FIFO Clear */ -+ u16 ccifc; /* 0x024 CMOS Camera IF Control */ -+ u16 hwt; /* 0x026 Hardware Test */ -+ u16 x03[0x6c]; -+ u16 lcdccrc;/* 0x100 LCDC Clock and Reset Control */ -+ u16 lcdcc; /* 0x102 LCDC Control */ -+ u16 lcdcopc;/* 0x104 LCDC Output Pin Control */ -+ u16 x04; -+ u16 lcdis; /* 0x108 LCD Interrupt Status */ -+ u16 lcdim; /* 0x10a LCD Interrupt Mask */ -+ u16 lcdie; /* 0x10c LCD Interrupt Enable */ -+ u16 x05[10]; -+ u16 gdsal; /* 0x122 Graphics Display Start Address Low */ -+ u16 gdsah; /* 0x124 Graphics Display Start Address High */ -+ u16 x06[2]; -+ u16 vhpcl; /* 0x12a VRAM Horizontal Pixel Count Low */ -+ u16 vhpch; /* 0x12c VRAM Horizontal Pixel Count High */ -+ u16 gm; /* 0x12e Graphic Mode(VRAM access enable) */ -+ u16 x07[8]; -+ u16 ht; /* 0x140 Horizontal Total */ -+ u16 hds; /* 0x142 Horizontal Display Start */ -+ u16 hss; /* 0x144 H-Sync Start */ -+ u16 hse; /* 0x146 H-Sync End */ -+ u16 x08[2]; -+ u16 hnp; /* 0x14c Horizontal Number of Pixels */ -+ u16 x09; -+ u16 vt; /* 0x150 Vertical Total */ -+ u16 vds; /* 0x152 Vertical Display Start */ -+ u16 vss; /* 0x154 V-Sync Start */ -+ u16 vse; /* 0x156 V-Sync End */ -+ u16 x0a[4]; -+ u16 cdln; /* 0x160 Current Display Line Number */ -+ u16 iln; /* 0x162 Interrupt Line Number */ -+ u16 sp; /* 0x164 Sync Polarity */ -+ u16 misc; /* 0x166 MISC(RGB565 mode) */ -+ u16 x0b; -+ u16 vihss; /* 0x16a Video Interface H-Sync Start */ -+ u16 vivs; /* 0x16c Video Interface Vertical Start */ -+ u16 vive; /* 0x16e Video Interface Vertical End */ -+ u16 vivss; /* 0x170 Video Interface V-Sync Start */ -+ u16 x0c[6]; -+ u16 vccis; /* 0x17e Video / CMOS Camera Interface Select */ -+ u16 vidwsal;/* 0x180 VI Data Write Start Address Low */ -+ u16 vidwsah;/* 0x182 VI Data Write Start Address High */ -+ u16 vidrsal;/* 0x184 VI Data Read Start Address Low */ -+ u16 vidrsah;/* 0x186 VI Data Read Start Address High */ -+ u16 vipddst;/* 0x188 VI Picture Data Display Start Timing */ -+ u16 vipddet;/* 0x186 VI Picture Data Display End Timing */ -+ u16 vie; /* 0x18c Video Interface Enable */ -+ u16 vcs; /* 0x18e Video/Camera Select */ -+ u16 x0d[2]; -+ u16 vphwc; /* 0x194 Video Picture Horizontal Wait Count */ -+ u16 vphs; /* 0x196 Video Picture Horizontal Size */ -+ u16 vpvwc; /* 0x198 Video Picture Vertical Wait Count */ -+ u16 vpvs; /* 0x19a Video Picture Vertical Size */ -+ u16 x0e[2]; -+ u16 plhpix; /* 0x1a0 PLHPIX */ -+ u16 xs; /* 0x1a2 XStart */ -+ u16 xckhw; /* 0x1a4 XCK High Width */ -+ u16 x0f; -+ u16 sths; /* 0x1a8 STH Start */ -+ u16 vt2; /* 0x1aa Vertical Total */ -+ u16 ycksw; /* 0x1ac YCK Start Wait */ -+ u16 ysts; /* 0x1ae YST Start */ -+ u16 ppols; /* 0x1b0 #PPOL Start */ -+ u16 precw; /* 0x1b2 PREC Width */ -+ u16 vclkhw; /* 0x1b4 VCLK High Width */ -+ u16 oc; /* 0x1b6 Output Control */ -+ u16 x10[0x24]; -+}; -+static char *mode_option __devinitdata; -+ -+struct tmiofb_par { -+ u32 pseudo_palette[16]; -+ -+#ifdef CONFIG_FB_TMIO_ACCELL -+ wait_queue_head_t wait_acc; -+ bool use_polling; -+#endif -+ -+ struct tmio_lhccr __iomem *ccr; -+ struct tmio_lcr __iomem *lcr; -+ void __iomem *vram; -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static irqreturn_t tmiofb_irq(int irq, void *__info); -+ -+/*--------------------------------------------------------------------------*/ -+ -+ -+/* -+ * Turns off the LCD controller and LCD host controller. -+ */ -+static int tmiofb_hw_stop(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_fb_data *data = cell->driver_data; -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct tmiofb_par *par = info->par; -+ struct tmio_lhccr __iomem *ccr = par->ccr; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ -+ iowrite16(0, &ccr->ugcc); -+ iowrite16(0, &lcr->gm); -+ data->lcd_set_power(dev, 0); -+ iowrite16(0x0010, &lcr->lcdccrc); -+ -+ return 0; -+} -+ -+/* -+ * Initializes the LCD host controller. -+ */ -+static int tmiofb_hw_init(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_fb_data *data = cell->driver_data; -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct tmiofb_par *par = info->par; -+ struct tmio_lhccr __iomem *ccr = par->ccr; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ const struct resource *nlcr = NULL; -+ const struct resource *vram = NULL; -+ unsigned long base; -+ int i; -+ -+ for (i = 0; i < cell->num_resources; i++) { -+ if (!strcmp((cell->resources+i)->name, TMIO_FB_CONTROL)) -+ nlcr = &cell->resources[i]; -+ if (!strcmp((cell->resources+i)->name, TMIO_FB_VRAM)) -+ vram = &cell->resources[i]; -+ } -+ -+ if (nlcr == NULL || vram == NULL) -+ return -EINVAL; -+ -+ base = nlcr->start; -+ -+ if (info->mode == NULL) { -+ printk(KERN_ERR "tmio-fb: null info->mode\n"); -+ info->mode = data->modes; -+ } -+ -+ data->lcd_mode(dev, info->mode); -+ -+ iowrite16(0x003a, &ccr->ugcc); -+ iowrite16(0x003a, &ccr->gcc); -+ iowrite16(0x3f00, &ccr->usc); -+ -+ data->lcd_set_power(dev, 1); -+ mdelay(2); -+ -+ iowrite16(0x0000, &ccr->usc); -+ iowrite16(base >> 16, &ccr->baseh); -+ iowrite16(base, &ccr->basel); -+ iowrite16(0x0002, &ccr->cmd); /* base address enable */ -+ iowrite16(0x40a8, &ccr->vramrtc); /* VRAMRC, VRAMTC */ -+ iowrite16(0x0018, &ccr->vramsac); /* VRAMSTS, VRAMAC */ -+ iowrite16(0x0002, &ccr->vrambc); -+ mdelay(2); -+ iowrite16(0x000b, &ccr->vrambc); -+ -+ base = vram->start + info->screen_size; -+ iowrite16(base >> 16, &lcr->cfsah); -+ iowrite16(base, &lcr->cfsal); -+ iowrite16(TMIOFB_FIFO_SIZE - 1, &lcr->cfs); -+ iowrite16(1, &lcr->cfc); -+ iowrite16(1, &lcr->bbie); -+ iowrite16(0, &lcr->cfws); -+ -+ return 0; -+} -+ -+/* -+ * Sets the LCD controller's output resolution and pixel clock -+ */ -+static void tmiofb_hw_mode(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_fb_data *data = cell->driver_data; -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct fb_videomode *mode = info->mode; -+ struct tmiofb_par *par = info->par; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ unsigned int i; -+ -+ iowrite16(0, &lcr->gm); -+ data->lcd_set_power(dev, 0); -+ iowrite16(0x0010, &lcr->lcdccrc); -+ data->lcd_mode(dev, mode); -+ data->lcd_set_power(dev, 1); -+ -+ iowrite16(i = mode->xres * 2, &lcr->vhpn); -+ iowrite16(0, &lcr->gdsah); -+ iowrite16(0, &lcr->gdsal); -+ iowrite16(i >> 16, &lcr->vhpch); -+ iowrite16(i, &lcr->vhpcl); -+ iowrite16(i = 0, &lcr->hss); -+ iowrite16(i += mode->hsync_len, &lcr->hse); -+ iowrite16(i += mode->left_margin, &lcr->hds); -+ iowrite16(i += mode->xres + mode->right_margin, &lcr->ht); -+ iowrite16(mode->xres, &lcr->hnp); -+ iowrite16(i = 0, &lcr->vss); -+ iowrite16(i += mode->vsync_len, &lcr->vse); -+ iowrite16(i += mode->upper_margin, &lcr->vds); -+ iowrite16(i += mode->yres, &lcr->iln); -+ iowrite16(i += mode->lower_margin, &lcr->vt); -+ iowrite16(3, /* RGB565 mode */ &lcr->misc); -+ iowrite16(1, /* VRAM enable */ &lcr->gm); -+ iowrite16(0x4007, &lcr->lcdcc); -+ iowrite16(3, /* sync polarity */ &lcr->sp); -+ -+ iowrite16(0x0010, &lcr->lcdccrc); -+ mdelay(5); -+ iowrite16(0x0014, &lcr->lcdccrc); /* STOP_CKP */ -+ mdelay(5); -+ iowrite16(0x0015, &lcr->lcdccrc); /* STOP_CKP | SOFT_RESET */ -+ iowrite16(0xfffa, &lcr->vcs); -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+#ifdef CONFIG_FB_TMIO_ACCELL -+static int __must_check -+tmiofb_acc_wait(struct fb_info *info, unsigned int ccs) -+{ -+ struct tmiofb_par *par = info->par; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ if (in_atomic() || par->use_polling) { -+ int i = 0; -+ while (ioread16(&lcr->ccs) > ccs) { -+ udelay(1); -+ i++; -+ if (i > 10000) { -+ printk(KERN_ERR "tmiofb: timeout waiting for %d\n", ccs); -+ return -ETIMEDOUT; -+ } -+ tmiofb_irq(-1, info); -+ } -+ } else { -+ if (!wait_event_interruptible_timeout(par->wait_acc, -+ ioread16(&par->lcr->ccs) <= ccs, 1000)) { -+ printk(KERN_ERR "tmiofb: timeout waiting for %d\n", ccs); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * Writes an accelerator command to the accelerator's FIFO. -+ */ -+static int -+tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count) -+{ -+ struct tmiofb_par *par = info->par; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ int ret; -+ -+ ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count); -+ if (ret) -+ return ret; -+ -+ for (; count; count--, cmd++) { -+ iowrite16(*cmd >> 16, &lcr->cmdh); -+ iowrite16(*cmd, &lcr->cmdl); -+ } -+ -+ return ret; -+} -+ -+/* -+ * Wait for the accelerator to finish its operations before writing -+ * to the framebuffer for consistent display output. -+ */ -+static int tmiofb_sync(struct fb_info *fbi) -+{ -+ struct tmiofb_par *par = fbi->par; -+ -+ int ret; -+ int i = 0; -+ -+ ret = tmiofb_acc_wait(fbi, 0); -+ -+ while (ioread16(&par->lcr->bbes) & 2) { /* blit active */ -+ udelay(1); -+ i++ ; -+ if (i > 10000) { -+ printk(KERN_ERR "timeout waiting for blit to end!\n"); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ return ret; -+} -+ -+static void -+tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect) -+{ -+ const u32 cmd [] = { -+ TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2), -+ TMIOFB_ACC_DHPIX(rect->width - 1), -+ TMIOFB_ACC_DVPIX(rect->height - 1), -+ TMIOFB_ACC_FILL(rect->color), -+ TMIOFB_ACC_FLGO, -+ }; -+ -+ if (fbi->state != FBINFO_STATE_RUNNING || -+ fbi->flags & FBINFO_HWACCEL_DISABLED) { -+ cfb_fillrect(fbi, rect); -+ return; -+ } -+ -+ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); -+} -+ -+static void -+tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area) -+{ -+ const u32 cmd [] = { -+ TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2), -+ TMIOFB_ACC_DHPIX(area->width - 1), -+ TMIOFB_ACC_DVPIX(area->height - 1), -+ TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2), -+ TMIOFB_ACC_SCGO, -+ }; -+ -+ if (fbi->state != FBINFO_STATE_RUNNING || -+ fbi->flags & FBINFO_HWACCEL_DISABLED) { -+ cfb_copyarea(fbi, area); -+ return; -+ } -+ -+ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); -+} -+#endif -+ -+static void tmiofb_clearscreen(struct fb_info *info) -+{ -+ const struct fb_fillrect rect = { -+ .dx = 0, -+ .dy = 0, -+ .width = info->mode->xres, -+ .height = info->mode->yres, -+ .color = 0, -+ }; -+ -+ info->fbops->fb_fillrect(info, &rect); -+} -+ -+static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank) -+{ -+ struct tmiofb_par *par = fbi->par; -+ struct fb_videomode *mode = fbi->mode; -+ unsigned int vcount = ioread16(&par->lcr->cdln); -+ unsigned int vds = mode->vsync_len + mode->upper_margin; -+ -+ vblank->vcount = vcount; -+ vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT -+ | FB_VBLANK_HAVE_VSYNC; -+ -+ if (vcount < mode->vsync_len) -+ vblank->flags |= FB_VBLANK_VSYNCING; -+ -+ if (vcount < vds || vcount > vds + mode->yres) -+ vblank->flags |= FB_VBLANK_VBLANKING; -+ -+ return 0; -+} -+ -+ -+static int tmiofb_ioctl(struct fb_info *fbi, -+ unsigned int cmd, unsigned long arg) -+{ -+ switch (cmd) { -+ case FBIOGET_VBLANK: { -+ struct fb_vblank vblank = {0}; -+ void __user *argp = (void __user *) arg; -+ -+ tmiofb_vblank(fbi, &vblank); -+ if (copy_to_user(argp, &vblank, sizeof vblank)) -+ return -EFAULT; -+ return 0; -+ } -+ -+#ifdef CONFIG_FB_TMIO_ACCELL -+ case FBIO_TMIO_ACC_SYNC: -+ tmiofb_sync(fbi); -+ return 0; -+ -+ case FBIO_TMIO_ACC_WRITE: { -+ u32 __user *argp = (void __user *) arg; -+ u32 len; -+ u32 acc [16]; -+ -+ if (copy_from_user(&len, argp, sizeof(u32))) -+ return -EFAULT; -+ if (len > ARRAY_SIZE(acc)) -+ return -EINVAL; -+ if (copy_from_user(acc, argp + 1, sizeof(u32) * len)) -+ return -EFAULT; -+ -+ return tmiofb_acc_write(fbi, acc, len); -+ } -+#endif -+ } -+ -+ return -EINVAL; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ -+/* Select the smallest mode that allows the desired resolution to be -+ * displayed. If desired, the x and y parameters can be rounded up to -+ * match the selected mode. -+ */ -+static struct fb_videomode* -+tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) -+{ -+ struct mfd_cell *cell = mfd_get_cell(to_platform_device(info->device)); -+ struct tmio_fb_data *data = cell->driver_data; -+ struct fb_videomode *best = NULL; -+ int i; -+ -+ for (i = 0; i < data->num_modes; i++) { -+ struct fb_videomode *mode = data->modes + i; -+ -+ if (mode->xres >= var->xres && mode->yres >= var->yres -+ && (!best || (mode->xres < best->xres -+ && mode->yres < best->yres))) -+ best = mode; -+ } -+ -+ return best; -+} -+ -+static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -+{ -+ -+ struct fb_videomode *mode; -+ -+ mode = tmiofb_find_mode(info, var); -+ if (!mode || var->bits_per_pixel > 16) -+ return -EINVAL; -+ -+ fb_videomode_to_var(var, mode); -+ -+ var->xres_virtual = mode->xres; -+ var->yres_virtual = info->screen_size / (mode->xres * 2); -+ var->xoffset = 0; -+ var->yoffset = 0; -+ var->bits_per_pixel = 16; -+ var->grayscale = 0; -+ var->red.offset = 11; var->red.length = 5; -+ var->green.offset = 5; var->green.length = 6; -+ var->blue.offset = 0; var->blue.length = 5; -+ var->transp.offset = 0; var->transp.length = 0; -+ var->nonstd = 0; -+ var->height = 82; /* mm */ -+ var->width = 60; /* mm */ -+ var->rotate = 0; -+ return 0; -+} -+ -+static int tmiofb_set_par(struct fb_info *info) -+{ -+/* struct fb_var_screeninfo *var = &info->var; -+ struct fb_videomode *mode; -+ -+ mode = tmiofb_find_mode(info, var); -+ if (!mode) -+ return -EINVAL; -+ -+ if (info->mode == mode) -+ return 0; -+ -+ info->mode = mode; */ -+ info->fix.line_length = info->mode->xres * 2; -+ -+ tmiofb_hw_mode(to_platform_device(info->device)); -+ tmiofb_clearscreen(info); -+ return 0; -+} -+ -+static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green, -+ unsigned blue, unsigned transp, -+ struct fb_info *info) -+{ -+ struct tmiofb_par *par = info->par; -+ -+ if (regno < ARRAY_SIZE(par->pseudo_palette)) { -+ par->pseudo_palette [regno] = -+ ((red & 0xf800)) | -+ ((green & 0xfc00) >> 5) | -+ ((blue & 0xf800) >> 11); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct fb_ops tmiofb_ops = { -+ .owner = THIS_MODULE, -+ -+ .fb_ioctl = tmiofb_ioctl, -+ .fb_check_var = tmiofb_check_var, -+ .fb_set_par = tmiofb_set_par, -+ .fb_setcolreg = tmiofb_setcolreg, -+ .fb_imageblit = cfb_imageblit, -+#ifdef CONFIG_FB_TMIO_ACCELL -+ .fb_sync = tmiofb_sync, -+ .fb_fillrect = tmiofb_fillrect, -+ .fb_copyarea = tmiofb_copyarea, -+#else -+ .fb_fillrect = cfb_fillrect, -+ .fb_copyarea = cfb_copyarea, -+#endif -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+/* -+ * reasons for an interrupt: -+ * uis bbisc lcdis -+ * 0100 0001 accelerator command completed -+ * 2000 0001 vsync start -+ * 2000 0002 display start -+ * 2000 0004 line number match(0x1ff mask???) -+ */ -+static irqreturn_t tmiofb_irq(int irq, void *__info) -+{ -+ struct fb_info *info = __info; -+ struct tmiofb_par *par = info->par; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ unsigned int bbisc = ioread16(&lcr->bbisc); -+ -+ -+ if (unlikely(par->use_polling && irq != -1)) { -+ printk(KERN_INFO "tmiofb: switching to waitq\n"); -+ par->use_polling = false; -+ } -+ -+ iowrite16(bbisc, &lcr->bbisc); -+ -+#ifdef CONFIG_FB_TMIO_ACCELL -+ if (bbisc & 1) -+ wake_up(&par->wait_acc); -+#endif -+ -+ return IRQ_HANDLED; -+} -+ -+static int tmiofb_probe(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_fb_data *data = cell->driver_data; -+ struct resource *ccr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_CONFIG); -+ struct resource *lcr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_CONTROL); -+ struct resource *vram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_VRAM); -+ int irq = platform_get_irq(dev, 0); -+ struct fb_info *info; -+ struct tmiofb_par *par; -+ int retval; -+ -+ if (data == NULL) { -+ dev_err(&dev->dev, "NULL platform data!\n"); -+ return -EINVAL; -+ } -+ -+ info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev); -+ -+ if (!info) { -+ retval = -ENOMEM; -+ goto err_framebuffer_alloc; -+ } -+ -+ par = info->par; -+ platform_set_drvdata(dev, info); -+ -+#ifdef CONFIG_FB_TMIO_ACCELL -+ init_waitqueue_head(&par->wait_acc); -+ -+ par->use_polling = true; -+ -+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA -+ | FBINFO_HWACCEL_FILLRECT; -+#else -+ info->flags = FBINFO_DEFAULT; -+#endif -+ -+ info->fbops = &tmiofb_ops; -+ -+ strcpy(info->fix.id, "tmio-fb"); -+ info->fix.smem_start = vram->start; -+ info->fix.smem_len = vram->end - vram->start + 1; -+ info->fix.type = FB_TYPE_PACKED_PIXELS; -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ info->fix.mmio_start = lcr->start; -+ info->fix.mmio_len = lcr->end - lcr->start + 1; -+ info->fix.accel = FB_ACCEL_NONE; -+ info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE); -+ info->pseudo_palette = par->pseudo_palette; -+ -+ par->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1); -+ if (!par->ccr) { -+ retval = -ENOMEM; -+ goto err_ioremap_ccr; -+ } -+ -+ par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len); -+ if (!par->lcr) { -+ retval = -ENOMEM; -+ goto err_ioremap_lcr; -+ } -+ -+ par->vram = ioremap(info->fix.smem_start, info->fix.smem_len); -+ if (!par->vram) { -+ retval = -ENOMEM; -+ goto err_ioremap_vram; -+ } -+ info->screen_base = par->vram; -+ -+ retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED, -+ dev->dev.bus_id, info); -+ -+ if (retval) -+ goto err_request_irq; -+ -+ retval = fb_find_mode(&info->var, info, mode_option, -+ data->modes, data->num_modes, -+ data->modes, 16); -+ if (!retval) { -+ retval = -EINVAL; -+ goto err_find_mode; -+ } -+ -+ retval = cell->enable(dev); -+ if (retval) -+ goto err_enable; -+ -+ retval = tmiofb_hw_init(dev); -+ if (retval) -+ goto err_hw_init; -+ -+/* retval = tmiofb_set_par(info); -+ if (retval) -+ goto err_set_par;*/ -+ -+ retval = register_framebuffer(info); -+ if (retval < 0) -+ goto err_register_framebuffer; -+ -+ printk(KERN_INFO "fb%d: %s frame buffer device\n", -+ info->node, info->fix.id); -+ -+ return 0; -+ -+err_register_framebuffer: -+/*err_set_par:*/ -+ tmiofb_hw_stop(dev); -+err_hw_init: -+ cell->disable(dev); -+err_enable: -+err_find_mode: -+ free_irq(irq, info); -+err_request_irq: -+ iounmap(par->vram); -+err_ioremap_vram: -+ iounmap(par->lcr); -+err_ioremap_lcr: -+ iounmap(par->ccr); -+err_ioremap_ccr: -+ platform_set_drvdata(dev, NULL); -+ framebuffer_release(info); -+err_framebuffer_alloc: -+ return retval; -+} -+ -+static int __devexit tmiofb_remove(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct fb_info *info = platform_get_drvdata(dev); -+ int irq = platform_get_irq(dev, 0); -+ struct tmiofb_par *par; -+ -+ if (info) { -+ par = info->par; -+ unregister_framebuffer(info); -+ -+ tmiofb_hw_stop(dev); -+ -+ cell->disable(dev); -+ -+ free_irq(irq, info); -+ -+ iounmap(par->vram); -+ iounmap(par->lcr); -+ iounmap(par->ccr); -+ -+ framebuffer_release(info); -+ platform_set_drvdata(dev, NULL); -+ } -+ -+ return 0; -+} -+ -+#if 0 -+static void tmiofb_dump_regs(struct platform_device *dev) -+{ -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct tmiofb_par *par = info->par; -+ struct tmio_lhccr __iomem *ccr = par->ccr; -+ struct tmio_lcr __iomem *lcr = par->lcr; -+ -+ printk("lhccr:\n"); -+#define CCR_PR(n) printk("\t" #n " = \t%04x\n", ioread16(&ccr->n)); -+ CCR_PR(cmd); -+ CCR_PR(revid); -+ CCR_PR(basel); -+ CCR_PR(baseh); -+ CCR_PR(ugcc); -+ CCR_PR(gcc); -+ CCR_PR(usc); -+ CCR_PR(vramrtc); -+ CCR_PR(vramsac); -+ CCR_PR(vrambc); -+#undef CCR_PR -+ -+ printk("lcr: \n"); -+#define LCR_PR(n) printk("\t" #n " = \t%04x\n", ioread16(&lcr->n)); -+ LCR_PR(uis); -+ LCR_PR(vhpn); -+ LCR_PR(cfsal); -+ LCR_PR(cfsah); -+ LCR_PR(cfs); -+ LCR_PR(cfws); -+ LCR_PR(bbie); -+ LCR_PR(bbisc); -+ LCR_PR(ccs); -+ LCR_PR(bbes); -+ LCR_PR(cmdl); -+ LCR_PR(cmdh); -+ LCR_PR(cfc); -+ LCR_PR(ccifc); -+ LCR_PR(hwt); -+ LCR_PR(lcdccrc); -+ LCR_PR(lcdcc); -+ LCR_PR(lcdcopc); -+ LCR_PR(lcdis); -+ LCR_PR(lcdim); -+ LCR_PR(lcdie); -+ LCR_PR(gdsal); -+ LCR_PR(gdsah); -+ LCR_PR(vhpcl); -+ LCR_PR(vhpch); -+ LCR_PR(gm); -+ LCR_PR(ht); -+ LCR_PR(hds); -+ LCR_PR(hss); -+ LCR_PR(hse); -+ LCR_PR(hnp); -+ LCR_PR(vt); -+ LCR_PR(vds); -+ LCR_PR(vss); -+ LCR_PR(vse); -+ LCR_PR(cdln); -+ LCR_PR(iln); -+ LCR_PR(sp); -+ LCR_PR(misc); -+ LCR_PR(vihss); -+ LCR_PR(vivs); -+ LCR_PR(vive); -+ LCR_PR(vivss); -+ LCR_PR(vccis); -+ LCR_PR(vidwsal); -+ LCR_PR(vidwsah); -+ LCR_PR(vidrsal); -+ LCR_PR(vidrsah); -+ LCR_PR(vipddst); -+ LCR_PR(vipddet); -+ LCR_PR(vie); -+ LCR_PR(vcs); -+ LCR_PR(vphwc); -+ LCR_PR(vphs); -+ LCR_PR(vpvwc); -+ LCR_PR(vpvs); -+ LCR_PR(plhpix); -+ LCR_PR(xs); -+ LCR_PR(xckhw); -+ LCR_PR(sths); -+ LCR_PR(vt2); -+ LCR_PR(ycksw); -+ LCR_PR(ysts); -+ LCR_PR(ppols); -+ LCR_PR(precw); -+ LCR_PR(vclkhw); -+ LCR_PR(oc); -+#undef LCR_PR -+} -+#endif -+ -+#ifdef CONFIG_PM -+static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct tmiofb_par *par = info->par; -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ int retval = 0; -+ -+ acquire_console_sem(); -+ -+ fb_set_suspend(info, 1); -+ -+ if (info->fbops->fb_sync) -+ info->fbops->fb_sync(info); -+ -+ -+ printk(KERN_INFO "tmiofb: switching to polling\n"); -+ par->use_polling = true; -+ tmiofb_hw_stop(dev); -+ -+ if (cell->suspend) -+ retval = cell->suspend(dev); -+ -+ release_console_sem(); -+ -+ return retval; -+} -+ -+static int tmiofb_resume(struct platform_device *dev) -+{ -+ struct fb_info *info = platform_get_drvdata(dev); -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ int retval; -+ -+ acquire_console_sem(); -+ -+ if (cell->resume) { -+ retval = cell->resume(dev); -+ if (retval) -+ return retval; -+ } -+ -+ tmiofb_irq(-1, info); -+ -+ tmiofb_hw_init(dev); -+ -+ tmiofb_hw_mode(dev); -+ -+ fb_set_suspend(info, 0); -+ release_console_sem(); -+ return 0; -+} -+#endif -+ -+static struct platform_driver tmiofb_driver = { -+ .driver.name = "tmio-fb", -+ .driver.owner = THIS_MODULE, -+ .probe = tmiofb_probe, -+ .remove = __devexit_p(tmiofb_remove), -+#ifdef CONFIG_PM -+ .suspend = tmiofb_suspend, -+ .resume = tmiofb_resume, -+#endif -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+#ifndef MODULE -+static void __init tmiofb_setup(char *options) -+{ -+ char *this_opt; -+ -+ if (!options || !*options) -+ return; -+ -+ while ((this_opt = strsep(&options, ",")) != NULL) { -+ if (!*this_opt) continue; -+ /* -+ * FIXME -+ */ -+ } -+} -+#endif -+ -+static int __init tmiofb_init(void) -+{ -+#ifndef MODULE -+ char *option = NULL; -+ -+ if (fb_get_options("tmiofb", &option)) -+ return -ENODEV; -+ tmiofb_setup(option); -+#endif -+ return platform_driver_register(&tmiofb_driver); -+} -+ -+static void __exit tmiofb_cleanup(void) -+{ -+ platform_driver_unregister(&tmiofb_driver); -+} -+ -+module_init(tmiofb_init); -+module_exit(tmiofb_cleanup); -+ -+MODULE_DESCRIPTION("TMIO framebuffer driver"); -+MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov"); -+MODULE_LICENSE("GPL"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch deleted file mode 100644 index f358c069d0..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch +++ /dev/null @@ -1,431 +0,0 @@ -From e5f06830bc8d3ef4792c9c0569825d0347b39852 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Fri, 4 Jan 2008 18:43:31 +0000 -Subject: [PATCH 10/64] OHCI driver for TMIO devices - ---- - drivers/usb/Kconfig | 1 + - drivers/usb/host/Kconfig | 1 + - drivers/usb/host/ohci-hcd.c | 5 + - drivers/usb/host/ohci-tmio.c | 369 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 376 insertions(+), 0 deletions(-) - create mode 100644 drivers/usb/host/ohci-tmio.c - -diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig -index 7580aa5..8912042 100644 ---- a/drivers/usb/Kconfig -+++ b/drivers/usb/Kconfig -@@ -36,6 +36,7 @@ config USB_ARCH_HAS_OHCI - default y if ARCH_EP93XX - default y if ARCH_AT91 - default y if ARCH_PNX4008 -+ default y if MFD_TC6393XB - # PPC: - default y if STB03xxx - default y if PPC_MPC52xx -diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 49a91c5..5ae3589 100644 ---- a/drivers/usb/host/Kconfig -+++ b/drivers/usb/host/Kconfig -@@ -101,6 +101,7 @@ config USB_OHCI_HCD - depends on USB && USB_ARCH_HAS_OHCI - select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 - select I2C if ARCH_PNX4008 -+ select DMABOUNCE if MFD_TC6393XB - ---help--- - The Open Host Controller Interface (OHCI) is a standard for accessing - USB 1.1 host controller hardware. It does more in hardware than Intel's -diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c -index ecfe800..77abf3e 100644 ---- a/drivers/usb/host/ohci-hcd.c -+++ b/drivers/usb/host/ohci-hcd.c -@@ -1043,6 +1043,11 @@ MODULE_LICENSE ("GPL"); - #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver - #endif - -+#ifdef CONFIG_MFD_TC6393XB -+#include "ohci-tmio.c" -+#define PLATFORM_DRIVER ohci_hcd_tmio_driver -+#endif -+ - #ifdef CONFIG_USB_OHCI_HCD_SSB - #include "ohci-ssb.c" - #define SSB_OHCI_DRIVER ssb_ohci_driver -diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c -new file mode 100644 -index 0000000..be609f3 ---- /dev/null -+++ b/drivers/usb/host/ohci-tmio.c -@@ -0,0 +1,369 @@ -+/* -+ * OHCI HCD(Host Controller Driver) for USB. -+ * -+ *(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> -+ *(C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> -+ *(C) Copyright 2002 Hewlett-Packard Company -+ * -+ * Bus glue for Toshiba Mobile IO(TMIO) Controller's OHCI core -+ *(C) Copyright 2005 Chris Humbert <mahadri-usb@drigon.com> -+ * -+ * This is known to work with the following variants: -+ * TC6393XB revision 3 (32kB SRAM) -+ * -+ * The TMIO's OHCI core DMAs through a small internal buffer that -+ * is directly addressable by the CPU. dma_declare_coherent_memory -+ * and DMA bounce buffers allow the higher-level OHCI host driver to -+ * work. However, the dma API doesn't handle dma mapping failures -+ * well(dma_sg_map() is a prime example), so it is unusable. -+ * -+ * This HC pretends be a PIO-ish controller and uses the kernel's -+ * generic allocator for the entire SRAM. Using the USB core's -+ * usb_operations, we provide hcd_buffer_alloc/free. Using the OHCI's -+ * ohci_ops, we provide memory management for OHCI's TDs and EDs. We -+ * internally queue a URB's TDs until enough dma memory is available -+ * to enqueue them with the HC. -+ * -+ * Written from sparse documentation from Toshiba and Sharp's driver -+ * for the 2.4 kernel, -+ * usb-ohci-tc6393.c(C) Copyright 2004 Lineo Solutions, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/*#include <linux/fs.h> -+#include <linux/mount.h> -+#include <linux/pagemap.h> -+#include <linux/init.h> -+#include <linux/namei.h> -+#include <linux/sched.h>*/ -+#include <linux/platform_device.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+#include <linux/dma-mapping.h> -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* -+ * USB Host Controller Configuration Register -+ */ -+struct tmio_uhccr { -+ u8 x00[8]; -+ u8 revid; /* 0x08 Revision ID */ -+ u8 x01[7]; -+ u16 basel; /* 0x10 USB Control Register Base Address Low */ -+ u16 baseh; /* 0x12 USB Control Register Base Address High */ -+ u8 x02[0x2c]; -+ u8 ilme; /* 0x40 Internal Local Memory Enable */ -+ u8 x03[0x0b]; -+ u16 pm; /* 0x4c Power Management */ -+ u8 x04[2]; -+ u8 intc; /* 0x50 INT Control */ -+ u8 x05[3]; -+ u16 lmw1l; /* 0x54 Local Memory Window 1 LMADRS Low */ -+ u16 lmw1h; /* 0x56 Local Memory Window 1 LMADRS High */ -+ u16 lmw1bl; /* 0x58 Local Memory Window 1 Base Address Low */ -+ u16 lmw1bh; /* 0x5A Local Memory Window 1 Base Address High */ -+ u16 lmw2l; /* 0x5C Local Memory Window 2 LMADRS Low */ -+ u16 lmw2h; /* 0x5E Local Memory Window 2 LMADRS High */ -+ u16 lmw2bl; /* 0x60 Local Memory Window 2 Base Address Low */ -+ u16 lmw2bh; /* 0x62 Local Memory Window 2 Base Address High */ -+ u8 x06[0x98]; -+ u8 misc; /* 0xFC MISC */ -+ u8 x07[3]; -+} __attribute__((packed)); -+ -+#define UHCCR_PM_GKEN 0x0001 -+#define UHCCR_PM_CKRNEN 0x0002 -+#define UHCCR_PM_USBPW1 0x0004 -+#define UHCCR_PM_USBPW2 0x0008 -+#define UHCCR_PM_PMEE 0x0100 -+#define UHCCR_PM_PMES 0x8000 -+ -+/*-------------------------------------------------------------------------*/ -+ -+struct tmio_hcd { -+ struct tmio_uhccr __iomem *ccr; -+}; -+ -+#define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1)) -+#define ohci_to_tmio(ohci) ((struct tmio_hcd *)(ohci + 1)) -+ -+/*-------------------------------------------------------------------------*/ -+ -+static void tmio_stop_hc(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ u16 pm; -+ -+ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | UHCCR_PM_USBPW1 | UHCCR_PM_USBPW2; -+ iowrite8(0, &ccr->intc); -+ iowrite8(0, &ccr->ilme); -+ iowrite16(0, &ccr->basel); -+ iowrite16(0, &ccr->baseh); -+ iowrite16(pm, &ccr->pm); -+ -+ cell->disable(dev); -+} -+ -+static void tmio_start_hc(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ u16 pm; -+ unsigned long base = hcd->rsrc_start; -+ -+ pm = UHCCR_PM_CKRNEN | UHCCR_PM_GKEN | UHCCR_PM_PMEE | UHCCR_PM_PMES; -+ cell->enable(dev); -+ -+ iowrite16(pm, &ccr->pm); -+ iowrite16(base, &ccr->basel); -+ iowrite16(base >> 16, &ccr->baseh); -+ iowrite8(1, &ccr->ilme); -+ iowrite8(2, &ccr->intc); -+ -+ dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n", -+ ioread8(&ccr->revid), hcd->rsrc_start, hcd->irq); -+} -+ -+static int usb_hcd_tmio_probe(const struct hc_driver *driver, -+ struct platform_device *dev) -+{ -+ struct resource *config = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONFIG); -+ struct resource *regs = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONTROL); -+ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -+ int irq = platform_get_irq(dev, 0); -+ struct tmio_hcd *tmio; -+ struct ohci_hcd *ohci; -+ struct usb_hcd *hcd; -+ int retval; -+ -+ if (usb_disabled()) -+ return -ENODEV; -+ -+ hcd = usb_create_hcd(driver, &dev->dev, dev->dev.bus_id); -+ if (!hcd) { -+ retval = -ENOMEM; -+ goto err_usb_create_hcd; -+ } -+ -+ hcd->rsrc_start = regs->start; -+ hcd->rsrc_len = regs->end - regs->start + 1; -+ -+ tmio = hcd_to_tmio(hcd); -+ -+ tmio->ccr = ioremap(config->start, config->end - config->start + 1); -+ if (!tmio->ccr) { -+ retval = -ENOMEM; -+ goto err_ioremap_ccr; -+ } -+ -+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -+ if (!hcd->regs) { -+ retval = -ENOMEM; -+ goto err_ioremap_regs; -+ } -+ -+ if (dma_declare_coherent_memory(&dev->dev, sram->start, -+ sram->start, -+ sram->end - sram->start + 1, -+ DMA_MEMORY_MAP) != DMA_MEMORY_MAP) { -+ retval = -EBUSY; -+ goto err_dma_declare; -+ } -+ -+ retval = dmabounce_register_dev(&dev->dev, 512, 4096); -+ if (retval) -+ goto err_dmabounce_register_dev; -+ -+ tmio_start_hc(dev); -+ ohci = hcd_to_ohci(hcd); -+ ohci_hcd_init(ohci); -+ -+ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); -+ -+ if (retval == 0) -+ return retval; -+ -+ tmio_stop_hc(dev); -+ -+ dmabounce_unregister_dev(&dev->dev); -+err_dmabounce_register_dev: -+ dma_release_declared_memory(&dev->dev); -+err_dma_declare: -+ iounmap(hcd->regs); -+err_ioremap_regs: -+ iounmap(tmio->ccr); -+err_ioremap_ccr: -+ usb_put_hcd(hcd); -+err_usb_create_hcd: -+ -+ return retval; -+} -+ -+static void usb_hcd_tmio_remove(struct usb_hcd *hcd, struct platform_device *dev) -+{ -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ -+ usb_remove_hcd(hcd); -+ tmio_stop_hc(dev); -+ dmabounce_unregister_dev(&dev->dev); -+ dma_release_declared_memory(&dev->dev); -+ iounmap(hcd->regs); -+ iounmap(tmio->ccr); -+ usb_put_hcd(hcd); -+} -+ -+static int __devinit -+ohci_tmio_start(struct usb_hcd *hcd) -+{ -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ int retval; -+ -+ if ((retval = ohci_init(ohci)) < 0) -+ return retval; -+ -+ if ((retval = ohci_run(ohci)) < 0) { -+ err("can't start %s", hcd->self.bus_name); -+ ohci_stop(hcd); -+ return retval; -+ } -+ -+ return 0; -+} -+ -+static const struct hc_driver ohci_tmio_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "TMIO OHCI USB Host Controller", -+ .hcd_priv_size = sizeof(struct ohci_hcd) + sizeof (struct tmio_hcd), -+ -+ /* generic hardware linkage */ -+ .irq = ohci_irq, -+ .flags = HCD_USB11 | HCD_MEMORY, -+ -+ /* basic lifecycle operations */ -+ .start = ohci_tmio_start, -+ .stop = ohci_stop, -+ .shutdown = ohci_shutdown, -+ -+ /* managing i/o requests and associated device resources */ -+ .urb_enqueue = ohci_urb_enqueue, -+ .urb_dequeue = ohci_urb_dequeue, -+ .endpoint_disable = ohci_endpoint_disable, -+ -+ /* scheduling support */ -+ .get_frame_number = ohci_get_frame, -+ -+ /* root hub support */ -+ .hub_status_data = ohci_hub_status_data, -+ .hub_control = ohci_hub_control, -+ .hub_irq_enable = ohci_rhsc_enable, -+#ifdef CONFIG_PM -+ .bus_suspend = ohci_bus_suspend, -+ .bus_resume = ohci_bus_resume, -+#endif -+ .start_port_reset = ohci_start_port_reset, -+}; -+ -+/*-------------------------------------------------------------------------*/ -+static struct platform_driver ohci_hcd_tmio_driver; -+ -+static int -+tmio_dmabounce_check(struct device *dev, dma_addr_t dma, size_t size, void *data) -+{ -+ struct resource *sram = data; -+#ifdef DEBUG -+ printk(KERN_ERR "tmio_dmabounce_check: %08x %d\n", dma, size); -+#endif -+ -+ if (dev->driver != &ohci_hcd_tmio_driver.driver) -+ return 0; -+ -+ if (sram->start <= dma && dma + size <= sram->end) -+ return 0; -+ -+ return 1; -+} -+ -+static u64 dma_mask = DMA_32BIT_MASK; -+ -+static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) -+{ -+ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -+ -+ dev->dev.dma_mask = &dma_mask; -+ dev->dev.coherent_dma_mask = DMA_32BIT_MASK; -+ -+ dmabounce_register_checker(tmio_dmabounce_check, sram); -+ -+ return usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev); -+} -+ -+static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -+ -+ usb_hcd_tmio_remove(hcd, dev); -+ -+ platform_set_drvdata(dev, NULL); -+ -+ dmabounce_remove_checker(tmio_dmabounce_check, sram); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ -+ if (time_before(jiffies, ohci->next_statechange)) -+ msleep(5); -+ ohci->next_statechange = jiffies; -+ -+ tmio_stop_hc(dev); -+ hcd->state = HC_STATE_SUSPENDED; -+ dev->dev.power.power_state = PMSG_SUSPEND; -+ -+ return 0; -+} -+ -+static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ -+ if (time_before(jiffies, ohci->next_statechange)) -+ msleep(5); -+ ohci->next_statechange = jiffies; -+ -+ tmio_start_hc(dev); -+ -+ dev->dev.power.power_state = PMSG_ON; -+ usb_hcd_resume_root_hub(hcd); -+ -+ return 0; -+} -+#endif -+ -+static struct platform_driver ohci_hcd_tmio_driver = { -+ .probe = ohci_hcd_tmio_drv_probe, -+ .remove = ohci_hcd_tmio_drv_remove, -+ .shutdown = usb_hcd_platform_shutdown, -+#ifdef CONFIG_PM -+ .suspend = ohci_hcd_tmio_drv_suspend, -+ .resume = ohci_hcd_tmio_drv_resume, -+#endif -+ .driver = { -+ .name = "tmio-ohci", -+ }, -+}; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch deleted file mode 100644 index 6ff752d1ff..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch +++ /dev/null @@ -1,891 +0,0 @@ -From b358a64c1fdd1eb80da57f919c893d910db95e37 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Sat, 29 Dec 2007 15:26:19 +0000 -Subject: [PATCH 11/64] MMC driver for TMIO devices - ---- - drivers/mmc/host/Kconfig | 6 + - drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/tmio_mmc.c | 633 +++++++++++++++++++++++++++++++++++++++++++ - drivers/mmc/host/tmio_mmc.h | 205 ++++++++++++++ - 4 files changed, 845 insertions(+), 0 deletions(-) - create mode 100644 drivers/mmc/host/tmio_mmc.c - create mode 100644 drivers/mmc/host/tmio_mmc.h - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 5fef678..f8f9b7e 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -130,3 +130,9 @@ config MMC_SPI - - If unsure, or if your system has no SPI master driver, say N. - -+config MMC_TMIO -+ tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" -+ depends on MMC -+ help -+ This provides support for the SD/MMC cell found in TC6393XB, -+ T7L66XB and also ipaq ASIC3 -diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 3877c87..7ac956b 100644 ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -17,4 +17,5 @@ obj-$(CONFIG_MMC_OMAP) += omap.o - obj-$(CONFIG_MMC_AT91) += at91_mci.o - obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o - obj-$(CONFIG_MMC_SPI) += mmc_spi.o -+obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o - -diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c -new file mode 100644 -index 0000000..735c386 ---- /dev/null -+++ b/drivers/mmc/host/tmio_mmc.c -@@ -0,0 +1,633 @@ -+/* -+ * linux/drivers/mmc/tmio_mmc.c -+ * -+ * Copyright (C) 2004 Ian Molton -+ * Copyright (C) 2007 Ian Molton -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Driver for the MMC / SD / SDIO cell found in: -+ * -+ * TC6393XB TC6391XB TC6387XB T7L66XB -+ * -+ * This driver draws mainly on scattered spec sheets, Reverse engineering -+ * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit -+ * support). (Further 4 bit support from a later datasheet). -+ * -+ * TODO: -+ * Investigate using a workqueue for PIO transfers -+ * Eliminate FIXMEs -+ * SDIO support -+ * Better Power management -+ * Handle MMC errors better -+ * double buffer support -+ * -+ */ -+#include <linux/module.h> -+#include <linux/irq.h> -+#include <linux/device.h> -+#include <linux/delay.h> -+#include <linux/mmc/mmc.h> -+#include <linux/mmc/host.h> -+#include <linux/mfd-core.h> -+#include <linux/mfd/tmio.h> -+ -+#include "tmio_mmc.h" -+ -+/* -+ * Fixme - documentation conflicts on what the clock values are for the -+ * various dividers. -+ * One document I have says that its a divisor of a 24MHz clock, another 33. -+ * This probably depends on HCLK for a given platform, so we may need to -+ * require HCLK be passed to us from the MFD core. -+ * -+ */ -+ -+static void tmio_mmc_set_clock (struct tmio_mmc_host *host, int new_clock) { -+ struct tmio_mmc_cnf __iomem *cnf = host->cnf; -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ u32 clk = 0, clock; -+ -+ if (new_clock) { -+ for(clock = 46875, clk = 0x100; new_clock >= (clock<<1); ){ -+ clock <<= 1; -+ clk >>= 1; -+ } -+ if(clk & 0x1) -+ clk = 0x20000; -+ -+ clk >>= 2; -+ if(clk & 0x8000) /* For full speed we disable the divider. */ -+ writeb(0, &cnf->sd_clk_mode); -+ else -+ writeb(1, &cnf->sd_clk_mode); -+ clk |= 0x100; -+ } -+ -+ writew(clk, &ctl->sd_card_clk_ctl); -+} -+ -+static void tmio_mmc_clk_stop (struct tmio_mmc_host *host) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ writew(0x0000, &ctl->clk_and_wait_ctl); -+ msleep(10); -+ writew(readw(&ctl->sd_card_clk_ctl) & ~0x0100, &ctl->sd_card_clk_ctl); -+ msleep(10); -+} -+ -+static void tmio_mmc_clk_start (struct tmio_mmc_host *host) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ writew(readw(&ctl->sd_card_clk_ctl) | 0x0100, &ctl->sd_card_clk_ctl); -+ msleep(10); -+ writew(0x0100, &ctl->clk_and_wait_ctl); -+ msleep(10); -+} -+ -+static void reset(struct tmio_mmc_host *host) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ /* FIXME - should we set stop clock reg here */ -+ writew(0x0000, &ctl->reset_sd); -+ writew(0x0000, &ctl->reset_sdio); -+ msleep(10); -+ writew(0x0001, &ctl->reset_sd); -+ writew(0x0001, &ctl->reset_sdio); -+ msleep(10); -+} -+ -+static void -+tmio_mmc_finish_request(struct tmio_mmc_host *host) -+{ -+ struct mmc_request *mrq = host->mrq; -+ -+ host->mrq = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ -+ mmc_request_done(host->mmc, mrq); -+} -+ -+/* These are the bitmasks the tmio chip requires to implement the MMC response -+ * types. Note that R1 and R6 are the same in this scheme. */ -+#define APP_CMD 0x0040 -+#define RESP_NONE 0x0300 -+#define RESP_R1 0x0400 -+#define RESP_R1B 0x0500 -+#define RESP_R2 0x0600 -+#define RESP_R3 0x0700 -+#define DATA_PRESENT 0x0800 -+#define TRANSFER_READ 0x1000 -+#define TRANSFER_MULTI 0x2000 -+#define SECURITY_CMD 0x4000 -+ -+static void -+tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) -+{ -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ struct mmc_data *data = host->data; -+ int c = cmd->opcode; -+ -+ if(cmd->opcode == MMC_STOP_TRANSMISSION) { -+ writew(0x001, &ctl->stop_internal_action); -+ return; -+ } -+ -+ switch(mmc_resp_type(cmd)) { -+ case MMC_RSP_NONE: c |= RESP_NONE; break; -+ case MMC_RSP_R1: c |= RESP_R1; break; -+ case MMC_RSP_R1B: c |= RESP_R1B; break; -+ case MMC_RSP_R2: c |= RESP_R2; break; -+ case MMC_RSP_R3: c |= RESP_R3; break; -+ default: -+ DBG("Unknown response type %d\n", mmc_resp_type(cmd)); -+ } -+ -+ host->cmd = cmd; -+ -+/* FIXME - this seems to be ok comented out but the spec suggest this bit should -+ * be set when issuing app commands. -+ * if(cmd->flags & MMC_FLAG_ACMD) -+ * c |= APP_CMD; -+ */ -+ if(data) { -+ c |= DATA_PRESENT; -+ if(data->blocks > 1) { -+ writew(0x100, &ctl->stop_internal_action); -+ c |= TRANSFER_MULTI; -+ } -+ if(data->flags & MMC_DATA_READ) -+ c |= TRANSFER_READ; -+ } -+ -+ enable_mmc_irqs(ctl, TMIO_MASK_CMD); -+ -+ /* Fire off the command */ -+ tmio_iowrite32(cmd->arg, ctl->arg_reg); -+ writew(c, &ctl->sd_cmd); -+} -+ -+/* This chip always returns (at least?) as much data as you ask for. -+ * Im unsure what happens if you ask for less than a block. This should be -+ * looked into to ensure that a funny length read doesnt hose the controller. -+ * -+ * FIXME - this chip cannot do 1 and 2 byte data requests in 4 bit mode -+ */ -+static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ struct mmc_data *data = host->data; -+ unsigned short *buf; -+ unsigned int count; -+ unsigned long flags; -+ -+ if(!data){ -+ DBG("Spurious PIO IRQ\n"); -+ return; -+ } -+ -+ buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) + -+ host->sg_off); -+ -+ /* Ensure we dont read more than one block. The chip will interrupt us -+ * When the next block is available. -+ * FIXME - this is probably not true now IRQ handling is fixed -+ */ -+ count = host->sg_ptr->length - host->sg_off; -+ if(count > data->blksz) -+ count = data->blksz; -+ -+ DBG("count: %08x offset: %08x flags %08x\n", -+ count, host->sg_off, data->flags); -+ -+ /* Transfer the data */ -+ if(data->flags & MMC_DATA_READ) -+ readsw(&ctl->sd_data_port[0], buf, count >> 1); -+ else -+ writesw(&ctl->sd_data_port[0], buf, count >> 1); -+ -+ host->sg_off += count; -+ -+ tmio_mmc_kunmap_atomic(host, &flags); -+ -+ if(host->sg_off == host->sg_ptr->length) -+ tmio_mmc_next_sg(host); -+ -+ return; -+} -+ -+static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ struct mmc_data *data = host->data; -+ -+ host->data = NULL; -+ -+ if(!data){ -+ DBG("Spurious data end IRQ\n"); -+ return; -+ } -+ -+ /* FIXME - return correct transfer count on errors */ -+ if (!data->error) -+ data->bytes_xfered = data->blocks * data->blksz; -+ else -+ data->bytes_xfered = 0; -+ -+ DBG("Completed data request\n"); -+ -+ /*FIXME - other drivers allow an optional stop command of any given type -+ * which we dont do, as the chip can auto generate them. -+ * Perhaps we can be smarter about when to use auto CMD12 and -+ * only issue the auto request when we know this is the desired -+ * stop command, allowing fallback to the stop command the -+ * upper layers expect. For now, we do what works. -+ */ -+ -+ writew(0x000, &ctl->stop_internal_action); -+ -+ if(data->flags & MMC_DATA_READ) -+ disable_mmc_irqs(ctl, TMIO_MASK_READOP); -+ else -+ disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); -+ -+ tmio_mmc_finish_request(host); -+} -+ -+static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat) { -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ struct mmc_command *cmd = host->cmd; -+ -+ if(!host->cmd) { -+ DBG("Spurious CMD irq\n"); -+ return; -+ } -+ -+ host->cmd = NULL; -+ -+ /* This controller is sicker than the PXA one. not only do we need to -+ * drop the top 8 bits of the first response word, we also need to -+ * modify the order of the response for short response command types. -+ */ -+ -+ /* FIXME - this works but readl is wrong and will break on asic3... */ -+ cmd->resp[3] = tmio_ioread32(&ctl->response[0]); -+ cmd->resp[2] = tmio_ioread32(&ctl->response[2]); -+ cmd->resp[1] = tmio_ioread32(&ctl->response[4]); -+ cmd->resp[0] = tmio_ioread32(&ctl->response[6]); -+ -+ if(cmd->flags & MMC_RSP_136) { -+ cmd->resp[0] = (cmd->resp[0] <<8) | (cmd->resp[1] >>24); -+ cmd->resp[1] = (cmd->resp[1] <<8) | (cmd->resp[2] >>24); -+ cmd->resp[2] = (cmd->resp[2] <<8) | (cmd->resp[3] >>24); -+ cmd->resp[3] <<= 8; -+ } -+ else if(cmd->flags & MMC_RSP_R3) { -+ cmd->resp[0] = cmd->resp[3]; -+ } -+ -+ if (stat & TMIO_STAT_CMDTIMEOUT) -+ cmd->error = -ETIMEDOUT; -+ else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) -+ cmd->error = -EILSEQ; -+ -+ /* If there is data to handle we enable data IRQs here, and -+ * we will ultimatley finish the request in the data_end handler. -+ * If theres no data or we encountered an error, finish now. -+ */ -+ if(host->data && !cmd->error){ -+ if(host->data->flags & MMC_DATA_READ) -+ enable_mmc_irqs(ctl, TMIO_MASK_READOP); -+ else -+ enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); -+ } -+ else { -+ tmio_mmc_finish_request(host); -+ } -+ -+ return; -+} -+ -+ -+static irqreturn_t tmio_mmc_irq(int irq, void *devid) -+{ -+ struct tmio_mmc_host *host = devid; -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ unsigned int ireg, irq_mask, status; -+ -+ DBG("MMC IRQ begin\n"); -+ -+ status = tmio_ioread32(ctl->status); -+ irq_mask = tmio_ioread32(ctl->irq_mask); -+ ireg = status & TMIO_MASK_IRQ & ~irq_mask; -+ -+#ifdef CONFIG_MMC_DEBUG -+ debug_status(status); -+ debug_status(ireg); -+#endif -+ if (!ireg) { -+ disable_mmc_irqs(ctl, status & ~irq_mask); -+#ifdef CONFIG_MMC_DEBUG -+ WARN("tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); -+ debug_status(status); -+#endif -+ goto out; -+ } -+ -+ while (ireg) { -+ /* Card insert / remove attempts */ -+ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)){ -+ ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE); -+ mmc_detect_change(host->mmc,0); -+ } -+ -+ /* CRC and other errors */ -+/* if (ireg & TMIO_STAT_ERR_IRQ) -+ * handled |= tmio_error_irq(host, irq, stat); -+ */ -+ -+ /* Command completion */ -+ if (ireg & TMIO_MASK_CMD) { -+ tmio_mmc_cmd_irq(host, status); -+ ack_mmc_irqs(ctl, TMIO_MASK_CMD); -+ } -+ -+ /* Data transfer */ -+ if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { -+ ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); -+ tmio_mmc_pio_irq(host); -+ } -+ -+ /* Data transfer completion */ -+ if (ireg & TMIO_STAT_DATAEND) { -+ tmio_mmc_data_irq(host); -+ ack_mmc_irqs(ctl, TMIO_STAT_DATAEND); -+ } -+ -+ /* Check status - keep going until we've handled it all */ -+ status = tmio_ioread32(ctl->status); -+ irq_mask = tmio_ioread32(ctl->irq_mask); -+ ireg = status & TMIO_MASK_IRQ & ~irq_mask; -+ -+#ifdef CONFIG_MMC_DEBUG -+ DBG("Status at end of loop: %08x\n", status); -+ debug_status(status); -+#endif -+ } -+ DBG("MMC IRQ end\n"); -+ -+out: -+ return IRQ_HANDLED; -+} -+ -+static void tmio_mmc_start_data(struct tmio_mmc_host *host, struct mmc_data *data) -+{ -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ DBG("setup data transfer: blocksize %08x nr_blocks %d\n", -+ data->blksz, data->blocks); -+ -+ tmio_mmc_init_sg(host, data); -+ host->data = data; -+ -+ /* Set transfer length / blocksize */ -+ writew(data->blksz, &ctl->sd_xfer_len); -+ writew(data->blocks, &ctl->xfer_blk_count); -+} -+ -+/* Process requests from the MMC layer */ -+static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct tmio_mmc_host *host = mmc_priv(mmc); -+ -+ WARN_ON(host->mrq != NULL); -+ -+ host->mrq = mrq; -+ -+ /* If we're performing a data request we need to setup some -+ extra information */ -+ if (mrq->data) -+ tmio_mmc_start_data(host, mrq->data); -+ -+ tmio_mmc_start_command(host, mrq->cmd); -+} -+ -+/* Set MMC clock / power. -+ * Note: This controller uses a simple divider scheme therefore it cannot -+ * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as -+ * MMC wont run that fast, it has to be clocked at 12MHz which is the next -+ * slowest setting. -+ */ -+static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct tmio_mmc_host *host = mmc_priv(mmc); -+ struct tmio_mmc_cnf __iomem *cnf = host->cnf; -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ if(ios->clock) -+ tmio_mmc_set_clock (host, ios->clock); -+ -+ /* Power sequence - OFF -> ON -> UP */ -+ switch (ios->power_mode) { -+ case MMC_POWER_OFF: -+ writeb(0x00, &cnf->pwr_ctl[1]); /* power down SD bus */ -+ tmio_mmc_clk_stop(host); -+ break; -+ case MMC_POWER_ON: -+ writeb(0x02, &cnf->pwr_ctl[1]); /* power up SD bus */ -+ break; -+ case MMC_POWER_UP: -+ tmio_mmc_clk_start(host); /* start bus clock */ -+ break; -+ } -+ -+ switch (ios->bus_width) { -+ case MMC_BUS_WIDTH_1: -+ writew(0x80e0, &ctl->sd_mem_card_opt); -+ break; -+ case MMC_BUS_WIDTH_4: -+ writew(0x00e0, &ctl->sd_mem_card_opt); -+ break; -+ } -+ -+ /* Potentially we may need a 140us pause here. FIXME */ -+ udelay(140); -+} -+ -+static int tmio_mmc_get_ro(struct mmc_host *mmc) { -+ struct tmio_mmc_host *host = mmc_priv(mmc); -+ struct tmio_mmc_ctl __iomem *ctl = host->ctl; -+ -+ return (readw(&ctl->status[0]) & TMIO_STAT_WRPROTECT)?0:1; -+} -+ -+static struct mmc_host_ops tmio_mmc_ops = { -+ .request = tmio_mmc_request, -+ .set_ios = tmio_mmc_set_ios, -+ .get_ro = tmio_mmc_get_ro, -+}; -+ -+static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) { -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct mmc_host *mmc = platform_get_drvdata(dev); -+ int ret; -+ -+ ret = mmc_suspend_host(mmc, state); -+ -+ /* Tell MFD core it can disable us now.*/ -+ if(!ret && cell->disable) -+ cell->disable(dev); -+ -+ return ret; -+} -+ -+static int tmio_mmc_resume(struct platform_device *dev) { -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct mmc_host *mmc = platform_get_drvdata(dev); -+ struct tmio_mmc_host *host = mmc_priv(mmc); -+ struct tmio_mmc_cnf __iomem *cnf = host->cnf; -+ -+ /* Enable the MMC/SD Control registers */ -+ writew(SDCREN, &cnf->cmd); -+ writel(dev->resource[0].start & 0xfffe, &cnf->ctl_base); -+ -+ /* Tell the MFD core we are ready to be enabled */ -+ if(cell->enable) -+ cell->enable(dev); -+ -+ mmc_resume_host(mmc); -+ -+ return 0; -+} -+ -+static int __devinit tmio_mmc_probe(struct platform_device *dev) -+{ -+ struct mfd_cell *cell = mfd_get_cell(dev); -+ struct tmio_mmc_cnf __iomem *cnf; -+ struct tmio_mmc_ctl __iomem *ctl; -+ struct tmio_mmc_host *host; -+ struct mmc_host *mmc; -+ int ret = -ENOMEM; -+ -+ mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); -+ if (!mmc) { -+ goto out; -+ } -+ -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ platform_set_drvdata(dev, mmc); /* Used so we can de-init safely. */ -+ -+ host->cnf = cnf = ioremap((unsigned long)dev->resource[1].start, -+ (unsigned long)dev->resource[1].end - -+ (unsigned long)dev->resource[1].start); -+ if(!host->cnf) -+ goto host_free; -+ -+ host->ctl = ctl = ioremap((unsigned long)dev->resource[0].start, -+ (unsigned long)dev->resource[0].end - -+ (unsigned long)dev->resource[0].start); -+ if (!host->ctl) { -+ goto unmap_cnf; -+ } -+ -+ mmc->ops = &tmio_mmc_ops; -+ mmc->caps = MMC_CAP_4_BIT_DATA; -+ mmc->f_min = 46875; -+ mmc->f_max = 24000000; -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ /* Enable the MMC/SD Control registers */ -+ writew(SDCREN, &cnf->cmd); -+ writel(dev->resource[0].start & 0xfffe, &cnf->ctl_base); -+ -+ /* Tell the MFD core we are ready to be enabled */ -+ if(cell->enable) -+ cell->enable(dev); -+ -+ writeb(0x01,&cnf->pwr_ctl[2]); /* Disable SD power during suspend */ -+ writeb(0x1f, &cnf->stop_clk_ctl); /* Route clock to SDIO??? FIXME */ -+ writeb(0x0, &cnf->pwr_ctl[1]); /* Power down SD bus*/ -+ tmio_mmc_clk_stop(host); /* Stop bus clock */ -+ reset(host); /* Reset MMC HC */ -+ -+ host->irq = (unsigned long)dev->resource[2].start; -+ ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", host); -+ if (ret){ -+ ret = -ENODEV; -+ DBG("Failed to allocate IRQ.\n"); -+ goto unmap_ctl; -+ } -+ set_irq_type(host->irq, IRQT_FALLING); -+ -+ mmc_add_host(mmc); -+ -+ printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), -+ (unsigned long)host->ctl, host->irq); -+ -+ /* Lets unmask the IRQs we want to know about */ -+ disable_mmc_irqs(ctl, TMIO_MASK_ALL); -+ enable_mmc_irqs(ctl, TMIO_MASK_IRQ); -+ -+ return 0; -+ -+unmap_ctl: -+ iounmap(host->ctl); -+unmap_cnf: -+ iounmap(host->cnf); -+host_free: -+ mmc_free_host(mmc); -+out: -+ return ret; -+} -+ -+static int __devexit tmio_mmc_remove(struct platform_device *dev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(dev); -+ -+ platform_set_drvdata(dev, NULL); -+ -+ if (mmc) { -+ struct tmio_mmc_host *host = mmc_priv(mmc); -+ mmc_remove_host(mmc); -+ free_irq(host->irq, host); -+ /* FIXME - we might want to consider stopping the chip here. */ -+ iounmap(host->ctl); -+ iounmap(host->cnf); -+ mmc_free_host(mmc); /* FIXME - why does this call hang ? */ -+ } -+ return 0; -+} -+ -+/* ------------------- device registration ----------------------- */ -+ -+static struct platform_driver tmio_mmc_driver = { -+ .driver = { -+ .name = "tmio-mmc", -+ }, -+ .probe = tmio_mmc_probe, -+ .remove = __devexit_p(tmio_mmc_remove), -+#ifdef CONFIG_PM -+ .suspend = tmio_mmc_suspend, -+ .resume = tmio_mmc_resume, -+#endif -+}; -+ -+ -+static int __init tmio_mmc_init(void) -+{ -+ return platform_driver_register (&tmio_mmc_driver); -+} -+ -+static void __exit tmio_mmc_exit(void) -+{ -+ platform_driver_unregister (&tmio_mmc_driver); -+} -+ -+module_init(tmio_mmc_init); -+module_exit(tmio_mmc_exit); -+ -+MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); -+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -+MODULE_LICENSE("GPLv2"); -diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h -new file mode 100644 -index 0000000..d4d9f8f ---- /dev/null -+++ b/drivers/mmc/host/tmio_mmc.h -@@ -0,0 +1,205 @@ -+/* Definitons for use with the tmio_mmc.c -+ * -+ * (c) 2005 Ian Molton <spyro@f2s.com> -+ * (c) 2007 Ian Molton <spyro@f2s.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+struct tmio_mmc_cnf { -+ u8 x00[4]; -+ u16 cmd; -+ u8 x01[10]; -+ u32 ctl_base; -+ u8 x02[41]; -+ u8 int_pin; -+ u8 x03[2]; -+ u8 stop_clk_ctl; -+ u8 gclk_ctl; /* Gated Clock Control */ -+ u8 sd_clk_mode; /* 0x42 */ -+ u8 x04; -+ u16 pin_status; -+ u8 x05[2]; -+ u8 pwr_ctl[3]; -+ u8 x06; -+ u8 card_detect_mode; -+ u8 x07[3]; -+ u8 sd_slot; -+ u8 x08[159]; -+ u8 ext_gclk_ctl_1; /* Extended Gated Clock Control 1 */ -+ u8 ext_gclk_ctl_2; /* Extended Gated Clock Control 2 */ -+ u8 x09[7]; -+ u8 ext_gclk_ctl_3; /* Extended Gated Clock Control 3 */ -+ u8 sd_led_en_1; -+ u8 x10[3]; -+ u8 sd_led_en_2; -+ u8 x11; -+} __attribute__ ((packed)); -+ -+#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ -+ -+struct tmio_mmc_ctl { -+ u16 sd_cmd; -+ u16 x00; -+ u16 arg_reg[2]; -+ u16 stop_internal_action; -+ u16 xfer_blk_count; -+ u16 response[8]; -+ u16 status[2]; -+ u16 irq_mask[2]; -+ u16 sd_card_clk_ctl; -+ u16 sd_xfer_len; -+ u16 sd_mem_card_opt; -+ u16 x01; -+ u16 sd_error_detail_status[2]; -+ u16 sd_data_port[2]; -+ u16 transaction_ctl; -+ u16 x02[85]; -+ u16 reset_sd; -+ u16 x03[15]; -+ u16 sdio_regs[28]; -+ u16 clk_and_wait_ctl; -+ u16 x04[83]; -+ u16 reset_sdio; -+ u16 x05[15]; -+} __attribute__ ((packed)); -+ -+/* Definitions for values the CTRL_STATUS register can take. */ -+#define TMIO_STAT_CMDRESPEND 0x00000001 -+#define TMIO_STAT_DATAEND 0x00000004 -+#define TMIO_STAT_CARD_REMOVE 0x00000008 -+#define TMIO_STAT_CARD_INSERT 0x00000010 -+#define TMIO_STAT_SIGSTATE 0x00000020 -+#define TMIO_STAT_WRPROTECT 0x00000080 -+#define TMIO_STAT_CARD_REMOVE_A 0x00000100 -+#define TMIO_STAT_CARD_INSERT_A 0x00000200 -+#define TMIO_STAT_SIGSTATE_A 0x00000400 -+#define TMIO_STAT_CMD_IDX_ERR 0x00010000 -+#define TMIO_STAT_CRCFAIL 0x00020000 -+#define TMIO_STAT_STOPBIT_ERR 0x00040000 -+#define TMIO_STAT_DATATIMEOUT 0x00080000 -+#define TMIO_STAT_RXOVERFLOW 0x00100000 -+#define TMIO_STAT_TXUNDERRUN 0x00200000 -+#define TMIO_STAT_CMDTIMEOUT 0x00400000 -+#define TMIO_STAT_RXRDY 0x01000000 -+#define TMIO_STAT_TXRQ 0x02000000 -+#define TMIO_STAT_ILL_FUNC 0x20000000 -+#define TMIO_STAT_CMD_BUSY 0x40000000 -+#define TMIO_STAT_ILL_ACCESS 0x80000000 -+ -+/* Define some IRQ masks */ -+/* This is the mask used at reset by the chip */ -+#define TMIO_MASK_ALL 0x837f031d -+#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ -+ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) -+#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \ -+ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) -+#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ -+ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) -+#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) -+ -+#define enable_mmc_irqs(ctl, i) \ -+ do { \ -+ u32 mask;\ -+ mask = tmio_ioread32((ctl)->irq_mask); \ -+ mask &= ~((i) & TMIO_MASK_IRQ); \ -+ tmio_iowrite32(mask, (ctl)->irq_mask); \ -+ } while (0) -+ -+#define disable_mmc_irqs(ctl, i) \ -+ do { \ -+ u32 mask;\ -+ mask = tmio_ioread32((ctl)->irq_mask); \ -+ mask |= ((i) & TMIO_MASK_IRQ); \ -+ tmio_iowrite32(mask, (ctl)->irq_mask); \ -+ } while (0) -+ -+#define ack_mmc_irqs(ctl, i) \ -+ do { \ -+ u32 mask;\ -+ mask = tmio_ioread32((ctl)->status); \ -+ mask &= ~((i) & TMIO_MASK_IRQ); \ -+ tmio_iowrite32(mask, (ctl)->status); \ -+ } while (0) -+ -+ -+struct tmio_mmc_host { -+ struct tmio_mmc_cnf __iomem *cnf; -+ struct tmio_mmc_ctl __iomem *ctl; -+ struct mmc_command *cmd; -+ struct mmc_request *mrq; -+ struct mmc_data *data; -+ struct mmc_host *mmc; -+ int irq; -+ -+ /* pio related stuff */ -+ struct scatterlist *sg_ptr; -+ unsigned int sg_len; -+ unsigned int sg_off; -+}; -+ -+#include <linux/scatterlist.h> -+#include <linux/blkdev.h> -+ -+static inline void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data) -+{ -+ host->sg_len = data->sg_len; -+ host->sg_ptr = data->sg; -+ host->sg_off = 0; -+} -+ -+static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host) -+{ -+ host->sg_ptr++; -+ host->sg_off = 0; -+ return --host->sg_len; -+} -+ -+static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host, unsigned long *flags) -+{ -+ struct scatterlist *sg = host->sg_ptr; -+ -+ local_irq_save(*flags); -+ return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; -+} -+ -+static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host, unsigned long *flags) -+{ -+ kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ); -+ local_irq_restore(*flags); -+} -+ -+#ifdef CONFIG_MMC_DEBUG -+#define DBG(args...) printk(args) -+ -+void debug_status(u32 status){ -+ printk("status: %08x = ", status); -+ if(status & TMIO_STAT_CARD_REMOVE) printk("Card_removed "); -+ if(status & TMIO_STAT_CARD_INSERT) printk("Card_insert "); -+ if(status & TMIO_STAT_SIGSTATE) printk("Sigstate "); -+ if(status & TMIO_STAT_WRPROTECT) printk("Write_protect "); -+ if(status & TMIO_STAT_CARD_REMOVE_A) printk("Card_remove_A "); -+ if(status & TMIO_STAT_CARD_INSERT_A) printk("Card_insert_A "); -+ if(status & TMIO_STAT_SIGSTATE_A) printk("Sigstate_A "); -+ if(status & TMIO_STAT_CMD_IDX_ERR) printk("Cmd_IDX_Err "); -+ if(status & TMIO_STAT_STOPBIT_ERR) printk("Stopbit_ERR "); -+ if(status & TMIO_STAT_ILL_FUNC) printk("ILLEGAL_FUNC "); -+ if(status & TMIO_STAT_CMD_BUSY) printk("CMD_BUSY "); -+ if(status & TMIO_STAT_CMDRESPEND) printk("Response_end "); -+ if(status & TMIO_STAT_DATAEND) printk("Data_end "); -+ if(status & TMIO_STAT_CRCFAIL) printk("CRC_failure "); -+ if(status & TMIO_STAT_DATATIMEOUT) printk("Data_timeout "); -+ if(status & TMIO_STAT_CMDTIMEOUT) printk("Command_timeout "); -+ if(status & TMIO_STAT_RXOVERFLOW) printk("RX_OVF "); -+ if(status & TMIO_STAT_TXUNDERRUN) printk("TX_UND "); -+ if(status & TMIO_STAT_RXRDY) printk("RX_rdy "); -+ if(status & TMIO_STAT_TXRQ) printk("TX_req "); -+ if(status & TMIO_STAT_ILL_ACCESS) printk("ILLEGAL_ACCESS "); -+ printk("\n"); -+} -+#else -+#define DBG(fmt,args...) do { } while (0) -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch deleted file mode 100644 index 0fa10ebd4c..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch +++ /dev/null @@ -1,593 +0,0 @@ -From 6d377e8f80ce421e6842ac5f42081345fbc70002 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 01:27:41 +0300 -Subject: [PATCH 12/64] Tosa keyboard support - -Support keyboard on tosa (Sharp Zaurus SL-6000x). -Largely based on patches by Dirk Opfer. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 43 ++++ - drivers/input/keyboard/Kconfig | 21 ++ - drivers/input/keyboard/Makefile | 1 + - drivers/input/keyboard/tosakbd.c | 415 ++++++++++++++++++++++++++++++++++++++ - include/asm-arm/arch-pxa/tosa.h | 30 +++ - 5 files changed, 510 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/keyboard/tosakbd.c - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index 240fd04..e7e0f52 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -21,6 +21,8 @@ - #include <linux/mmc/host.h> - #include <linux/pm.h> - #include <linux/delay.h> -+#include <linux/gpio_keys.h> -+#include <linux/input.h> - - #include <asm/setup.h> - #include <asm/memory.h> -@@ -253,6 +255,46 @@ static struct platform_device tosakbd_device = { - .id = -1, - }; - -+static struct gpio_keys_button tosa_gpio_keys[] = { -+ { -+ .type = EV_PWR, -+ .code = KEY_SUSPEND, -+ .gpio = TOSA_GPIO_ON_KEY, -+ .desc = "On key", -+ .wakeup = 1, -+ .active_low = 1, -+ }, -+ { -+ .type = EV_KEY, -+ .code = TOSA_KEY_RECORD, -+ .gpio = TOSA_GPIO_RECORD_BTN, -+ .desc = "Record Button", -+ .wakeup = 1, -+ .active_low = 1, -+ }, -+ { -+ .type = EV_KEY, -+ .code = TOSA_KEY_SYNC, -+ .gpio = TOSA_GPIO_SYNC, -+ .desc = "Sync Button", -+ .wakeup = 1, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = { -+ .buttons = tosa_gpio_keys, -+ .nbuttons = ARRAY_SIZE(tosa_gpio_keys), -+}; -+ -+static struct platform_device tosa_gpio_keys_device = { -+ .name = "gpio-keys", -+ .id = -1, -+ .dev = { -+ .platform_data = &tosa_gpio_keys_platform_data, -+ }, -+}; -+ - /* - * Tosa LEDs - */ -@@ -265,6 +307,7 @@ static struct platform_device *devices[] __initdata = { - &tosascoop_device, - &tosascoop_jc_device, - &tosakbd_device, -+ &tosa_gpio_keys_device, - &tosaled_device, - }; - -diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig -index 086d58c..0c32762 100644 ---- a/drivers/input/keyboard/Kconfig -+++ b/drivers/input/keyboard/Kconfig -@@ -154,6 +154,27 @@ config KEYBOARD_SPITZ - To compile this driver as a module, choose M here: the - module will be called spitzkbd. - -+config KEYBOARD_TOSA -+ tristate "Tosa keyboard" -+ depends on MACH_TOSA -+ default y -+ help -+ Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) -+ -+ To compile this driver as a module, choose M here: the -+ module will be called tosakbd. -+ -+config KEYBOARD_TOSA_USE_EXT_KEYCODES -+ bool "Tosa keyboard: use extended keycodes" -+ depends on KEYBOARD_TOSA -+ default n -+ help -+ Say Y here to enable the tosa keyboard driver to generate extended -+ (>= 127) keycodes. Be aware, that they can't be correctly interpreted -+ by either console keyboard driver or by Kdrive keybd driver. -+ -+ Say Y only if you know, what you are doing! -+ - config KEYBOARD_AMIGA - tristate "Amiga keyboard" - depends on AMIGA -diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile -index e97455f..6caa065 100644 ---- a/drivers/input/keyboard/Makefile -+++ b/drivers/input/keyboard/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o - obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o - obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o - obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o -+obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o - obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o - obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o - obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o -diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c -new file mode 100644 -index 0000000..3884d1e ---- /dev/null -+++ b/drivers/input/keyboard/tosakbd.c -@@ -0,0 +1,415 @@ -+/* -+ * Keyboard driver for Sharp Tosa models (SL-6000x) -+ * -+ * Copyright (c) 2005 Dirk Opfer -+ * Copyright (c) 2007 Dmitry Baryshkov -+ * -+ * Based on xtkbd.c/locomkbd.c/corgikbd.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/input.h> -+#include <linux/delay.h> -+#include <linux/interrupt.h> -+ -+#include <asm/arch/gpio.h> -+#include <asm/arch/tosa.h> -+ -+#define KB_ROWMASK(r) (1 << (r)) -+#define SCANCODE(r, c) (((r)<<4) + (c) + 1) -+#define NR_SCANCODES SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1 -+ -+#define SCAN_INTERVAL (HZ/10) -+ -+#define KB_DISCHARGE_DELAY 10 -+#define KB_ACTIVATE_DELAY 10 -+ -+static unsigned int tosakbd_keycode[NR_SCANCODES] = { -+0, -+0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P, -+0, 0, 0, 0, 0, 0, 0, 0, -+KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA, -+0, 0, 0, 0, 0, 0, 0, 0, -+KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT, -+0, 0, 0, 0, 0, 0, 0, 0, -+KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK, -+KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0, -+KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT, -+0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, -+KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0, -+0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0, -+KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT, -+0, 0, 0, -+}; -+ -+struct tosakbd { -+ unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; -+ struct input_dev *input; -+ -+ spinlock_t lock; /* protect kbd scanning */ -+ struct timer_list timer; -+}; -+ -+ -+/* Helper functions for reading the keyboard matrix -+ * Note: We should really be using pxa_gpio_mode to alter GPDR but it -+ * requires a function call per GPIO bit which is excessive -+ * when we need to access 12 bits at once, multiple times. -+ * These functions must be called within local_irq_save()/local_irq_restore() -+ * or similar. -+ */ -+#define GET_ROWS_STATUS(c) ((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT) -+ -+static inline void tosakbd_discharge_all(void) -+{ -+ /* STROBE All HiZ */ -+ GPCR1 = TOSA_GPIO_HIGH_STROBE_BIT; -+ GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT; -+ GPCR2 = TOSA_GPIO_LOW_STROBE_BIT; -+ GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT; -+} -+ -+static inline void tosakbd_activate_all(void) -+{ -+ /* STROBE ALL -> High */ -+ GPSR1 = TOSA_GPIO_HIGH_STROBE_BIT; -+ GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT; -+ GPSR2 = TOSA_GPIO_LOW_STROBE_BIT; -+ GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT; -+ -+ udelay(KB_DISCHARGE_DELAY); -+ -+ /* STATE CLEAR */ -+ GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT; -+} -+ -+static inline void tosakbd_activate_col(int col) -+{ -+ if (col <= 5) { -+ /* STROBE col -> High, not col -> HiZ */ -+ GPSR1 = TOSA_GPIO_STROBE_BIT(col); -+ GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); -+ } else { -+ /* STROBE col -> High, not col -> HiZ */ -+ GPSR2 = TOSA_GPIO_STROBE_BIT(col); -+ GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); -+ } -+} -+ -+static inline void tosakbd_reset_col(int col) -+{ -+ if (col <= 5) { -+ /* STROBE col -> Low */ -+ GPCR1 = TOSA_GPIO_STROBE_BIT(col); -+ /* STROBE col -> out, not col -> HiZ */ -+ GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); -+ } else { -+ /* STROBE col -> Low */ -+ GPCR2 = TOSA_GPIO_STROBE_BIT(col); -+ /* STROBE col -> out, not col -> HiZ */ -+ GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col); -+ } -+} -+/* -+ * The tosa keyboard only generates interrupts when a key is pressed. -+ * So when a key is pressed, we enable a timer. This timer scans the -+ * keyboard, and this is how we detect when the key is released. -+ */ -+ -+/* Scan the hardware keyboard and push any changes up through the input layer */ -+static void tosakbd_scankeyboard(struct platform_device *dev) -+{ -+ struct tosakbd *tosakbd = platform_get_drvdata(dev); -+ unsigned int row, col, rowd; -+ unsigned long flags; -+ unsigned int num_pressed = 0; -+ -+ spin_lock_irqsave(&tosakbd->lock, flags); -+ -+ for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { -+ /* -+ * Discharge the output driver capacitatance -+ * in the keyboard matrix. (Yes it is significant..) -+ */ -+ tosakbd_discharge_all(); -+ udelay(KB_DISCHARGE_DELAY); -+ -+ tosakbd_activate_col(col); -+ udelay(KB_ACTIVATE_DELAY); -+ -+ rowd = GET_ROWS_STATUS(col); -+ -+ for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) { -+ unsigned int scancode, pressed; -+ scancode = SCANCODE(row, col); -+ pressed = rowd & KB_ROWMASK(row); -+ -+ if (pressed && !tosakbd->keycode[scancode]) -+ dev_warn(&dev->dev, -+ "unhandled scancode: 0x%02x\n", -+ scancode); -+ -+ input_report_key(tosakbd->input, -+ tosakbd->keycode[scancode], -+ pressed); -+ if (pressed) -+ num_pressed++; -+ } -+ -+ tosakbd_reset_col(col); -+ } -+ -+ tosakbd_activate_all(); -+ -+ input_sync(tosakbd->input); -+ -+ /* if any keys are pressed, enable the timer */ -+ if (num_pressed) -+ mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); -+ -+ spin_unlock_irqrestore(&tosakbd->lock, flags); -+} -+ -+/* -+ * tosa keyboard interrupt handler. -+ */ -+static irqreturn_t tosakbd_interrupt(int irq, void *__dev) -+{ -+ struct platform_device *dev = __dev; -+ struct tosakbd *tosakbd = platform_get_drvdata(dev); -+ -+ if (!timer_pending(&tosakbd->timer)) { -+ /** wait chattering delay **/ -+ udelay(20); -+ tosakbd_scankeyboard(dev); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+/* -+ * tosa timer checking for released keys -+ */ -+static void tosakbd_timer_callback(unsigned long __dev) -+{ -+ struct platform_device *dev = (struct platform_device *)__dev; -+ tosakbd_scankeyboard(dev); -+} -+ -+#ifdef CONFIG_PM -+static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct tosakbd *tosakbd = platform_get_drvdata(dev); -+ -+ del_timer_sync(&tosakbd->timer); -+ -+ return 0; -+} -+ -+static int tosakbd_resume(struct platform_device *dev) -+{ -+ tosakbd_scankeyboard(dev); -+ -+ return 0; -+} -+#else -+#define tosakbd_suspend NULL -+#define tosakbd_resume NULL -+#endif -+ -+static int __devinit tosakbd_probe(struct platform_device *pdev) { -+ -+ int i; -+ struct tosakbd *tosakbd; -+ struct input_dev *input_dev; -+ int error; -+ -+ tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL); -+ if (!tosakbd) -+ return -ENOMEM; -+ -+ input_dev = input_allocate_device(); -+ if (!input_dev) { -+ kfree(tosakbd); -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, tosakbd); -+ -+ spin_lock_init(&tosakbd->lock); -+ -+ /* Init Keyboard rescan timer */ -+ init_timer(&tosakbd->timer); -+ tosakbd->timer.function = tosakbd_timer_callback; -+ tosakbd->timer.data = (unsigned long) pdev; -+ -+ tosakbd->input = input_dev; -+ -+ input_set_drvdata(input_dev, tosakbd); -+ input_dev->name = "Tosa Keyboard"; -+ input_dev->phys = "tosakbd/input0"; -+ input_dev->dev.parent = &pdev->dev; -+ -+ input_dev->id.bustype = BUS_HOST; -+ input_dev->id.vendor = 0x0001; -+ input_dev->id.product = 0x0001; -+ input_dev->id.version = 0x0100; -+ -+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); -+ input_dev->keycode = tosakbd->keycode; -+ input_dev->keycodesize = sizeof(unsigned int); -+ input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode); -+ -+ memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode)); -+ -+ for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++) -+ __set_bit(tosakbd->keycode[i], input_dev->keybit); -+ clear_bit(0, input_dev->keybit); -+ -+ /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ -+ for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { -+ int gpio = TOSA_GPIO_KEY_SENSE(i); -+ int irq; -+ error = gpio_request(gpio, "tosakbd"); -+ if (error < 0) { -+ printk(KERN_ERR "tosakbd: failed to request GPIO %d, " -+ " error %d\n", gpio, error); -+ goto fail; -+ } -+ -+ error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i)); -+ if (error < 0) { -+ printk(KERN_ERR "tosakbd: failed to configure input" -+ " direction for GPIO %d, error %d\n", -+ gpio, error); -+ gpio_free(gpio); -+ goto fail; -+ } -+ -+ irq = gpio_to_irq(gpio); -+ if (irq < 0) { -+ error = irq; -+ printk(KERN_ERR "gpio-keys: Unable to get irq number" -+ " for GPIO %d, error %d\n", -+ gpio, error); -+ gpio_free(gpio); -+ goto fail; -+ } -+ -+ error = request_irq(irq, tosakbd_interrupt, -+ IRQF_DISABLED | IRQF_TRIGGER_RISING, -+ "tosakbd", pdev); -+ -+ if (error) { -+ printk("tosakbd: Can't get IRQ: %d: error %d!\n", -+ irq, error); -+ gpio_free(gpio); -+ goto fail; -+ } -+ } -+ -+ /* Set Strobe lines as outputs - set high */ -+ for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) { -+ int gpio = TOSA_GPIO_KEY_STROBE(i); -+ error = gpio_request(gpio, "tosakbd"); -+ if (error < 0) { -+ printk(KERN_ERR "tosakbd: failed to request GPIO %d, " -+ " error %d\n", gpio, error); -+ goto fail2; -+ } -+ -+ error = gpio_direction_output(gpio, 1); -+ if (error < 0) { -+ printk(KERN_ERR "tosakbd: failed to configure input" -+ " direction for GPIO %d, error %d\n", -+ gpio, error); -+ gpio_free(gpio); -+ goto fail; -+ } -+ -+ } -+ -+ error = input_register_device(input_dev); -+ if (error) { -+ printk(KERN_ERR "tosakbd: Unable to register input device, " -+ "error: %d\n", error); -+ goto fail; -+ } -+ -+ printk(KERN_INFO "input: Tosa Keyboard Registered\n"); -+ -+ return 0; -+ -+fail2: -+ while (--i >= 0) -+ gpio_free(TOSA_GPIO_KEY_STROBE(i)); -+ -+ i = TOSA_KEY_SENSE_NUM; -+fail: -+ while (--i >= 0) { -+ free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev); -+ gpio_free(TOSA_GPIO_KEY_SENSE(i)); -+ } -+ -+ platform_set_drvdata(pdev, NULL); -+ input_free_device(input_dev); -+ kfree(tosakbd); -+ -+ return error; -+} -+ -+static int __devexit tosakbd_remove(struct platform_device *dev) { -+ -+ int i; -+ struct tosakbd *tosakbd = platform_get_drvdata(dev); -+ -+ for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) -+ gpio_free(TOSA_GPIO_KEY_STROBE(i)); -+ -+ for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { -+ free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev); -+ gpio_free(TOSA_GPIO_KEY_SENSE(i)); -+ } -+ -+ del_timer_sync(&tosakbd->timer); -+ -+ input_unregister_device(tosakbd->input); -+ -+ kfree(tosakbd); -+ -+ return 0; -+} -+ -+static struct platform_driver tosakbd_driver = { -+ .probe = tosakbd_probe, -+ .remove = __devexit_p(tosakbd_remove), -+ .suspend = tosakbd_suspend, -+ .resume = tosakbd_resume, -+ .driver = { -+ .name = "tosa-keyboard", -+ }, -+}; -+ -+static int __devinit tosakbd_init(void) -+{ -+ return platform_driver_register(&tosakbd_driver); -+} -+ -+static void __exit tosakbd_exit(void) -+{ -+ platform_driver_unregister(&tosakbd_driver); -+} -+ -+module_init(tosakbd_init); -+module_exit(tosakbd_exit); -+ -+MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); -+MODULE_DESCRIPTION("Tosa Keyboard Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h -index c3364a2..c05e4fa 100644 ---- a/include/asm-arm/arch-pxa/tosa.h -+++ b/include/asm-arm/arch-pxa/tosa.h -@@ -163,4 +163,34 @@ - - extern struct platform_device tosascoop_jc_device; - extern struct platform_device tosascoop_device; -+ -+#define TOSA_KEY_SYNC KEY_102ND /* ??? */ -+ -+ -+#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES -+#define TOSA_KEY_RECORD KEY_YEN -+#define TOSA_KEY_ADDRESSBOOK KEY_KATAKANA -+#define TOSA_KEY_CANCEL KEY_ESC -+#define TOSA_KEY_CENTER KEY_HIRAGANA -+#define TOSA_KEY_OK KEY_HENKAN -+#define TOSA_KEY_CALENDAR KEY_KATAKANAHIRAGANA -+#define TOSA_KEY_HOMEPAGE KEY_HANGEUL -+#define TOSA_KEY_LIGHT KEY_MUHENKAN -+#define TOSA_KEY_MENU KEY_HANJA -+#define TOSA_KEY_FN KEY_RIGHTALT -+#define TOSA_KEY_MAIL KEY_ZENKAKUHANKAKU -+#else -+#define TOSA_KEY_RECORD KEY_RECORD -+#define TOSA_KEY_ADDRESSBOOK KEY_ADDRESSBOOK -+#define TOSA_KEY_CANCEL KEY_CANCEL -+#define TOSA_KEY_CENTER KEY_SELECT /* ??? */ -+#define TOSA_KEY_OK KEY_OK -+#define TOSA_KEY_CALENDAR KEY_CALENDAR -+#define TOSA_KEY_HOMEPAGE KEY_HOMEPAGE -+#define TOSA_KEY_LIGHT KEY_KBDILLUMTOGGLE -+#define TOSA_KEY_MENU KEY_MENU -+#define TOSA_KEY_FN KEY_FN -+#define TOSA_KEY_MAIL KEY_MAIL -+#endif -+ - #endif /* _ASM_ARCH_TOSA_H_ */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch b/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch deleted file mode 100644 index 082a2c72b8..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 18c1a92a09faf75ebdac7ac471c741a6622cf3e2 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 01:27:49 +0300 -Subject: [PATCH 13/64] USB: gadget: pxa2xx_udc supports inverted vbus - -Some boards (like e.g. Tosa) invert the VBUS-detection signal: -it's low when a host is supplying VBUS, and high otherwise. -Allow specifying whether gpio_vbus value is inverted. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> ---- - drivers/usb/gadget/pxa2xx_udc.c | 9 +++++++-- - include/asm-arm/mach/udc_pxa2xx.h | 2 ++ - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c -index 3173b39..4f7d4ef 100644 ---- a/drivers/usb/gadget/pxa2xx_udc.c -+++ b/drivers/usb/gadget/pxa2xx_udc.c -@@ -127,8 +127,10 @@ static int is_vbus_present(void) - { - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - -- if (mach->gpio_vbus) -- return gpio_get_value(mach->gpio_vbus); -+ if (mach->gpio_vbus) { -+ int value = gpio_get_value(mach->gpio_vbus); -+ return mach->gpio_vbus_inverted ? !value : value; -+ } - if (mach->udc_is_connected) - return mach->udc_is_connected(); - return 1; -@@ -1397,6 +1399,9 @@ static irqreturn_t udc_vbus_irq(int irq, void *_dev) - struct pxa2xx_udc *dev = _dev; - int vbus = gpio_get_value(dev->mach->gpio_vbus); - -+ if (dev->mach->gpio_vbus_inverted) -+ vbus = !vbus; -+ - pxa2xx_udc_vbus_session(&dev->gadget, vbus); - return IRQ_HANDLED; - } -diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/include/asm-arm/mach/udc_pxa2xx.h -index ff0a957..f191e14 100644 ---- a/include/asm-arm/mach/udc_pxa2xx.h -+++ b/include/asm-arm/mach/udc_pxa2xx.h -@@ -19,7 +19,9 @@ struct pxa2xx_udc_mach_info { - * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane - * VBUS IRQ and omit the methods above. Store the GPIO number - * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits. -+ * Note that sometimes the signals go through inverters... - */ -+ bool gpio_vbus_inverted; - u16 gpio_vbus; /* high == vbus present */ - u16 gpio_pullup; /* high == pullup activated */ - }; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch b/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch deleted file mode 100644 index 98783efea0..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 932ff38b17c7847c43e2bad01b510b64c27f9810 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 01:27:59 +0300 -Subject: [PATCH 14/64] tosa_udc_use_gpio_vbus.patch - -Use gpio_vbus instead of udc_is_connected for udc on tosa. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> -Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> ---- - arch/arm/mach-pxa/tosa.c | 9 ++------- - 1 files changed, 2 insertions(+), 7 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index e7e0f52..5268e94 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -159,15 +159,10 @@ static void tosa_udc_command(int cmd) - } - } - --static int tosa_udc_is_connected(void) --{ -- return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0); --} -- -- - static struct pxa2xx_udc_mach_info udc_info __initdata = { - .udc_command = tosa_udc_command, -- .udc_is_connected = tosa_udc_is_connected, -+ .gpio_vbus = TOSA_GPIO_USB_IN, -+ .gpio_vbus_inverted = 1, - }; - - /* --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch b/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch deleted file mode 100644 index f8e57e8306..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch +++ /dev/null @@ -1,32 +0,0 @@ -From bba216220d17d1091413e82c9924ac5614402c05 Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Wed, 9 Jan 2008 01:28:06 +0300 -Subject: [PATCH 15/64] sharpsl export params - ---- - arch/arm/common/sharpsl_param.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c -index aad4d94..d56c932 100644 ---- a/arch/arm/common/sharpsl_param.c -+++ b/arch/arm/common/sharpsl_param.c -@@ -12,6 +12,7 @@ - */ - - #include <linux/kernel.h> -+#include <linux/module.h> - #include <linux/string.h> - #include <asm/mach/sharpsl_param.h> - -@@ -36,6 +37,7 @@ - #define PHAD_MAGIC MAGIC_CHG('P','H','A','D') - - struct sharpsl_param_info sharpsl_param; -+EXPORT_SYMBOL(sharpsl_param); - - void sharpsl_save_param(void) - { --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch b/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch deleted file mode 100644 index d73de0698c..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0fe7b491b70efafbd41185f8e95a3eada65984a1 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 28 Jan 2008 01:49:28 +0300 -Subject: [PATCH 16/64] This patch fixes the pxa25x clocks definitions to add hwuart. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/pxa25x.c | 9 ++++++++- - 1 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c -index 9732d5d..006a6e0 100644 ---- a/arch/arm/mach-pxa/pxa25x.c -+++ b/arch/arm/mach-pxa/pxa25x.c -@@ -111,11 +111,14 @@ static const struct clkops clk_pxa25x_lcd_ops = { - * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz - * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) - */ -+static struct clk pxa25x_hwuart_clk = -+ INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) -+; -+ - static struct clk pxa25x_clks[] = { - INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), - INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), - INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), -- INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), - INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), - INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), - INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), -@@ -303,6 +306,10 @@ static int __init pxa25x_init(void) - { - int ret = 0; - -+ /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ -+ if (cpu_is_pxa25x()) -+ clks_register(&pxa25x_hwuart_clk, 1); -+ - if (cpu_is_pxa21x() || cpu_is_pxa25x()) { - clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch b/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch deleted file mode 100644 index 5163361da3..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 71857e8f6c4a8d2d3eac3037f02e0c30c6fdb37e Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 01:43:28 +0300 -Subject: [PATCH 17/64] Convert pxa2xx UDC to use debugfs - -Use debugfs instead of /proc/driver/udc - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/usb/gadget/pxa2xx_udc.c | 100 +++++++++++++++++---------------------- - drivers/usb/gadget/pxa2xx_udc.h | 10 +++- - 2 files changed, 51 insertions(+), 59 deletions(-) - -diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c -index 4f7d4ef..2900556 100644 ---- a/drivers/usb/gadget/pxa2xx_udc.c -+++ b/drivers/usb/gadget/pxa2xx_udc.c -@@ -38,13 +38,14 @@ - #include <linux/timer.h> - #include <linux/list.h> - #include <linux/interrupt.h> --#include <linux/proc_fs.h> - #include <linux/mm.h> - #include <linux/platform_device.h> - #include <linux/dma-mapping.h> - #include <linux/irq.h> - #include <linux/clk.h> - #include <linux/err.h> -+#include <linux/seq_file.h> -+#include <linux/debugfs.h> - - #include <asm/byteorder.h> - #include <asm/dma.h> -@@ -993,45 +994,36 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { - - /*-------------------------------------------------------------------------*/ - --#ifdef CONFIG_USB_GADGET_DEBUG_FILES -- --static const char proc_node_name [] = "driver/udc"; -+#ifdef CONFIG_USB_GADGET_DEBUG_FS - -+static struct pxa2xx_udc memory; - static int --udc_proc_read(char *page, char **start, off_t off, int count, -- int *eof, void *_dev) -+udc_seq_show(struct seq_file *m, void *d) - { -- char *buf = page; -- struct pxa2xx_udc *dev = _dev; -- char *next = buf; -- unsigned size = count; -+ struct pxa2xx_udc *dev = m->private; - unsigned long flags; -- int i, t; -+ int i; - u32 tmp; - -- if (off != 0) -- return 0; -+ -+ BUG_ON(dev == NULL); - - local_irq_save(flags); - - /* basic device status */ -- t = scnprintf(next, size, DRIVER_DESC "\n" -+ seq_printf(m, DRIVER_DESC "\n" - "%s version: %s\nGadget driver: %s\nHost %s\n\n", - driver_name, DRIVER_VERSION SIZE_STR "(pio)", - dev->driver ? dev->driver->driver.name : "(none)", - is_vbus_present() ? "full speed" : "disconnected"); -- size -= t; -- next += t; - - /* registers for device and ep0 */ -- t = scnprintf(next, size, -+ seq_printf(m, - "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", - UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); -- size -= t; -- next += t; - - tmp = UDCCR; -- t = scnprintf(next, size, -+ seq_printf(m, - "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, - (tmp & UDCCR_REM) ? " rem" : "", - (tmp & UDCCR_RSTIR) ? " rstir" : "", -@@ -1041,11 +1033,9 @@ udc_proc_read(char *page, char **start, off_t off, int count, - (tmp & UDCCR_RSM) ? " rsm" : "", - (tmp & UDCCR_UDA) ? " uda" : "", - (tmp & UDCCR_UDE) ? " ude" : ""); -- size -= t; -- next += t; - - tmp = UDCCS0; -- t = scnprintf(next, size, -+ seq_printf(m, - "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, - (tmp & UDCCS0_SA) ? " sa" : "", - (tmp & UDCCS0_RNE) ? " rne" : "", -@@ -1055,28 +1045,22 @@ udc_proc_read(char *page, char **start, off_t off, int count, - (tmp & UDCCS0_FTF) ? " ftf" : "", - (tmp & UDCCS0_IPR) ? " ipr" : "", - (tmp & UDCCS0_OPR) ? " opr" : ""); -- size -= t; -- next += t; - - if (dev->has_cfr) { - tmp = UDCCFR; -- t = scnprintf(next, size, -+ seq_printf(m, - "udccfr %02X =%s%s\n", tmp, - (tmp & UDCCFR_AREN) ? " aren" : "", - (tmp & UDCCFR_ACM) ? " acm" : ""); -- size -= t; -- next += t; - } - - if (!is_vbus_present() || !dev->driver) - goto done; - -- t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", -+ seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", - dev->stats.write.bytes, dev->stats.write.ops, - dev->stats.read.bytes, dev->stats.read.ops, - dev->stats.irqs); -- size -= t; -- next += t; - - /* dump endpoint queues */ - for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { -@@ -1090,55 +1074,57 @@ udc_proc_read(char *page, char **start, off_t off, int count, - if (!d) - continue; - tmp = *dev->ep [i].reg_udccs; -- t = scnprintf(next, size, -+ seq_printf(m, - "%s max %d %s udccs %02x irqs %lu\n", - ep->ep.name, le16_to_cpu (d->wMaxPacketSize), - "pio", tmp, ep->pio_irqs); - /* TODO translate all five groups of udccs bits! */ - - } else /* ep0 should only have one transfer queued */ -- t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n", -+ seq_printf(m, "ep0 max 16 pio irqs %lu\n", - ep->pio_irqs); -- if (t <= 0 || t > size) -- goto done; -- size -= t; -- next += t; - - if (list_empty(&ep->queue)) { -- t = scnprintf(next, size, "\t(nothing queued)\n"); -- if (t <= 0 || t > size) -- goto done; -- size -= t; -- next += t; -+ seq_printf(m, "\t(nothing queued)\n"); - continue; - } - list_for_each_entry(req, &ep->queue, queue) { -- t = scnprintf(next, size, -+ seq_printf(m, - "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, - req->req.length, req->req.buf); -- if (t <= 0 || t > size) -- goto done; -- size -= t; -- next += t; - } - } - - done: - local_irq_restore(flags); -- *eof = 1; -- return count - size; -+ return 0; - } - --#define create_proc_files() \ -- create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) --#define remove_proc_files() \ -- remove_proc_entry(proc_node_name, NULL) -+static int -+udc_debugfs_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, udc_seq_show, inode->i_private); -+} -+ -+static const struct file_operations debug_fops = { -+ .open = udc_debugfs_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .owner = THIS_MODULE, -+}; -+ -+#define create_debug_files(dev) \ -+ dev->debugfs_udc = debugfs_create_file(dev->gadget.name, S_IRUGO, \ -+ NULL, dev, &debug_fops) -+#define remove_debug_files(dev) \ -+ if (dev->debugfs_udc) debugfs_remove(dev->debugfs_udc) - - #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ - --#define create_proc_files() do {} while (0) --#define remove_proc_files() do {} while (0) -+#define create_debug_files(dev) do {} while (0) -+#define remove_debug_files(dev) do {} while (0) - - #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ - -@@ -2245,7 +2231,7 @@ lubbock_fail0: - goto err_vbus_irq; - } - } -- create_proc_files(); -+ create_debug_files(dev); - - return 0; - -@@ -2282,7 +2268,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) - return -EBUSY; - - udc_disable(dev); -- remove_proc_files(); -+ remove_debug_files(dev); - - if (dev->got_irq) { - free_irq(platform_get_irq(pdev, 0), dev); -diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h -index 1db46d7..c08b1a2 100644 ---- a/drivers/usb/gadget/pxa2xx_udc.h -+++ b/drivers/usb/gadget/pxa2xx_udc.h -@@ -129,6 +129,10 @@ struct pxa2xx_udc { - struct pxa2xx_udc_mach_info *mach; - u64 dma_mask; - struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; -+ -+#ifdef CONFIG_USB_GADGET_DEBUG_FS -+ struct dentry *debugfs_udc; -+#endif - }; - - /*-------------------------------------------------------------------------*/ -@@ -153,6 +157,8 @@ static struct pxa2xx_udc *the_controller; - - #ifdef DEBUG - -+static int is_vbus_present(void); -+ - static const char *state_name[] = { - "EP0_IDLE", - "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", -@@ -207,8 +213,7 @@ dump_state(struct pxa2xx_udc *dev) - unsigned i; - - DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", -- //is_usb_connected() ? "host " : "disconnected", -- "host ", -+ is_vbus_present() ? "host " : "disconnected", - state_name[dev->ep0state], - UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); - dump_udccr("udccr"); -@@ -224,7 +230,7 @@ dump_state(struct pxa2xx_udc *dev) - } else - DMSG("ep0 driver '%s'\n", dev->driver->driver.name); - -- //if (!is_usb_connected()) -- // return; -+ if (!is_vbus_present()) -+ return; - - dump_udccs0 ("udccs0"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch b/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch deleted file mode 100644 index 7bf4ad02d6..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch +++ /dev/null @@ -1,225 +0,0 @@ -From b9a0fdbf333b461682d5da8b9aaa42f4de91ffcf Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sun, 10 Feb 2008 03:29:17 +0300 -Subject: [PATCH 18/64] Fix the pxa2xx_udc to balance calls to clk_enable/clk_disable - -Signed-off-by: Dmitry Baryshkov dbaryshkov@gmail.com ---- - drivers/usb/gadget/pxa2xx_udc.c | 84 +++++++++++++++++++++++---------------- - drivers/usb/gadget/pxa2xx_udc.h | 6 ++- - 2 files changed, 54 insertions(+), 36 deletions(-) - -diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c -index 2900556..8e32d07 100644 ---- a/drivers/usb/gadget/pxa2xx_udc.c -+++ b/drivers/usb/gadget/pxa2xx_udc.c -@@ -680,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) - - /* kickstart this i/o queue? */ - if (list_empty(&ep->queue) && !ep->stopped) { -- if (ep->desc == 0 /* ep0 */) { -+ if (ep->desc == NULL /* ep0 */) { - unsigned length = _req->length; - - switch (dev->ep0state) { -@@ -734,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) - } - - /* pio or dma irq handler advances the queue. */ -- if (likely (req != 0)) -+ if (likely (req != NULL)) - list_add_tail(&req->queue, &ep->queue); - local_irq_restore(flags); - -@@ -934,20 +934,35 @@ static void udc_disable(struct pxa2xx_udc *); - /* We disable the UDC -- and its 48 MHz clock -- whenever it's not - * in active use. - */ --static int pullup(struct pxa2xx_udc *udc, int is_active) -+static int pullup(struct pxa2xx_udc *udc) - { -- is_active = is_active && udc->vbus && udc->pullup; -+ int is_active = udc->vbus && udc->pullup && ! udc->suspended; - DMSG("%s\n", is_active ? "active" : "inactive"); -- if (is_active) -- udc_enable(udc); -- else { -- if (udc->gadget.speed != USB_SPEED_UNKNOWN) { -- DMSG("disconnect %s\n", udc->driver -- ? udc->driver->driver.name -- : "(no driver)"); -- stop_activity(udc, udc->driver); -+ if (is_active) { -+ if (!udc->active) { -+ udc->active = 1; -+#ifdef CONFIG_ARCH_PXA -+ /* Enable clock for USB device */ -+ clk_enable(udc->clk); -+#endif -+ udc_enable(udc); - } -- udc_disable(udc); -+ } else { -+ if (udc->active) { -+ if (udc->gadget.speed != USB_SPEED_UNKNOWN) { -+ DMSG("disconnect %s\n", udc->driver -+ ? udc->driver->driver.name -+ : "(no driver)"); -+ stop_activity(udc, udc->driver); -+ } -+ udc_disable(udc); -+#ifdef CONFIG_ARCH_PXA -+ /* Disable clock for USB device */ -+ clk_disable(udc->clk); -+#endif -+ udc->active = 0; -+ } -+ - } - return 0; - } -@@ -958,9 +973,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) - struct pxa2xx_udc *udc; - - udc = container_of(_gadget, struct pxa2xx_udc, gadget); -- udc->vbus = is_active = (is_active != 0); -+ udc->vbus = (is_active != 0); - DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); -- pullup(udc, is_active); -+ pullup(udc); - return 0; - } - -@@ -975,9 +990,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) - if (!udc->mach->gpio_pullup && !udc->mach->udc_command) - return -EOPNOTSUPP; - -- is_active = (is_active != 0); -- udc->pullup = is_active; -- pullup(udc, is_active); -+ udc->pullup = (is_active != 0); -+ pullup(udc); - return 0; - } - -@@ -998,7 +1012,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { - - static struct pxa2xx_udc memory; - static int --udc_seq_show(struct seq_file *m, void *d) -+udc_seq_show(struct seq_file *m, void *_d) - { - struct pxa2xx_udc *dev = m->private; - unsigned long flags; -@@ -1145,11 +1159,6 @@ static void udc_disable(struct pxa2xx_udc *dev) - - udc_clear_mask_UDCCR(UDCCR_UDE); - --#ifdef CONFIG_ARCH_PXA -- /* Disable clock for USB device */ -- clk_disable(dev->clk); --#endif -- - ep0_idle (dev); - dev->gadget.speed = USB_SPEED_UNKNOWN; - } -@@ -1190,11 +1199,6 @@ static void udc_enable (struct pxa2xx_udc *dev) - { - udc_clear_mask_UDCCR(UDCCR_UDE); - --#ifdef CONFIG_ARCH_PXA -- /* Enable clock for USB device */ -- clk_enable(dev->clk); --#endif -- - /* try to clear these bits before we enable the udc */ - udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); - -@@ -1285,7 +1289,7 @@ fail: - * for set_configuration as well as eventual disconnect. - */ - DMSG("registered gadget driver '%s'\n", driver->driver.name); -- pullup(dev, 1); -+ pullup(dev); - dump_state(dev); - return 0; - } -@@ -1328,7 +1332,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) - return -EINVAL; - - local_irq_disable(); -- pullup(dev, 0); -+ dev->pullup = 0; -+ pullup(dev); - stop_activity(dev, driver); - local_irq_enable(); - -@@ -2267,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) - if (dev->driver) - return -EBUSY; - -- udc_disable(dev); -+ dev->pullup = 0; -+ pullup(dev); -+ - remove_debug_files(dev); - - if (dev->got_irq) { -@@ -2315,10 +2322,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) - static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) - { - struct pxa2xx_udc *udc = platform_get_drvdata(dev); -+ unsigned long flags; - - if (!udc->mach->gpio_pullup && !udc->mach->udc_command) - WARN("USB host won't detect disconnect!\n"); -- pullup(udc, 0); -+ udc->suspended = 1; -+ -+ local_irq_save(flags); -+ pullup(udc); -+ local_irq_restore(flags); - - return 0; - } -@@ -2326,8 +2338,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) - static int pxa2xx_udc_resume(struct platform_device *dev) - { - struct pxa2xx_udc *udc = platform_get_drvdata(dev); -+ unsigned long flags; - -- pullup(udc, 1); -+ udc->suspended = 0; -+ local_irq_save(flags); -+ pullup(udc); -+ local_irq_restore(flags); - - return 0; - } -diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h -index c08b1a2..93586b2 100644 ---- a/drivers/usb/gadget/pxa2xx_udc.h -+++ b/drivers/usb/gadget/pxa2xx_udc.h -@@ -119,7 +119,9 @@ struct pxa2xx_udc { - has_cfr : 1, - req_pending : 1, - req_std : 1, -- req_config : 1; -+ req_config : 1, -+ suspended : 1, -+ active : 1; - - #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) - struct timer_list timer; -@@ -239,7 +241,7 @@ dump_state(struct pxa2xx_udc *dev) - dev->stats.read.bytes, dev->stats.read.ops); - - for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { -- if (dev->ep [i].desc == 0) -+ if (dev->ep [i].desc == NULL) - continue; - DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); - } --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch deleted file mode 100644 index 4b4107d655..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch +++ /dev/null @@ -1,128 +0,0 @@ -From bda65817167cce5294e1d84670f36815262ed550 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk@dyn-67.arm.linux.org.uk> -Date: Sun, 3 Feb 2008 21:58:12 +0300 -Subject: [PATCH 19/64] pxa: remove periodic mode emulation support - -Apparantly, the generic time subsystem can accurately emulate periodic -mode via the one-shot support code, so we don't need our own periodic -emulation code anymore. Just ensure that we build support for one shot -into the generic time subsystem. - -Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> ---- - arch/arm/Kconfig | 1 + - arch/arm/mach-pxa/time.c | 61 ++++++---------------------------------------- - 2 files changed, 9 insertions(+), 53 deletions(-) - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index a04f507..1be7182 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -345,6 +345,7 @@ config ARCH_PXA - select GENERIC_GPIO - select GENERIC_TIME - select GENERIC_CLOCKEVENTS -+ select TICK_ONESHOT - help - Support for Intel/Marvell's PXA2xx/PXA3xx processor line. - -diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c -index fbfa192..3c4abbf 100644 ---- a/arch/arm/mach-pxa/time.c -+++ b/arch/arm/mach-pxa/time.c -@@ -59,55 +59,17 @@ unsigned long long sched_clock(void) - } - - -+#define MIN_OSCR_DELTA 16 -+ - static irqreturn_t - pxa_ost0_interrupt(int irq, void *dev_id) - { -- int next_match; - struct clock_event_device *c = dev_id; - -- if (c->mode == CLOCK_EVT_MODE_ONESHOT) { -- /* Disarm the compare/match, signal the event. */ -- OIER &= ~OIER_E0; -- OSSR = OSSR_M0; -- c->event_handler(c); -- } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) { -- /* Call the event handler as many times as necessary -- * to recover missed events, if any (if we update -- * OSMR0 and OSCR0 is still ahead of us, we've missed -- * the event). As we're dealing with that, re-arm the -- * compare/match for the next event. -- * -- * HACK ALERT: -- * -- * There's a latency between the instruction that -- * writes to OSMR0 and the actual commit to the -- * physical hardware, because the CPU doesn't (have -- * to) run at bus speed, there's a write buffer -- * between the CPU and the bus, etc. etc. So if the -- * target OSCR0 is "very close", to the OSMR0 load -- * value, the update to OSMR0 might not get to the -- * hardware in time and we'll miss that interrupt. -- * -- * To be safe, if the new OSMR0 is "very close" to the -- * target OSCR0 value, we call the event_handler as -- * though the event actually happened. According to -- * Nico's comment in the previous version of this -- * code, experience has shown that 6 OSCR ticks is -- * "very close" but he went with 8. We will use 16, -- * based on the results of testing on PXA270. -- * -- * To be doubly sure, we also tell clkevt via -- * clockevents_register_device() not to ask for -- * anything that might put us "very close". -- */ --#define MIN_OSCR_DELTA 16 -- do { -- OSSR = OSSR_M0; -- next_match = (OSMR0 += LATCH); -- c->event_handler(c); -- } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA) -- && (c->mode == CLOCK_EVT_MODE_PERIODIC)); -- } -+ /* Disarm the compare/match, signal the event. */ -+ OIER &= ~OIER_E0; -+ OSSR = OSSR_M0; -+ c->event_handler(c); - - return IRQ_HANDLED; - } -@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) - unsigned long irqflags; - - switch (mode) { -- case CLOCK_EVT_MODE_PERIODIC: -- raw_local_irq_save(irqflags); -- OSSR = OSSR_M0; -- OIER |= OIER_E0; -- OSMR0 = OSCR + LATCH; -- raw_local_irq_restore(irqflags); -- break; -- - case CLOCK_EVT_MODE_ONESHOT: - raw_local_irq_save(irqflags); - OIER &= ~OIER_E0; -@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) - break; - - case CLOCK_EVT_MODE_RESUME: -+ case CLOCK_EVT_MODE_PERIODIC: - break; - } - } - - static struct clock_event_device ckevt_pxa_osmr0 = { - .name = "osmr0", -- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, -+ .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .rating = 200, - .cpumask = CPU_MASK_CPU0, --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch b/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch deleted file mode 100644 index 0a42bc5855..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch +++ /dev/null @@ -1,257 +0,0 @@ -From ee8ca5742e0000dd2369ef4d328c2c1117276a3b Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 02:56:28 +0300 -Subject: [PATCH 20/64] Provide dew device/clock backports from 2.6.24-git - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/Kconfig | 1 + - arch/arm/mach-pxa/devices.h | 12 ++++++++++++ - arch/arm/mach-pxa/pxa25x.c | 18 ++++++++++++------ - arch/arm/mach-pxa/pxa27x.c | 22 ++++++++++++++++------ - arch/arm/mach-pxa/pxa3xx.c | 30 ++++++++++++++++++++++++++++++ - kernel/Makefile | 1 + - 6 files changed, 72 insertions(+), 12 deletions(-) - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 1be7182..10faf9c 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -367,6 +367,7 @@ config ARCH_SA1100 - select ARCH_DISCONTIGMEM_ENABLE - select ARCH_MTD_XIP - select GENERIC_GPIO -+ select GENERIC_TIME - help - Support for StrongARM 11x0 based boards. - -diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h -index 94c8d5c..96c7c89 100644 ---- a/arch/arm/mach-pxa/devices.h -+++ b/arch/arm/mach-pxa/devices.h -@@ -1,4 +1,6 @@ - extern struct platform_device pxa_device_mci; -+extern struct platform_device pxa3xx_device_mci2; -+extern struct platform_device pxa3xx_device_mci3; - extern struct platform_device pxa_device_udc; - extern struct platform_device pxa_device_fb; - extern struct platform_device pxa_device_ffuart; -@@ -12,3 +14,13 @@ extern struct platform_device pxa_device_rtc; - - extern struct platform_device pxa27x_device_i2c_power; - extern struct platform_device pxa27x_device_ohci; -+ -+extern struct platform_device pxa25x_device_ssp; -+extern struct platform_device pxa25x_device_nssp; -+extern struct platform_device pxa25x_device_assp; -+extern struct platform_device pxa27x_device_ssp1; -+extern struct platform_device pxa27x_device_ssp2; -+extern struct platform_device pxa27x_device_ssp3; -+extern struct platform_device pxa3xx_device_ssp4; -+ -+void __init pxa_register_device(struct platform_device *dev, void *data); -diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c -index 006a6e0..5988d99 100644 ---- a/arch/arm/mach-pxa/pxa25x.c -+++ b/arch/arm/mach-pxa/pxa25x.c -@@ -123,12 +123,15 @@ static struct clk pxa25x_clks[] = { - INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), - INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), - INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), -+ -+ INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), -+ INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), -+ INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), -+ - /* - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), -- INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL), - INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), -- INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL), - */ - INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), - }; -@@ -216,8 +219,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) - - static void pxa25x_cpu_pm_enter(suspend_state_t state) - { -- CKEN = 0; -- - switch (state) { - case PM_SUSPEND_MEM: - /* set resume return address */ -@@ -239,6 +240,8 @@ static void __init pxa25x_init_pm(void) - { - pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; - } -+#else -+static inline void pxa25x_init_pm(void) {} - #endif - - /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm -@@ -300,6 +303,9 @@ static struct platform_device *pxa25x_devices[] __initdata = { - &pxa_device_i2s, - &pxa_device_ficp, - &pxa_device_rtc, -+ &pxa25x_device_ssp, -+ &pxa25x_device_nssp, -+ &pxa25x_device_assp, - }; - - static int __init pxa25x_init(void) -@@ -315,9 +321,9 @@ static int __init pxa25x_init(void) - - if ((ret = pxa_init_dma(16))) - return ret; --#ifdef CONFIG_PM -+ - pxa25x_init_pm(); --#endif -+ - ret = platform_add_devices(pxa25x_devices, - ARRAY_SIZE(pxa25x_devices)); - } -diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c -index 8e126e6..30ca4fd 100644 ---- a/arch/arm/mach-pxa/pxa27x.c -+++ b/arch/arm/mach-pxa/pxa27x.c -@@ -150,11 +150,12 @@ static struct clk pxa27x_clks[] = { - INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), - INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), - -+ INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), -+ INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), -+ INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), -+ - /* - INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), -- INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL), -- INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL), -- INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL), - INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), - INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), - INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), -@@ -304,6 +305,8 @@ static void __init pxa27x_init_pm(void) - { - pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; - } -+#else -+static inline void pxa27x_init_pm(void) {} - #endif - - /* PXA27x: Various gpios can issue wakeup events. This logic only -@@ -423,6 +426,11 @@ struct platform_device pxa27x_device_i2c_power = { - .num_resources = ARRAY_SIZE(i2c_power_resources), - }; - -+void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) -+{ -+ pxa27x_device_i2c_power.dev.platform_data = info; -+} -+ - static struct platform_device *devices[] __initdata = { - &pxa_device_mci, - &pxa_device_udc, -@@ -435,7 +443,9 @@ static struct platform_device *devices[] __initdata = { - &pxa_device_ficp, - &pxa_device_rtc, - &pxa27x_device_i2c_power, -- &pxa27x_device_ohci, -+ &pxa27x_device_ssp1, -+ &pxa27x_device_ssp2, -+ &pxa27x_device_ssp3, - }; - - static int __init pxa27x_init(void) -@@ -446,9 +456,9 @@ static int __init pxa27x_init(void) - - if ((ret = pxa_init_dma(32))) - return ret; --#ifdef CONFIG_PM -+ - pxa27x_init_pm(); --#endif -+ - ret = platform_add_devices(devices, ARRAY_SIZE(devices)); - } - return ret; -diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c -index 61d9c9d..ccab9da 100644 ---- a/arch/arm/mach-pxa/pxa3xx.c -+++ b/arch/arm/mach-pxa/pxa3xx.c -@@ -189,8 +189,31 @@ static struct clk pxa3xx_clks[] = { - - PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), -+ PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev), -+ -+ PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), -+ PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), -+ PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), -+ PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), -+ -+ PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), -+ PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), -+ PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), - }; - -+#ifdef CONFIG_PM -+#define SLEEP_SAVE_SIZE 4 -+ -+#define ISRAM_START 0x5c000000 -+#define ISRAM_SIZE SZ_256K -+ -+static inline void pxa3xx_init_pm(void) {} -+static inline void pxa3xx_init_irq_pm(void) {} -+#else -+static inline void pxa3xx_init_pm(void) {} -+static inline void pxa3xx_init_irq_pm(void) {} -+#endif -+ - void __init pxa3xx_init_irq(void) - { - /* enable CP6 access */ -@@ -202,6 +225,7 @@ void __init pxa3xx_init_irq(void) - pxa_init_irq_low(); - pxa_init_irq_high(); - pxa_init_irq_gpio(128); -+ pxa3xx_init_irq_pm(); - } - - /* -@@ -219,6 +243,10 @@ static struct platform_device *devices[] __initdata = { - &pxa_device_i2s, - &pxa_device_ficp, - &pxa_device_rtc, -+ &pxa27x_device_ssp1, -+ &pxa27x_device_ssp2, -+ &pxa27x_device_ssp3, -+ &pxa3xx_device_ssp4, - }; - - static int __init pxa3xx_init(void) -@@ -231,6 +259,8 @@ static int __init pxa3xx_init(void) - if ((ret = pxa_init_dma(32))) - return ret; - -+ pxa3xx_init_pm(); -+ - return platform_add_devices(devices, ARRAY_SIZE(devices)); - } - return 0; -diff --git a/kernel/Makefile b/kernel/Makefile -index dfa9695..6d9a87c 100644 ---- a/kernel/Makefile -+++ b/kernel/Makefile -@@ -57,6 +57,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o - obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o - obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o - obj-$(CONFIG_MARKERS) += marker.o -+obj-$(CONFIG_LATENCYTOP) += latencytop.o - - ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) - # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch b/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch deleted file mode 100644 index 3f8512128a..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch +++ /dev/null @@ -1,121 +0,0 @@ -From b77665c545bc260d2b93add129413e4a724d7e6e Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell@users.sourceforge.net> -Date: Fri, 18 Jan 2008 00:35:00 +0300 -Subject: [PATCH 21/64] Add an empty drivers/gpio directory for gpiolib infrastructure and GPIO - expanders. It will be populated by later patches. - -This won't be the only place to hold such gpio_chip code. Many external chips -add a few GPIOs as secondary functionality (such as MFD drivers) and platform -code frequently needs to closely integrate GPIO and IRQ support. - -This is placed *early* in the build/link sequence since it's common for other -drivers to depend on GPIOs to do their work, so they must be initialized early -in the device_initcall() sequence. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Acked-by: Jean Delvare <khali@linux-fr.org> -Cc: Eric Miao <eric.miao@marvell.com> -Cc: Sam Ravnborg <sam@ravnborg.org> -Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> -Cc: Philipp Zabel <philipp.zabel@gmail.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Ben Gardner <bgardner@wabtec.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> ---- - arch/arm/Kconfig | 2 ++ - drivers/Kconfig | 2 ++ - drivers/Makefile | 1 + - drivers/gpio/Kconfig | 32 ++++++++++++++++++++++++++++++++ - drivers/gpio/Makefile | 3 +++ - 5 files changed, 40 insertions(+), 0 deletions(-) - create mode 100644 drivers/gpio/Kconfig - create mode 100644 drivers/gpio/Makefile - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 10faf9c..06ca241 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1042,6 +1042,8 @@ source "drivers/i2c/Kconfig" - - source "drivers/spi/Kconfig" - -+source "drivers/gpio/Kconfig" -+ - source "drivers/w1/Kconfig" - - source "drivers/power/Kconfig" -diff --git a/drivers/Kconfig b/drivers/Kconfig -index f4076d9..90e295a 100644 ---- a/drivers/Kconfig -+++ b/drivers/Kconfig -@@ -52,6 +52,8 @@ source "drivers/i2c/Kconfig" - - source "drivers/spi/Kconfig" - -+source "drivers/gpio/Kconfig" -+ - source "drivers/w1/Kconfig" - - source "drivers/power/Kconfig" -diff --git a/drivers/Makefile b/drivers/Makefile -index 8cb37e3..8e5101f 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -5,6 +5,7 @@ - # Rewritten to use lists instead of if-statements. - # - -+obj-$(CONFIG_HAVE_GPIO_LIB) += gpio/ - obj-$(CONFIG_PCI) += pci/ - obj-$(CONFIG_PARISC) += parisc/ - obj-$(CONFIG_RAPIDIO) += rapidio/ -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -new file mode 100644 -index 0000000..560687c ---- /dev/null -+++ b/drivers/gpio/Kconfig -@@ -0,0 +1,32 @@ -+# -+# GPIO infrastructure and expanders -+# -+ -+config HAVE_GPIO_LIB -+ bool -+ help -+ Platforms select gpiolib if they use this infrastructure -+ for all their GPIOs, usually starting with ones integrated -+ into SOC processors. -+ -+menu "GPIO Support" -+ depends on HAVE_GPIO_LIB -+ -+config DEBUG_GPIO -+ bool "Debug GPIO calls" -+ depends on DEBUG_KERNEL -+ help -+ Say Y here to add some extra checks and diagnostics to GPIO calls. -+ The checks help ensure that GPIOs have been properly initialized -+ before they are used and that sleeping calls aren not made from -+ nonsleeping contexts. They can make bitbanged serial protocols -+ slower. The diagnostics help catch the type of setup errors -+ that are most common when setting up new platforms or boards. -+ -+# put expanders in the right section, in alphabetical order -+ -+comment "I2C GPIO expanders:" -+ -+comment "SPI GPIO expanders:" -+ -+endmenu -diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -new file mode 100644 -index 0000000..cdbba6b ---- /dev/null -+++ b/drivers/gpio/Makefile -@@ -0,0 +1,3 @@ -+# gpio support: dedicated expander chips, etc -+ -+ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch b/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch deleted file mode 100644 index f39fedbbaa..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch +++ /dev/null @@ -1,746 +0,0 @@ -From 3a0251c01446f3a6763e4406ca5495102db63aa4 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell@users.sourceforge.net> -Date: Fri, 18 Jan 2008 00:35:20 +0300 -Subject: [PATCH 22/64] Provide new implementation infrastructure that platforms may choose to use - when implementing the GPIO programming interface. Platforms can update their - GPIO support to use this. In many cases the incremental cost to access a - non-inlined GPIO should be less than a dozen instructions, with the memory - cost being about a page (total) of extra data and code. The upside is: - - * Providing two features which were "want to have (but OK to defer)" when - GPIO interfaces were first discussed in November 2006: - - - A "struct gpio_chip" to plug in GPIOs that aren't directly supported - by SOC platforms, but come from FPGAs or other multifunction devices - using conventional device registers (like UCB-1x00 or SM501 GPIOs, - and southbridges in PCs with more open specs than usual). - - - Full support for message-based GPIO expanders, where registers are - accessed through sleeping I/O calls. Previous support for these - "cansleep" calls was just stubs. (One example: the widely used - pcf8574 I2C chips, with 8 GPIOs each.) - - * Including a non-stub implementation of the gpio_{request,free}() calls, - making those calls much more useful. The diagnostic labels are also - recorded given DEBUG_FS, so /sys/kernel/debug/gpio can show a snapshot - of all GPIOs known to this infrastructure. - -The driver programming interfaces introduced in 2.6.21 do not change at all; -this infrastructure is entirely below those covers. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Cc: Sam Ravnborg <sam@ravnborg.org> -Cc: Jean Delvare <khali@linux-fr.org> -Cc: Eric Miao <eric.miao@marvell.com> -Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> -Cc: Philipp Zabel <philipp.zabel@gmail.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Ben Gardner <bgardner@wabtec.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> ---- - drivers/gpio/Makefile | 2 + - drivers/gpio/gpiolib.c | 567 ++++++++++++++++++++++++++++++++++++++++++++ - include/asm-generic/gpio.h | 98 ++++++++ - 3 files changed, 667 insertions(+), 0 deletions(-) - create mode 100644 drivers/gpio/gpiolib.c - -diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index cdbba6b..2db28ce 100644 ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -1,3 +1,5 @@ - # gpio support: dedicated expander chips, etc - - ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG -+ -+obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o -diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c -new file mode 100644 -index 0000000..d8db2f8 ---- /dev/null -+++ b/drivers/gpio/gpiolib.c -@@ -0,0 +1,567 @@ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/irq.h> -+#include <linux/spinlock.h> -+ -+#include <asm/gpio.h> -+ -+ -+/* Optional implementation infrastructure for GPIO interfaces. -+ * -+ * Platforms may want to use this if they tend to use very many GPIOs -+ * that aren't part of a System-On-Chip core; or across I2C/SPI/etc. -+ * -+ * When kernel footprint or instruction count is an issue, simpler -+ * implementations may be preferred. The GPIO programming interface -+ * allows for inlining speed-critical get/set operations for common -+ * cases, so that access to SOC-integrated GPIOs can sometimes cost -+ * only an instruction or two per bit. -+ */ -+ -+ -+/* When debugging, extend minimal trust to callers and platform code. -+ * Also emit diagnostic messages that may help initial bringup, when -+ * board setup or driver bugs are most common. -+ * -+ * Otherwise, minimize overhead in what may be bitbanging codepaths. -+ */ -+#ifdef DEBUG -+#define extra_checks 1 -+#else -+#define extra_checks 0 -+#endif -+ -+/* gpio_lock prevents conflicts during gpio_desc[] table updates. -+ * While any GPIO is requested, its gpio_chip is not removable; -+ * each GPIO's "requested" flag serves as a lock and refcount. -+ */ -+static DEFINE_SPINLOCK(gpio_lock); -+ -+struct gpio_desc { -+ struct gpio_chip *chip; -+ unsigned long flags; -+/* flag symbols are bit numbers */ -+#define FLAG_REQUESTED 0 -+#define FLAG_IS_OUT 1 -+ -+#ifdef CONFIG_DEBUG_FS -+ const char *label; -+#endif -+}; -+static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; -+ -+static inline void desc_set_label(struct gpio_desc *d, const char *label) -+{ -+#ifdef CONFIG_DEBUG_FS -+ d->label = label; -+#endif -+} -+ -+/* Warn when drivers omit gpio_request() calls -- legal but ill-advised -+ * when setting direction, and otherwise illegal. Until board setup code -+ * and drivers use explicit requests everywhere (which won't happen when -+ * those calls have no teeth) we can't avoid autorequesting. This nag -+ * message should motivate switching to explicit requests... -+ */ -+static void gpio_ensure_requested(struct gpio_desc *desc) -+{ -+ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { -+ pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); -+ desc_set_label(desc, "[auto]"); -+ } -+} -+ -+/* caller holds gpio_lock *OR* gpio is marked as requested */ -+static inline struct gpio_chip *gpio_to_chip(unsigned gpio) -+{ -+ return gpio_desc[gpio].chip; -+} -+ -+/** -+ * gpiochip_add() - register a gpio_chip -+ * @chip: the chip to register, with chip->base initialized -+ * Context: potentially before irqs or kmalloc will work -+ * -+ * Returns a negative errno if the chip can't be registered, such as -+ * because the chip->base is invalid or already associated with a -+ * different chip. Otherwise it returns zero as a success code. -+ */ -+int gpiochip_add(struct gpio_chip *chip) -+{ -+ unsigned long flags; -+ int status = 0; -+ unsigned id; -+ -+ /* NOTE chip->base negative is reserved to mean a request for -+ * dynamic allocation. We don't currently support that. -+ */ -+ -+ if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) { -+ status = -EINVAL; -+ goto fail; -+ } -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ /* these GPIO numbers must not be managed by another gpio_chip */ -+ for (id = chip->base; id < chip->base + chip->ngpio; id++) { -+ if (gpio_desc[id].chip != NULL) { -+ status = -EBUSY; -+ break; -+ } -+ } -+ if (status == 0) { -+ for (id = chip->base; id < chip->base + chip->ngpio; id++) { -+ gpio_desc[id].chip = chip; -+ gpio_desc[id].flags = 0; -+ } -+ } -+ -+ spin_unlock_irqrestore(&gpio_lock, flags); -+fail: -+ /* failures here can mean systems won't boot... */ -+ if (status) -+ pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", -+ chip->base, chip->base + chip->ngpio, -+ chip->label ? : "generic"); -+ return status; -+} -+EXPORT_SYMBOL_GPL(gpiochip_add); -+ -+/** -+ * gpiochip_remove() - unregister a gpio_chip -+ * @chip: the chip to unregister -+ * -+ * A gpio_chip with any GPIOs still requested may not be removed. -+ */ -+int gpiochip_remove(struct gpio_chip *chip) -+{ -+ unsigned long flags; -+ int status = 0; -+ unsigned id; -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ for (id = chip->base; id < chip->base + chip->ngpio; id++) { -+ if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { -+ status = -EBUSY; -+ break; -+ } -+ } -+ if (status == 0) { -+ for (id = chip->base; id < chip->base + chip->ngpio; id++) -+ gpio_desc[id].chip = NULL; -+ } -+ -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ return status; -+} -+EXPORT_SYMBOL_GPL(gpiochip_remove); -+ -+ -+/* These "optional" allocation calls help prevent drivers from stomping -+ * on each other, and help provide better diagnostics in debugfs. -+ * They're called even less than the "set direction" calls. -+ */ -+int gpio_request(unsigned gpio, const char *label) -+{ -+ struct gpio_desc *desc; -+ int status = -EINVAL; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ if (gpio >= ARCH_NR_GPIOS) -+ goto done; -+ desc = &gpio_desc[gpio]; -+ if (desc->chip == NULL) -+ goto done; -+ -+ /* NOTE: gpio_request() can be called in early boot, -+ * before IRQs are enabled. -+ */ -+ -+ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { -+ desc_set_label(desc, label ? : "?"); -+ status = 0; -+ } else -+ status = -EBUSY; -+ -+done: -+ if (status) -+ pr_debug("gpio_request: gpio-%d (%s) status %d\n", -+ gpio, label ? : "?", status); -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ return status; -+} -+EXPORT_SYMBOL_GPL(gpio_request); -+ -+void gpio_free(unsigned gpio) -+{ -+ unsigned long flags; -+ struct gpio_desc *desc; -+ -+ if (gpio >= ARCH_NR_GPIOS) { -+ WARN_ON(extra_checks); -+ return; -+ } -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ desc = &gpio_desc[gpio]; -+ if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) -+ desc_set_label(desc, NULL); -+ else -+ WARN_ON(extra_checks); -+ -+ spin_unlock_irqrestore(&gpio_lock, flags); -+} -+EXPORT_SYMBOL_GPL(gpio_free); -+ -+ -+/** -+ * gpiochip_is_requested - return string iff signal was requested -+ * @chip: controller managing the signal -+ * @offset: of signal within controller's 0..(ngpio - 1) range -+ * -+ * Returns NULL if the GPIO is not currently requested, else a string. -+ * If debugfs support is enabled, the string returned is the label passed -+ * to gpio_request(); otherwise it is a meaningless constant. -+ * -+ * This function is for use by GPIO controller drivers. The label can -+ * help with diagnostics, and knowing that the signal is used as a GPIO -+ * can help avoid accidentally multiplexing it to another controller. -+ */ -+const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) -+{ -+ unsigned gpio = chip->base + offset; -+ -+ if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip) -+ return NULL; -+ if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0) -+ return NULL; -+#ifdef CONFIG_DEBUG_FS -+ return gpio_desc[gpio].label; -+#else -+ return "?"; -+#endif -+} -+EXPORT_SYMBOL_GPL(gpiochip_is_requested); -+ -+ -+/* Drivers MUST set GPIO direction before making get/set calls. In -+ * some cases this is done in early boot, before IRQs are enabled. -+ * -+ * As a rule these aren't called more than once (except for drivers -+ * using the open-drain emulation idiom) so these are natural places -+ * to accumulate extra debugging checks. Note that we can't (yet) -+ * rely on gpio_request() having been called beforehand. -+ */ -+ -+int gpio_direction_input(unsigned gpio) -+{ -+ unsigned long flags; -+ struct gpio_chip *chip; -+ struct gpio_desc *desc = &gpio_desc[gpio]; -+ int status = -EINVAL; -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ if (gpio >= ARCH_NR_GPIOS) -+ goto fail; -+ chip = desc->chip; -+ if (!chip || !chip->get || !chip->direction_input) -+ goto fail; -+ gpio -= chip->base; -+ if (gpio >= chip->ngpio) -+ goto fail; -+ gpio_ensure_requested(desc); -+ -+ /* now we know the gpio is valid and chip won't vanish */ -+ -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ -+ might_sleep_if(extra_checks && chip->can_sleep); -+ -+ status = chip->direction_input(chip, gpio); -+ if (status == 0) -+ clear_bit(FLAG_IS_OUT, &desc->flags); -+ return status; -+fail: -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ if (status) -+ pr_debug("%s: gpio-%d status %d\n", -+ __FUNCTION__, gpio, status); -+ return status; -+} -+EXPORT_SYMBOL_GPL(gpio_direction_input); -+ -+int gpio_direction_output(unsigned gpio, int value) -+{ -+ unsigned long flags; -+ struct gpio_chip *chip; -+ struct gpio_desc *desc = &gpio_desc[gpio]; -+ int status = -EINVAL; -+ -+ spin_lock_irqsave(&gpio_lock, flags); -+ -+ if (gpio >= ARCH_NR_GPIOS) -+ goto fail; -+ chip = desc->chip; -+ if (!chip || !chip->set || !chip->direction_output) -+ goto fail; -+ gpio -= chip->base; -+ if (gpio >= chip->ngpio) -+ goto fail; -+ gpio_ensure_requested(desc); -+ -+ /* now we know the gpio is valid and chip won't vanish */ -+ -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ -+ might_sleep_if(extra_checks && chip->can_sleep); -+ -+ status = chip->direction_output(chip, gpio, value); -+ if (status == 0) -+ set_bit(FLAG_IS_OUT, &desc->flags); -+ return status; -+fail: -+ spin_unlock_irqrestore(&gpio_lock, flags); -+ if (status) -+ pr_debug("%s: gpio-%d status %d\n", -+ __FUNCTION__, gpio, status); -+ return status; -+} -+EXPORT_SYMBOL_GPL(gpio_direction_output); -+ -+ -+/* I/O calls are only valid after configuration completed; the relevant -+ * "is this a valid GPIO" error checks should already have been done. -+ * -+ * "Get" operations are often inlinable as reading a pin value register, -+ * and masking the relevant bit in that register. -+ * -+ * When "set" operations are inlinable, they involve writing that mask to -+ * one register to set a low value, or a different register to set it high. -+ * Otherwise locking is needed, so there may be little value to inlining. -+ * -+ *------------------------------------------------------------------------ -+ * -+ * IMPORTANT!!! The hot paths -- get/set value -- assume that callers -+ * have requested the GPIO. That can include implicit requesting by -+ * a direction setting call. Marking a gpio as requested locks its chip -+ * in memory, guaranteeing that these table lookups need no more locking -+ * and that gpiochip_remove() will fail. -+ * -+ * REVISIT when debugging, consider adding some instrumentation to ensure -+ * that the GPIO was actually requested. -+ */ -+ -+/** -+ * __gpio_get_value() - return a gpio's value -+ * @gpio: gpio whose value will be returned -+ * Context: any -+ * -+ * This is used directly or indirectly to implement gpio_get_value(). -+ * It returns the zero or nonzero value provided by the associated -+ * gpio_chip.get() method; or zero if no such method is provided. -+ */ -+int __gpio_get_value(unsigned gpio) -+{ -+ struct gpio_chip *chip; -+ -+ chip = gpio_to_chip(gpio); -+ WARN_ON(extra_checks && chip->can_sleep); -+ return chip->get ? chip->get(chip, gpio - chip->base) : 0; -+} -+EXPORT_SYMBOL_GPL(__gpio_get_value); -+ -+/** -+ * __gpio_set_value() - assign a gpio's value -+ * @gpio: gpio whose value will be assigned -+ * @value: value to assign -+ * Context: any -+ * -+ * This is used directly or indirectly to implement gpio_set_value(). -+ * It invokes the associated gpio_chip.set() method. -+ */ -+void __gpio_set_value(unsigned gpio, int value) -+{ -+ struct gpio_chip *chip; -+ -+ chip = gpio_to_chip(gpio); -+ WARN_ON(extra_checks && chip->can_sleep); -+ chip->set(chip, gpio - chip->base, value); -+} -+EXPORT_SYMBOL_GPL(__gpio_set_value); -+ -+/** -+ * __gpio_cansleep() - report whether gpio value access will sleep -+ * @gpio: gpio in question -+ * Context: any -+ * -+ * This is used directly or indirectly to implement gpio_cansleep(). It -+ * returns nonzero if access reading or writing the GPIO value can sleep. -+ */ -+int __gpio_cansleep(unsigned gpio) -+{ -+ struct gpio_chip *chip; -+ -+ /* only call this on GPIOs that are valid! */ -+ chip = gpio_to_chip(gpio); -+ -+ return chip->can_sleep; -+} -+EXPORT_SYMBOL_GPL(__gpio_cansleep); -+ -+ -+ -+/* There's no value in making it easy to inline GPIO calls that may sleep. -+ * Common examples include ones connected to I2C or SPI chips. -+ */ -+ -+int gpio_get_value_cansleep(unsigned gpio) -+{ -+ struct gpio_chip *chip; -+ -+ might_sleep_if(extra_checks); -+ chip = gpio_to_chip(gpio); -+ return chip->get(chip, gpio - chip->base); -+} -+EXPORT_SYMBOL_GPL(gpio_get_value_cansleep); -+ -+void gpio_set_value_cansleep(unsigned gpio, int value) -+{ -+ struct gpio_chip *chip; -+ -+ might_sleep_if(extra_checks); -+ chip = gpio_to_chip(gpio); -+ chip->set(chip, gpio - chip->base, value); -+} -+EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); -+ -+ -+#ifdef CONFIG_DEBUG_FS -+ -+#include <linux/debugfs.h> -+#include <linux/seq_file.h> -+ -+ -+static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) -+{ -+ unsigned i; -+ unsigned gpio = chip->base; -+ struct gpio_desc *gdesc = &gpio_desc[gpio]; -+ int is_out; -+ -+ for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) { -+ if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) -+ continue; -+ -+ is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); -+ seq_printf(s, " gpio-%-3d (%-12s) %s %s", -+ gpio, gdesc->label, -+ is_out ? "out" : "in ", -+ chip->get -+ ? (chip->get(chip, i) ? "hi" : "lo") -+ : "? "); -+ -+ if (!is_out) { -+ int irq = gpio_to_irq(gpio); -+ struct irq_desc *desc = irq_desc + irq; -+ -+ /* This races with request_irq(), set_irq_type(), -+ * and set_irq_wake() ... but those are "rare". -+ * -+ * More significantly, trigger type flags aren't -+ * currently maintained by genirq. -+ */ -+ if (irq >= 0 && desc->action) { -+ char *trigger; -+ -+ switch (desc->status & IRQ_TYPE_SENSE_MASK) { -+ case IRQ_TYPE_NONE: -+ trigger = "(default)"; -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ trigger = "edge-falling"; -+ break; -+ case IRQ_TYPE_EDGE_RISING: -+ trigger = "edge-rising"; -+ break; -+ case IRQ_TYPE_EDGE_BOTH: -+ trigger = "edge-both"; -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ trigger = "level-high"; -+ break; -+ case IRQ_TYPE_LEVEL_LOW: -+ trigger = "level-low"; -+ break; -+ default: -+ trigger = "?trigger?"; -+ break; -+ } -+ -+ seq_printf(s, " irq-%d %s%s", -+ irq, trigger, -+ (desc->status & IRQ_WAKEUP) -+ ? " wakeup" : ""); -+ } -+ } -+ -+ seq_printf(s, "\n"); -+ } -+} -+ -+static int gpiolib_show(struct seq_file *s, void *unused) -+{ -+ struct gpio_chip *chip = NULL; -+ unsigned gpio; -+ int started = 0; -+ -+ /* REVISIT this isn't locked against gpio_chip removal ... */ -+ -+ for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) { -+ if (chip == gpio_desc[gpio].chip) -+ continue; -+ chip = gpio_desc[gpio].chip; -+ if (!chip) -+ continue; -+ -+ seq_printf(s, "%sGPIOs %d-%d, %s%s:\n", -+ started ? "\n" : "", -+ chip->base, chip->base + chip->ngpio - 1, -+ chip->label ? : "generic", -+ chip->can_sleep ? ", can sleep" : ""); -+ started = 1; -+ if (chip->dbg_show) -+ chip->dbg_show(s, chip); -+ else -+ gpiolib_dbg_show(s, chip); -+ } -+ return 0; -+} -+ -+static int gpiolib_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, gpiolib_show, NULL); -+} -+ -+static struct file_operations gpiolib_operations = { -+ .open = gpiolib_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init gpiolib_debugfs_init(void) -+{ -+ /* /sys/kernel/debug/gpio */ -+ (void) debugfs_create_file("gpio", S_IFREG | S_IRUGO, -+ NULL, NULL, &gpiolib_operations); -+ return 0; -+} -+subsys_initcall(gpiolib_debugfs_init); -+ -+#endif /* DEBUG_FS */ -diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h -index 2d0aab1..f29a502 100644 ---- a/include/asm-generic/gpio.h -+++ b/include/asm-generic/gpio.h -@@ -1,6 +1,102 @@ - #ifndef _ASM_GENERIC_GPIO_H - #define _ASM_GENERIC_GPIO_H - -+#ifdef CONFIG_HAVE_GPIO_LIB -+ -+/* Platforms may implement their GPIO interface with library code, -+ * at a small performance cost for non-inlined operations and some -+ * extra memory (for code and for per-GPIO table entries). -+ * -+ * While the GPIO programming interface defines valid GPIO numbers -+ * to be in the range 0..MAX_INT, this library restricts them to the -+ * smaller range 0..ARCH_NR_GPIOS. -+ */ -+ -+#ifndef ARCH_NR_GPIOS -+#define ARCH_NR_GPIOS 256 -+#endif -+ -+struct seq_file; -+ -+/** -+ * struct gpio_chip - abstract a GPIO controller -+ * @label: for diagnostics -+ * @direction_input: configures signal "offset" as input, or returns error -+ * @get: returns value for signal "offset"; for output signals this -+ * returns either the value actually sensed, or zero -+ * @direction_output: configures signal "offset" as output, or returns error -+ * @set: assigns output value for signal "offset" -+ * @dbg_show: optional routine to show contents in debugfs; default code -+ * will be used when this is omitted, but custom code can show extra -+ * state (such as pullup/pulldown configuration). -+ * @base: identifies the first GPIO number handled by this chip; or, if -+ * negative during registration, requests dynamic ID allocation. -+ * @ngpio: the number of GPIOs handled by this controller; the last GPIO -+ * handled is (base + ngpio - 1). -+ * @can_sleep: flag must be set iff get()/set() methods sleep, as they -+ * must while accessing GPIO expander chips over I2C or SPI -+ * -+ * A gpio_chip can help platforms abstract various sources of GPIOs so -+ * they can all be accessed through a common programing interface. -+ * Example sources would be SOC controllers, FPGAs, multifunction -+ * chips, dedicated GPIO expanders, and so on. -+ * -+ * Each chip controls a number of signals, identified in method calls -+ * by "offset" values in the range 0..(@ngpio - 1). When those signals -+ * are referenced through calls like gpio_get_value(gpio), the offset -+ * is calculated by subtracting @base from the gpio number. -+ */ -+struct gpio_chip { -+ char *label; -+ -+ int (*direction_input)(struct gpio_chip *chip, -+ unsigned offset); -+ int (*get)(struct gpio_chip *chip, -+ unsigned offset); -+ int (*direction_output)(struct gpio_chip *chip, -+ unsigned offset, int value); -+ void (*set)(struct gpio_chip *chip, -+ unsigned offset, int value); -+ void (*dbg_show)(struct seq_file *s, -+ struct gpio_chip *chip); -+ int base; -+ u16 ngpio; -+ unsigned can_sleep:1; -+}; -+ -+extern const char *gpiochip_is_requested(struct gpio_chip *chip, -+ unsigned offset); -+ -+/* add/remove chips */ -+extern int gpiochip_add(struct gpio_chip *chip); -+extern int __must_check gpiochip_remove(struct gpio_chip *chip); -+ -+ -+/* Always use the library code for GPIO management calls, -+ * or when sleeping may be involved. -+ */ -+extern int gpio_request(unsigned gpio, const char *label); -+extern void gpio_free(unsigned gpio); -+ -+extern int gpio_direction_input(unsigned gpio); -+extern int gpio_direction_output(unsigned gpio, int value); -+ -+extern int gpio_get_value_cansleep(unsigned gpio); -+extern void gpio_set_value_cansleep(unsigned gpio, int value); -+ -+ -+/* A platform's <asm/gpio.h> code may want to inline the I/O calls when -+ * the GPIO is constant and refers to some always-present controller, -+ * giving direct access to chip registers and tight bitbanging loops. -+ */ -+extern int __gpio_get_value(unsigned gpio); -+extern void __gpio_set_value(unsigned gpio, int value); -+ -+extern int __gpio_cansleep(unsigned gpio); -+ -+ -+#else -+ - /* platforms that don't directly support access to GPIOs through I2C, SPI, - * or other blocking infrastructure can use these wrappers. - */ -@@ -22,4 +118,6 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) - gpio_set_value(gpio, value); - } - -+#endif -+ - #endif /* _ASM_GENERIC_GPIO_H */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch b/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch deleted file mode 100644 index 7a37be85cf..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch +++ /dev/null @@ -1,498 +0,0 @@ -From 49da9bd487e54164a75503e0037a054cce697ed5 Mon Sep 17 00:00:00 2001 -From: Philipp Zabel <philipp.zabel@gmail.com> -Date: Tue, 12 Feb 2008 04:38:12 +0300 -Subject: [PATCH 23/64] This adds gpiolib support for the PXA architecture: - - move all GPIO API functions from generic.c into gpio.c - - convert the gpio_get/set_value macros into inline functions - -This makes it easier to hook up GPIOs provided by external chips like -ASICs and CPLDs. - -Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> -Cc: Jean Delvare <khali@linux-fr.org> -Cc: Eric Miao <eric.miao@marvell.com> -Cc: Sam Ravnborg <sam@ravnborg.org> -Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> -Cc: Ben Gardner <bgardner@wabtec.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> ---- - arch/arm/Kconfig | 1 + - arch/arm/mach-pxa/Makefile | 3 +- - arch/arm/mach-pxa/generic.c | 93 ---------------- - arch/arm/mach-pxa/generic.h | 1 + - arch/arm/mach-pxa/gpio.c | 197 +++++++++++++++++++++++++++++++++++ - arch/arm/mach-pxa/irq.c | 2 + - include/asm-arm/arch-pxa/gpio.h | 48 ++++----- - include/asm-arm/arch-pxa/pxa-regs.h | 13 +++ - 8 files changed, 236 insertions(+), 122 deletions(-) - create mode 100644 arch/arm/mach-pxa/gpio.c - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 06ca241..423e953 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -346,6 +346,7 @@ config ARCH_PXA - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select TICK_ONESHOT -+ select HAVE_GPIO_LIB - help - Support for Intel/Marvell's PXA2xx/PXA3xx processor line. - -diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile -index 4263527..5cb0216 100644 ---- a/arch/arm/mach-pxa/Makefile -+++ b/arch/arm/mach-pxa/Makefile -@@ -3,7 +3,8 @@ - # - - # Common support (must be linked before board specific support) --obj-y += clock.o generic.o irq.o dma.o time.o -+obj-y += clock.o generic.o irq.o dma.o \ -+ time.o gpio.o - obj-$(CONFIG_PXA25x) += pxa25x.o - obj-$(CONFIG_PXA27x) += pxa27x.o - obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o -diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c -index 1c34946..6c07292 100644 ---- a/arch/arm/mach-pxa/generic.c -+++ b/arch/arm/mach-pxa/generic.c -@@ -32,7 +32,6 @@ - #include <asm/mach/map.h> - - #include <asm/arch/pxa-regs.h> --#include <asm/arch/gpio.h> - #include <asm/arch/udc.h> - #include <asm/arch/pxafb.h> - #include <asm/arch/mmc.h> -@@ -73,97 +72,6 @@ unsigned int get_memclk_frequency_10khz(void) - EXPORT_SYMBOL(get_memclk_frequency_10khz); - - /* -- * Handy function to set GPIO alternate functions -- */ --int pxa_last_gpio; -- --int pxa_gpio_mode(int gpio_mode) --{ -- unsigned long flags; -- int gpio = gpio_mode & GPIO_MD_MASK_NR; -- int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; -- int gafr; -- -- if (gpio > pxa_last_gpio) -- return -EINVAL; -- -- local_irq_save(flags); -- if (gpio_mode & GPIO_DFLT_LOW) -- GPCR(gpio) = GPIO_bit(gpio); -- else if (gpio_mode & GPIO_DFLT_HIGH) -- GPSR(gpio) = GPIO_bit(gpio); -- if (gpio_mode & GPIO_MD_MASK_DIR) -- GPDR(gpio) |= GPIO_bit(gpio); -- else -- GPDR(gpio) &= ~GPIO_bit(gpio); -- gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); -- GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); -- local_irq_restore(flags); -- -- return 0; --} -- --EXPORT_SYMBOL(pxa_gpio_mode); -- --int gpio_direction_input(unsigned gpio) --{ -- unsigned long flags; -- u32 mask; -- -- if (gpio > pxa_last_gpio) -- return -EINVAL; -- -- mask = GPIO_bit(gpio); -- local_irq_save(flags); -- GPDR(gpio) &= ~mask; -- local_irq_restore(flags); -- -- return 0; --} --EXPORT_SYMBOL(gpio_direction_input); -- --int gpio_direction_output(unsigned gpio, int value) --{ -- unsigned long flags; -- u32 mask; -- -- if (gpio > pxa_last_gpio) -- return -EINVAL; -- -- mask = GPIO_bit(gpio); -- local_irq_save(flags); -- if (value) -- GPSR(gpio) = mask; -- else -- GPCR(gpio) = mask; -- GPDR(gpio) |= mask; -- local_irq_restore(flags); -- -- return 0; --} --EXPORT_SYMBOL(gpio_direction_output); -- --/* -- * Return GPIO level -- */ --int pxa_gpio_get_value(unsigned gpio) --{ -- return __gpio_get_value(gpio); --} -- --EXPORT_SYMBOL(pxa_gpio_get_value); -- --/* -- * Set output GPIO level -- */ --void pxa_gpio_set_value(unsigned gpio, int value) --{ -- __gpio_set_value(gpio, value); --} -- --EXPORT_SYMBOL(pxa_gpio_set_value); -- --/* - * Routine to safely enable or disable a clock in the CKEN - */ - void __pxa_set_cken(int clock, int enable) -@@ -178,7 +86,6 @@ void __pxa_set_cken(int clock, int enable) - - local_irq_restore(flags); - } -- - EXPORT_SYMBOL(__pxa_set_cken); - - /* -diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h -index b30f240..727a9f5 100644 ---- a/arch/arm/mach-pxa/generic.h -+++ b/arch/arm/mach-pxa/generic.h -@@ -16,6 +16,7 @@ extern void __init pxa_init_irq_low(void); - extern void __init pxa_init_irq_high(void); - extern void __init pxa_init_irq_gpio(int gpio_nr); - extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); -+extern void __init pxa_init_gpio(int gpio_nr); - extern void __init pxa25x_init_irq(void); - extern void __init pxa27x_init_irq(void); - extern void __init pxa3xx_init_irq(void); -diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c -new file mode 100644 -index 0000000..8638dd7 ---- /dev/null -+++ b/arch/arm/mach-pxa/gpio.c -@@ -0,0 +1,197 @@ -+/* -+ * linux/arch/arm/mach-pxa/gpio.c -+ * -+ * Generic PXA GPIO handling -+ * -+ * Author: Nicolas Pitre -+ * Created: Jun 15, 2001 -+ * Copyright: MontaVista Software Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/init.h> -+#include <linux/module.h> -+ -+#include <asm/gpio.h> -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/arch/pxa-regs.h> -+ -+#include "generic.h" -+ -+ -+struct pxa_gpio_chip { -+ struct gpio_chip chip; -+ void __iomem *regbase; -+}; -+ -+int pxa_last_gpio; -+ -+/* -+ * Configure pins for GPIO or other functions -+ */ -+int pxa_gpio_mode(int gpio_mode) -+{ -+ unsigned long flags; -+ int gpio = gpio_mode & GPIO_MD_MASK_NR; -+ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; -+ int gafr; -+ -+ if (gpio > pxa_last_gpio) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ if (gpio_mode & GPIO_DFLT_LOW) -+ GPCR(gpio) = GPIO_bit(gpio); -+ else if (gpio_mode & GPIO_DFLT_HIGH) -+ GPSR(gpio) = GPIO_bit(gpio); -+ if (gpio_mode & GPIO_MD_MASK_DIR) -+ GPDR(gpio) |= GPIO_bit(gpio); -+ else -+ GPDR(gpio) &= ~GPIO_bit(gpio); -+ gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); -+ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); -+ local_irq_restore(flags); -+ -+ return 0; -+} -+EXPORT_SYMBOL(pxa_gpio_mode); -+ -+static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -+{ -+ unsigned long flags; -+ u32 mask = 1 << offset; -+ u32 value; -+ struct pxa_gpio_chip *pxa; -+ void __iomem *gpdr; -+ -+ pxa = container_of(chip, struct pxa_gpio_chip, chip); -+ gpdr = pxa->regbase + GPDR_OFFSET; -+ local_irq_save(flags); -+ value = __raw_readl(gpdr); -+ value &= ~mask; -+ __raw_writel(value, gpdr); -+ local_irq_restore(flags); -+ -+ return 0; -+} -+ -+static int pxa_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ unsigned long flags; -+ u32 mask = 1 << offset; -+ u32 tmp; -+ struct pxa_gpio_chip *pxa; -+ void __iomem *gpdr; -+ -+ pxa = container_of(chip, struct pxa_gpio_chip, chip); -+ __raw_writel(mask, -+ pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET)); -+ gpdr = pxa->regbase + GPDR_OFFSET; -+ local_irq_save(flags); -+ tmp = __raw_readl(gpdr); -+ tmp |= mask; -+ __raw_writel(tmp, gpdr); -+ local_irq_restore(flags); -+ -+ return 0; -+} -+ -+/* -+ * Return GPIO level -+ */ -+static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ u32 mask = 1 << offset; -+ struct pxa_gpio_chip *pxa; -+ -+ pxa = container_of(chip, struct pxa_gpio_chip, chip); -+ return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask; -+} -+ -+/* -+ * Set output GPIO level -+ */ -+static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -+{ -+ u32 mask = 1 << offset; -+ struct pxa_gpio_chip *pxa; -+ -+ pxa = container_of(chip, struct pxa_gpio_chip, chip); -+ -+ if (value) -+ __raw_writel(mask, pxa->regbase + GPSR_OFFSET); -+ else -+ __raw_writel(mask, pxa->regbase + GPCR_OFFSET); -+} -+ -+static struct pxa_gpio_chip pxa_gpio_chip[] = { -+ [0] = { -+ .regbase = GPIO0_BASE, -+ .chip = { -+ .label = "gpio-0", -+ .direction_input = pxa_gpio_direction_input, -+ .direction_output = pxa_gpio_direction_output, -+ .get = pxa_gpio_get, -+ .set = pxa_gpio_set, -+ .base = 0, -+ .ngpio = 32, -+ }, -+ }, -+ [1] = { -+ .regbase = GPIO1_BASE, -+ .chip = { -+ .label = "gpio-1", -+ .direction_input = pxa_gpio_direction_input, -+ .direction_output = pxa_gpio_direction_output, -+ .get = pxa_gpio_get, -+ .set = pxa_gpio_set, -+ .base = 32, -+ .ngpio = 32, -+ }, -+ }, -+ [2] = { -+ .regbase = GPIO2_BASE, -+ .chip = { -+ .label = "gpio-2", -+ .direction_input = pxa_gpio_direction_input, -+ .direction_output = pxa_gpio_direction_output, -+ .get = pxa_gpio_get, -+ .set = pxa_gpio_set, -+ .base = 64, -+ .ngpio = 32, /* 21 for PXA25x */ -+ }, -+ }, -+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -+ [3] = { -+ .regbase = GPIO3_BASE, -+ .chip = { -+ .label = "gpio-3", -+ .direction_input = pxa_gpio_direction_input, -+ .direction_output = pxa_gpio_direction_output, -+ .get = pxa_gpio_get, -+ .set = pxa_gpio_set, -+ .base = 96, -+ .ngpio = 32, -+ }, -+ }, -+#endif -+}; -+ -+void __init pxa_init_gpio(int gpio_nr) -+{ -+ int i; -+ -+ /* add a GPIO chip for each register bank. -+ * the last PXA25x register only contains 21 GPIOs -+ */ -+ for (i = 0; i < gpio_nr; i += 32) { -+ if (i+32 > gpio_nr) -+ pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i; -+ gpiochip_add(&pxa_gpio_chip[i/32].chip); -+ } -+} -diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c -index 07acb45..d0965ef 100644 ---- a/arch/arm/mach-pxa/irq.c -+++ b/arch/arm/mach-pxa/irq.c -@@ -310,6 +310,8 @@ void __init pxa_init_irq_gpio(int gpio_nr) - /* Install handler for GPIO>=2 edge detect interrupts */ - set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); - set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); -+ -+ pxa_init_gpio(gpio_nr); - } - - void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) -diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h -index 9dbc2dc..bdbf5f9 100644 ---- a/include/asm-arm/arch-pxa/gpio.h -+++ b/include/asm-arm/arch-pxa/gpio.h -@@ -28,43 +28,35 @@ - #include <asm/irq.h> - #include <asm/hardware.h> - --static inline int gpio_request(unsigned gpio, const char *label) --{ -- return 0; --} -+#include <asm-generic/gpio.h> - --static inline void gpio_free(unsigned gpio) --{ -- return; --} - --extern int gpio_direction_input(unsigned gpio); --extern int gpio_direction_output(unsigned gpio, int value); -+/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). -+ * Those cases currently cause holes in the GPIO number space. -+ */ -+#define NR_BUILTIN_GPIO 128 - --static inline int __gpio_get_value(unsigned gpio) -+static inline int gpio_get_value(unsigned gpio) - { -- return GPLR(gpio) & GPIO_bit(gpio); -+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) -+ return GPLR(gpio) & GPIO_bit(gpio); -+ else -+ return __gpio_get_value(gpio); - } - --#define gpio_get_value(gpio) \ -- (__builtin_constant_p(gpio) ? \ -- __gpio_get_value(gpio) : \ -- pxa_gpio_get_value(gpio)) -- --static inline void __gpio_set_value(unsigned gpio, int value) -+static inline void gpio_set_value(unsigned gpio, int value) - { -- if (value) -- GPSR(gpio) = GPIO_bit(gpio); -- else -- GPCR(gpio) = GPIO_bit(gpio); -+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) { -+ if (value) -+ GPSR(gpio) = GPIO_bit(gpio); -+ else -+ GPCR(gpio) = GPIO_bit(gpio); -+ } else { -+ __gpio_set_value(gpio, value); -+ } - } - --#define gpio_set_value(gpio,value) \ -- (__builtin_constant_p(gpio) ? \ -- __gpio_set_value(gpio, value) : \ -- pxa_gpio_set_value(gpio, value)) -- --#include <asm-generic/gpio.h> /* cansleep wrappers */ -+#define gpio_cansleep __gpio_cansleep - - #define gpio_to_irq(gpio) IRQ_GPIO(gpio) - #define irq_to_gpio(irq) IRQ_TO_GPIO(irq) -diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h -index 1bd398d..bd57417 100644 ---- a/include/asm-arm/arch-pxa/pxa-regs.h -+++ b/include/asm-arm/arch-pxa/pxa-regs.h -@@ -1131,6 +1131,19 @@ - * General Purpose I/O - */ - -+#define GPIO0_BASE ((void __iomem *)io_p2v(0x40E00000)) -+#define GPIO1_BASE ((void __iomem *)io_p2v(0x40E00004)) -+#define GPIO2_BASE ((void __iomem *)io_p2v(0x40E00008)) -+#define GPIO3_BASE ((void __iomem *)io_p2v(0x40E00100)) -+ -+#define GPLR_OFFSET 0x00 -+#define GPDR_OFFSET 0x0C -+#define GPSR_OFFSET 0x18 -+#define GPCR_OFFSET 0x24 -+#define GRER_OFFSET 0x30 -+#define GFER_OFFSET 0x3C -+#define GEDR_OFFSET 0x48 -+ - #define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */ - #define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */ - #define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch b/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch deleted file mode 100644 index e460379de6..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 7ba82399f2d2df6114ad552999f2e1b9a19cb47a Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell@users.sourceforge.net> -Date: Sat, 19 Jan 2008 19:41:18 +0300 -Subject: [PATCH 24/64] Update Documentation/gpio.txt, primarily to include the new "gpiolib" - infrastructure. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Cc: Jean Delvare <khali@linux-fr.org> -Cc: Eric Miao <eric.miao@marvell.com> -Cc: Sam Ravnborg <sam@ravnborg.org> -Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> -Cc: Philipp Zabel <philipp.zabel@gmail.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Ben Gardner <bgardner@wabtec.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> ---- - Documentation/gpio.txt | 133 +++++++++++++++++++++++++++++++++++++++++++---- - 1 files changed, 121 insertions(+), 12 deletions(-) - -diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt -index 6bc2ba2..8da724e 100644 ---- a/Documentation/gpio.txt -+++ b/Documentation/gpio.txt -@@ -32,7 +32,7 @@ The exact capabilities of GPIOs vary between systems. Common options: - - Input values are likewise readable (1, 0). Some chips support readback - of pins configured as "output", which is very useful in such "wire-OR" - cases (to support bidirectional signaling). GPIO controllers may have -- input de-glitch logic, sometimes with software controls. -+ input de-glitch/debounce logic, sometimes with software controls. - - - Inputs can often be used as IRQ signals, often edge triggered but - sometimes level triggered. Such IRQs may be configurable as system -@@ -60,10 +60,13 @@ used on a board that's wired differently. Only least-common-denominator - functionality can be very portable. Other features are platform-specific, - and that can be critical for glue logic. - --Plus, this doesn't define an implementation framework, just an interface. -+Plus, this doesn't require any implementation framework, just an interface. - One platform might implement it as simple inline functions accessing chip - registers; another might implement it by delegating through abstractions --used for several very different kinds of GPIO controller. -+used for several very different kinds of GPIO controller. (There is some -+optional code supporting such an implementation strategy, described later -+in this document, but drivers acting as clients to the GPIO interface must -+not care how it's implemented.) - - That said, if the convention is supported on their platform, drivers should - use it when possible. Platforms should declare GENERIC_GPIO support in -@@ -121,6 +124,11 @@ before tasking is enabled, as part of early board setup. - For output GPIOs, the value provided becomes the initial output value. - This helps avoid signal glitching during system startup. - -+For compatibility with legacy interfaces to GPIOs, setting the direction -+of a GPIO implicitly requests that GPIO (see below) if it has not been -+requested already. That compatibility may be removed in the future; -+explicitly requesting GPIOs is strongly preferred. -+ - Setting the direction can fail if the GPIO number is invalid, or when - that particular GPIO can't be used in that mode. It's generally a bad - idea to rely on boot firmware to have set the direction correctly, since -@@ -133,6 +141,7 @@ Spinlock-Safe GPIO access - ------------------------- - Most GPIO controllers can be accessed with memory read/write instructions. - That doesn't need to sleep, and can safely be done from inside IRQ handlers. -+(That includes hardirq contexts on RT kernels.) - - Use these calls to access such GPIOs: - -@@ -145,7 +154,7 @@ Use these calls to access such GPIOs: - The values are boolean, zero for low, nonzero for high. When reading the - value of an output pin, the value returned should be what's seen on the - pin ... that won't always match the specified output value, because of --issues including wire-OR and output latencies. -+issues including open-drain signaling and output latencies. - - The get/set calls have no error returns because "invalid GPIO" should have - been reported earlier from gpio_direction_*(). However, note that not all -@@ -170,7 +179,8 @@ get to the head of a queue to transmit a command and get its response. - This requires sleeping, which can't be done from inside IRQ handlers. - - Platforms that support this type of GPIO distinguish them from other GPIOs --by returning nonzero from this call: -+by returning nonzero from this call (which requires a valid GPIO number, -+either explicitly or implicitly requested): - - int gpio_cansleep(unsigned gpio); - -@@ -209,8 +219,11 @@ before tasking is enabled, as part of early board setup. - These calls serve two basic purposes. One is marking the signals which - are actually in use as GPIOs, for better diagnostics; systems may have - several hundred potential GPIOs, but often only a dozen are used on any --given board. Another is to catch conflicts between drivers, reporting --errors when drivers wrongly think they have exclusive use of that signal. -+given board. Another is to catch conflicts, identifying errors when -+(a) two or more drivers wrongly think they have exclusive use of that -+signal, or (b) something wrongly believes it's safe to remove drivers -+needed to manage a signal that's in active use. That is, requesting a -+GPIO can serve as a kind of lock. - - These two calls are optional because not not all current Linux platforms - offer such functionality in their GPIO support; a valid implementation -@@ -223,6 +236,9 @@ Note that requesting a GPIO does NOT cause it to be configured in any - way; it just marks that GPIO as in use. Separate code must handle any - pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown). - -+Also note that it's your responsibility to have stopped using a GPIO -+before you free it. -+ - - GPIOs mapped to IRQs - -------------------- -@@ -238,7 +254,7 @@ map between them using calls like: - - Those return either the corresponding number in the other namespace, or - else a negative errno code if the mapping can't be done. (For example, --some GPIOs can't used as IRQs.) It is an unchecked error to use a GPIO -+some GPIOs can't be used as IRQs.) It is an unchecked error to use a GPIO - number that wasn't set up as an input using gpio_direction_input(), or - to use an IRQ number that didn't originally come from gpio_to_irq(). - -@@ -299,17 +315,110 @@ Related to multiplexing is configuration and enabling of the pullups or - pulldowns integrated on some platforms. Not all platforms support them, - or support them in the same way; and any given board might use external - pullups (or pulldowns) so that the on-chip ones should not be used. -+(When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.) - - There are other system-specific mechanisms that are not specified here, - like the aforementioned options for input de-glitching and wire-OR output. - Hardware may support reading or writing GPIOs in gangs, but that's usually - configuration dependent: for GPIOs sharing the same bank. (GPIOs are - commonly grouped in banks of 16 or 32, with a given SOC having several such --banks.) Some systems can trigger IRQs from output GPIOs. Code relying on --such mechanisms will necessarily be nonportable. -+banks.) Some systems can trigger IRQs from output GPIOs, or read values -+from pins not managed as GPIOs. Code relying on such mechanisms will -+necessarily be nonportable. - --Dynamic definition of GPIOs is not currently supported; for example, as -+Dynamic definition of GPIOs is not currently standard; for example, as - a side effect of configuring an add-on board with some GPIO expanders. - - These calls are purely for kernel space, but a userspace API could be built --on top of it. -+on top of them. -+ -+ -+GPIO implementor's framework (OPTIONAL) -+======================================= -+As noted earlier, there is an optional implementation framework making it -+easier for platforms to support different kinds of GPIO controller using -+the same programming interface. -+ -+As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file -+will be found there. That will list all the controllers registered through -+this framework, and the state of the GPIOs currently in use. -+ -+ -+Controller Drivers: gpio_chip -+----------------------------- -+In this framework each GPIO controller is packaged as a "struct gpio_chip" -+with information common to each controller of that type: -+ -+ - methods to establish GPIO direction -+ - methods used to access GPIO values -+ - flag saying whether calls to its methods may sleep -+ - optional debugfs dump method (showing extra state like pullup config) -+ - label for diagnostics -+ -+There is also per-instance data, which may come from device.platform_data: -+the number of its first GPIO, and how many GPIOs it exposes. -+ -+The code implementing a gpio_chip should support multiple instances of the -+controller, possibly using the driver model. That code will configure each -+gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be -+rare; use gpiochip_remove() when it is unavoidable. -+ -+Most often a gpio_chip is part of an instance-specific structure with state -+not exposed by the GPIO interfaces, such as addressing, power management, -+and more. Chips such as codecs will have complex non-GPIO state, -+ -+Any debugfs dump method should normally ignore signals which haven't been -+requested as GPIOs. They can use gpiochip_is_requested(), which returns -+either NULL or the label associated with that GPIO when it was requested. -+ -+ -+Platform Support -+---------------- -+To support this framework, a platform's Kconfig will "select HAVE_GPIO_LIB" -+and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines -+three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep(). -+They may also want to provide a custom value for ARCH_NR_GPIOS. -+ -+Trivial implementations of those functions can directly use framework -+code, which always dispatches through the gpio_chip: -+ -+ #define gpio_get_value __gpio_get_value -+ #define gpio_set_value __gpio_set_value -+ #define gpio_cansleep __gpio_cansleep -+ -+Fancier implementations could instead define those as inline functions with -+logic optimizing access to specific SOC-based GPIOs. For example, if the -+referenced GPIO is the constant "12", getting or setting its value could -+cost as little as two or three instructions, never sleeping. When such an -+optimization is not possible those calls must delegate to the framework -+code, costing at least a few dozen instructions. For bitbanged I/O, such -+instruction savings can be significant. -+ -+For SOCs, platform-specific code defines and registers gpio_chip instances -+for each bank of on-chip GPIOs. Those GPIOs should be numbered/labeled to -+match chip vendor documentation, and directly match board schematics. They -+may well start at zero and go up to a platform-specific limit. Such GPIOs -+are normally integrated into platform initialization to make them always be -+available, from arch_initcall() or earlier; they can often serve as IRQs. -+ -+ -+Board Support -+------------- -+For external GPIO controllers -- such as I2C or SPI expanders, ASICs, multi -+function devices, FPGAs or CPLDs -- most often board-specific code handles -+registering controller devices and ensures that their drivers know what GPIO -+numbers to use with gpiochip_add(). Their numbers often start right after -+platform-specific GPIOs. -+ -+For example, board setup code could create structures identifying the range -+of GPIOs that chip will expose, and passes them to each GPIO expander chip -+using platform_data. Then the chip driver's probe() routine could pass that -+data to gpiochip_add(). -+ -+Initialization order can be important. For example, when a device relies on -+an I2C-based GPIO, its probe() routine should only be called after that GPIO -+becomes available. That may mean the device should not be registered until -+calls for that GPIO can work. One way to address such dependencies is for -+such gpio_chip controllers to provide setup() and teardown() callbacks to -+board specific code; those board specific callbacks would register devices -+once all the necessary resources are available. --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch b/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch deleted file mode 100644 index 84d0fd3e19..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch +++ /dev/null @@ -1,434 +0,0 @@ -From 39717c1328f6aa13330eded0e0e268993cfd1eea Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Tue, 12 Feb 2008 10:39:53 +0300 -Subject: [PATCH 25/64] Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> - ---- - arch/arm/mach-pxa/Makefile | 2 +- - arch/arm/mach-pxa/devices.c | 401 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 402 insertions(+), 1 deletions(-) - create mode 100644 arch/arm/mach-pxa/devices.c - -diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile -index 5cb0216..f276d24 100644 ---- a/arch/arm/mach-pxa/Makefile -+++ b/arch/arm/mach-pxa/Makefile -@@ -4,7 +4,7 @@ - - # Common support (must be linked before board specific support) - obj-y += clock.o generic.o irq.o dma.o \ -- time.o gpio.o -+ time.o gpio.o devices.o - obj-$(CONFIG_PXA25x) += pxa25x.o - obj-$(CONFIG_PXA27x) += pxa27x.o - obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o -diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c -new file mode 100644 -index 0000000..928131a ---- /dev/null -+++ b/arch/arm/mach-pxa/devices.c -@@ -0,0 +1,401 @@ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> -+#include <linux/dma-mapping.h> -+ -+#include <asm/arch/gpio.h> -+#include <asm/arch/udc.h> -+#include <asm/arch/pxafb.h> -+#include <asm/arch/mmc.h> -+#include <asm/arch/irda.h> -+#include <asm/arch/i2c.h> -+#include <asm/arch/ohci.h> -+ -+#include "devices.h" -+ -+#ifdef CONFIG_PXA25x -+ -+static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa25x_resource_ssp[] = { -+ [0] = { -+ .start = 0x41000000, -+ .end = 0x4100001f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_SSP, -+ .end = IRQ_SSP, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 13, -+ .end = 13, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 14, -+ .end = 14, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa25x_device_ssp = { -+ .name = "pxa25x-ssp", -+ .id = 0, -+ .dev = { -+ .dma_mask = &pxa25x_ssp_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa25x_resource_ssp, -+ .num_resources = ARRAY_SIZE(pxa25x_resource_ssp), -+}; -+ -+static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa25x_resource_nssp[] = { -+ [0] = { -+ .start = 0x41400000, -+ .end = 0x4140002f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_NSSP, -+ .end = IRQ_NSSP, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 15, -+ .end = 15, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 16, -+ .end = 16, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa25x_device_nssp = { -+ .name = "pxa25x-nssp", -+ .id = 1, -+ .dev = { -+ .dma_mask = &pxa25x_nssp_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa25x_resource_nssp, -+ .num_resources = ARRAY_SIZE(pxa25x_resource_nssp), -+}; -+ -+static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa25x_resource_assp[] = { -+ [0] = { -+ .start = 0x41500000, -+ .end = 0x4150002f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_ASSP, -+ .end = IRQ_ASSP, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 23, -+ .end = 23, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 24, -+ .end = 24, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa25x_device_assp = { -+ /* ASSP is basically equivalent to NSSP */ -+ .name = "pxa25x-nssp", -+ .id = 2, -+ .dev = { -+ .dma_mask = &pxa25x_assp_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa25x_resource_assp, -+ .num_resources = ARRAY_SIZE(pxa25x_resource_assp), -+}; -+#endif /* CONFIG_PXA25x */ -+ -+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -+ -+static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa27x_resource_ohci[] = { -+ [0] = { -+ .start = 0x4C000000, -+ .end = 0x4C00ff6f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_USBH1, -+ .end = IRQ_USBH1, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+struct platform_device pxa27x_device_ohci = { -+ .name = "pxa27x-ohci", -+ .id = -1, -+ .dev = { -+ .dma_mask = &pxa27x_ohci_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .num_resources = ARRAY_SIZE(pxa27x_resource_ohci), -+ .resource = pxa27x_resource_ohci, -+}; -+ -+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) -+{ -+ pxa_register_device(&pxa27x_device_ohci, info); -+} -+ -+static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa27x_resource_ssp1[] = { -+ [0] = { -+ .start = 0x41000000, -+ .end = 0x4100003f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_SSP, -+ .end = IRQ_SSP, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 13, -+ .end = 13, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 14, -+ .end = 14, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa27x_device_ssp1 = { -+ .name = "pxa27x-ssp", -+ .id = 0, -+ .dev = { -+ .dma_mask = &pxa27x_ssp1_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa27x_resource_ssp1, -+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1), -+}; -+ -+static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa27x_resource_ssp2[] = { -+ [0] = { -+ .start = 0x41700000, -+ .end = 0x4170003f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_SSP2, -+ .end = IRQ_SSP2, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 15, -+ .end = 15, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 16, -+ .end = 16, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa27x_device_ssp2 = { -+ .name = "pxa27x-ssp", -+ .id = 1, -+ .dev = { -+ .dma_mask = &pxa27x_ssp2_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa27x_resource_ssp2, -+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2), -+}; -+ -+static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa27x_resource_ssp3[] = { -+ [0] = { -+ .start = 0x41900000, -+ .end = 0x4190003f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_SSP3, -+ .end = IRQ_SSP3, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 66, -+ .end = 66, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 67, -+ .end = 67, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa27x_device_ssp3 = { -+ .name = "pxa27x-ssp", -+ .id = 2, -+ .dev = { -+ .dma_mask = &pxa27x_ssp3_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa27x_resource_ssp3, -+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), -+}; -+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ -+ -+#ifdef CONFIG_PXA3xx -+static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32); -+ -+static struct resource pxa3xx_resource_ssp4[] = { -+ [0] = { -+ .start = 0x41a00000, -+ .end = 0x41a0003f, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_SSP4, -+ .end = IRQ_SSP4, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ /* DRCMR for RX */ -+ .start = 2, -+ .end = 2, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ /* DRCMR for TX */ -+ .start = 3, -+ .end = 3, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa3xx_device_ssp4 = { -+ /* PXA3xx SSP is basically equivalent to PXA27x */ -+ .name = "pxa27x-ssp", -+ .id = 3, -+ .dev = { -+ .dma_mask = &pxa3xx_ssp4_dma_mask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, -+ .resource = pxa3xx_resource_ssp4, -+ .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4), -+}; -+ -+static struct resource pxa3xx_resources_mci2[] = { -+ [0] = { -+ .start = 0x42000000, -+ .end = 0x42000fff, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_MMC2, -+ .end = IRQ_MMC2, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ .start = 93, -+ .end = 93, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ .start = 94, -+ .end = 94, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa3xx_device_mci2 = { -+ .name = "pxa2xx-mci", -+ .id = 1, -+ .dev = { -+ .dma_mask = &pxamci_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2), -+ .resource = pxa3xx_resources_mci2, -+}; -+ -+void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info) -+{ -+ pxa_register_device(&pxa3xx_device_mci2, info); -+} -+ -+static struct resource pxa3xx_resources_mci3[] = { -+ [0] = { -+ .start = 0x42500000, -+ .end = 0x42500fff, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_MMC3, -+ .end = IRQ_MMC3, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [2] = { -+ .start = 100, -+ .end = 100, -+ .flags = IORESOURCE_DMA, -+ }, -+ [3] = { -+ .start = 101, -+ .end = 101, -+ .flags = IORESOURCE_DMA, -+ }, -+}; -+ -+struct platform_device pxa3xx_device_mci3 = { -+ .name = "pxa2xx-mci", -+ .id = 2, -+ .dev = { -+ .dma_mask = &pxamci_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3), -+ .resource = pxa3xx_resources_mci3, -+}; -+ -+void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) -+{ -+ pxa_register_device(&pxa3xx_device_mci3, info); -+} -+ -+#endif /* CONFIG_PXA3xx */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch b/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch deleted file mode 100644 index e1323e4edc..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch +++ /dev/null @@ -1,134 +0,0 @@ -From cbe46408b666983284e8be290950d526dbc0f0a4 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:08:16 +0300 -Subject: [PATCH 26/64] I don't think we should check for IRQs when determining which one - of power supplies to register. Better use is_{ac,usb}_online - callbacks, this will not produce an obstacle to implement polling -- - when irqs aren't mandatory. I'll send my two pending patches to show - the idea. - -For this particular issue, I think something like that should work. -If it works for you, I'll commit that version, preserving your -authorship, of course. ---- - drivers/power/pda_power.c | 80 ++++++++++++++++++++++++-------------------- - 1 files changed, 44 insertions(+), 36 deletions(-) - -diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c -index c058f28..d98622f 100644 ---- a/drivers/power/pda_power.c -+++ b/drivers/power/pda_power.c -@@ -168,66 +168,74 @@ static int pda_power_probe(struct platform_device *pdev) - pda_power_supplies[1].num_supplicants = pdata->num_supplicants; - } - -- ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); -- if (ret) { -- dev_err(dev, "failed to register %s power supply\n", -- pda_power_supplies[0].name); -- goto supply0_failed; -- } -+ if (pdata->is_ac_online) { -+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); -+ if (ret) { -+ dev_err(dev, "failed to register %s power supply\n", -+ pda_power_supplies[0].name); -+ goto ac_supply_failed; -+ } - -- ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); -- if (ret) { -- dev_err(dev, "failed to register %s power supply\n", -- pda_power_supplies[1].name); -- goto supply1_failed; -+ if (ac_irq) { -+ ret = request_irq(ac_irq->start, power_changed_isr, -+ get_irq_flags(ac_irq), ac_irq->name, -+ &pda_power_supplies[0]); -+ if (ret) { -+ dev_err(dev, "request ac irq failed\n"); -+ goto ac_irq_failed; -+ } -+ } - } - -- if (ac_irq) { -- ret = request_irq(ac_irq->start, power_changed_isr, -- get_irq_flags(ac_irq), ac_irq->name, -- &pda_power_supplies[0]); -+ if (pdata->is_usb_online) { -+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); - if (ret) { -- dev_err(dev, "request ac irq failed\n"); -- goto ac_irq_failed; -+ dev_err(dev, "failed to register %s power supply\n", -+ pda_power_supplies[1].name); -+ goto usb_supply_failed; - } -- } - -- if (usb_irq) { -- ret = request_irq(usb_irq->start, power_changed_isr, -- get_irq_flags(usb_irq), usb_irq->name, -- &pda_power_supplies[1]); -- if (ret) { -- dev_err(dev, "request usb irq failed\n"); -- goto usb_irq_failed; -+ if (usb_irq) { -+ ret = request_irq(usb_irq->start, power_changed_isr, -+ get_irq_flags(usb_irq), -+ usb_irq->name, -+ &pda_power_supplies[1]); -+ if (ret) { -+ dev_err(dev, "request usb irq failed\n"); -+ goto usb_irq_failed; -+ } - } - } - -- goto success; -+ return 0; - - usb_irq_failed: -- if (ac_irq) -+ if (pdata->is_usb_online) -+ power_supply_unregister(&pda_power_supplies[1]); -+usb_supply_failed: -+ if (pdata->is_ac_online && ac_irq) - free_irq(ac_irq->start, &pda_power_supplies[0]); - ac_irq_failed: -- power_supply_unregister(&pda_power_supplies[1]); --supply1_failed: -- power_supply_unregister(&pda_power_supplies[0]); --supply0_failed: -+ if (pdata->is_ac_online) -+ power_supply_unregister(&pda_power_supplies[0]); -+ac_supply_failed: - noirqs: - wrongid: --success: - return ret; - } - - static int pda_power_remove(struct platform_device *pdev) - { -- if (usb_irq) -+ if (pdata->is_usb_online && usb_irq) - free_irq(usb_irq->start, &pda_power_supplies[1]); -- if (ac_irq) -+ if (pdata->is_ac_online && ac_irq) - free_irq(ac_irq->start, &pda_power_supplies[0]); - del_timer_sync(&charger_timer); - del_timer_sync(&supply_timer); -- power_supply_unregister(&pda_power_supplies[1]); -- power_supply_unregister(&pda_power_supplies[0]); -+ if (pdata->is_usb_online) -+ power_supply_unregister(&pda_power_supplies[1]); -+ if (pdata->is_ac_online) -+ power_supply_unregister(&pda_power_supplies[0]); - return 0; - } - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch b/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch deleted file mode 100644 index 240d2d0bd9..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e5e9808fd5ed9cb54dd9da9fb91b32c4f7e9da52 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:08:17 +0300 -Subject: [PATCH 27/64] Add LiMn (one of the most common for small non-rechargable batteries)i - battery technology and voltage_min/_max properties support. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/power/power_supply_sysfs.c | 5 ++++- - include/linux/power_supply.h | 3 +++ - 2 files changed, 7 insertions(+), 1 deletions(-) - -diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c -index 249f61b..45d2f95 100644 ---- a/drivers/power/power_supply_sysfs.c -+++ b/drivers/power/power_supply_sysfs.c -@@ -46,7 +46,8 @@ static ssize_t power_supply_show_property(struct device *dev, - "Unspecified failure" - }; - static char *technology_text[] = { -- "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd" -+ "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd", -+ "LiMn" - }; - static char *capacity_level_text[] = { - "Unknown", "Critical", "Low", "Normal", "High", "Full" -@@ -88,6 +89,8 @@ static struct device_attribute power_supply_attrs[] = { - POWER_SUPPLY_ATTR(present), - POWER_SUPPLY_ATTR(online), - POWER_SUPPLY_ATTR(technology), -+ POWER_SUPPLY_ATTR(voltage_max), -+ POWER_SUPPLY_ATTR(voltage_min), - POWER_SUPPLY_ATTR(voltage_max_design), - POWER_SUPPLY_ATTR(voltage_min_design), - POWER_SUPPLY_ATTR(voltage_now), -diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h -index 606c095..cdbc5b8 100644 ---- a/include/linux/power_supply.h -+++ b/include/linux/power_supply.h -@@ -54,6 +54,7 @@ enum { - POWER_SUPPLY_TECHNOLOGY_LIPO, - POWER_SUPPLY_TECHNOLOGY_LiFe, - POWER_SUPPLY_TECHNOLOGY_NiCd, -+ POWER_SUPPLY_TECHNOLOGY_LiMn, - }; - - enum { -@@ -72,6 +73,8 @@ enum power_supply_property { - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch b/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch deleted file mode 100644 index ac5df97dff..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch +++ /dev/null @@ -1,72 +0,0 @@ -From df0801d2cd6a7081700c79f437d1185cbe1960a7 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:08:18 +0300 -Subject: [PATCH 28/64] Add suspend/resume/wakeup support for pda_power. - Now with device_init_wakeup. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/power/pda_power.c | 34 ++++++++++++++++++++++++++++++++++ - 1 files changed, 34 insertions(+), 0 deletions(-) - -diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c -index d98622f..28360e8 100644 ---- a/drivers/power/pda_power.c -+++ b/drivers/power/pda_power.c -@@ -207,6 +207,8 @@ static int pda_power_probe(struct platform_device *pdev) - } - } - -+ device_init_wakeup(&pdev->dev, 1); -+ - return 0; - - usb_irq_failed: -@@ -239,12 +241,44 @@ static int pda_power_remove(struct platform_device *pdev) - return 0; - } - -+#ifdef CONFIG_PM -+static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ if (device_may_wakeup(&pdev->dev)) { -+ if (ac_irq) -+ enable_irq_wake(ac_irq->start); -+ if (usb_irq) -+ enable_irq_wake(usb_irq->start); -+ } -+ -+ return 0; -+} -+ -+static int pda_power_resume(struct platform_device *pdev) -+{ -+ if (device_may_wakeup(&pdev->dev)) { -+ if (usb_irq) -+ disable_irq_wake(usb_irq->start); -+ if (ac_irq) -+ disable_irq_wake(ac_irq->start); -+ } -+ -+ return 0; -+} -+#else -+#define pda_power_suspend NULL -+#define pda_power_resume NULL -+#endif -+ -+ - static struct platform_driver pda_power_pdrv = { - .driver = { - .name = "pda-power", - }, - .probe = pda_power_probe, - .remove = pda_power_remove, -+ .suspend = pda_power_suspend, -+ .resume = pda_power_resume, - }; - - static int __init pda_power_init(void) --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch b/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch deleted file mode 100644 index 7347fd5a00..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 57d1450b4e5f27fa78c75895dc30213bde7191bc Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:08:18 +0300 -Subject: [PATCH 29/64] Support using VOLTAGE_* properties for apm calculations. It's pretty - dummy, but useful for batteries for which we can only get voltages. - ---- - drivers/power/apm_power.c | 63 ++++++++++++++++++++++++++++++++++++-------- - 1 files changed, 51 insertions(+), 12 deletions(-) - -diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c -index bbf3ee1..526c96e 100644 ---- a/drivers/power/apm_power.c -+++ b/drivers/power/apm_power.c -@@ -13,6 +13,12 @@ - #include <linux/power_supply.h> - #include <linux/apm-emulation.h> - -+typedef enum { -+ SOURCE_ENERGY, -+ SOURCE_CHARGE, -+ SOURCE_VOLTAGE, -+} apm_source; -+ - #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ - POWER_SUPPLY_PROP_##prop, val) - -@@ -87,7 +93,7 @@ static void find_main_battery(void) - } - } - --static int calculate_time(int status, int using_charge) -+static int calculate_time(int status, apm_source source) - { - union power_supply_propval full; - union power_supply_propval empty; -@@ -106,20 +112,34 @@ static int calculate_time(int status, int using_charge) - return -1; - } - -- if (using_charge) { -+ switch (source) { -+ case SOURCE_CHARGE: - full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; - full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; - empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; - empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; - cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; - cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; -- } else { -+ break; -+ case SOURCE_ENERGY: - full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; - full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; - empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; - empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; - cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; - cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; -+ break; -+ case SOURCE_VOLTAGE: -+ full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; -+ full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; -+ empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; -+ empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; -+ cur_avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; -+ cur_now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; -+ break; -+ default: -+ printk(KERN_ERR "Unsupported source: %d\n", source); -+ return -1; - } - - if (_MPSY_PROP(full_prop, &full)) { -@@ -146,7 +166,7 @@ static int calculate_time(int status, int using_charge) - return -((cur.intval - empty.intval) * 60L) / I.intval; - } - --static int calculate_capacity(int using_charge) -+static int calculate_capacity(apm_source source) - { - enum power_supply_property full_prop, empty_prop; - enum power_supply_property full_design_prop, empty_design_prop; -@@ -154,20 +174,33 @@ static int calculate_capacity(int using_charge) - union power_supply_propval empty, full, cur; - int ret; - -- if (using_charge) { -+ switch (source) { -+ case SOURCE_CHARGE: - full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; - empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; - full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; - empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN; - now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; - avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; -- } else { -+ break; -+ case SOURCE_ENERGY: - full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; - empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; - full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; - empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; - now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; - avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; -+ case SOURCE_VOLTAGE: -+ full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; -+ empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; -+ full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; -+ empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; -+ now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; -+ avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; -+ break; -+ default: -+ printk(KERN_ERR "Unsupported source: %d\n", source); -+ return -1; - } - - if (_MPSY_PROP(full_prop, &full)) { -@@ -234,10 +267,12 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info) - info->battery_life = capacity.intval; - } else { - /* try calculate using energy */ -- info->battery_life = calculate_capacity(0); -+ info->battery_life = calculate_capacity(SOURCE_ENERGY); - /* if failed try calculate using charge instead */ - if (info->battery_life == -1) -- info->battery_life = calculate_capacity(1); -+ info->battery_life = calculate_capacity(SOURCE_CHARGE); -+ if (info->battery_life == -1) -+ info->battery_life = calculate_capacity(SOURCE_VOLTAGE); - } - - /* charging status */ -@@ -263,18 +298,22 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info) - !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) { - info->time = time_to_full.intval / 60; - } else { -- info->time = calculate_time(status.intval, 0); -+ info->time = calculate_time(status.intval, SOURCE_ENERGY); - if (info->time == -1) -- info->time = calculate_time(status.intval, 1); -+ info->time = calculate_time(status.intval, SOURCE_CHARGE); -+ if (info->time == -1) -+ info->time = calculate_time(status.intval, SOURCE_VOLTAGE); - } - } else { - if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) || - !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) { - info->time = time_to_empty.intval / 60; - } else { -- info->time = calculate_time(status.intval, 0); -+ info->time = calculate_time(status.intval, SOURCE_ENERGY); -+ if (info->time == -1) -+ info->time = calculate_time(status.intval, SOURCE_CHARGE); - if (info->time == -1) -- info->time = calculate_time(status.intval, 1); -+ info->time = calculate_time(status.intval, SOURCE_VOLTAGE); - } - } - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch b/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch deleted file mode 100644 index 1c86a39c74..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch +++ /dev/null @@ -1,1083 +0,0 @@ -From d3e044e0e10e6c6b75716cb927e92b4ec284132f Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:20 +0300 -Subject: [PATCH 30/64] Core driver for WM97xx touchscreens - -This patch series adds support for the touchscreen controllers provided -by Wolfson Microelectronics WM97xx series chips in both polled and -streaming modes. - -These drivers have been maintained out of tree since 2003. During that -time the driver the primary maintainer was Liam Girdwood and a number of -people have made contributions including Stanley Cai, Rodolfo Giometti, -Russell King, Marc Kleine-Budde, Ian Molton, Vincent Sanders, Andrew -Zabolotny, Graeme Gregory, Mike Arthur and myself. Apologies to anyone -I have omitted. - -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> -Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com> -Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> -Cc: Stanley Cai <stanley.cai@intel.com> -Cc: Rodolfo Giometti <giometti@enneenne.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Marc Kleine-Budde <mkl@pengutronix.de> -Cc: Ian Molton <spyro@f2s.com> -Cc: Vincent Sanders <vince@kyllikki.org> -Cc: Andrew Zabolotny <zap@homelink.ru> ---- - drivers/input/touchscreen/wm97xx-core.c | 724 +++++++++++++++++++++++++++++++ - include/linux/wm97xx.h | 309 +++++++++++++ - 2 files changed, 1033 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/wm97xx-core.c - create mode 100644 include/linux/wm97xx.h - -diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c -new file mode 100644 -index 0000000..27a0a99 ---- /dev/null -+++ b/drivers/input/touchscreen/wm97xx-core.c -@@ -0,0 +1,724 @@ -+/* -+ * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712 -+ * and WM9713 AC97 Codecs. -+ * -+ * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. -+ * Author: Liam Girdwood -+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com -+ * Parts Copyright : Ian Molton <spyro@f2s.com> -+ * Andrew Zabolotny <zap@homelink.ru> -+ * Russell King <rmk@arm.linux.org.uk> -+ * -+ * 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. -+ * -+ * Notes: -+ * -+ * Features: -+ * - supports WM9705, WM9712, WM9713 -+ * - polling mode -+ * - continuous mode (arch-dependent) -+ * - adjustable rpu/dpp settings -+ * - adjustable pressure current -+ * - adjustable sample settle delay -+ * - 4 and 5 wire touchscreens (5 wire is WM9712 only) -+ * - pen down detection -+ * - battery monitor -+ * - sample AUX adcs -+ * - power management -+ * - codec GPIO -+ * - codec event notification -+ * Todo -+ * - Support for async sampling control for noisy LCDs. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/string.h> -+#include <linux/proc_fs.h> -+#include <linux/pm.h> -+#include <linux/interrupt.h> -+#include <linux/bitops.h> -+#include <linux/workqueue.h> -+#include <linux/wm97xx.h> -+#include <linux/uaccess.h> -+#include <linux/io.h> -+ -+#define TS_NAME "wm97xx" -+#define WM_CORE_VERSION "0.65" -+#define DEFAULT_PRESSURE 0xb0c0 -+ -+ -+/* -+ * Touchscreen absolute values -+ * -+ * These parameters are used to help the input layer discard out of -+ * range readings and reduce jitter etc. -+ * -+ * o min, max:- indicate the min and max values your touch screen returns -+ * o fuzz:- use a higher number to reduce jitter -+ * -+ * The default values correspond to Mainstone II in QVGA mode -+ * -+ * Please read -+ * Documentation/input/input-programming.txt for more details. -+ */ -+ -+static int abs_x[3] = {350, 3900, 5}; -+module_param_array(abs_x, int, NULL, 0); -+MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz"); -+ -+static int abs_y[3] = {320, 3750, 40}; -+module_param_array(abs_y, int, NULL, 0); -+MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz"); -+ -+static int abs_p[3] = {0, 150, 4}; -+module_param_array(abs_p, int, NULL, 0); -+MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz"); -+ -+/* -+ * wm97xx IO access, all IO locking done by AC97 layer -+ */ -+int wm97xx_reg_read(struct wm97xx *wm, u16 reg) -+{ -+ if (wm->ac97) -+ return wm->ac97->bus->ops->read(wm->ac97, reg); -+ else -+ return -1; -+} -+EXPORT_SYMBOL_GPL(wm97xx_reg_read); -+ -+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val) -+{ -+ /* cache digitiser registers */ -+ if (reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3) -+ wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val; -+ -+ /* cache gpio regs */ -+ if (reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE) -+ wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val; -+ -+ /* wm9713 irq reg */ -+ if (reg == 0x5a) -+ wm->misc = val; -+ -+ if (wm->ac97) -+ wm->ac97->bus->ops->write(wm->ac97, reg, val); -+} -+EXPORT_SYMBOL_GPL(wm97xx_reg_write); -+ -+/** -+ * wm97xx_read_aux_adc - Read the aux adc. -+ * @wm: wm97xx device. -+ * @adcsel: codec ADC to be read -+ * -+ * Reads the selected AUX ADC. -+ */ -+ -+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) -+{ -+ int power_adc = 0, auxval; -+ u16 power = 0; -+ -+ /* get codec */ -+ mutex_lock(&wm->codec_mutex); -+ -+ /* When the touchscreen is not in use, we may have to power up -+ * the AUX ADC before we can use sample the AUX inputs-> -+ */ -+ if (wm->id == WM9713_ID2 && -+ (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) { -+ power_adc = 1; -+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff); -+ } -+ -+ /* Prepare the codec for AUX reading */ -+ wm->codec->aux_prepare(wm); -+ -+ /* Turn polling mode on to read AUX ADC */ -+ wm->pen_probably_down = 1; -+ wm->codec->poll_sample(wm, adcsel, &auxval); -+ -+ if (power_adc) -+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); -+ -+ wm->codec->dig_restore(wm); -+ -+ wm->pen_probably_down = 0; -+ -+ mutex_unlock(&wm->codec_mutex); -+ return auxval & 0xfff; -+} -+EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); -+ -+/** -+ * wm97xx_get_gpio - Get the status of a codec GPIO. -+ * @wm: wm97xx device. -+ * @gpio: gpio -+ * -+ * Get the status of a codec GPIO pin -+ */ -+ -+enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio) -+{ -+ u16 status; -+ enum wm97xx_gpio_status ret; -+ -+ mutex_lock(&wm->codec_mutex); -+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); -+ -+ if (status & gpio) -+ ret = WM97XX_GPIO_HIGH; -+ else -+ ret = WM97XX_GPIO_LOW; -+ -+ mutex_unlock(&wm->codec_mutex); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(wm97xx_get_gpio); -+ -+/** -+ * wm97xx_set_gpio - Set the status of a codec GPIO. -+ * @wm: wm97xx device. -+ * @gpio: gpio -+ * -+ * -+ * Set the status of a codec GPIO pin -+ */ -+ -+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, -+ enum wm97xx_gpio_status status) -+{ -+ u16 reg; -+ -+ mutex_lock(&wm->codec_mutex); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS); -+ -+ if (status & WM97XX_GPIO_HIGH) -+ reg |= gpio; -+ else -+ reg &= ~gpio; -+ -+ if (wm->id == WM9712_ID2) -+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1); -+ else -+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg); -+ mutex_unlock(&wm->codec_mutex); -+} -+EXPORT_SYMBOL_GPL(wm97xx_set_gpio); -+ -+/* -+ * Codec GPIO pin configuration, this sets pin direction, polarity, -+ * stickyness and wake up. -+ */ -+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir, -+ enum wm97xx_gpio_pol pol, enum wm97xx_gpio_sticky sticky, -+ enum wm97xx_gpio_wake wake) -+{ -+ u16 reg; -+ -+ mutex_lock(&wm->codec_mutex); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); -+ -+ if (pol == WM97XX_GPIO_POL_HIGH) -+ reg |= gpio; -+ else -+ reg &= ~gpio; -+ -+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY); -+ -+ if (sticky == WM97XX_GPIO_STICKY) -+ reg |= gpio; -+ else -+ reg &= ~gpio; -+ -+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); -+ -+ if (wake == WM97XX_GPIO_WAKE) -+ reg |= gpio; -+ else -+ reg &= ~gpio; -+ -+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); -+ -+ if (dir == WM97XX_GPIO_IN) -+ reg |= gpio; -+ else -+ reg &= ~gpio; -+ -+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg); -+ mutex_unlock(&wm->codec_mutex); -+} -+EXPORT_SYMBOL_GPL(wm97xx_config_gpio); -+ -+/* -+ * Handle a pen down interrupt. -+ */ -+static void wm97xx_pen_irq_worker(struct work_struct *work) -+{ -+ struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work); -+ -+ /* do we need to enable the touch panel reader */ -+ if (wm->id == WM9705_ID2) { -+ if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & -+ WM97XX_PEN_DOWN) -+ wm->pen_is_down = 1; -+ else -+ wm->pen_is_down = 0; -+ } else { -+ u16 status, pol; -+ mutex_lock(&wm->codec_mutex); -+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); -+ pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); -+ -+ if (WM97XX_GPIO_13 & pol & status) { -+ wm->pen_is_down = 1; -+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & -+ ~WM97XX_GPIO_13); -+ } else { -+ wm->pen_is_down = 0; -+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | -+ WM97XX_GPIO_13); -+ } -+ -+ if (wm->id == WM9712_ID2) -+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & -+ ~WM97XX_GPIO_13) << 1); -+ else -+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & -+ ~WM97XX_GPIO_13); -+ mutex_unlock(&wm->codec_mutex); -+ } -+ -+ queue_delayed_work(wm->ts_workq, &wm->ts_reader, 0); -+ -+ if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled) -+ wm->mach_ops->acc_pen_up(wm); -+ wm->mach_ops->irq_enable(wm, 1); -+} -+ -+/* -+ * Codec PENDOWN irq handler -+ * -+ * We have to disable the codec interrupt in the handler because it can -+ * take upto 1ms to clear the interrupt source. The interrupt is then enabled -+ * again in the slow handler when the source has been cleared. -+ */ -+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) -+{ -+ struct wm97xx *wm = dev_id; -+ wm->mach_ops->irq_enable(wm, 0); -+ queue_work(wm->ts_workq, &wm->pen_event_work); -+ return IRQ_HANDLED; -+} -+ -+/* -+ * initialise pen IRQ handler and workqueue -+ */ -+static int wm97xx_init_pen_irq(struct wm97xx *wm) -+{ -+ u16 reg; -+ -+ /* If an interrupt is supplied an IRQ enable operation must also be -+ * provided. */ -+ BUG_ON(!wm->mach_ops->irq_enable); -+ -+ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker); -+ -+ if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, -+ "wm97xx-pen", wm)) { -+ dev_err(wm->dev, -+ "Failed to register pen down interrupt, polling"); -+ wm->pen_irq = 0; -+ return -EINVAL; -+ } -+ -+ /* enable PEN down on wm9712/13 */ -+ if (wm->id != WM9705_ID2) { -+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE); -+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb); -+ reg = wm97xx_reg_read(wm, 0x5a); -+ wm97xx_reg_write(wm, 0x5a, reg & ~0x0001); -+ } -+ -+ return 0; -+} -+ -+static int wm97xx_read_samples(struct wm97xx *wm) -+{ -+ struct wm97xx_data data; -+ int rc; -+ -+ mutex_lock(&wm->codec_mutex); -+ -+ if (wm->mach_ops && wm->mach_ops->acc_enabled) -+ rc = wm->mach_ops->acc_pen_down(wm); -+ else -+ rc = wm->codec->poll_touch(wm, &data); -+ -+ if (rc & RC_PENUP) { -+ if (wm->pen_is_down) { -+ wm->pen_is_down = 0; -+ dev_dbg(wm->dev, "pen up\n"); -+ input_report_abs(wm->input_dev, ABS_PRESSURE, 0); -+ input_sync(wm->input_dev); -+ } else if (!(rc & RC_AGAIN)) { -+ /* We need high frequency updates only while -+ * pen is down, the user never will be able to -+ * touch screen faster than a few times per -+ * second... On the other hand, when the user -+ * is actively working with the touchscreen we -+ * don't want to lose the quick response. So we -+ * will slowly increase sleep time after the -+ * pen is up and quicky restore it to ~one task -+ * switch when pen is down again. -+ */ -+ if (wm->ts_reader_interval < HZ / 10) -+ wm->ts_reader_interval++; -+ } -+ -+ } else if (rc & RC_VALID) { -+ dev_dbg(wm->dev, -+ "pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n", -+ data.x >> 12, data.x & 0xfff, data.y >> 12, -+ data.y & 0xfff, data.p >> 12, data.p & 0xfff); -+ input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); -+ input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); -+ input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); -+ input_sync(wm->input_dev); -+ wm->pen_is_down = 1; -+ wm->ts_reader_interval = wm->ts_reader_min_interval; -+ } else if (rc & RC_PENDOWN) { -+ dev_dbg(wm->dev, "pen down"); -+ wm->pen_is_down = 1; -+ wm->ts_reader_interval = wm->ts_reader_min_interval; -+ } -+ -+ mutex_unlock(&wm->codec_mutex); -+ return rc; -+} -+ -+/* -+* The touchscreen sample reader. -+*/ -+static void wm97xx_ts_reader(struct work_struct *work) -+{ -+ int rc; -+ struct wm97xx *wm = container_of(work, struct wm97xx, ts_reader.work); -+ -+ BUG_ON(!wm->codec); -+ -+ do { -+ rc = wm97xx_read_samples(wm); -+ } while (rc & RC_AGAIN); -+ -+ if (wm->pen_is_down || !wm->pen_irq) -+ queue_delayed_work(wm->ts_workq, &wm->ts_reader, -+ wm->ts_reader_interval); -+} -+ -+/** -+ * wm97xx_ts_input_open - Open the touch screen input device. -+ * @idev: Input device to be opened. -+ * -+ * Called by the input sub system to open a wm97xx touchscreen device. -+ * Starts the touchscreen thread and touch digitiser. -+ */ -+static int wm97xx_ts_input_open(struct input_dev *idev) -+{ -+ struct wm97xx *wm = input_get_drvdata(idev); -+ -+ wm->ts_workq = create_singlethread_workqueue("kwm97xx"); -+ if (wm->ts_workq == NULL) { -+ dev_err(wm->dev, -+ "Failed to create workqueue\n"); -+ return -EINVAL; -+ } -+ -+ /* start digitiser */ -+ if (wm->mach_ops && wm->mach_ops->acc_enabled) -+ wm->codec->acc_enable(wm, 1); -+ wm->codec->dig_enable(wm, 1); -+ -+ INIT_DELAYED_WORK(&wm->ts_reader, wm97xx_ts_reader); -+ -+ wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1; -+ if (wm->ts_reader_min_interval < 1) -+ wm->ts_reader_min_interval = 1; -+ wm->ts_reader_interval = wm->ts_reader_min_interval; -+ -+ wm->pen_is_down = 0; -+ if (wm->pen_irq) -+ wm97xx_init_pen_irq(wm); -+ else -+ dev_err(wm->dev, "No IRQ specified\n"); -+ -+ /* If we either don't have an interrupt for pen down events or -+ * failed to acquire it then we need to poll. -+ */ -+ if (wm->pen_irq == 0) -+ queue_delayed_work(wm->ts_workq, &wm->ts_reader, -+ wm->ts_reader_interval); -+ -+ return 0; -+} -+ -+/** -+ * wm97xx_ts_input_close - Close the touch screen input device. -+ * @idev: Input device to be closed. -+ * -+ * Called by the input sub system to close a wm97xx touchscreen device. -+ * Kills the touchscreen thread and stops the touch digitiser. -+ */ -+ -+static void wm97xx_ts_input_close(struct input_dev *idev) -+{ -+ struct wm97xx *wm = input_get_drvdata(idev); -+ -+ if (wm->pen_irq) -+ free_irq(wm->pen_irq, wm); -+ -+ wm->pen_is_down = 0; -+ -+ /* ts_reader rearms itself so we need to explicitly stop it -+ * before we destroy the workqueue. -+ */ -+ cancel_delayed_work_sync(&wm->ts_reader); -+ destroy_workqueue(wm->ts_workq); -+ -+ /* stop digitiser */ -+ wm->codec->dig_enable(wm, 0); -+ if (wm->mach_ops && wm->mach_ops->acc_enabled) -+ wm->codec->acc_enable(wm, 0); -+} -+ -+static int wm97xx_probe(struct device *dev) -+{ -+ struct wm97xx *wm; -+ int ret = 0, id = 0; -+ -+ wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); -+ if (!wm) -+ return -ENOMEM; -+ mutex_init(&wm->codec_mutex); -+ -+ wm->dev = dev; -+ dev->driver_data = wm; -+ wm->ac97 = to_ac97_t(dev); -+ -+ /* check that we have a supported codec */ -+ id = wm97xx_reg_read(wm, AC97_VENDOR_ID1); -+ if (id != WM97XX_ID1) { -+ dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id); -+ kfree(wm); -+ return -ENODEV; -+ } -+ -+ wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2); -+ -+ dev_info(wm->dev, "detected a wm97%02x codec", wm->id & 0xff); -+ -+ switch (wm->id & 0xff) { -+#ifdef CONFIG_TOUCHSCREEN_WM9705 -+ case 0x05: -+ wm->codec = &wm9705_codec; -+ break; -+#endif -+#ifdef CONFIG_TOUCHSCREEN_WM9712 -+ case 0x12: -+ wm->codec = &wm9712_codec; -+ break; -+#endif -+#ifdef CONFIG_TOUCHSCREEN_WM9713 -+ case 0x13: -+ wm->codec = &wm9713_codec; -+ break; -+#endif -+ default: -+ dev_err(wm->dev, "Support for wm97%02x not compiled in.\n", -+ wm->id & 0xff); -+ kfree(wm); -+ return -ENODEV; -+ } -+ -+ wm->input_dev = input_allocate_device(); -+ if (wm->input_dev == NULL) { -+ kfree(wm); -+ return -ENOMEM; -+ } -+ -+ /* set up touch configuration */ -+ wm->input_dev->name = "wm97xx touchscreen"; -+ wm->input_dev->open = wm97xx_ts_input_open; -+ wm->input_dev->close = wm97xx_ts_input_close; -+ set_bit(EV_ABS, wm->input_dev->evbit); -+ set_bit(ABS_X, wm->input_dev->absbit); -+ set_bit(ABS_Y, wm->input_dev->absbit); -+ set_bit(ABS_PRESSURE, wm->input_dev->absbit); -+ input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1], -+ abs_x[2], 0); -+ input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1], -+ abs_y[2], 0); -+ input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], -+ abs_p[2], 0); -+ input_set_drvdata(wm->input_dev, wm); -+ wm->input_dev->dev.parent = dev; -+ ret = input_register_device(wm->input_dev); -+ if (ret < 0) { -+ input_free_device(wm->input_dev); -+ kfree(wm); -+ return -ENOMEM; -+ } -+ -+ /* set up physical characteristics */ -+ wm->codec->phy_init(wm); -+ -+ /* load gpio cache */ -+ wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG); -+ wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); -+ wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY); -+ wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); -+ wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS); -+ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); -+ -+ /* register our battery device */ -+ wm->battery_dev = platform_device_alloc("wm97xx-battery", 0); -+ if (!wm->battery_dev) -+ goto batt_err; -+ platform_set_drvdata(wm->battery_dev, wm); -+ wm->battery_dev->dev.parent = dev; -+ ret = platform_device_register(wm->battery_dev); -+ if (ret < 0) -+ goto batt_reg_err; -+ -+ /* register our extended touch device (for machine specific -+ * extensions) */ -+ wm->touch_dev = platform_device_alloc("wm97xx-touch", 0); -+ if (!wm->touch_dev) -+ goto touch_err; -+ platform_set_drvdata(wm->touch_dev, wm); -+ wm->touch_dev->dev.parent = dev; -+ ret = platform_device_register(wm->touch_dev); -+ if (ret < 0) -+ goto touch_reg_err; -+ -+ return ret; -+ -+ touch_reg_err: -+ platform_device_put(wm->touch_dev); -+ touch_err: -+ platform_device_unregister(wm->battery_dev); -+ batt_reg_err: -+ platform_device_put(wm->battery_dev); -+ batt_err: -+ input_unregister_device(wm->input_dev); -+ kfree(wm); -+ return ret; -+} -+ -+static int wm97xx_remove(struct device *dev) -+{ -+ struct wm97xx *wm = dev_get_drvdata(dev); -+ -+ platform_device_unregister(wm->battery_dev); -+ platform_device_unregister(wm->touch_dev); -+ input_unregister_device(wm->input_dev); -+ -+ kfree(wm); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int wm97xx_resume(struct device *dev) -+{ -+ struct wm97xx *wm = dev_get_drvdata(dev); -+ -+ /* restore digitiser and gpios */ -+ if (wm->id == WM9713_ID2) { -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]); -+ wm97xx_reg_write(wm, 0x5a, wm->misc); -+ if (wm->input_dev->users) { -+ u16 reg; -+ reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff; -+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg); -+ } -+ } -+ -+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]); -+ -+ wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]); -+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]); -+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]); -+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]); -+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]); -+ wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]); -+ -+ return 0; -+} -+ -+#else -+#define wm97xx_resume NULL -+#endif -+ -+/* -+ * Machine specific operations -+ */ -+int wm97xx_register_mach_ops(struct wm97xx *wm, -+ struct wm97xx_mach_ops *mach_ops) -+{ -+ mutex_lock(&wm->codec_mutex); -+ if (wm->mach_ops) { -+ mutex_unlock(&wm->codec_mutex); -+ return -EINVAL; -+ } -+ wm->mach_ops = mach_ops; -+ mutex_unlock(&wm->codec_mutex); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops); -+ -+void wm97xx_unregister_mach_ops(struct wm97xx *wm) -+{ -+ mutex_lock(&wm->codec_mutex); -+ wm->mach_ops = NULL; -+ mutex_unlock(&wm->codec_mutex); -+} -+EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); -+ -+static struct device_driver wm97xx_driver = { -+ .name = "ac97", -+ .bus = &ac97_bus_type, -+ .owner = THIS_MODULE, -+ .probe = wm97xx_probe, -+ .remove = wm97xx_remove, -+ .resume = wm97xx_resume, -+}; -+ -+static int __init wm97xx_init(void) -+{ -+ return driver_register(&wm97xx_driver); -+} -+ -+static void __exit wm97xx_exit(void) -+{ -+ driver_unregister(&wm97xx_driver); -+} -+ -+module_init(wm97xx_init); -+module_exit(wm97xx_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); -+MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h -new file mode 100644 -index 0000000..fc6e0b3 ---- /dev/null -+++ b/include/linux/wm97xx.h -@@ -0,0 +1,309 @@ -+ -+/* -+ * Register bits and API for Wolfson WM97xx series of codecs -+ */ -+ -+#ifndef _LINUX_WM97XX_H -+#define _LINUX_WM97XX_H -+ -+#include <sound/driver.h> -+#include <sound/core.h> -+#include <sound/pcm.h> -+#include <sound/ac97_codec.h> -+#include <sound/initval.h> -+#include <linux/types.h> -+#include <linux/list.h> -+#include <linux/input.h> /* Input device layer */ -+#include <linux/platform_device.h> -+ -+/* -+ * WM97xx AC97 Touchscreen registers -+ */ -+#define AC97_WM97XX_DIGITISER1 0x76 -+#define AC97_WM97XX_DIGITISER2 0x78 -+#define AC97_WM97XX_DIGITISER_RD 0x7a -+#define AC97_WM9713_DIG1 0x74 -+#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1 -+#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2 -+ -+/* -+ * WM97xx register bits -+ */ -+#define WM97XX_POLL 0x8000 /* initiate a polling measurement */ -+#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ -+#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ -+#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ -+#define WM97XX_ADCSEL_MASK 0x7000 -+#define WM97XX_COO 0x0800 /* enable coordinate mode */ -+#define WM97XX_CTC 0x0400 /* enable continuous mode */ -+#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ -+#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */ -+#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */ -+#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */ -+#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */ -+#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */ -+#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */ -+#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */ -+#define WM97XX_CM_RATE_MASK 0x03f0 -+#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0)) -+#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */ -+#define WM97XX_DELAY_MASK 0x00f0 -+#define WM97XX_SLEN 0x0008 /* slot read back enable */ -+#define WM97XX_SLT(i) ((i - 5) & 0x7) /* panel slot (5-11) */ -+#define WM97XX_SLT_MASK 0x0007 -+#define WM97XX_PRP_DETW 0x4000 /* detect on, digitise off, wake */ -+#define WM97XX_PRP_DET 0x8000 /* detect on, digitise off, no wake */ -+#define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */ -+#define WM97XX_RPR 0x2000 /* wake up on pen down */ -+#define WM97XX_PEN_DOWN 0x8000 /* pen is down */ -+#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */ -+ -+#define WM97XX_AUX_ID1 0x8001 -+#define WM97XX_AUX_ID2 0x8002 -+#define WM97XX_AUX_ID3 0x8003 -+#define WM97XX_AUX_ID4 0x8004 -+ -+ -+/* WM9712 Bits */ -+#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ -+#define WM9712_PDEN 0x0800 /* measure only when pen down */ -+#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */ -+#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */ -+#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */ -+#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */ -+#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */ -+#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */ -+#define WM9712_PD(i) (0x1 << i) /* power management */ -+ -+/* WM9712 Registers */ -+#define AC97_WM9712_POWER 0x24 -+#define AC97_WM9712_REV 0x58 -+ -+/* WM9705 Bits */ -+#define WM9705_PDEN 0x1000 /* measure only when pen is down */ -+#define WM9705_PINV 0x0800 /* inverts sense of pen down output */ -+#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */ -+#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */ -+#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */ -+#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */ -+#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */ -+#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */ -+#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */ -+#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */ -+#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */ -+ -+ -+/* WM9713 Bits */ -+#define WM9713_PDPOL 0x0400 /* Pen down polarity */ -+#define WM9713_POLL 0x0200 /* initiate a polling measurement */ -+#define WM9713_CTC 0x0100 /* enable continuous mode */ -+#define WM9713_ADCSEL_X 0x0002 /* X measurement */ -+#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */ -+#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */ -+#define WM9713_COO 0x0001 /* enable coordinate mode */ -+#define WM9713_PDEN 0x0800 /* measure only when pen down */ -+#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */ -+#define WM9713_WAIT 0x0200 /* coordinate wait */ -+ -+/* AUX ADC ID's */ -+#define TS_COMP1 0x0 -+#define TS_COMP2 0x1 -+#define TS_BMON 0x2 -+#define TS_WIPER 0x3 -+ -+/* ID numbers */ -+#define WM97XX_ID1 0x574d -+#define WM9712_ID2 0x4c12 -+#define WM9705_ID2 0x4c05 -+#define WM9713_ID2 0x4c13 -+ -+/* Codec GPIO's */ -+#define WM97XX_MAX_GPIO 16 -+#define WM97XX_GPIO_1 (1 << 1) -+#define WM97XX_GPIO_2 (1 << 2) -+#define WM97XX_GPIO_3 (1 << 3) -+#define WM97XX_GPIO_4 (1 << 4) -+#define WM97XX_GPIO_5 (1 << 5) -+#define WM97XX_GPIO_6 (1 << 6) -+#define WM97XX_GPIO_7 (1 << 7) -+#define WM97XX_GPIO_8 (1 << 8) -+#define WM97XX_GPIO_9 (1 << 9) -+#define WM97XX_GPIO_10 (1 << 10) -+#define WM97XX_GPIO_11 (1 << 11) -+#define WM97XX_GPIO_12 (1 << 12) -+#define WM97XX_GPIO_13 (1 << 13) -+#define WM97XX_GPIO_14 (1 << 14) -+#define WM97XX_GPIO_15 (1 << 15) -+ -+ -+#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */ -+ -+ -+/*---------------- Return codes from sample reading functions ---------------*/ -+ -+/* More data is available; call the sample gathering function again */ -+#define RC_AGAIN 0x00000001 -+/* The returned sample is valid */ -+#define RC_VALID 0x00000002 -+/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */ -+#define RC_PENUP 0x00000004 -+/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful -+ to tell the handler that the pen is down but we don't know yet his coords, -+ so the handler should not sleep or wait for pendown irq) */ -+#define RC_PENDOWN 0x00000008 -+ -+/* -+ * The wm97xx driver provides a private API for writing platform-specific -+ * drivers. -+ */ -+ -+/* The structure used to return arch specific sampled data into */ -+struct wm97xx_data { -+ int x; -+ int y; -+ int p; -+}; -+ -+/* -+ * Codec GPIO status -+ */ -+enum wm97xx_gpio_status { -+ WM97XX_GPIO_HIGH, -+ WM97XX_GPIO_LOW -+}; -+ -+/* -+ * Codec GPIO direction -+ */ -+enum wm97xx_gpio_dir { -+ WM97XX_GPIO_IN, -+ WM97XX_GPIO_OUT -+}; -+ -+/* -+ * Codec GPIO polarity -+ */ -+enum wm97xx_gpio_pol { -+ WM97XX_GPIO_POL_HIGH, -+ WM97XX_GPIO_POL_LOW -+}; -+ -+/* -+ * Codec GPIO sticky -+ */ -+enum wm97xx_gpio_sticky { -+ WM97XX_GPIO_STICKY, -+ WM97XX_GPIO_NOTSTICKY -+}; -+ -+/* -+ * Codec GPIO wake -+ */ -+enum wm97xx_gpio_wake { -+ WM97XX_GPIO_WAKE, -+ WM97XX_GPIO_NOWAKE -+}; -+ -+/* -+ * Digitiser ioctl commands -+ */ -+#define WM97XX_DIG_START 0x1 -+#define WM97XX_DIG_STOP 0x2 -+#define WM97XX_PHY_INIT 0x3 -+#define WM97XX_AUX_PREPARE 0x4 -+#define WM97XX_DIG_RESTORE 0x5 -+ -+struct wm97xx; -+ -+extern struct wm97xx_codec_drv wm9705_codec; -+extern struct wm97xx_codec_drv wm9712_codec; -+extern struct wm97xx_codec_drv wm9713_codec; -+ -+/* -+ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs -+ */ -+struct wm97xx_codec_drv { -+ u16 id; -+ char *name; -+ -+ /* read 1 sample */ -+ int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); -+ -+ /* read X,Y,[P] in poll */ -+ int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); -+ -+ int (*acc_enable) (struct wm97xx *, int enable); -+ void (*phy_init) (struct wm97xx *); -+ void (*dig_enable) (struct wm97xx *, int enable); -+ void (*dig_restore) (struct wm97xx *); -+ void (*aux_prepare) (struct wm97xx *); -+}; -+ -+ -+/* Machine specific and accelerated touch operations */ -+struct wm97xx_mach_ops { -+ -+ /* accelerated touch readback - coords are transmited on AC97 link */ -+ int acc_enabled; -+ void (*acc_pen_up) (struct wm97xx *); -+ int (*acc_pen_down) (struct wm97xx *); -+ int (*acc_startup) (struct wm97xx *); -+ void (*acc_shutdown) (struct wm97xx *); -+ -+ /* interrupt mask control - required for accelerated operation */ -+ void (*irq_enable) (struct wm97xx *, int enable); -+ -+ /* pre and post sample - can be used to minimise any analog noise */ -+ void (*pre_sample) (int); /* function to run before sampling */ -+ void (*post_sample) (int); /* function to run after sampling */ -+}; -+ -+struct wm97xx { -+ u16 dig[3], id, gpio[6], misc; /* Cached codec registers */ -+ u16 dig_save[3]; /* saved during aux reading */ -+ struct wm97xx_codec_drv *codec; /* attached codec driver*/ -+ struct input_dev *input_dev; /* touchscreen input device */ -+ struct snd_ac97 *ac97; /* ALSA codec access */ -+ struct device *dev; /* ALSA device */ -+ struct platform_device *battery_dev; -+ struct platform_device *touch_dev; -+ struct wm97xx_mach_ops *mach_ops; -+ struct mutex codec_mutex; -+ struct delayed_work ts_reader; /* Used to poll touchscreen */ -+ unsigned long ts_reader_interval; /* Current interval for timer */ -+ unsigned long ts_reader_min_interval; /* Minimum interval */ -+ unsigned int pen_irq; /* Pen IRQ number in use */ -+ struct workqueue_struct *ts_workq; -+ struct work_struct pen_event_work; -+ u16 acc_slot; /* AC97 slot used for acc touch data */ -+ u16 acc_rate; /* acc touch data rate */ -+ unsigned pen_is_down:1; /* Pen is down */ -+ unsigned aux_waiting:1; /* aux measurement waiting */ -+ unsigned pen_probably_down:1; /* used in polling mode */ -+}; -+ -+/* -+ * Codec GPIO access (not supported on WM9705) -+ * This can be used to set/get codec GPIO and Virtual GPIO status. -+ */ -+enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio); -+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, -+ enum wm97xx_gpio_status status); -+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, -+ enum wm97xx_gpio_dir dir, -+ enum wm97xx_gpio_pol pol, -+ enum wm97xx_gpio_sticky sticky, -+ enum wm97xx_gpio_wake wake); -+ -+/* codec AC97 IO access */ -+int wm97xx_reg_read(struct wm97xx *wm, u16 reg); -+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val); -+ -+/* aux adc readback */ -+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel); -+ -+/* machine ops */ -+int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *); -+void wm97xx_unregister_mach_ops(struct wm97xx *); -+ -+#endif --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch deleted file mode 100644 index 3890795f61..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch +++ /dev/null @@ -1,383 +0,0 @@ -From 7b366ca784d0540613a43908de803e4dedc100d3 Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:20 +0300 -Subject: [PATCH 31/64] Add chip driver for WM9705 touchscreen - -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> -Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com> -Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> -Cc: Stanley Cai <stanley.cai@intel.com> -Cc: Rodolfo Giometti <giometti@enneenne.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Marc Kleine-Budde <mkl@pengutronix.de> -Cc: Ian Molton <spyro@f2s.com> -Cc: Vince Sanders <vince@kyllikki.org> -Cc: Andrew Zabolotny <zap@homelink.ru> ---- - drivers/input/touchscreen/wm9705.c | 352 ++++++++++++++++++++++++++++++++++++ - 1 files changed, 352 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/wm9705.c - -diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c -new file mode 100644 -index 0000000..f185104 ---- /dev/null -+++ b/drivers/input/touchscreen/wm9705.c -@@ -0,0 +1,352 @@ -+/* -+ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. -+ * -+ * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. -+ * Author: Liam Girdwood -+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com -+ * Parts Copyright : Ian Molton <spyro@f2s.com> -+ * Andrew Zabolotny <zap@homelink.ru> -+ * Russell King <rmk@arm.linux.org.uk> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/input.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+#include <linux/wm97xx.h> -+ -+#define TS_NAME "wm97xx" -+#define WM9705_VERSION "0.62" -+#define DEFAULT_PRESSURE 0xb0c0 -+ -+/* -+ * Module parameters -+ */ -+ -+/* -+ * Set current used for pressure measurement. -+ * -+ * Set pil = 2 to use 400uA -+ * pil = 1 to use 200uA and -+ * pil = 0 to disable pressure measurement. -+ * -+ * This is used to increase the range of values returned by the adc -+ * when measureing touchpanel pressure. -+ */ -+static int pil; -+module_param(pil, int, 0); -+MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); -+ -+/* -+ * Set threshold for pressure measurement. -+ * -+ * Pen down pressure below threshold is ignored. -+ */ -+static int pressure = DEFAULT_PRESSURE & 0xfff; -+module_param(pressure, int, 0); -+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); -+ -+/* -+ * Set adc sample delay. -+ * -+ * For accurate touchpanel measurements, some settling time may be -+ * required between the switch matrix applying a voltage across the -+ * touchpanel plate and the ADC sampling the signal. -+ * -+ * This delay can be set by setting delay = n, where n is the array -+ * position of the delay in the array delay_table below. -+ * Long delays > 1ms are supported for completeness, but are not -+ * recommended. -+ */ -+static int delay = 4; -+module_param(delay, int, 0); -+MODULE_PARM_DESC(delay, "Set adc sample delay."); -+ -+/* -+ * Pen detect comparator threshold. -+ * -+ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold -+ * i.e. 1 = Vmid/15 threshold -+ * 15 = Vmid/1 threshold -+ * -+ * Adjust this value if you are having problems with pen detect not -+ * detecting any down events. -+ */ -+static int pdd = 8; -+module_param(pdd, int, 0); -+MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold"); -+ -+/* -+ * Set adc mask function. -+ * -+ * Sources of glitch noise, such as signals driving an LCD display, may feed -+ * through to the touch screen plates and affect measurement accuracy. In -+ * order to minimise this, a signal may be applied to the MASK pin to delay or -+ * synchronise the sampling. -+ * -+ * 0 = No delay or sync -+ * 1 = High on pin stops conversions -+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) -+ * 3 = Edge triggered, edge on pin starts conversion after delay param -+ */ -+static int mask; -+module_param(mask, int, 0); -+MODULE_PARM_DESC(mask, "Set adc mask function."); -+ -+/* -+ * ADC sample delay times in uS -+ */ -+static const int delay_table[] = { -+ 21, /* 1 AC97 Link frames */ -+ 42, /* 2 */ -+ 84, /* 4 */ -+ 167, /* 8 */ -+ 333, /* 16 */ -+ 667, /* 32 */ -+ 1000, /* 48 */ -+ 1333, /* 64 */ -+ 2000, /* 96 */ -+ 2667, /* 128 */ -+ 3333, /* 160 */ -+ 4000, /* 192 */ -+ 4667, /* 224 */ -+ 5333, /* 256 */ -+ 6000, /* 288 */ -+ 0 /* No delay, switch matrix always on */ -+}; -+ -+/* -+ * Delay after issuing a POLL command. -+ * -+ * The delay is 3 AC97 link frames + the touchpanel settling delay -+ */ -+static inline void poll_delay(int d) -+{ -+ udelay(3 * AC97_LINK_FRAME + delay_table[d]); -+} -+ -+/* -+ * set up the physical settings of the WM9705 -+ */ -+static void wm9705_phy_init(struct wm97xx *wm) -+{ -+ u16 dig1 = 0, dig2 = WM97XX_RPR; -+ -+ /* -+ * mute VIDEO and AUX as they share X and Y touchscreen -+ * inputs on the WM9705 -+ */ -+ wm97xx_reg_write(wm, AC97_AUX, 0x8000); -+ wm97xx_reg_write(wm, AC97_VIDEO, 0x8000); -+ -+ /* touchpanel pressure current*/ -+ if (pil == 2) { -+ dig2 |= WM9705_PIL; -+ dev_dbg(wm->dev, -+ "setting pressure measurement current to 400uA."); -+ } else if (pil) -+ dev_dbg(wm->dev, -+ "setting pressure measurement current to 200uA."); -+ if (!pil) -+ pressure = 0; -+ -+ /* polling mode sample settling delay */ -+ if (delay != 4) { -+ if (delay < 0 || delay > 15) { -+ dev_dbg(wm->dev, "supplied delay out of range."); -+ delay = 4; -+ } -+ } -+ dig1 &= 0xff0f; -+ dig1 |= WM97XX_DELAY(delay); -+ dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", -+ delay_table[delay]); -+ -+ /* WM9705 pdd */ -+ dig2 |= (pdd & 0x000f); -+ dev_dbg(wm->dev, "setting pdd to Vmid/%d", 1 - (pdd & 0x000f)); -+ -+ /* mask */ -+ dig2 |= ((mask & 0x3) << 4); -+ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); -+} -+ -+static void wm9705_dig_enable(struct wm97xx *wm, int enable) -+{ -+ if (enable) { -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, -+ wm->dig[2] | WM97XX_PRP_DET_DIG); -+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ -+ } else -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, -+ wm->dig[2] & ~WM97XX_PRP_DET_DIG); -+} -+ -+static void wm9705_aux_prepare(struct wm97xx *wm) -+{ -+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); -+} -+ -+static void wm9705_dig_restore(struct wm97xx *wm) -+{ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); -+} -+ -+static inline int is_pden(struct wm97xx *wm) -+{ -+ return wm->dig[2] & WM9705_PDEN; -+} -+ -+/* -+ * Read a sample from the WM9705 adc in polling mode. -+ */ -+static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) -+{ -+ int timeout = 5 * delay; -+ -+ if (!wm->pen_probably_down) { -+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (!(data & WM97XX_PEN_DOWN)) -+ return RC_PENUP; -+ wm->pen_probably_down = 1; -+ } -+ -+ /* set up digitiser */ -+ if (adcsel & 0x8000) -+ adcsel = ((adcsel & 0x7fff) + 3) << 12; -+ -+ if (wm->mach_ops && wm->mach_ops->pre_sample) -+ wm->mach_ops->pre_sample(adcsel); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, -+ adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); -+ -+ /* wait 3 AC97 time slots + delay for conversion */ -+ poll_delay(delay); -+ -+ /* wait for POLL to go low */ -+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) -+ && timeout) { -+ udelay(AC97_LINK_FRAME); -+ timeout--; -+ } -+ -+ if (timeout <= 0) { -+ /* If PDEN is set, we can get a timeout when pen goes up */ -+ if (is_pden(wm)) -+ wm->pen_probably_down = 0; -+ else -+ dev_dbg(wm->dev, "adc sample timeout"); -+ return RC_PENUP; -+ } -+ -+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (wm->mach_ops && wm->mach_ops->post_sample) -+ wm->mach_ops->post_sample(adcsel); -+ -+ /* check we have correct sample */ -+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { -+ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, -+ *sample & WM97XX_ADCSEL_MASK); -+ return RC_PENUP; -+ } -+ -+ if (!(*sample & WM97XX_PEN_DOWN)) { -+ wm->pen_probably_down = 0; -+ return RC_PENUP; -+ } -+ -+ return RC_VALID; -+} -+ -+/* -+ * Sample the WM9705 touchscreen in polling mode -+ */ -+static int wm9705_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) -+{ -+ int rc; -+ -+ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); -+ if (rc != RC_VALID) -+ return rc; -+ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); -+ if (rc != RC_VALID) -+ return rc; -+ if (pil) { -+ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p); -+ if (rc != RC_VALID) -+ return rc; -+ } else -+ data->p = DEFAULT_PRESSURE; -+ -+ return RC_VALID; -+} -+ -+/* -+ * Enable WM9705 continuous mode, i.e. touch data is streamed across -+ * an AC97 slot -+ */ -+static int wm9705_acc_enable(struct wm97xx *wm, int enable) -+{ -+ u16 dig1, dig2; -+ int ret = 0; -+ -+ dig1 = wm->dig[1]; -+ dig2 = wm->dig[2]; -+ -+ if (enable) { -+ /* continous mode */ -+ if (wm->mach_ops->acc_startup && -+ (ret = wm->mach_ops->acc_startup(wm)) < 0) -+ return ret; -+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | -+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK); -+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | -+ WM97XX_DELAY(delay) | -+ WM97XX_SLT(wm->acc_slot) | -+ WM97XX_RATE(wm->acc_rate); -+ if (pil) -+ dig1 |= WM97XX_ADCSEL_PRES; -+ dig2 |= WM9705_PDEN; -+ } else { -+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); -+ dig2 &= ~WM9705_PDEN; -+ if (wm->mach_ops->acc_shutdown) -+ wm->mach_ops->acc_shutdown(wm); -+ } -+ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); -+ return ret; -+} -+ -+struct wm97xx_codec_drv wm9705_codec = { -+ .id = WM9705_ID2, -+ .name = "wm9705", -+ .poll_sample = wm9705_poll_sample, -+ .poll_touch = wm9705_poll_touch, -+ .acc_enable = wm9705_acc_enable, -+ .phy_init = wm9705_phy_init, -+ .dig_enable = wm9705_dig_enable, -+ .dig_restore = wm9705_dig_restore, -+ .aux_prepare = wm9705_aux_prepare, -+}; -+EXPORT_SYMBOL_GPL(wm9705_codec); -+ -+/* Module information */ -+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); -+MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); -+MODULE_LICENSE("GPL"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch deleted file mode 100644 index 6265910a1e..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch +++ /dev/null @@ -1,492 +0,0 @@ -From b2640063b8321bdfb324c00d5f0c3366ac31696b Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:19 +0300 -Subject: [PATCH 32/64] Add chip driver for WM9712 touchscreen - -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> -Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com> -Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> -Cc: Stanley Cai <stanley.cai@intel.com> -Cc: Rodolfo Giometti <giometti@enneenne.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Marc Kleine-Budde <mkl@pengutronix.de> -Cc: Ian Molton <spyro@f2s.com> -Cc: Vince Sanders <vince@kyllikki.org> -Cc: Andrew Zabolotny <zap@homelink.ru> ---- - drivers/input/touchscreen/wm9712.c | 461 ++++++++++++++++++++++++++++++++++++ - 1 files changed, 461 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/wm9712.c - -diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c -new file mode 100644 -index 0000000..eaab326 ---- /dev/null -+++ b/drivers/input/touchscreen/wm9712.c -@@ -0,0 +1,461 @@ -+/* -+ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. -+ * -+ * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. -+ * Author: Liam Girdwood -+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com -+ * Parts Copyright : Ian Molton <spyro@f2s.com> -+ * Andrew Zabolotny <zap@homelink.ru> -+ * Russell King <rmk@arm.linux.org.uk> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/input.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+#include <linux/wm97xx.h> -+ -+#define TS_NAME "wm97xx" -+#define WM9712_VERSION "0.61" -+#define DEFAULT_PRESSURE 0xb0c0 -+ -+/* -+ * Module parameters -+ */ -+ -+/* -+ * Set internal pull up for pen detect. -+ * -+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) -+ * i.e. pull up resistance = 64k Ohms / rpu. -+ * -+ * Adjust this value if you are having problems with pen detect not -+ * detecting any down event. -+ */ -+static int rpu = 8; -+module_param(rpu, int, 0); -+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); -+ -+/* -+ * Set current used for pressure measurement. -+ * -+ * Set pil = 2 to use 400uA -+ * pil = 1 to use 200uA and -+ * pil = 0 to disable pressure measurement. -+ * -+ * This is used to increase the range of values returned by the adc -+ * when measureing touchpanel pressure. -+ */ -+static int pil; -+module_param(pil, int, 0); -+MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); -+ -+/* -+ * Set threshold for pressure measurement. -+ * -+ * Pen down pressure below threshold is ignored. -+ */ -+static int pressure = DEFAULT_PRESSURE & 0xfff; -+module_param(pressure, int, 0); -+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); -+ -+/* -+ * Set adc sample delay. -+ * -+ * For accurate touchpanel measurements, some settling time may be -+ * required between the switch matrix applying a voltage across the -+ * touchpanel plate and the ADC sampling the signal. -+ * -+ * This delay can be set by setting delay = n, where n is the array -+ * position of the delay in the array delay_table below. -+ * Long delays > 1ms are supported for completeness, but are not -+ * recommended. -+ */ -+static int delay = 3; -+module_param(delay, int, 0); -+MODULE_PARM_DESC(delay, "Set adc sample delay."); -+ -+/* -+ * Set five_wire = 1 to use a 5 wire touchscreen. -+ * -+ * NOTE: Five wire mode does not allow for readback of pressure. -+ */ -+static int five_wire; -+module_param(five_wire, int, 0); -+MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen."); -+ -+/* -+ * Set adc mask function. -+ * -+ * Sources of glitch noise, such as signals driving an LCD display, may feed -+ * through to the touch screen plates and affect measurement accuracy. In -+ * order to minimise this, a signal may be applied to the MASK pin to delay or -+ * synchronise the sampling. -+ * -+ * 0 = No delay or sync -+ * 1 = High on pin stops conversions -+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) -+ * 3 = Edge triggered, edge on pin starts conversion after delay param -+ */ -+static int mask; -+module_param(mask, int, 0); -+MODULE_PARM_DESC(mask, "Set adc mask function."); -+ -+/* -+ * Coordinate Polling Enable. -+ * -+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together -+ * for every poll. -+ */ -+static int coord; -+module_param(coord, int, 0); -+MODULE_PARM_DESC(coord, "Polling coordinate mode"); -+ -+/* -+ * ADC sample delay times in uS -+ */ -+static const int delay_table[] = { -+ 21, /* 1 AC97 Link frames */ -+ 42, /* 2 */ -+ 84, /* 4 */ -+ 167, /* 8 */ -+ 333, /* 16 */ -+ 667, /* 32 */ -+ 1000, /* 48 */ -+ 1333, /* 64 */ -+ 2000, /* 96 */ -+ 2667, /* 128 */ -+ 3333, /* 160 */ -+ 4000, /* 192 */ -+ 4667, /* 224 */ -+ 5333, /* 256 */ -+ 6000, /* 288 */ -+ 0 /* No delay, switch matrix always on */ -+}; -+ -+/* -+ * Delay after issuing a POLL command. -+ * -+ * The delay is 3 AC97 link frames + the touchpanel settling delay -+ */ -+static inline void poll_delay(int d) -+{ -+ udelay(3 * AC97_LINK_FRAME + delay_table[d]); -+} -+ -+/* -+ * set up the physical settings of the WM9712 -+ */ -+static void wm9712_phy_init(struct wm97xx *wm) -+{ -+ u16 dig1 = 0; -+ u16 dig2 = WM97XX_RPR | WM9712_RPU(1); -+ -+ /* WM9712 rpu */ -+ if (rpu) { -+ dig2 &= 0xffc0; -+ dig2 |= WM9712_RPU(rpu); -+ dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms", -+ 64000 / rpu); -+ } -+ -+ /* touchpanel pressure current*/ -+ if (pil == 2) { -+ dig2 |= WM9712_PIL; -+ dev_dbg(wm->dev, -+ "setting pressure measurement current to 400uA."); -+ } else if (pil) -+ dev_dbg(wm->dev, -+ "setting pressure measurement current to 200uA."); -+ if (!pil) -+ pressure = 0; -+ -+ /* WM9712 five wire */ -+ if (five_wire) { -+ dig2 |= WM9712_45W; -+ dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); -+ } -+ -+ /* polling mode sample settling delay */ -+ if (delay < 0 || delay > 15) { -+ dev_dbg(wm->dev, "supplied delay out of range."); -+ delay = 4; -+ } -+ dig1 &= 0xff0f; -+ dig1 |= WM97XX_DELAY(delay); -+ dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", -+ delay_table[delay]); -+ -+ /* mask */ -+ dig2 |= ((mask & 0x3) << 6); -+ if (mask) { -+ u16 reg; -+ /* Set GPIO4 as Mask Pin*/ -+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE); -+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4); -+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); -+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4); -+ } -+ -+ /* wait - coord mode */ -+ if (coord) -+ dig2 |= WM9712_WAIT; -+ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); -+} -+ -+static void wm9712_dig_enable(struct wm97xx *wm, int enable) -+{ -+ u16 dig2 = wm->dig[2]; -+ -+ if (enable) { -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, -+ dig2 | WM97XX_PRP_DET_DIG); -+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ -+ } else -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, -+ dig2 & ~WM97XX_PRP_DET_DIG); -+} -+ -+static void wm9712_aux_prepare(struct wm97xx *wm) -+{ -+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); -+} -+ -+static void wm9712_dig_restore(struct wm97xx *wm) -+{ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); -+} -+ -+static inline int is_pden(struct wm97xx *wm) -+{ -+ return wm->dig[2] & WM9712_PDEN; -+} -+ -+/* -+ * Read a sample from the WM9712 adc in polling mode. -+ */ -+static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) -+{ -+ int timeout = 5 * delay; -+ -+ if (!wm->pen_probably_down) { -+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (!(data & WM97XX_PEN_DOWN)) -+ return RC_PENUP; -+ wm->pen_probably_down = 1; -+ } -+ -+ /* set up digitiser */ -+ if (adcsel & 0x8000) -+ adcsel = ((adcsel & 0x7fff) + 3) << 12; -+ -+ if (wm->mach_ops && wm->mach_ops->pre_sample) -+ wm->mach_ops->pre_sample(adcsel); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, -+ adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); -+ -+ /* wait 3 AC97 time slots + delay for conversion */ -+ poll_delay(delay); -+ -+ /* wait for POLL to go low */ -+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) -+ && timeout) { -+ udelay(AC97_LINK_FRAME); -+ timeout--; -+ } -+ -+ if (timeout <= 0) { -+ /* If PDEN is set, we can get a timeout when pen goes up */ -+ if (is_pden(wm)) -+ wm->pen_probably_down = 0; -+ else -+ dev_dbg(wm->dev, "adc sample timeout"); -+ return RC_PENUP; -+ } -+ -+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (wm->mach_ops && wm->mach_ops->post_sample) -+ wm->mach_ops->post_sample(adcsel); -+ -+ /* check we have correct sample */ -+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { -+ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, -+ *sample & WM97XX_ADCSEL_MASK); -+ return RC_PENUP; -+ } -+ -+ if (!(*sample & WM97XX_PEN_DOWN)) { -+ wm->pen_probably_down = 0; -+ return RC_PENUP; -+ } -+ -+ return RC_VALID; -+} -+ -+/* -+ * Read a coord from the WM9712 adc in polling mode. -+ */ -+static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) -+{ -+ int timeout = 5 * delay; -+ -+ if (!wm->pen_probably_down) { -+ u16 data_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (!(data_rd & WM97XX_PEN_DOWN)) -+ return RC_PENUP; -+ wm->pen_probably_down = 1; -+ } -+ -+ /* set up digitiser */ -+ if (wm->mach_ops && wm->mach_ops->pre_sample) -+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); -+ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, -+ WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay)); -+ -+ /* wait 3 AC97 time slots + delay for conversion and read x */ -+ poll_delay(delay); -+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ /* wait for POLL to go low */ -+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) -+ && timeout) { -+ udelay(AC97_LINK_FRAME); -+ timeout--; -+ } -+ -+ if (timeout <= 0) { -+ /* If PDEN is set, we can get a timeout when pen goes up */ -+ if (is_pden(wm)) -+ wm->pen_probably_down = 0; -+ else -+ dev_dbg(wm->dev, "adc sample timeout"); -+ return RC_PENUP; -+ } -+ -+ /* read back y data */ -+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (pil) -+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ else -+ data->p = DEFAULT_PRESSURE; -+ -+ if (wm->mach_ops && wm->mach_ops->post_sample) -+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); -+ -+ /* check we have correct sample */ -+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) -+ goto err; -+ if (pil && !(data->p & WM97XX_ADCSEL_PRES)) -+ goto err; -+ -+ if (!(data->x & WM97XX_PEN_DOWN)) { -+ wm->pen_probably_down = 0; -+ return RC_PENUP; -+ } -+ return RC_VALID; -+err: -+ return RC_PENUP; -+} -+ -+/* -+ * Sample the WM9712 touchscreen in polling mode -+ */ -+static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) -+{ -+ int rc; -+ -+ if (coord) { -+ rc = wm9712_poll_coord(wm, data); -+ if (rc != RC_VALID) -+ return rc; -+ } else { -+ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); -+ if (rc != RC_VALID) -+ return rc; -+ -+ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); -+ if (rc != RC_VALID) -+ return rc; -+ -+ if (pil && !five_wire) { -+ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, -+ &data->p); -+ if (rc != RC_VALID) -+ return rc; -+ } else -+ data->p = DEFAULT_PRESSURE; -+ } -+ return RC_VALID; -+} -+ -+/* -+ * Enable WM9712 continuous mode, i.e. touch data is streamed across -+ * an AC97 slot -+ */ -+static int wm9712_acc_enable(struct wm97xx *wm, int enable) -+{ -+ u16 dig1, dig2; -+ int ret = 0; -+ -+ dig1 = wm->dig[1]; -+ dig2 = wm->dig[2]; -+ -+ if (enable) { -+ /* continous mode */ -+ if (wm->mach_ops->acc_startup) { -+ ret = wm->mach_ops->acc_startup(wm); -+ if (ret < 0) -+ return ret; -+ } -+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | -+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK); -+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | -+ WM97XX_DELAY(delay) | -+ WM97XX_SLT(wm->acc_slot) | -+ WM97XX_RATE(wm->acc_rate); -+ if (pil) -+ dig1 |= WM97XX_ADCSEL_PRES; -+ dig2 |= WM9712_PDEN; -+ } else { -+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); -+ dig2 &= ~WM9712_PDEN; -+ if (wm->mach_ops->acc_shutdown) -+ wm->mach_ops->acc_shutdown(wm); -+ } -+ -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); -+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); -+ return 0; -+} -+ -+struct wm97xx_codec_drv wm9712_codec = { -+ .id = WM9712_ID2, -+ .name = "wm9712", -+ .poll_sample = wm9712_poll_sample, -+ .poll_touch = wm9712_poll_touch, -+ .acc_enable = wm9712_acc_enable, -+ .phy_init = wm9712_phy_init, -+ .dig_enable = wm9712_dig_enable, -+ .dig_restore = wm9712_dig_restore, -+ .aux_prepare = wm9712_aux_prepare, -+}; -+EXPORT_SYMBOL_GPL(wm9712_codec); -+ -+/* Module information */ -+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); -+MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); -+MODULE_LICENSE("GPL"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch deleted file mode 100644 index a9dfa18557..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch +++ /dev/null @@ -1,490 +0,0 @@ -From 05b2a361eedb5461e902c73ebc6e30f9916b3a8a Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:19 +0300 -Subject: [PATCH 33/64] Add chip driver for WM9713 touchscreen - -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> -Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com> -Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> -Cc: Stanley Cai <stanley.cai@intel.com> -Cc: Rodolfo Giometti <giometti@enneenne.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Marc Kleine-Budde <mkl@pengutronix.de> -Cc: Ian Molton <spyro@f2s.com> -Cc: Vince Sanders <vince@kyllikki.org> -Cc: Andrew Zabolotny <zap@homelink.ru> ---- - drivers/input/touchscreen/wm9713.c | 459 ++++++++++++++++++++++++++++++++++++ - 1 files changed, 459 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/wm9713.c - -diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c -new file mode 100644 -index 0000000..5067e59 ---- /dev/null -+++ b/drivers/input/touchscreen/wm9713.c -@@ -0,0 +1,459 @@ -+/* -+ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. -+ * -+ * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. -+ * Author: Liam Girdwood -+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com -+ * Parts Copyright : Ian Molton <spyro@f2s.com> -+ * Andrew Zabolotny <zap@homelink.ru> -+ * Russell King <rmk@arm.linux.org.uk> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/input.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+#include <linux/wm97xx.h> -+ -+#define TS_NAME "wm97xx" -+#define WM9713_VERSION "0.53" -+#define DEFAULT_PRESSURE 0xb0c0 -+ -+/* -+ * Module parameters -+ */ -+ -+/* -+ * Set internal pull up for pen detect. -+ * -+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) -+ * i.e. pull up resistance = 64k Ohms / rpu. -+ * -+ * Adjust this value if you are having problems with pen detect not -+ * detecting any down event. -+ */ -+static int rpu = 8; -+module_param(rpu, int, 0); -+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); -+ -+/* -+ * Set current used for pressure measurement. -+ * -+ * Set pil = 2 to use 400uA -+ * pil = 1 to use 200uA and -+ * pil = 0 to disable pressure measurement. -+ * -+ * This is used to increase the range of values returned by the adc -+ * when measureing touchpanel pressure. -+ */ -+static int pil; -+module_param(pil, int, 0); -+MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); -+ -+/* -+ * Set threshold for pressure measurement. -+ * -+ * Pen down pressure below threshold is ignored. -+ */ -+static int pressure = DEFAULT_PRESSURE & 0xfff; -+module_param(pressure, int, 0); -+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); -+ -+/* -+ * Set adc sample delay. -+ * -+ * For accurate touchpanel measurements, some settling time may be -+ * required between the switch matrix applying a voltage across the -+ * touchpanel plate and the ADC sampling the signal. -+ * -+ * This delay can be set by setting delay = n, where n is the array -+ * position of the delay in the array delay_table below. -+ * Long delays > 1ms are supported for completeness, but are not -+ * recommended. -+ */ -+static int delay = 4; -+module_param(delay, int, 0); -+MODULE_PARM_DESC(delay, "Set adc sample delay."); -+ -+/* -+ * Set adc mask function. -+ * -+ * Sources of glitch noise, such as signals driving an LCD display, may feed -+ * through to the touch screen plates and affect measurement accuracy. In -+ * order to minimise this, a signal may be applied to the MASK pin to delay or -+ * synchronise the sampling. -+ * -+ * 0 = No delay or sync -+ * 1 = High on pin stops conversions -+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) -+ * 3 = Edge triggered, edge on pin starts conversion after delay param -+ */ -+static int mask; -+module_param(mask, int, 0); -+MODULE_PARM_DESC(mask, "Set adc mask function."); -+ -+/* -+ * Coordinate Polling Enable. -+ * -+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together -+ * for every poll. -+ */ -+static int coord; -+module_param(coord, int, 0); -+MODULE_PARM_DESC(coord, "Polling coordinate mode"); -+ -+/* -+ * ADC sample delay times in uS -+ */ -+static const int delay_table[] = { -+ 21, /* 1 AC97 Link frames */ -+ 42, /* 2 */ -+ 84, /* 4 */ -+ 167, /* 8 */ -+ 333, /* 16 */ -+ 667, /* 32 */ -+ 1000, /* 48 */ -+ 1333, /* 64 */ -+ 2000, /* 96 */ -+ 2667, /* 128 */ -+ 3333, /* 160 */ -+ 4000, /* 192 */ -+ 4667, /* 224 */ -+ 5333, /* 256 */ -+ 6000, /* 288 */ -+ 0 /* No delay, switch matrix always on */ -+}; -+ -+/* -+ * Delay after issuing a POLL command. -+ * -+ * The delay is 3 AC97 link frames + the touchpanel settling delay -+ */ -+static inline void poll_delay(int d) -+{ -+ udelay(3 * AC97_LINK_FRAME + delay_table[d]); -+} -+ -+/* -+ * set up the physical settings of the WM9713 -+ */ -+static void wm9713_phy_init(struct wm97xx *wm) -+{ -+ u16 dig1 = 0, dig2, dig3; -+ -+ /* default values */ -+ dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5); -+ dig3 = WM9712_RPU(1); -+ -+ /* rpu */ -+ if (rpu) { -+ dig3 &= 0xffc0; -+ dig3 |= WM9712_RPU(rpu); -+ dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n", -+ 64000 / rpu); -+ } -+ -+ /* touchpanel pressure */ -+ if (pil == 2) { -+ dig3 |= WM9712_PIL; -+ dev_info(wm->dev, -+ "setting pressure measurement current to 400uA."); -+ } else if (pil) -+ dev_info(wm->dev, -+ "setting pressure measurement current to 200uA."); -+ if (!pil) -+ pressure = 0; -+ -+ /* sample settling delay */ -+ if (delay < 0 || delay > 15) { -+ dev_info(wm->dev, "supplied delay out of range."); -+ delay = 4; -+ dev_info(wm->dev, "setting adc sample delay to %d u Secs.", -+ delay_table[delay]); -+ } -+ dig2 &= 0xff0f; -+ dig2 |= WM97XX_DELAY(delay); -+ -+ /* mask */ -+ dig3 |= ((mask & 0x3) << 4); -+ if (coord) -+ dig3 |= WM9713_WAIT; -+ -+ wm->misc = wm97xx_reg_read(wm, 0x5a); -+ -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); -+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0); -+} -+ -+static void wm9713_dig_enable(struct wm97xx *wm, int enable) -+{ -+ u16 val; -+ -+ if (enable) { -+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); -+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | -+ WM97XX_PRP_DET_DIG); -+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ -+ } else { -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & -+ ~WM97XX_PRP_DET_DIG); -+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); -+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000); -+ } -+} -+ -+static void wm9713_dig_restore(struct wm97xx *wm) -+{ -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]); -+} -+ -+static void wm9713_aux_prepare(struct wm97xx *wm) -+{ -+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG); -+} -+ -+static inline int is_pden(struct wm97xx *wm) -+{ -+ return wm->dig[2] & WM9713_PDEN; -+} -+ -+/* -+ * Read a sample from the WM9713 adc in polling mode. -+ */ -+static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) -+{ -+ u16 dig1; -+ int timeout = 5 * delay; -+ -+ if (!wm->pen_probably_down) { -+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (!(data & WM97XX_PEN_DOWN)) -+ return RC_PENUP; -+ wm->pen_probably_down = 1; -+ } -+ -+ /* set up digitiser */ -+ if (adcsel & 0x8000) -+ adcsel = 1 << ((adcsel & 0x7fff) + 3); -+ -+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); -+ dig1 &= ~WM9713_ADCSEL_MASK; -+ -+ if (wm->mach_ops && wm->mach_ops->pre_sample) -+ wm->mach_ops->pre_sample(adcsel); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL); -+ -+ /* wait 3 AC97 time slots + delay for conversion */ -+ poll_delay(delay); -+ -+ /* wait for POLL to go low */ -+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && -+ timeout) { -+ udelay(AC97_LINK_FRAME); -+ timeout--; -+ } -+ -+ if (timeout <= 0) { -+ /* If PDEN is set, we can get a timeout when pen goes up */ -+ if (is_pden(wm)) -+ wm->pen_probably_down = 0; -+ else -+ dev_dbg(wm->dev, "adc sample timeout"); -+ return RC_PENUP; -+ } -+ -+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (wm->mach_ops && wm->mach_ops->post_sample) -+ wm->mach_ops->post_sample(adcsel); -+ -+ /* check we have correct sample */ -+ if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) { -+ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, -+ *sample & WM97XX_ADCSRC_MASK); -+ return RC_PENUP; -+ } -+ -+ if (!(*sample & WM97XX_PEN_DOWN)) { -+ wm->pen_probably_down = 0; -+ return RC_PENUP; -+ } -+ -+ return RC_VALID; -+} -+ -+/* -+ * Read a coordinate from the WM9713 adc in polling mode. -+ */ -+static int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) -+{ -+ u16 dig1; -+ int timeout = 5 * delay; -+ -+ if (!wm->pen_probably_down) { -+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (!(data & WM97XX_PEN_DOWN)) -+ return RC_PENUP; -+ wm->pen_probably_down = 1; -+ } -+ -+ /* set up digitiser */ -+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); -+ dig1 &= ~WM9713_ADCSEL_MASK; -+ if (pil) -+ dig1 |= WM97XX_ADCSEL_PRES; -+ -+ if (wm->mach_ops && wm->mach_ops->pre_sample) -+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, -+ dig1 | WM9713_POLL | WM9713_COO); -+ -+ /* wait 3 AC97 time slots + delay for conversion */ -+ poll_delay(delay); -+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ /* wait for POLL to go low */ -+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) -+ && timeout) { -+ udelay(AC97_LINK_FRAME); -+ timeout--; -+ } -+ -+ if (timeout <= 0) { -+ /* If PDEN is set, we can get a timeout when pen goes up */ -+ if (is_pden(wm)) -+ wm->pen_probably_down = 0; -+ else -+ dev_dbg(wm->dev, "adc sample timeout"); -+ return RC_PENUP; -+ } -+ -+ /* read back data */ -+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ if (pil) -+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); -+ else -+ data->p = DEFAULT_PRESSURE; -+ -+ if (wm->mach_ops && wm->mach_ops->post_sample) -+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); -+ -+ /* check we have correct sample */ -+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) -+ goto err; -+ if (pil && !(data->p & WM97XX_ADCSEL_PRES)) -+ goto err; -+ -+ if (!(data->x & WM97XX_PEN_DOWN)) { -+ wm->pen_probably_down = 0; -+ return RC_PENUP; -+ } -+ return RC_VALID; -+err: -+ return RC_PENUP; -+} -+ -+/* -+ * Sample the WM9713 touchscreen in polling mode -+ */ -+static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) -+{ -+ int rc; -+ -+ if (coord) { -+ rc = wm9713_poll_coord(wm, data); -+ if (rc != RC_VALID) -+ return rc; -+ } else { -+ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); -+ if (rc != RC_VALID) -+ return rc; -+ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); -+ if (rc != RC_VALID) -+ return rc; -+ if (pil) { -+ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, -+ &data->p); -+ if (rc != RC_VALID) -+ return rc; -+ } else -+ data->p = DEFAULT_PRESSURE; -+ } -+ return RC_VALID; -+} -+ -+/* -+ * Enable WM9713 continuous mode, i.e. touch data is streamed across -+ * an AC97 slot -+ */ -+static int wm9713_acc_enable(struct wm97xx *wm, int enable) -+{ -+ u16 dig1, dig2, dig3; -+ int ret = 0; -+ -+ dig1 = wm->dig[0]; -+ dig2 = wm->dig[1]; -+ dig3 = wm->dig[2]; -+ -+ if (enable) { -+ /* continous mode */ -+ if (wm->mach_ops->acc_startup && -+ (ret = wm->mach_ops->acc_startup(wm)) < 0) -+ return ret; -+ -+ dig1 &= ~WM9713_ADCSEL_MASK; -+ dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | -+ WM9713_ADCSEL_Y; -+ if (pil) -+ dig1 |= WM9713_ADCSEL_PRES; -+ dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | -+ WM97XX_CM_RATE_MASK); -+ dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) | -+ WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate); -+ dig3 |= WM9713_PDEN; -+ } else { -+ dig1 &= ~(WM9713_CTC | WM9713_COO); -+ dig2 &= ~WM97XX_SLEN; -+ dig3 &= ~WM9713_PDEN; -+ if (wm->mach_ops->acc_shutdown) -+ wm->mach_ops->acc_shutdown(wm); -+ } -+ -+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); -+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); -+ return ret; -+} -+ -+struct wm97xx_codec_drv wm9713_codec = { -+ .id = WM9713_ID2, -+ .name = "wm9713", -+ .poll_sample = wm9713_poll_sample, -+ .poll_touch = wm9713_poll_touch, -+ .acc_enable = wm9713_acc_enable, -+ .phy_init = wm9713_phy_init, -+ .dig_enable = wm9713_dig_enable, -+ .dig_restore = wm9713_dig_restore, -+ .aux_prepare = wm9713_aux_prepare, -+}; -+EXPORT_SYMBOL_GPL(wm9713_codec); -+ -+/* Module information */ -+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); -+MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); -+MODULE_LICENSE("GPL"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch b/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch deleted file mode 100644 index 0391cfcd83..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch +++ /dev/null @@ -1,329 +0,0 @@ -From 821604bad5ce1ef942eeb420afd9ea2c5c92875e Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:19 +0300 -Subject: [PATCH 34/64] Driver for WM97xx touchscreens in streaming mode on Mainstone - -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> -Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com> -Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> -Cc: Stanley Cai <stanley.cai@intel.com> -Cc: Rodolfo Giometti <giometti@enneenne.com> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Marc Kleine-Budde <mkl@pengutronix.de> -Cc: Ian Molton <spyro@f2s.com> -Cc: Vince Sanders <vince@kyllikki.org> -Cc: Andrew Zabolotny <zap@homelink.ru> ---- - drivers/input/touchscreen/mainstone-wm97xx.c | 298 ++++++++++++++++++++++++++ - 1 files changed, 298 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/mainstone-wm97xx.c - -diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c -new file mode 100644 -index 0000000..8e1c35d ---- /dev/null -+++ b/drivers/input/touchscreen/mainstone-wm97xx.c -@@ -0,0 +1,298 @@ -+/* -+ * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for -+ * Wolfson WM97xx AC97 Codecs. -+ * -+ * Copyright 2004, 2007 Wolfson Microelectronics PLC. -+ * Author: Liam Girdwood -+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com -+ * Parts Copyright : Ian Molton <spyro@f2s.com> -+ * Andrew Zabolotny <zap@homelink.ru> -+ * -+ * 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. -+ * -+ * Notes: -+ * This is a wm97xx extended touch driver to capture touch -+ * data in a continuous manner on the Intel XScale archictecture -+ * -+ * Features: -+ * - codecs supported:- WM9705, WM9712, WM9713 -+ * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/wm97xx.h> -+#include <linux/io.h> -+#include <asm/arch/pxa-regs.h> -+ -+#define VERSION "0.13" -+ -+struct continuous { -+ u16 id; /* codec id */ -+ u8 code; /* continuous code */ -+ u8 reads; /* number of coord reads per read cycle */ -+ u32 speed; /* number of coords per second */ -+}; -+ -+#define WM_READS(sp) ((sp / HZ) + 1) -+ -+static const struct continuous cinfo[] = { -+ {WM9705_ID2, 0, WM_READS(94), 94}, -+ {WM9705_ID2, 1, WM_READS(188), 188}, -+ {WM9705_ID2, 2, WM_READS(375), 375}, -+ {WM9705_ID2, 3, WM_READS(750), 750}, -+ {WM9712_ID2, 0, WM_READS(94), 94}, -+ {WM9712_ID2, 1, WM_READS(188), 188}, -+ {WM9712_ID2, 2, WM_READS(375), 375}, -+ {WM9712_ID2, 3, WM_READS(750), 750}, -+ {WM9713_ID2, 0, WM_READS(94), 94}, -+ {WM9713_ID2, 1, WM_READS(120), 120}, -+ {WM9713_ID2, 2, WM_READS(154), 154}, -+ {WM9713_ID2, 3, WM_READS(188), 188}, -+}; -+ -+/* continuous speed index */ -+static int sp_idx; -+static u16 last, tries; -+ -+/* -+ * Pen sampling frequency (Hz) in continuous mode. -+ */ -+static int cont_rate = 200; -+module_param(cont_rate, int, 0); -+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); -+ -+/* -+ * Pen down detection. -+ * -+ * This driver can either poll or use an interrupt to indicate a pen down -+ * event. If the irq request fails then it will fall back to polling mode. -+ */ -+static int pen_int; -+module_param(pen_int, int, 0); -+MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)"); -+ -+/* -+ * Pressure readback. -+ * -+ * Set to 1 to read back pen down pressure -+ */ -+static int pressure; -+module_param(pressure, int, 0); -+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); -+ -+/* -+ * AC97 touch data slot. -+ * -+ * Touch screen readback data ac97 slot -+ */ -+static int ac97_touch_slot = 5; -+module_param(ac97_touch_slot, int, 0); -+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); -+ -+ -+/* flush AC97 slot 5 FIFO on pxa machines */ -+#ifdef CONFIG_PXA27x -+static void wm97xx_acc_pen_up(struct wm97xx *wm) -+{ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ -+ while (MISR & (1 << 2)) -+ MODR; -+} -+#else -+static void wm97xx_acc_pen_up(struct wm97xx *wm) -+{ -+ int count = 16; -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ -+ while (count < 16) { -+ MODR; -+ count--; -+ } -+} -+#endif -+ -+static int wm97xx_acc_pen_down(struct wm97xx *wm) -+{ -+ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; -+ int reads = 0; -+ -+ /* data is never immediately available after pen down irq */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ -+ if (tries > 5) { -+ tries = 0; -+ return RC_PENUP; -+ } -+ -+ x = MODR; -+ if (x == last) { -+ tries++; -+ return RC_AGAIN; -+ } -+ last = x; -+ do { -+ if (reads) -+ x = MODR; -+ y = MODR; -+ if (pressure) -+ p = MODR; -+ -+ /* are samples valid */ -+ if ((x & 0x7000) != WM97XX_ADCSEL_X || -+ (y & 0x7000) != WM97XX_ADCSEL_Y || -+ (p & 0x7000) != WM97XX_ADCSEL_PRES) -+ goto up; -+ -+ /* coordinate is good */ -+ tries = 0; -+ input_report_abs(wm->input_dev, ABS_X, x & 0xfff); -+ input_report_abs(wm->input_dev, ABS_Y, y & 0xfff); -+ input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff); -+ input_sync(wm->input_dev); -+ reads++; -+ } while (reads < cinfo[sp_idx].reads); -+up: -+ return RC_PENDOWN | RC_AGAIN; -+} -+ -+static int wm97xx_acc_startup(struct wm97xx *wm) -+{ -+ int idx = 0; -+ -+ /* check we have a codec */ -+ if (wm->ac97 == NULL) -+ return -ENODEV; -+ -+ /* Go you big red fire engine */ -+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { -+ if (wm->id != cinfo[idx].id) -+ continue; -+ sp_idx = idx; -+ if (cont_rate <= cinfo[idx].speed) -+ break; -+ } -+ wm->acc_rate = cinfo[sp_idx].code; -+ wm->acc_slot = ac97_touch_slot; -+ dev_info(wm->dev, -+ "mainstone accelerated touchscreen driver, %d samples/sec\n", -+ cinfo[sp_idx].speed); -+ -+ /* codec specific irq config */ -+ if (pen_int) { -+ switch (wm->id) { -+ case WM9705_ID2: -+ wm->pen_irq = IRQ_GPIO(4); -+ set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE); -+ break; -+ case WM9712_ID2: -+ case WM9713_ID2: -+ /* enable pen down interrupt */ -+ /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */ -+ wm->pen_irq = MAINSTONE_AC97_IRQ; -+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, -+ WM97XX_GPIO_POL_HIGH, -+ WM97XX_GPIO_STICKY, -+ WM97XX_GPIO_WAKE); -+ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT, -+ WM97XX_GPIO_POL_HIGH, -+ WM97XX_GPIO_NOTSTICKY, -+ WM97XX_GPIO_NOWAKE); -+ break; -+ default: -+ dev_err(wm->dev, -+ "pen down irq not supported on this device\n"); -+ pen_int = 0; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static void wm97xx_acc_shutdown(struct wm97xx *wm) -+{ -+ /* codec specific deconfig */ -+ if (pen_int) { -+ switch (wm->id & 0xffff) { -+ case WM9705_ID2: -+ wm->pen_irq = 0; -+ break; -+ case WM9712_ID2: -+ case WM9713_ID2: -+ /* disable interrupt */ -+ wm->pen_irq = 0; -+ break; -+ } -+ } -+} -+ -+static void wm97xx_irq_enable(struct wm97xx *wm, int enable) -+{ -+ if (enable) -+ enable_irq(wm->pen_irq); -+ else -+ disable_irq(wm->pen_irq); -+} -+ -+static struct wm97xx_mach_ops mainstone_mach_ops = { -+ .acc_enabled = 1, -+ .acc_pen_up = wm97xx_acc_pen_up, -+ .acc_pen_down = wm97xx_acc_pen_down, -+ .acc_startup = wm97xx_acc_startup, -+ .acc_shutdown = wm97xx_acc_shutdown, -+ .irq_enable = wm97xx_irq_enable, -+}; -+ -+static int mainstone_wm97xx_probe(struct platform_device *pdev) -+{ -+ struct wm97xx *wm = platform_get_drvdata(pdev); -+ return wm97xx_register_mach_ops(wm, &mainstone_mach_ops); -+} -+ -+static int mainstone_wm97xx_remove(struct platform_device *pdev) -+{ -+ struct wm97xx *wm = platform_get_drvdata(pdev); -+ wm97xx_unregister_mach_ops(wm); -+ return 0; -+} -+ -+static struct platform_driver mainstone_wm97xx_driver = { -+ .probe = mainstone_wm97xx_probe, -+ .remove = mainstone_wm97xx_remove, -+ .driver = { -+ .name = "wm97xx-touch", -+ }, -+}; -+ -+static int __init mainstone_wm97xx_init(void) -+{ -+ return platform_driver_register(&mainstone_wm97xx_driver); -+} -+ -+static void __exit mainstone_wm97xx_exit(void) -+{ -+ platform_driver_unregister(&mainstone_wm97xx_driver); -+} -+ -+module_init(mainstone_wm97xx_init); -+module_exit(mainstone_wm97xx_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); -+MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); -+MODULE_LICENSE("GPL"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch b/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch deleted file mode 100644 index aa0918f43e..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch +++ /dev/null @@ -1,122 +0,0 @@ -From eba6a504393932764a33aae64021827dd2c5c70c Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sat, 26 Jan 2008 21:14:18 +0300 -Subject: [PATCH 35/64] Build system and MAINTAINERS entry for WM97xx touchscreen drivers - -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com> ---- - MAINTAINERS | 10 +++++++ - drivers/input/touchscreen/Kconfig | 52 ++++++++++++++++++++++++++++++++++++ - drivers/input/touchscreen/Makefile | 7 +++++ - 3 files changed, 69 insertions(+), 0 deletions(-) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 2340cfb..f02851c 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -4204,6 +4204,16 @@ L: linux-wireless@vger.kernel.org - W: http://oops.ghostprotocols.net:81/blog - S: Maintained - -+WM97XX TOUCHSCREEN DRIVERS -+P: Mark Brown -+M: broonie@opensource.wolfsonmicro.com -+P: Liam Girdwood -+M: liam.girdwood@wolfsonmicro.com -+L: linux-input@vger.kernel.org -+T: git git://opensource.wolfsonmicro.com/linux-2.6-touch -+W: http://opensource.wolfsonmicro.com/node/7 -+S: Supported -+ - X.25 NETWORK LAYER - P: Henner Eisen - M: eis@baty.hanse.de -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 90e8e92..0be05a2 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -158,6 +158,58 @@ config TOUCHSCREEN_TOUCHRIGHT - To compile this driver as a module, choose M here: the - module will be called touchright. - -+config TOUCHSCREEN_WM97XX -+ tristate "Support for WM97xx AC97 touchscreen controllers" -+ depends on AC97_BUS -+ -+config TOUCHSCREEN_WM9705 -+ bool "WM9705 Touchscreen interface support" -+ depends on TOUCHSCREEN_WM97XX -+ help -+ Say Y here if you have a Wolfson Microelectronics WM9705 touchscreen -+ controller connected to your system. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called wm9705. -+ -+config TOUCHSCREEN_WM9712 -+ bool "WM9712 Touchscreen interface support" -+ depends on TOUCHSCREEN_WM97XX -+ help -+ Say Y here if you have a Wolfson Microelectronics WM9712 touchscreen -+ controller connected to your system. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called wm9712. -+ -+config TOUCHSCREEN_WM9713 -+ bool "WM9713 Touchscreen interface support" -+ depends on TOUCHSCREEN_WM97XX -+ help -+ Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen -+ controller connected to your system. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called wm9713. -+ -+config TOUCHSCREEN_WM97XX_MAINSTONE -+ tristate "WM97xx Mainstone accelerated touch" -+ depends on TOUCHSCREEN_WM97XX && ARCH_PXA -+ help -+ Say Y here for support for streaming mode with WM97xx touchscreens -+ on Mainstone systems. -+ -+ If unsure, say N -+ -+ To compile this driver as a module, choose M here: the -+ module will be called mainstone-wm97xx -+ - config TOUCHSCREEN_TOUCHWIN - tristate "Touchwin serial touchscreen" - select SERIO -diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 35d4097..d38156e 100644 ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -4,6 +4,8 @@ - - # Each configuration option enables a list of files. - -+wm97xx-ts-y := wm97xx-core.o -+ - obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o - obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o - obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o -@@ -19,3 +21,8 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o - obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o - obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o - obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o -+obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o -+obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o -+wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o -+wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o -+wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch b/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch deleted file mode 100644 index dd10b34586..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9ea478cbd5473f52ca036cccc00dddad717d7861 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 30 Jan 2008 19:27:13 +0300 -Subject: [PATCH 36/64] Set id to -1 for wm97xx subdevices - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/input/touchscreen/wm97xx-core.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c -index 27a0a99..e066acc 100644 ---- a/drivers/input/touchscreen/wm97xx-core.c -+++ b/drivers/input/touchscreen/wm97xx-core.c -@@ -592,7 +592,7 @@ static int wm97xx_probe(struct device *dev) - wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); - - /* register our battery device */ -- wm->battery_dev = platform_device_alloc("wm97xx-battery", 0); -+ wm->battery_dev = platform_device_alloc("wm97xx-battery", -1); - if (!wm->battery_dev) - goto batt_err; - platform_set_drvdata(wm->battery_dev, wm); -@@ -603,7 +603,7 @@ static int wm97xx_probe(struct device *dev) - - /* register our extended touch device (for machine specific - * extensions) */ -- wm->touch_dev = platform_device_alloc("wm97xx-touch", 0); -+ wm->touch_dev = platform_device_alloc("wm97xx-touch", -1); - if (!wm->touch_dev) - goto touch_err; - platform_set_drvdata(wm->touch_dev, wm); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch b/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch deleted file mode 100644 index 010194dd96..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch +++ /dev/null @@ -1,41 +0,0 @@ -From d2888c7643b07687b14a839239cbe7fc5bf565e6 Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Mon, 14 Jan 2008 23:24:26 +0300 -Subject: [PATCH 37/64] Don't lock the codec list in snd_soc_dapm_new_widgets() - -snd_soc_dapm_new_widgets() takes the codec lock when adding new widgets, -causing lockdep warnings when applications later call down through ALSA -to adjust controls. Since widgets are only added during probe this lock -should be unneeded so don't take it. - -Thanks to Dmitry Baryshkov <dbaryshkov@gmail.com> for reporting this issue. - -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> -Cc: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - sound/soc/soc-dapm.c | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c -index 29a546f..e46cdc5 100644 ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -963,7 +963,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) - { - struct snd_soc_dapm_widget *w; - -- mutex_lock(&codec->mutex); - list_for_each_entry(w, &codec->dapm_widgets, list) - { - if (w->new) -@@ -998,7 +997,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) - } - - dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); -- mutex_unlock(&codec->mutex); - return 0; - } - EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch b/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch deleted file mode 100644 index 7a3eb61a27..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 5bae1fab16c7b14a458aa90e5654fe3a1d8d960f Mon Sep 17 00:00:00 2001 -From: Mark Brown <broonie@opensource.wolfsonmicro.com> -Date: Sun, 20 Jan 2008 00:06:06 +0300 -Subject: [PATCH 38/64] Don't lock the codec list in snd_soc_dapm_new_widgets() - -On Wed, Jan 16, 2008 at 02:40:55AM +0300, Dmitry wrote: - -> I'm sorry, but I tested this patch only now. And I just got another -> message from lockdep: - -Could you give this patch a try, please? ---- - sound/soc/soc-core.c | 7 +++++-- - 1 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c -index e6a67b5..7f3ed9f 100644 ---- a/sound/soc/soc-core.c -+++ b/sound/soc/soc-core.c -@@ -1090,7 +1090,6 @@ int snd_soc_register_card(struct snd_soc_device *socdev) - struct snd_soc_machine *machine = socdev->machine; - int ret = 0, i, ac97 = 0, err = 0; - -- mutex_lock(&codec->mutex); - for(i = 0; i < machine->num_links; i++) { - if (socdev->machine->dai_link[i].init) { - err = socdev->machine->dai_link[i].init(codec); -@@ -1116,12 +1115,14 @@ int snd_soc_register_card(struct snd_soc_device *socdev) - goto out; - } - -+ mutex_lock(&codec->mutex); - #ifdef CONFIG_SND_SOC_AC97_BUS - if (ac97) { - ret = soc_ac97_dev_register(codec); - if (ret < 0) { - printk(KERN_ERR "asoc: AC97 device register failed\n"); - snd_card_free(codec->card); -+ mutex_unlock(&codec->mutex); - goto out; - } - } -@@ -1134,8 +1135,10 @@ int snd_soc_register_card(struct snd_soc_device *socdev) - err = device_create_file(socdev->dev, &dev_attr_codec_reg); - if (err < 0) - printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n"); --out: -+ - mutex_unlock(&codec->mutex); -+ -+out: - return ret; - } - EXPORT_SYMBOL_GPL(snd_soc_register_card); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch b/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch deleted file mode 100644 index c09c208c6a..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch +++ /dev/null @@ -1,446 +0,0 @@ -From 62c9a23cfa7181369637d0b61a8e90c83c562f03 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 03:01:06 +0300 -Subject: [PATCH 39/64] Add generic framework for managing clocks. - -Provide a generic framework that platform may choose -to support clocks api. In particular this provides -platform-independant struct clk definition, a full -implementation of clocks api and a set of functions -for registering and unregistering clocks in a safe way. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - include/linux/clklib.h | 85 ++++++++++++++ - init/Kconfig | 7 + - kernel/Makefile | 1 + - kernel/clklib.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 388 insertions(+), 0 deletions(-) - create mode 100644 include/linux/clklib.h - create mode 100644 kernel/clklib.c - -diff --git a/include/linux/clklib.h b/include/linux/clklib.h -new file mode 100644 -index 0000000..4bd9b4a ---- /dev/null -+++ b/include/linux/clklib.h -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2008 Dmitry Baryshkov -+ * -+ * This file is released under the GPL v2. -+ */ -+ -+#ifndef CLKLIB_H -+#define CLKLIB_H -+ -+#include <linux/list.h> -+ -+struct clk { -+ struct list_head node; -+ struct clk *parent; -+ -+ const char *name; -+ struct module *owner; -+ -+ int users; -+ unsigned long rate; -+ int delay; -+ -+ int (*can_get) (struct clk *, struct device *); -+ int (*set_parent) (struct clk *, struct clk *); -+ int (*enable) (struct clk *); -+ void (*disable) (struct clk *); -+ unsigned long (*getrate) (struct clk*); -+ int (*setrate) (struct clk *, unsigned long); -+ long (*roundrate) (struct clk *, unsigned long); -+ -+ void *priv; -+}; -+ -+int clk_register(struct clk *clk); -+void clk_unregister(struct clk *clk); -+static void __maybe_unused clks_register(struct clk *clks, size_t num) -+{ -+ int i; -+ for (i = 0; i < num; i++) { -+ clk_register(&clks[i]); -+ } -+} -+ -+ -+int clk_alloc_function(const char *parent, struct clk *clk); -+ -+struct clk_function { -+ const char *parent; -+ struct clk *clk; -+}; -+ -+#define CLK_FUNC(_clock, _function, _can_get, _data, _format) \ -+ { \ -+ .parent = _clock, \ -+ .clk = &(struct clk) { \ -+ .name= _function, \ -+ .owner = THIS_MODULE, \ -+ .can_get = _can_get, \ -+ .priv = _data, \ -+ .format = _format, \ -+ }, \ -+ } -+ -+static int __maybe_unused clk_alloc_functions( -+ struct clk_function *funcs, -+ int num) -+{ -+ int i; -+ int rc; -+ -+ for (i = 0; i < num; i++) { -+ rc = clk_alloc_function(funcs[i].parent, funcs[i].clk); -+ -+ if (rc) { -+ printk(KERN_ERR "Error allocating %s.%s function.\n", -+ funcs[i].parent, -+ funcs[i].clk->name); -+ return rc; -+ } -+ } -+ -+ return 0; -+} -+ -+#endif -diff --git a/init/Kconfig b/init/Kconfig -index b9d11a8..05b62ba 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -435,6 +435,13 @@ config CC_OPTIMIZE_FOR_SIZE - config SYSCTL - bool - -+config HAVE_CLOCK_LIB -+ bool -+ help -+ Platforms select clocklib if they use this infrastructure -+ for managing their clocks both built into SoC and provided -+ by external devices. -+ - menuconfig EMBEDDED - bool "Configure standard kernel features (for small systems)" - help -diff --git a/kernel/Makefile b/kernel/Makefile -index 6d9a87c..0b2ade7 100644 ---- a/kernel/Makefile -+++ b/kernel/Makefile -@@ -58,6 +58,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o - obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o - obj-$(CONFIG_MARKERS) += marker.o - obj-$(CONFIG_LATENCYTOP) += latencytop.o -+obj-$(CONFIG_HAVE_CLOCK_LIB) += clklib.o - - ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) - # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is -diff --git a/kernel/clklib.c b/kernel/clklib.c -new file mode 100644 -index 0000000..203af3d ---- /dev/null -+++ b/kernel/clklib.c -@@ -0,0 +1,295 @@ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/clk.h> -+#include <linux/clklib.h> -+#include <linux/spinlock.h> -+#include <linux/err.h> -+#include <linux/delay.h> -+ -+static LIST_HEAD(clocks); -+static DEFINE_SPINLOCK(clocks_lock); -+ -+static int __clk_register(struct clk *clk) -+{ -+ if (clk->parent && -+ !try_module_get(clk->parent->owner)) -+ return -EINVAL; -+ -+ list_add_tail(&clk->node, &clocks); -+ -+ return 0; -+} -+ -+int clk_register(struct clk *clk) -+{ -+ unsigned long flags; -+ int rc; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ rc = __clk_register(clk); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rc; -+} -+EXPORT_SYMBOL(clk_register); -+ -+void clk_unregister(struct clk *clk) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ list_del(&clk->node); -+ if (clk->parent) -+ module_put(clk->parent->owner); -+ spin_unlock_irqrestore(&clocks_lock, flags); -+} -+EXPORT_SYMBOL(clk_unregister); -+ -+struct clk *clk_get(struct device *dev, const char *id) -+{ -+ struct clk *p, *clk = ERR_PTR(-ENOENT); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ list_for_each_entry(p, &clocks, node) { -+ if (strcmp(id, p->name) == 0 && -+ (!p->can_get || p->can_get(p, dev)) && -+ try_module_get(p->owner)) { -+ clk = p; -+ break; -+ } -+ } -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return clk; -+} -+EXPORT_SYMBOL(clk_get); -+ -+void clk_put(struct clk *clk) -+{ -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ module_put(clk->owner); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+} -+EXPORT_SYMBOL(clk_put); -+ -+int clk_set_parent(struct clk *clk, struct clk *parent) -+{ -+ int rc; -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return -EINVAL; -+ -+ if (!clk->set_parent) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ rc = clk->set_parent(clk, parent); -+ if (!rc) -+ clk->parent = parent; -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rc; -+} -+EXPORT_SYMBOL(clk_set_parent); -+ -+static int __clk_enable(struct clk *clk) -+{ -+ int rc = 0; -+ -+ if (clk->parent) { -+ rc = __clk_enable(clk->parent); -+ -+ if (rc) -+ return rc; -+ } -+ -+ if (clk->users++ == 0) -+ if (clk->enable) -+ rc = clk->enable(clk); -+ -+ if (clk->delay) -+ udelay(clk->delay); -+ -+ return rc; -+} -+ -+int clk_enable(struct clk *clk) -+{ -+ unsigned long flags; -+ int rc; -+ -+ if (!clk || IS_ERR(clk)) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ rc = __clk_enable(clk); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rc; -+} -+EXPORT_SYMBOL(clk_enable); -+ -+static void __clk_disable(struct clk *clk) -+{ -+ if (clk->users <= 0) { -+ WARN_ON(1); -+ return; -+ } -+ -+ if (--clk->users == 0) -+ if (clk->disable) -+ clk->disable(clk); -+ -+ if (clk->parent) -+ __clk_disable(clk->parent); -+} -+ -+void clk_disable(struct clk *clk) -+{ -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ __clk_disable(clk); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+} -+EXPORT_SYMBOL(clk_disable); -+ -+static unsigned long __clk_get_rate(struct clk *clk) -+{ -+ unsigned long rate = 0; -+ -+ for (;;) { -+ if (rate || !clk) -+ return rate; -+ -+ if (clk->getrate) -+ rate = clk->getrate(clk); -+ else if (clk->rate) -+ rate = clk->rate; -+ else -+ clk = clk->parent; -+ } -+} -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ unsigned long rate = 0; -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ rate = __clk_get_rate(clk); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rate; -+} -+EXPORT_SYMBOL(clk_get_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ long res; -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return -EINVAL; -+ -+ if (!clk->roundrate) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ res = clk->roundrate(clk, rate); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return res; -+} -+EXPORT_SYMBOL(clk_round_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ int rc; -+ unsigned long flags; -+ -+ if (!clk || IS_ERR(clk)) -+ return -EINVAL; -+ -+ if (!clk->setrate) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ rc = clk->setrate(clk, rate); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rc; -+} -+EXPORT_SYMBOL(clk_set_rate); -+ -+int clk_alloc_function(const char *parent, struct clk *clk) -+{ -+ int rc = 0; -+ unsigned long flags; -+ struct clk *pclk; -+ bool found = false; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ list_for_each_entry(pclk, &clocks, node) { -+ if (strcmp(parent, pclk->name) == 0 && -+ try_module_get(pclk->owner)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) { -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ clk->parent = pclk; -+ -+ __clk_register(clk); -+ /* -+ * We locked parent owner during search -+ * and also in __clk_register. Free one reference -+ */ -+ module_put(pclk->owner); -+ -+out: -+ if (rc) { -+ kfree(clk); -+ } -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return rc; -+} -+EXPORT_SYMBOL(clk_alloc_function); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch deleted file mode 100644 index 160b274f4f..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch +++ /dev/null @@ -1,108 +0,0 @@ -From cae12d96586dac77d223559d686487ea2d457a41 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 03:01:05 +0300 -Subject: [PATCH 40/64] Clocklib debugfs support - -Provide /sys/kernel/debug/clock to ease debugging. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - include/linux/clklib.h | 5 +++ - kernel/clklib.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 73 insertions(+), 0 deletions(-) - -diff --git a/include/linux/clklib.h b/include/linux/clklib.h -index 4bd9b4a..f916693 100644 ---- a/include/linux/clklib.h -+++ b/include/linux/clklib.h -@@ -28,6 +28,11 @@ struct clk { - int (*setrate) (struct clk *, unsigned long); - long (*roundrate) (struct clk *, unsigned long); - -+ /* -+ * format any additional info -+ */ -+ int (*format) (struct clk *, struct seq_file *); -+ - void *priv; - }; - -diff --git a/kernel/clklib.c b/kernel/clklib.c -index 203af3d..b782220 100644 ---- a/kernel/clklib.c -+++ b/kernel/clklib.c -@@ -293,3 +293,71 @@ out: - return rc; - } - EXPORT_SYMBOL(clk_alloc_function); -+ -+#ifdef CONFIG_DEBUG_FS -+ -+#include <linux/debugfs.h> -+#include <linux/seq_file.h> -+static void dump_clocks(struct seq_file *s, struct clk *parent, int nest) -+{ -+ struct clk *clk; -+ int i; -+ -+ list_for_each_entry(clk, &clocks, node) { -+ if (clk->parent == parent) { -+ for (i = 0; i < nest; i++) -+ seq_putc(s, ' '); -+ seq_puts(s, clk->name); -+ -+ i = nest + strlen(clk->name); -+ if (i >= 16) -+ i = 15; -+ for (; i < 16; i++) -+ seq_putc(s, ' '); -+ seq_printf(s, "%c use=%d rate=%lu KHz", -+ clk->set_parent ? '*' : ' ', -+ clk->users, -+ __clk_get_rate(clk)); -+ if (clk->format) -+ clk->format(clk, s); -+ seq_putc(s, '\n'); -+ -+ dump_clocks(s, clk, nest + 1); -+ } -+ } -+} -+ -+static int clocklib_show(struct seq_file *s, void *unused) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&clocks_lock, flags); -+ -+ dump_clocks(s, NULL, 0); -+ -+ spin_unlock_irqrestore(&clocks_lock, flags); -+ -+ return 0; -+} -+ -+static int clocklib_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, clocklib_show, NULL); -+} -+ -+static struct file_operations clocklib_operations = { -+ .open = clocklib_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init clocklib_debugfs_init(void) -+{ -+ debugfs_create_file("clock", S_IFREG | S_IRUGO, -+ NULL, NULL, &clocklib_operations); -+ return 0; -+} -+subsys_initcall(clocklib_debugfs_init); -+ -+#endif /* DEBUG_FS */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch b/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch deleted file mode 100644 index 9c95c67e78..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch +++ /dev/null @@ -1,593 +0,0 @@ -From 2a143b9546b01fd6c58ebaac7eb46568a17d6a41 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Tue, 12 Feb 2008 04:58:59 +0300 -Subject: [PATCH 41/64] From 80a359e60c2aec59ccf4fca0a7fd20495f82b1d2 Mon Sep 17 00:00:00 2001 - In-Reply-To: <20080207005839.GA28509@doriath.ww600.siemens.net> - References: <20080207005839.GA28509@doriath.ww600.siemens.net> - Date: Thu, 7 Feb 2008 03:35:08 +0300 - Subject: [PATCH 3/5] Use clocklib for ARM pxa sub-arch. - Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> - ---- - arch/arm/Kconfig | 1 + - arch/arm/mach-pxa/clock.c | 108 ++++++-------------------------------------- - arch/arm/mach-pxa/clock.h | 58 +++++++++++++----------- - arch/arm/mach-pxa/pxa25x.c | 64 +++++++++++++++----------- - arch/arm/mach-pxa/pxa27x.c | 61 +++++++++++++----------- - arch/arm/mach-pxa/pxa3xx.c | 91 +++++++++++++++++++++---------------- - 6 files changed, 169 insertions(+), 214 deletions(-) - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 423e953..47f3c73 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -347,6 +347,7 @@ config ARCH_PXA - select GENERIC_CLOCKEVENTS - select TICK_ONESHOT - select HAVE_GPIO_LIB -+ select HAVE_CLOCK_LIB - help - Support for Intel/Marvell's PXA2xx/PXA3xx processor line. - -diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c -index 83ef5ec..3296b02 100644 ---- a/arch/arm/mach-pxa/clock.c -+++ b/arch/arm/mach-pxa/clock.c -@@ -8,6 +8,7 @@ - #include <linux/err.h> - #include <linux/string.h> - #include <linux/clk.h> -+#include <linux/clklib.h> - #include <linux/spinlock.h> - #include <linux/platform_device.h> - #include <linux/delay.h> -@@ -19,123 +20,42 @@ - #include "generic.h" - #include "clock.h" - --static LIST_HEAD(clocks); --static DEFINE_MUTEX(clocks_mutex); --static DEFINE_SPINLOCK(clocks_lock); -- --struct clk *clk_get(struct device *dev, const char *id) --{ -- struct clk *p, *clk = ERR_PTR(-ENOENT); -- -- mutex_lock(&clocks_mutex); -- list_for_each_entry(p, &clocks, node) { -- if (strcmp(id, p->name) == 0 && -- (p->dev == NULL || p->dev == dev)) { -- clk = p; -- break; -- } -- } -- mutex_unlock(&clocks_mutex); -- -- return clk; --} --EXPORT_SYMBOL(clk_get); -- --void clk_put(struct clk *clk) -+static int clk_gpio27_enable(struct clk *clk) - { --} --EXPORT_SYMBOL(clk_put); -- --int clk_enable(struct clk *clk) --{ -- unsigned long flags; -- -- spin_lock_irqsave(&clocks_lock, flags); -- if (clk->enabled++ == 0) -- clk->ops->enable(clk); -- spin_unlock_irqrestore(&clocks_lock, flags); -- -- if (clk->delay) -- udelay(clk->delay); -+ pxa_gpio_mode(GPIO11_3_6MHz_MD); - - return 0; - } --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ -- unsigned long flags; -- -- WARN_ON(clk->enabled == 0); -- -- spin_lock_irqsave(&clocks_lock, flags); -- if (--clk->enabled == 0) -- clk->ops->disable(clk); -- spin_unlock_irqrestore(&clocks_lock, flags); --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- unsigned long rate; -- -- rate = clk->rate; -- if (clk->ops->getrate) -- rate = clk->ops->getrate(clk); -- -- return rate; --} --EXPORT_SYMBOL(clk_get_rate); -- -- --static void clk_gpio27_enable(struct clk *clk) --{ -- pxa_gpio_mode(GPIO11_3_6MHz_MD); --} - - static void clk_gpio27_disable(struct clk *clk) - { -+ /* FIXME: disable clock */ - } - --static const struct clkops clk_gpio27_ops = { -- .enable = clk_gpio27_enable, -- .disable = clk_gpio27_disable, --}; -- -- --void clk_cken_enable(struct clk *clk) -+int clk_cken_enable(struct clk *clk) - { -- CKEN |= 1 << clk->cken; -+ int cken = ((struct clk_cken_priv *)clk->priv)->cken; -+ CKEN |= 1 << cken; -+ -+ return 0; - } - - void clk_cken_disable(struct clk *clk) - { -- CKEN &= ~(1 << clk->cken); -+ int cken = ((struct clk_cken_priv *)clk->priv)->cken; -+ CKEN &= ~(1 << cken); - } - --const struct clkops clk_cken_ops = { -- .enable = clk_cken_enable, -- .disable = clk_cken_disable, --}; -- - static struct clk common_clks[] = { - { - .name = "GPIO27_CLK", -- .ops = &clk_gpio27_ops, - .rate = 3686400, -+ .owner = THIS_MODULE, -+ .enable = clk_gpio27_enable, -+ .disable = clk_gpio27_disable, - }, - }; - --void clks_register(struct clk *clks, size_t num) --{ -- int i; -- -- mutex_lock(&clocks_mutex); -- for (i = 0; i < num; i++) -- list_add(&clks[i].node, &clocks); -- mutex_unlock(&clocks_mutex); --} -- - static int __init clk_init(void) - { - clks_register(common_clks, ARRAY_SIZE(common_clks)); -diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h -index bc6b77e..5d0d067 100644 ---- a/arch/arm/mach-pxa/clock.h -+++ b/arch/arm/mach-pxa/clock.h -@@ -1,43 +1,47 @@ --struct clk; -+#include <linux/clklib.h> -+#include <linux/seq_file.h> - --struct clkops { -- void (*enable)(struct clk *); -- void (*disable)(struct clk *); -- unsigned long (*getrate)(struct clk *); -+struct clk_cken_priv { -+ unsigned int cken; - }; - --struct clk { -- struct list_head node; -- const char *name; -- struct device *dev; -- const struct clkops *ops; -- unsigned long rate; -- unsigned int cken; -- unsigned int delay; -- unsigned int enabled; --}; -- --#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ -+#define INIT_CKEN(_name, _cken, _rate, _delay) \ - { \ - .name = _name, \ -- .dev = _dev, \ -- .ops = &clk_cken_ops, \ -+ .enable = clk_cken_enable, \ -+ .disable = clk_cken_disable, \ - .rate = _rate, \ -- .cken = CKEN_##_cken, \ - .delay = _delay, \ -+ .priv = &(struct clk_cken_priv) { \ -+ .cken = CKEN_##_cken, \ -+ }, \ - } - --#define INIT_CK(_name, _cken, _ops, _dev) \ -+#define INIT_CK(_name, _cken, _getrate) \ - { \ - .name = _name, \ -- .dev = _dev, \ -- .ops = _ops, \ -- .cken = CKEN_##_cken, \ -+ .enable = clk_cken_enable, \ -+ .disable = clk_cken_disable, \ -+ .getrate = _getrate, \ -+ .priv = &(struct clk_cken_priv) { \ -+ .cken = CKEN_##_cken, \ -+ }, \ - } - --extern const struct clkops clk_cken_ops; -- --void clk_cken_enable(struct clk *clk); -+int clk_cken_enable(struct clk *clk); - void clk_cken_disable(struct clk *clk); - - void clks_register(struct clk *clks, size_t num); -+ -+static int __maybe_unused clk_dev_can_get(struct clk *clk, struct device *dev) -+{ -+ return (dev == clk->priv); -+} -+ -+static int __maybe_unused clk_dev_format(struct clk *clk, struct seq_file *s) -+{ -+ BUG_ON(!clk->priv); -+ seq_puts(s, "for device "); -+ seq_puts(s, ((struct device *)clk->priv)->bus_id); -+ return 0; -+} -diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c -index 5988d99..ed3719b 100644 ---- a/arch/arm/mach-pxa/pxa25x.c -+++ b/arch/arm/mach-pxa/pxa25x.c -@@ -100,40 +100,50 @@ static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk) - return pxa25x_get_memclk_frequency_10khz() * 10000; - } - --static const struct clkops clk_pxa25x_lcd_ops = { -- .enable = clk_cken_enable, -- .disable = clk_cken_disable, -- .getrate = clk_pxa25x_lcd_getrate, --}; -- - /* - * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz) - * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz - * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) - */ --static struct clk pxa25x_hwuart_clk = -- INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) --; -+static struct clk pxa25x_hwuart_clk[] = { -+ INIT_CKEN("HWUARTCLK", HWUART, 14745600, 1), -+ { -+ .parent = &pxa25x_hwuart_clk[0], -+ .name = "UARTCLK", -+ .can_get = clk_dev_can_get, -+ .priv = &pxa_device_hwuart.dev, -+ }, -+}; - - static struct clk pxa25x_clks[] = { -- INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), -- INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), -- INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), -- INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), -- INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), -- INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), -- INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), -- -- INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), -- INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), -- INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), -+ INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_getrate), -+ INIT_CKEN("FFUARTCLK", FFUART, 14745600, 1), -+ INIT_CKEN("BTUARTCLK", BTUART, 14745600, 1), -+ INIT_CKEN("STUARTCLK", STUART, 14745600, 1), -+ INIT_CKEN("UDCCLK", USB, 47923000, 5), -+ INIT_CKEN("MMCCLK", MMC, 19169000, 0), -+ INIT_CKEN("I2CCLK", I2C, 31949000, 0), -+ -+ INIT_CKEN("SSP_CLK", SSP, 3686400, 0), -+ INIT_CKEN("NSSPCLK", NSSP, 3686400, 0), -+ INIT_CKEN("ASSPCLK", ASSP, 3686400, 0), - - /* -- INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), -- INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), -- INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), -+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0), -+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0), -+ INIT_CKEN("I2SCLK", I2S, 14745600, 0), - */ -- INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), -+ INIT_CKEN("FICPCLK", FICP, 47923000, 0), -+}; -+ -+static struct clk_function __initdata pxa25x_clk_funcs[] = { -+ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format), -+ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL), -+ CLK_FUNC("SSP_CLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_ssp.dev, clk_dev_format), -+ CLK_FUNC("NSSPCLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_nssp.dev, clk_dev_format), -+ CLK_FUNC("ASSPCLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_assp.dev, clk_dev_format), - }; - - #ifdef CONFIG_PM -@@ -313,11 +323,13 @@ static int __init pxa25x_init(void) - int ret = 0; - - /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ -- if (cpu_is_pxa25x()) -- clks_register(&pxa25x_hwuart_clk, 1); -+ if (cpu_is_pxa25x()) { -+ clks_register(pxa25x_hwuart_clk, ARRAY_SIZE(pxa25x_hwuart_clk)); -+ } - - if (cpu_is_pxa21x() || cpu_is_pxa25x()) { - clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); -+ clk_alloc_functions(pxa25x_clk_funcs, ARRAY_SIZE(pxa25x_clk_funcs)); - - if ((ret = pxa_init_dma(16))) - return ret; -diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c -index 30ca4fd..c51e7b2 100644 ---- a/arch/arm/mach-pxa/pxa27x.c -+++ b/arch/arm/mach-pxa/pxa27x.c -@@ -126,44 +126,48 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) - return pxa27x_get_lcdclk_frequency_10khz() * 10000; - } - --static const struct clkops clk_pxa27x_lcd_ops = { -- .enable = clk_cken_enable, -- .disable = clk_cken_disable, -- .getrate = clk_pxa27x_lcd_getrate, --}; -- - static struct clk pxa27x_clks[] = { -- INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), -- INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), -+ INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_getrate), -+ INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_getrate), - -- INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), -- INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), -- INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), -+ INIT_CKEN("FFUARTCLK", FFUART, 14857000, 1), -+ INIT_CKEN("BTUARTCLK", BTUART, 14857000, 1), -+ INIT_CKEN("STUARTCLK", STUART, 14857000, 1), - -- INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), -- INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), -- INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), -- INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), -- INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), -+ INIT_CKEN("I2SCLK", I2S, 14682000, 0), -+ INIT_CKEN("I2CCLK", I2C, 32842000, 0), -+ INIT_CKEN("UDCCLK", USB, 48000000, 5), -+ INIT_CKEN("MMCCLK", MMC, 19500000, 0), -+ INIT_CKEN("FICPCLK", FICP, 48000000, 0), - -- INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev), -- INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), -- INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), -+ INIT_CKEN("USBCLK", USBHOST, 48000000, 0), -+ INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0), -+ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0), - -- INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), -- INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), -- INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), -+ INIT_CKEN("SSP1CLK", SSP1, 13000000, 0), -+ INIT_CKEN("SSP2CLK", SSP2, 13000000, 0), -+ INIT_CKEN("SSP3CLK", SSP3, 13000000, 0), - - /* -- INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), -- INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), -- INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), -- INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), -- INIT_CKEN("IMCLK", IM, 0, 0, NULL), -- INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), -+ INIT_CKEN("PWMCLK", PWM0, 13000000, 0), -+ INIT_CKEN("MSLCLK", MSL, 48000000, 0), -+ INIT_CKEN("USIMCLK", USIM, 48000000, 0), -+ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0), -+ INIT_CKEN("IMCLK", IM, 0, 0), -+ INIT_CKEN("MEMCLK", MEMC, 0, 0), - */ - }; - -+static struct clk_function __initdata pxa27x_clk_funcs[] = { -+ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format), -+ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL), -+ CLK_FUNC("SSP1CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp1.dev, clk_dev_format), -+ CLK_FUNC("SSP2CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp2.dev, clk_dev_format), -+ CLK_FUNC("SSP3CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp3.dev, clk_dev_format), -+}; -+ - #ifdef CONFIG_PM - - #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x -@@ -453,6 +457,7 @@ static int __init pxa27x_init(void) - int ret = 0; - if (cpu_is_pxa27x()) { - clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); -+ clk_alloc_functions(pxa27x_clk_funcs, ARRAY_SIZE(pxa27x_clk_funcs)); - - if ((ret = pxa_init_dma(32))) - return ret; -diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c -index ccab9da..0f8bbf3 100644 ---- a/arch/arm/mach-pxa/pxa3xx.c -+++ b/arch/arm/mach-pxa/pxa3xx.c -@@ -122,27 +122,31 @@ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) - return hsio_clk; - } - --static void clk_pxa3xx_cken_enable(struct clk *clk) -+static int clk_pxa3xx_cken_enable(struct clk *clk) - { -- unsigned long mask = 1ul << (clk->cken & 0x1f); -+ int cken = ((struct clk_cken_priv *)clk->priv)->cken; -+ unsigned long mask = 1ul << (cken & 0x1f); - - local_irq_disable(); - -- if (clk->cken < 32) -+ if (cken < 32) - CKENA |= mask; - else - CKENB |= mask; - - local_irq_enable(); -+ -+ return 0; - } - - static void clk_pxa3xx_cken_disable(struct clk *clk) - { -- unsigned long mask = 1ul << (clk->cken & 0x1f); -+ int cken = ((struct clk_cken_priv *)clk->priv)->cken; -+ unsigned long mask = 1ul << (cken & 0x1f); - - local_irq_disable(); - -- if (clk->cken < 32) -+ if (cken < 32) - CKENA &= ~mask; - else - CKENB &= ~mask; -@@ -150,55 +154,63 @@ static void clk_pxa3xx_cken_disable(struct clk *clk) - local_irq_enable(); - } - --static const struct clkops clk_pxa3xx_cken_ops = { -- .enable = clk_pxa3xx_cken_enable, -- .disable = clk_pxa3xx_cken_disable, --}; -- --static const struct clkops clk_pxa3xx_hsio_ops = { -- .enable = clk_pxa3xx_cken_enable, -- .disable = clk_pxa3xx_cken_disable, -- .getrate = clk_pxa3xx_hsio_getrate, --}; -- --#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \ -+#define PXA3xx_CKEN(_name, _cken, _rate, _delay) \ - { \ - .name = _name, \ -- .dev = _dev, \ -- .ops = &clk_pxa3xx_cken_ops, \ -+ .enable = clk_pxa3xx_cken_enable, \ -+ .disable = clk_pxa3xx_cken_disable, \ - .rate = _rate, \ -- .cken = CKEN_##_cken, \ - .delay = _delay, \ -+ .priv = &(struct clk_cken_priv) { \ -+ .cken = CKEN_##_cken, \ -+ }, \ - } - --#define PXA3xx_CK(_name, _cken, _ops, _dev) \ -+#define PXA3xx_CK(_name, _cken, _getrate) \ - { \ - .name = _name, \ -- .dev = _dev, \ -- .ops = _ops, \ -- .cken = CKEN_##_cken, \ -+ .enable = clk_pxa3xx_cken_enable, \ -+ .disable = clk_pxa3xx_cken_disable, \ -+ .getrate = _getrate, \ -+ .priv = &(struct clk_cken_priv) { \ -+ .cken = CKEN_##_cken, \ -+ }, \ - } - - static struct clk pxa3xx_clks[] = { -- PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev), -- PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL), -+ PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_getrate), -+ PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_getrate), - -- PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), -- PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), -- PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL), -+ PXA3xx_CKEN("FFUARTCLK", FFUART, 14857000, 1), -+ PXA3xx_CKEN("BTUARTCLK", BTUART, 14857000, 1), -+ PXA3xx_CKEN("STUARTCLK", STUART, 14857000, 1), - -- PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), -- PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), -- PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev), -+ PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0), -+ PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5), -+ PXA3xx_CKEN("USBCLK", USBH, 48000000, 0), - -- PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), -- PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), -- PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), -- PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), -+ PXA3xx_CKEN("SSP1CLK", SSP1, 13000000, 0), -+ PXA3xx_CKEN("SSP2CLK", SSP2, 13000000, 0), -+ PXA3xx_CKEN("SSP3CLK", SSP3, 13000000, 0), -+ PXA3xx_CKEN("SSP4CLK", SSP4, 13000000, 0), -+ -+ PXA3xx_CKEN("MMC1CLK", MMC1, 19500000, 0), -+ PXA3xx_CKEN("MMC2CLK", MMC2, 19500000, 0), -+ PXA3xx_CKEN("MMC3CLK", MMC3, 19500000, 0), -+}; - -- PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), -- PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), -- PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), -+static struct clk_function __initdata pxa3xx_clk_funcs[] = { -+ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format), -+ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format), -+ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL), -+ CLK_FUNC("SSP1CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp1.dev, clk_dev_format), -+ CLK_FUNC("SSP2CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp2.dev, clk_dev_format), -+ CLK_FUNC("SSP3CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp3.dev, clk_dev_format), -+ CLK_FUNC("SSP4CLK", "SSPCLK", clk_dev_can_get, &pxa3xx_device_ssp4.dev, clk_dev_format), -+ CLK_FUNC("MMC1CLK", "MMCCLK", clk_dev_can_get, &pxa_device_mci.dev, clk_dev_format), -+ CLK_FUNC("MMC2CLK", "MMCCLK", clk_dev_can_get, &pxa3xx_device_mci2.dev, clk_dev_format), -+ CLK_FUNC("MMC3CLK", "MMCCLK", clk_dev_can_get, &pxa3xx_device_mci3.dev, clk_dev_format), - }; - - #ifdef CONFIG_PM -@@ -255,6 +267,7 @@ static int __init pxa3xx_init(void) - - if (cpu_is_pxa3xx()) { - clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); -+ clk_alloc_functions(pxa3xx_clk_funcs, ARRAY_SIZE(pxa3xx_clk_funcs)); - - if ((ret = pxa_init_dma(32))) - return ret; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch b/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch deleted file mode 100644 index a605735df0..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 70dfe7e736467af6242c61092cb64f44d2fd50e3 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 03:01:05 +0300 -Subject: [PATCH 42/64] Use correct clock for IrDA on pxa - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/net/irda/pxaficp_ir.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c -index 8c09344..36d2ec0 100644 ---- a/drivers/net/irda/pxaficp_ir.c -+++ b/drivers/net/irda/pxaficp_ir.c -@@ -814,7 +814,7 @@ static int pxa_irda_probe(struct platform_device *pdev) - si->dev = &pdev->dev; - si->pdata = pdev->dev.platform_data; - -- si->sir_clk = clk_get(&pdev->dev, "UARTCLK"); -+ si->sir_clk = clk_get(&pdev->dev, "SIRCLK"); - si->fir_clk = clk_get(&pdev->dev, "FICPCLK"); - if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) { - err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch b/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch deleted file mode 100644 index 22b8414b2d..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 3932e0f5c4c05200c030b60606ed2eb83550f4bb Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 03:01:04 +0300 -Subject: [PATCH 43/64] Use clocklib for sa1100 sub-arch. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/Kconfig | 1 + - arch/arm/mach-sa1100/clock.c | 95 ++--------------------------------------- - 2 files changed, 6 insertions(+), 90 deletions(-) - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 47f3c73..fa47201 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -370,6 +370,7 @@ config ARCH_SA1100 - select ARCH_MTD_XIP - select GENERIC_GPIO - select GENERIC_TIME -+ select HAVE_CLOCK_LIB - help - Support for StrongARM 11x0 based boards. - -diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c -index fc97fe5..6b3cc51 100644 ---- a/arch/arm/mach-sa1100/clock.c -+++ b/arch/arm/mach-sa1100/clock.c -@@ -8,83 +8,13 @@ - #include <linux/err.h> - #include <linux/string.h> - #include <linux/clk.h> -+#include <linux/clklib.h> - #include <linux/spinlock.h> - #include <linux/mutex.h> - - #include <asm/hardware.h> - --/* -- * Very simple clock implementation - we only have one clock to -- * deal with at the moment, so we only match using the "name". -- */ --struct clk { -- struct list_head node; -- unsigned long rate; -- const char *name; -- unsigned int enabled; -- void (*enable)(void); -- void (*disable)(void); --}; -- --static LIST_HEAD(clocks); --static DEFINE_MUTEX(clocks_mutex); --static DEFINE_SPINLOCK(clocks_lock); -- --struct clk *clk_get(struct device *dev, const char *id) --{ -- struct clk *p, *clk = ERR_PTR(-ENOENT); -- -- mutex_lock(&clocks_mutex); -- list_for_each_entry(p, &clocks, node) { -- if (strcmp(id, p->name) == 0) { -- clk = p; -- break; -- } -- } -- mutex_unlock(&clocks_mutex); -- -- return clk; --} --EXPORT_SYMBOL(clk_get); -- --void clk_put(struct clk *clk) --{ --} --EXPORT_SYMBOL(clk_put); -- --int clk_enable(struct clk *clk) --{ -- unsigned long flags; -- -- spin_lock_irqsave(&clocks_lock, flags); -- if (clk->enabled++ == 0) -- clk->enable(); -- spin_unlock_irqrestore(&clocks_lock, flags); -- return 0; --} --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ -- unsigned long flags; -- -- WARN_ON(clk->enabled == 0); -- -- spin_lock_irqsave(&clocks_lock, flags); -- if (--clk->enabled == 0) -- clk->disable(); -- spin_unlock_irqrestore(&clocks_lock, flags); --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_get_rate); -- -- --static void clk_gpio27_enable(void) -+static int clk_gpio27_enable(struct clk *clk) - { - /* - * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: -@@ -93,9 +23,11 @@ static void clk_gpio27_enable(void) - GAFR |= GPIO_32_768kHz; - GPDR |= GPIO_32_768kHz; - TUCR = TUCR_3_6864MHz; -+ -+ return 0; - } - --static void clk_gpio27_disable(void) -+static void clk_gpio27_disable(struct clk *clk) - { - TUCR = 0; - GPDR &= ~GPIO_32_768kHz; -@@ -109,23 +41,6 @@ static struct clk clk_gpio27 = { - .disable = clk_gpio27_disable, - }; - --int clk_register(struct clk *clk) --{ -- mutex_lock(&clocks_mutex); -- list_add(&clk->node, &clocks); -- mutex_unlock(&clocks_mutex); -- return 0; --} --EXPORT_SYMBOL(clk_register); -- --void clk_unregister(struct clk *clk) --{ -- mutex_lock(&clocks_mutex); -- list_del(&clk->node); -- mutex_unlock(&clocks_mutex); --} --EXPORT_SYMBOL(clk_unregister); -- - static int __init clk_init(void) - { - clk_register(&clk_gpio27); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch b/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch deleted file mode 100644 index 5ca8228604..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 03fdebde257197c13c0d10882e16a2a888ab4e0a Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sat, 2 Feb 2008 20:23:01 +0300 -Subject: [PATCH 44/64] fix tmio_mmc debug compilation - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/mmc/host/tmio_mmc.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c -index 735c386..b0d38e2 100644 ---- a/drivers/mmc/host/tmio_mmc.c -+++ b/drivers/mmc/host/tmio_mmc.c -@@ -329,7 +329,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) - if (!ireg) { - disable_mmc_irqs(ctl, status & ~irq_mask); - #ifdef CONFIG_MMC_DEBUG -- WARN("tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); -+ printk(KERN_WARNING "tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); - debug_status(status); - #endif - goto out; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch b/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch deleted file mode 100644 index 10f483b89d..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch +++ /dev/null @@ -1,416 +0,0 @@ -From fe3c05491370965eb821aedc95f771b86ebab3ab Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:01:44 +0300 -Subject: [PATCH 45/64] Update tmio_ohci: - Ports management. - Basic support for ohci suspend/resume. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/mfd/tc6393xb.c | 40 ++++++++ - drivers/usb/host/ohci-tmio.c | 206 +++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 235 insertions(+), 11 deletions(-) - -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index 9439f39..5d17687 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -224,6 +224,44 @@ static int tc6393xb_ohci_enable(struct platform_device *ohci) - return 0; - } - -+static int tc6393xb_ohci_suspend(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 0; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_ohci_resume(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 1; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ - static int tc6393xb_fb_disable(struct platform_device *fb) - { - struct platform_device *dev = to_platform_device(fb->dev.parent); -@@ -423,6 +461,8 @@ static struct mfd_cell tc6393xb_cells[] = { - .name = "tmio-ohci", - .enable = tc6393xb_ohci_enable, - .disable = tc6393xb_ohci_disable, -+ .suspend = tc6393xb_ohci_suspend, -+ .resume = tc6393xb_ohci_resume, - .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), - .resources = tc6393xb_ohci_resources, - }, -diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c -index be609f3..65e3cd3 100644 ---- a/drivers/usb/host/ohci-tmio.c -+++ b/drivers/usb/host/ohci-tmio.c -@@ -75,10 +75,13 @@ struct tmio_uhccr { - u8 x07[3]; - } __attribute__((packed)); - -+#define MAX_TMIO_OHCI_PORTS 3 -+ - #define UHCCR_PM_GKEN 0x0001 - #define UHCCR_PM_CKRNEN 0x0002 - #define UHCCR_PM_USBPW1 0x0004 - #define UHCCR_PM_USBPW2 0x0008 -+#define UHCCR_PM_USBPW3 0x0008 - #define UHCCR_PM_PMEE 0x0100 - #define UHCCR_PM_PMES 0x8000 - -@@ -86,44 +89,96 @@ struct tmio_uhccr { - - struct tmio_hcd { - struct tmio_uhccr __iomem *ccr; -+ spinlock_t lock; /* protects RMW cycles and disabled_ports data */ -+ bool disabled_ports[MAX_TMIO_OHCI_PORTS]; - }; - - #define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1)) - #define ohci_to_tmio(ohci) ((struct tmio_hcd *)(ohci + 1)) - -+struct indexed_device_attribute{ -+ struct device_attribute dev_attr; -+ int index; -+}; -+#define to_indexed_dev_attr(_dev_attr) \ -+ container_of(_dev_attr, struct indexed_device_attribute, dev_attr) -+ -+#define INDEXED_ATTR(_name, _mode, _show, _store, _index) \ -+ { .dev_attr = __ATTR(_name ## _index, _mode, _show, _store), \ -+ .index = _index } -+ -+#define INDEXED_DEVICE_ATTR(_name, _mode, _show, _store, _index) \ -+struct indexed_device_attribute dev_attr_##_name ## _index \ -+ = INDEXED_ATTR(_name, _mode, _show, _store, _index) -+ -+static bool disabled_tmio_ports[MAX_TMIO_OHCI_PORTS]; -+module_param_array(disabled_tmio_ports, bool, NULL, 0644); -+MODULE_PARM_DESC(disabled_tmio_ports, -+ "disable specified TC6393 usb ports (default: all enabled)"); -+ - /*-------------------------------------------------------------------------*/ - -+static void tmio_write_pm(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ u16 pm; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | -+ UHCCR_PM_PMEE | UHCCR_PM_PMES; -+ -+ if (tmio->disabled_ports[0]) -+ pm |= UHCCR_PM_USBPW1; -+ if (tmio->disabled_ports[1]) -+ pm |= UHCCR_PM_USBPW2; -+ if (tmio->disabled_ports[2]) -+ pm |= UHCCR_PM_USBPW3; -+ -+ iowrite16(pm, &ccr->pm); -+ spin_unlock_irqrestore(&tmio->lock, flags); -+} -+ - static void tmio_stop_hc(struct platform_device *dev) - { - struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - struct tmio_uhccr __iomem *ccr = tmio->ccr; - u16 pm; - -- pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | UHCCR_PM_USBPW1 | UHCCR_PM_USBPW2; -+ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN; -+ switch (ohci->num_ports) { -+ default: -+ dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports); -+ case 3: -+ pm |= UHCCR_PM_USBPW3; -+ case 2: -+ pm |= UHCCR_PM_USBPW2; -+ case 1: -+ pm |= UHCCR_PM_USBPW1; -+ } - iowrite8(0, &ccr->intc); - iowrite8(0, &ccr->ilme); - iowrite16(0, &ccr->basel); - iowrite16(0, &ccr->baseh); -- iowrite16(pm, &ccr->pm); -+ iowrite16(pm, &ccr->pm); - - cell->disable(dev); - } - - static void tmio_start_hc(struct platform_device *dev) - { -- struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - struct tmio_uhccr __iomem *ccr = tmio->ccr; -- u16 pm; - unsigned long base = hcd->rsrc_start; - -- pm = UHCCR_PM_CKRNEN | UHCCR_PM_GKEN | UHCCR_PM_PMEE | UHCCR_PM_PMES; -- cell->enable(dev); -- -- iowrite16(pm, &ccr->pm); -+ tmio_write_pm(dev); - iowrite16(base, &ccr->basel); - iowrite16(base >> 16, &ccr->baseh); - iowrite8(1, &ccr->ilme); -@@ -133,9 +188,56 @@ static void tmio_start_hc(struct platform_device *dev) - ioread8(&ccr->revid), hcd->rsrc_start, hcd->irq); - } - -+static ssize_t tmio_disabled_port_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct usb_hcd *hcd = dev_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ int index = to_indexed_dev_attr(attr)->index; -+ return snprintf(buf, PAGE_SIZE, "%c", -+ tmio->disabled_ports[index-1]? 'Y': 'N'); -+} -+ -+static ssize_t tmio_disabled_port_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct usb_hcd *hcd = dev_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ int index = to_indexed_dev_attr(attr)->index; -+ -+ if (!count) -+ return -EINVAL; -+ -+ switch (buf[0]) { -+ case 'y': case 'Y': case '1': -+ tmio->disabled_ports[index-1] = true; -+ break; -+ case 'n': case 'N': case '0': -+ tmio->disabled_ports[index-1] = false; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ tmio_write_pm(to_platform_device(dev)); -+ -+ return 1; -+} -+ -+ -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 1); -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 2); -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 3); -+ - static int usb_hcd_tmio_probe(const struct hc_driver *driver, - struct platform_device *dev) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct resource *config = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONFIG); - struct resource *regs = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONTROL); - struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -@@ -159,6 +261,12 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver, - - tmio = hcd_to_tmio(hcd); - -+ spin_lock_init(&tmio->lock); -+ -+ memcpy(tmio->disabled_ports, -+ disabled_tmio_ports, -+ sizeof(disabled_tmio_ports)); -+ - tmio->ccr = ioremap(config->start, config->end - config->start + 1); - if (!tmio->ccr) { - retval = -ENOMEM; -@@ -183,17 +291,46 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver, - if (retval) - goto err_dmabounce_register_dev; - -+ retval = cell->enable(dev); -+ if (retval) -+ goto err_enable; -+ - tmio_start_hc(dev); - ohci = hcd_to_ohci(hcd); - ohci_hcd_init(ohci); - - retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); -+ if (retval) -+ goto err_add_hcd; -+ -+ switch (ohci->num_ports) { -+ default: -+ dev_err(&dev->dev, "Unsupported amount of ports: %d\n", -+ ohci->num_ports); -+ case 3: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port3.dev_attr); -+ case 2: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port2.dev_attr); -+ case 1: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port1.dev_attr); -+ } - - if (retval == 0) - return retval; - -- tmio_stop_hc(dev); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr); -+ -+ usb_remove_hcd(hcd); - -+err_add_hcd: -+ tmio_stop_hc(dev); -+ cell->disable(dev); -+err_enable: - dmabounce_unregister_dev(&dev->dev); - err_dmabounce_register_dev: - dma_release_declared_memory(&dev->dev); -@@ -212,6 +349,9 @@ static void usb_hcd_tmio_remove(struct usb_hcd *hcd, struct platform_device *dev - { - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr); - usb_remove_hcd(hcd); - tmio_stop_hc(dev); - dmabounce_unregister_dev(&dev->dev); -@@ -297,13 +437,22 @@ static u64 dma_mask = DMA_32BIT_MASK; - static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) - { - struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -+ int retval; - - dev->dev.dma_mask = &dma_mask; - dev->dev.coherent_dma_mask = DMA_32BIT_MASK; - -+ /* FIXME: move dmabounce checkers to tc6393xb core? */ - dmabounce_register_checker(tmio_dmabounce_check, sram); - -- return usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev); -+ retval = usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev); -+ -+ if (retval == 0) -+ return retval; -+ -+ dmabounce_remove_checker(tmio_dmabounce_check, sram); -+ -+ return retval; - } - - static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) -@@ -323,14 +472,31 @@ static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) - #ifdef CONFIG_PM - static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ unsigned long flags; -+ u8 misc; -+ int ret; - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - -- tmio_stop_hc(dev); -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ misc = ioread8(&ccr->misc); -+ misc |= 1 << 3; /* USSUSP */ -+ iowrite8(misc, &ccr->misc); -+ -+ spin_unlock_irqrestore(&tmio->lock, flags); -+ -+ ret = cell->suspend(dev); -+ if (ret) -+ return ret; -+ - hcd->state = HC_STATE_SUSPENDED; - dev->dev.power.power_state = PMSG_SUSPEND; - -@@ -339,15 +505,33 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s - - static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ unsigned long flags; -+ u8 misc; -+ int ret; - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - -+ ret = cell->resume(dev); -+ if (ret) -+ return ret; -+ - tmio_start_hc(dev); - -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ misc = ioread8(&ccr->misc); -+ misc &= ~(1 << 3); /* USSUSP */ -+ iowrite8(misc, &ccr->misc); -+ -+ spin_unlock_irqrestore(&tmio->lock, flags); -+ - dev->dev.power.power_state = PMSG_ON; - usb_hcd_resume_root_hub(hcd); - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch b/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch deleted file mode 100644 index c4b57cb2d1..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch +++ /dev/null @@ -1,66 +0,0 @@ -From edaab7ec86235871d8ad219a1d225ce12f67f8af Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:13:29 +0300 -Subject: [PATCH 46/64] patch tc6393xb-cleanup - ---- - drivers/mfd/tc6393xb.c | 20 ++++++++++++-------- - 1 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index 5d17687..dfae61d 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -590,16 +590,8 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume) - struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- int ret; - int i; - -- if (resume) -- ret = tcpd->resume(dev); -- else -- ret = tcpd->enable(dev); -- if (ret) -- return ret; -- - iowrite8(resume ? - tc6393xb->suspend_state.fer.raw : - 0, &scr->fer); -@@ -664,6 +656,10 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) - goto err_ioremap; - } - -+ retval = tcpd->enable(dev); -+ if (retval) -+ goto err_enable; -+ - retval = tc6393xb_hw_init(dev, 0); - if (retval) - goto err_hw_init; -@@ -690,6 +686,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) - tc6393xb_detach_irq(dev); - - err_hw_init: -+ tcpd->disable(dev); -+err_enable: - iounmap(tc6393xb->scr); - err_ioremap: - release_resource(rscr); -@@ -743,6 +741,12 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) - - static int tc6393xb_resume(struct platform_device *dev) - { -+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; -+ int ret = tcpd->resume(dev); -+ -+ if (ret) -+ return ret; -+ - return tc6393xb_hw_init(dev, 1); - } - #else --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch b/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch deleted file mode 100644 index 54e88253d1..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch +++ /dev/null @@ -1,412 +0,0 @@ -From c18b8e34c39ec0d395988318e6651076a748d6bd Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Tue, 12 Feb 2008 04:40:54 +0300 -Subject: [PATCH 47/64] tc6393xb: use bitmasks instead of bit-field structs - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/mfd/tc6393xb.c | 162 ++++++++++++++++++++++++----------------- - include/linux/mfd/tc6393xb.h | 63 +++------------- - 2 files changed, 107 insertions(+), 118 deletions(-) - -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index dfae61d..1a394e4 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -24,6 +24,31 @@ - #include <linux/mfd/tmio.h> - #include <linux/mfd/tc6393xb.h> - -+#define TC6393XB_FER_USBEN BIT(0) /* USB host enable */ -+#define TC6393XB_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */ -+#define TC6393XB_FER_SLCDEN BIT(2) /* SLCD enable */ -+ -+enum pincontrol { -+ opendrain = 0, -+ tristate = 1, -+ pushpull = 2, -+ /* reserved = 3, */ -+}; -+ -+#define TC6393XB_MCR_RDY_MASK (3 << 0) -+#define TC6393XB_MCR_RDY_OPENDRAIN (0 << 0) -+#define TC6393XB_MCR_RDY_TRISTATE (1 << 0) -+#define TC6393XB_MCR_RDY_PUSHPULL (2 << 0) -+#define TC6393XB_MCR_RDY_UNK BIT(2) -+#define TC6393XB_MCR_RDY_EN BIT(3) -+#define TC6393XB_MCR_INT_MASK (3 << 4) -+#define TC6393XB_MCR_INT_OPENDRAIN (0 << 4) -+#define TC6393XB_MCR_INT_TRISTATE (1 << 4) -+#define TC6393XB_MCR_INT_PUSHPULL (2 << 4) -+#define TC6393XB_MCR_INT_UNK BIT(6) -+#define TC6393XB_MCR_INT_EN BIT(7) -+/* bits 8 - 16 are unknown */ -+ - struct tc6393xb_scr { - u8 x00[8]; - u8 revid; /* 0x08 Revision ID */ -@@ -74,8 +99,8 @@ struct tc6393xb { - spinlock_t lock; /* protects RMW cycles */ - - struct { -- union tc6393xb_scr_fer fer; -- union tc6393xb_scr_ccr ccr; -+ u8 fer; -+ u16 ccr; - u8 gpi_bcr[4]; - } suspend_state; - -@@ -90,13 +115,13 @@ static int tc6393xb_mmc_enable(struct platform_device *mmc) { - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.ck32ken = 1; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr |= TC6393XB_CCR_CK32K; -+ iowrite16(ccr, &scr->ccr); - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -@@ -106,13 +131,13 @@ static int tc6393xb_mmc_disable(struct platform_device *mmc) { - struct platform_device *dev = to_platform_device(mmc->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.ck32ken = 0; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr &= ~TC6393XB_CCR_CK32K; -+ iowrite16(ccr, &scr->ccr); - spin_unlock_irqrestore(&tc6393xb->lock, flags); - - return 0; -@@ -148,14 +173,17 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_fer fer; -+ u8 fer; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- fer.raw = ioread8(&scr->fer); -- fer.bits.slcden = on ? 1 : 0; -- iowrite8(fer.raw, &scr->fer); -+ fer = ioread8(&scr->fer); -+ if (on) -+ fer |= TC6393XB_FER_SLCDEN; -+ else -+ fer &= ~TC6393XB_FER_SLCDEN; -+ iowrite8(fer, &scr->fer); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -181,19 +209,19 @@ static int tc6393xb_ohci_disable(struct platform_device *ohci) - struct platform_device *dev = to_platform_device(ohci->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -- union tc6393xb_scr_fer fer; -+ u16 ccr; -+ u8 fer; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- fer.raw = ioread8(&scr->fer); -- fer.bits.usben = 0; -- iowrite8(fer.raw, &scr->fer); -+ fer = ioread8(&scr->fer); -+ fer &= ~TC6393XB_FER_USBEN; -+ iowrite8(fer, &scr->fer); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.usbcken = 0; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr &= ~TC6393XB_CCR_USBCK; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -205,19 +233,19 @@ static int tc6393xb_ohci_enable(struct platform_device *ohci) - struct platform_device *dev = to_platform_device(ohci->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -- union tc6393xb_scr_fer fer; -+ u16 ccr; -+ u8 fer; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.usbcken = 1; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr |= TC6393XB_CCR_USBCK; -+ iowrite16(ccr, &scr->ccr); - -- fer.raw = ioread8(&scr->fer); -- fer.bits.usben = 1; -- iowrite8(fer.raw, &scr->fer); -+ fer = ioread8(&scr->fer); -+ fer |= TC6393XB_FER_USBEN; -+ iowrite8(fer, &scr->fer); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -229,14 +257,14 @@ static int tc6393xb_ohci_suspend(struct platform_device *ohci) - struct platform_device *dev = to_platform_device(ohci->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.usbcken = 0; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr &= ~TC6393XB_CCR_USBCK; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -248,14 +276,14 @@ static int tc6393xb_ohci_resume(struct platform_device *ohci) - struct platform_device *dev = to_platform_device(ohci->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.usbcken = 1; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr |= TC6393XB_CCR_USBCK; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -267,8 +295,8 @@ static int tc6393xb_fb_disable(struct platform_device *fb) - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -- union tc6393xb_scr_fer fer; -+ u16 ccr; -+ u8 fer; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); -@@ -276,14 +304,13 @@ static int tc6393xb_fb_disable(struct platform_device *fb) - /* - * FIXME: is this correct or it should be moved to other _disable? - */ -- fer.raw = ioread8(&scr->fer); -- fer.bits.slcden = 0; --/* fer.bits.lcdcven = 0; */ -- iowrite8(fer.raw, &scr->fer); -+ fer = ioread8(&scr->fer); -+ fer &= ~TC6393XB_FER_SLCDEN; -+ iowrite8(fer, &scr->fer); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.mclksel = disable; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_OFF; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -295,14 +322,14 @@ static int tc6393xb_fb_enable(struct platform_device *fb) - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.mclksel = m48MHz; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_48; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -314,14 +341,14 @@ static int tc6393xb_fb_suspend(struct platform_device *fb) - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.mclksel = disable; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_OFF; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -333,14 +360,14 @@ static int tc6393xb_fb_resume(struct platform_device *fb) - struct platform_device *dev = to_platform_device(fb->dev.parent); - struct tc6393xb *tc6393xb = platform_get_drvdata(dev); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -- union tc6393xb_scr_ccr ccr; -+ u16 ccr; - unsigned long flags; - - spin_lock_irqsave(&tc6393xb->lock, flags); - -- ccr.raw = ioread16(&scr->ccr); -- ccr.bits.mclksel = m48MHz; -- iowrite16(ccr.raw, &scr->ccr); -+ ccr = ioread16(&scr->ccr); -+ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_48; -+ iowrite16(ccr, &scr->ccr); - - spin_unlock_irqrestore(&tc6393xb->lock, flags); - -@@ -592,14 +619,15 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume) - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; - int i; - -- iowrite8(resume ? -- tc6393xb->suspend_state.fer.raw : -- 0, &scr->fer); -+ iowrite8(resume ? tc6393xb->suspend_state.fer : 0, -+ &scr->fer); - iowrite16(tcpd->scr_pll2cr, &scr->pll2cr); - iowrite16(resume? -- tc6393xb->suspend_state.ccr.raw : -- tcpd->scr_ccr.raw, &scr->ccr); -- iowrite16(tcpd->scr_mcr.raw, &scr->mcr); -+ tc6393xb->suspend_state.ccr : -+ tcpd->scr_ccr, &scr->ccr); -+ iowrite16(TC6393XB_MCR_RDY_OPENDRAIN | TC6393XB_MCR_RDY_UNK | TC6393XB_MCR_RDY_EN | -+ TC6393XB_MCR_INT_OPENDRAIN | TC6393XB_MCR_INT_UNK | TC6393XB_MCR_INT_EN | -+ BIT(15), &scr->mcr); - iowrite16(tcpd->scr_gper, &scr->gper); - iowrite8(0, &scr->irr); - iowrite8(0xbf, &scr->imr); -@@ -730,8 +758,8 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) - int i; - - -- tc6393xb->suspend_state.ccr.raw = ioread16(&scr->ccr); -- tc6393xb->suspend_state.fer.raw = ioread8(&scr->fer); -+ tc6393xb->suspend_state.ccr = ioread16(&scr->ccr); -+ tc6393xb->suspend_state.fer = ioread8(&scr->fer); - for (i = 0; i < 4; i++) - tc6393xb->suspend_state.gpi_bcr[i] = - ioread8(scr->gpi_bcr + i); -diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h -index e699294..2c69f63 100644 ---- a/include/linux/mfd/tc6393xb.h -+++ b/include/linux/mfd/tc6393xb.h -@@ -20,60 +20,21 @@ - #include <linux/mfd-core.h> - #include <linux/mfd/tmio.h> - --union tc6393xb_scr_fer { -- u8 raw; --struct { -- unsigned usben:1; /* D0 USB enable */ -- unsigned lcdcven:1; /* D1 polysylicon TFT enable */ -- unsigned slcden:1; /* D2 SLCD enable */ --} __attribute__ ((packed)) bits; --} __attribute__ ((packed)); -- --union tc6393xb_scr_ccr { -- u16 raw; --struct { -- unsigned ck32ken:1; /* D0 SD host clock enable */ -- unsigned usbcken:1; /* D1 USB host clock enable */ -- unsigned x00:2; -- unsigned sharp:1; /* D4 ??? set in Sharp's code */ -- unsigned x01:3; -- enum { disable = 0, -- m12MHz = 1, -- m24MHz = 2, -- m48MHz = 3, -- } mclksel:3; /* D10-D8 LCD controller clock */ -- unsigned x02:1; -- enum { h24MHz = 0, -- h48MHz = 1, -- } hclksel:2; /* D13-D12 host bus clock */ -- unsigned x03:2; --} __attribute__ ((packed)) bits; --} __attribute__ ((packed)); -- --enum pincontrol { -- opendrain = 0, -- tristate = 1, -- pushpull = 2, -- /* reserved = 3, */ --}; -- --union tc6393xb_scr_mcr { -- u16 raw; --struct { -- enum pincontrol rdyst:2; /* D1-D0 HRDY control */ -- unsigned x00:1; -- unsigned aren:1; /* D3 HRDY pull up resistance cut off */ -- enum pincontrol intst:2; /* D5-D4 #HINT control */ -- unsigned x01:1; -- unsigned aien:1; /* D7 #HINT pull up resitance cut off */ -- unsigned x02:8; --} __attribute__ ((packed)) bits; --} __attribute__ ((packed)); -+#define TC6393XB_CCR_CK32K BIT(0) -+#define TC6393XB_CCR_USBCK BIT(1) -+#define TC6393XB_CCR_UNK1 BIT(4) -+#define TC6393XB_CCR_MCLK_MASK (7 << 8) -+#define TC6393XB_CCR_MCLK_OFF (0 << 8) -+#define TC6393XB_CCR_MCLK_12 (1 << 8) -+#define TC6393XB_CCR_MCLK_24 (2 << 8) -+#define TC6393XB_CCR_MCLK_48 (3 << 8) -+#define TC6393XB_CCR_HCLK_MASK (3 << 12) -+#define TC6393XB_CCR_HCLK_24 (0 << 12) -+#define TC6393XB_CCR_HCLK_48 (1 << 12) - - struct tc6393xb_platform_data { - u16 scr_pll2cr; /* PLL2 Control */ -- union tc6393xb_scr_ccr scr_ccr; /* Clock Control */ -- union tc6393xb_scr_mcr scr_mcr; /* Mode Control */ -+ u16 scr_ccr; /* Clock Control */ - u16 scr_gper; /* GP Enable */ - u32 scr_gpo_doecr; /* GPO Data OE Control */ - u32 scr_gpo_dsr; /* GPO Data Set */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch deleted file mode 100644 index ef47d6cc21..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 4fb4d83c7090ea21619bb652f2ea9b5c8c0c453e Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 01:42:58 +0300 -Subject: [PATCH 48/64] tc6393xb GPIO support - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/mfd/tc6393xb.c | 124 ++++++++++++++++++++++++++++++++++++++++-- - include/linux/mfd/tc6393xb.h | 2 +- - 2 files changed, 119 insertions(+), 7 deletions(-) - -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index 1a394e4..9001687 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -49,6 +49,8 @@ enum pincontrol { - #define TC6393XB_MCR_INT_EN BIT(7) - /* bits 8 - 16 are unknown */ - -+#include <asm/gpio.h> -+ - struct tc6393xb_scr { - u8 x00[8]; - u8 revid; /* 0x08 Revision ID */ -@@ -96,6 +98,8 @@ struct tc6393xb_scr { - struct tc6393xb { - struct tc6393xb_scr __iomem *scr; - -+ struct gpio_chip gpio; -+ - spinlock_t lock; /* protects RMW cycles */ - - struct { -@@ -513,6 +517,96 @@ static struct mfd_cell tc6393xb_cells[] = { - - /*--------------------------------------------------------------------------*/ - -+static int tc6393xb_gpio_get(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ struct tc6393xb *tc6393xb = container_of(chip, -+ struct tc6393xb, gpio); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ u32 mask = 1 << offset; -+ -+ return tmio_ioread32(scr->gpo_dsr) & mask; -+} -+ -+static void __tc6393xb_gpio_set(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ struct tc6393xb *tc6393xb = container_of(chip, -+ struct tc6393xb, gpio); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ u32 dsr; -+ -+ dsr = tmio_ioread32(scr->gpo_dsr); -+ if (value) -+ dsr |= (1L << offset); -+ else -+ dsr &= ~(1L << offset); -+ -+ tmio_iowrite32(dsr, scr->gpo_dsr); -+} -+ -+static void tc6393xb_gpio_set(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ struct tc6393xb *tc6393xb = container_of(chip, -+ struct tc6393xb, gpio); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ __tc6393xb_gpio_set(chip, offset, value); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+} -+ -+static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ struct tc6393xb *tc6393xb = container_of(chip, -+ struct tc6393xb, gpio); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned long flags; -+ u32 doecr; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ doecr = tmio_ioread32(scr->gpo_doecr); -+ -+ doecr &= ~(1 << offset); -+ -+ tmio_iowrite32(doecr, scr->gpo_doecr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ struct tc6393xb *tc6393xb = container_of(chip, -+ struct tc6393xb, gpio); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ unsigned long flags; -+ u32 doecr; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ doecr = tmio_ioread32(scr->gpo_doecr); -+ -+ doecr |= (1 << offset); -+ -+ tmio_iowrite32(doecr, scr->gpo_doecr); -+ -+ __tc6393xb_gpio_set(chip, offset, value); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+/*--------------------------------------------------------------------------*/ -+ - static void - tc6393xb_irq(unsigned int irq, struct irq_desc *desc) - { -@@ -631,10 +725,8 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume) - iowrite16(tcpd->scr_gper, &scr->gper); - iowrite8(0, &scr->irr); - iowrite8(0xbf, &scr->imr); -- iowrite16(tcpd->scr_gpo_dsr, scr->gpo_dsr + 0); -- iowrite16(tcpd->scr_gpo_dsr >> 16, scr->gpo_dsr + 1); -- iowrite16(tcpd->scr_gpo_doecr, scr->gpo_doecr + 0); -- iowrite16(tcpd->scr_gpo_doecr >> 16, scr->gpo_doecr + 1); -+ tmio_iowrite32(tcpd->scr_gpo_dsr, &scr->gpo_dsr); -+ tmio_iowrite32(tcpd->scr_gpo_doecr, &scr->gpo_doecr); - - if (resume) - for (i = 0; i < 4; i++) -@@ -650,7 +742,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) - struct tc6393xb *tc6393xb; - struct resource *iomem; - struct resource *rscr; -- int retval; -+ int retval, temp; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!iomem) -@@ -696,6 +788,18 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) - ioread8(&tc6393xb->scr->revid), - (unsigned long) iomem->start, tc6393xb->irq); - -+ tc6393xb->gpio.label = "tc6393xb"; -+ tc6393xb->gpio.base = tcpd->gpio_base; -+ tc6393xb->gpio.ngpio = 16; /* FIXME: actually 32, but I'm not sure */ -+ tc6393xb->gpio.set = tc6393xb_gpio_set; -+ tc6393xb->gpio.get = tc6393xb_gpio_get; -+ tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input; -+ tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output; -+ -+ retval = gpiochip_add(&tc6393xb->gpio); -+ if (retval) -+ goto err_gpio_add; -+ - if (tc6393xb->irq) - tc6393xb_attach_irq(dev); - -@@ -713,6 +817,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) - if (tc6393xb->irq) - tc6393xb_detach_irq(dev); - -+err_gpio_add: -+ temp = gpiochip_remove(&tc6393xb->gpio); - err_hw_init: - tcpd->disable(dev); - err_enable: -@@ -734,6 +840,12 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) { - if (tc6393xb->irq) - tc6393xb_detach_irq(dev); - -+ ret = gpiochip_remove(&tc6393xb->gpio); -+ if (ret) { -+ dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret); -+ return ret; -+ } -+ - ret = tcpd->disable(dev); - - iounmap(tc6393xb->scr); -@@ -804,7 +916,7 @@ static void __exit tc6393xb_exit(void) - platform_driver_unregister(&tc6393xb_driver); - } - --module_init(tc6393xb_init); -+subsys_initcall(tc6393xb_init); - module_exit(tc6393xb_exit); - - MODULE_LICENSE("GPL"); -diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h -index 2c69f63..97c4c7c 100644 ---- a/include/linux/mfd/tc6393xb.h -+++ b/include/linux/mfd/tc6393xb.h -@@ -45,6 +45,7 @@ struct tc6393xb_platform_data { - int (*resume)(struct platform_device *dev); - - int irq_base; /* a base for cascaded irq */ -+ int gpio_base; - - struct tmio_nand_data *nand_data; - struct tmio_fb_data *fb_data; -@@ -54,7 +55,6 @@ extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on); - extern int tc6393xb_lcd_mode(struct platform_device *fb_dev, - struct fb_videomode *mode); - -- - /* - * Relative to irq_base - */ --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch b/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch deleted file mode 100644 index ff1186cb71..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch +++ /dev/null @@ -1,373 +0,0 @@ -From 30588bdd5c5cdd9fbe269643f582862a76f09efb Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Tue, 12 Feb 2008 04:52:48 +0300 -Subject: [PATCH 49/64] platform support for TMIO on tosa - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 179 ++++++++++++++++++++++++++++++++++++++- - include/asm-arm/arch-pxa/irqs.h | 1 + - include/asm-arm/arch-pxa/tosa.h | 45 ++++++++-- - sound/soc/pxa/tosa.c | 3 +- - 4 files changed, 216 insertions(+), 12 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index 5268e94..e2eec0f 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -18,7 +18,13 @@ - #include <linux/major.h> - #include <linux/fs.h> - #include <linux/interrupt.h> -+#include <linux/delay.h> -+#include <linux/fb.h> - #include <linux/mmc/host.h> -+#include <linux/mfd/tc6393xb.h> -+#include <linux/mfd/tmio.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/partitions.h> - #include <linux/pm.h> - #include <linux/delay.h> - #include <linux/gpio_keys.h> -@@ -298,12 +304,183 @@ static struct platform_device tosaled_device = { - .id = -1, - }; - -+/* -+ * Toshiba Mobile IO Controller -+ */ -+static struct resource tc6393xb_resources[] = { -+ [0] = { -+ .start = TOSA_LCDC_PHYS, -+ .end = TOSA_LCDC_PHYS + 0x3ffffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ -+ [1] = { -+ .start = TOSA_IRQ_GPIO_TC6393XB_INT, -+ .end = TOSA_IRQ_GPIO_TC6393XB_INT, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+ -+static int tosa_tc6393xb_enable(struct platform_device *dev) -+{ -+ -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND); -+ reset_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */ -+ pxa_gpio_mode(GPIO11_3_6MHz_MD); -+ pxa_gpio_mode(GPIO18_RDY_MD); -+ mdelay(1); -+ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND); -+ mdelay(10); -+ set_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */ -+ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ -+ return 0; -+} -+ -+static int tosa_tc6393xb_disable(struct platform_device *dev) -+{ -+ -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND); -+ reset_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */ -+ pxa_gpio_mode(GPIO11_3_6MHz_MD|GPIO_OUT); -+ GPSR0 = GPIO_bit(GPIO11_3_6MHz); -+ -+ return 0; -+} -+ -+static int tosa_tc6393xb_resume(struct platform_device *dev) -+{ -+ -+ pxa_gpio_mode(GPIO11_3_6MHz_MD); -+ pxa_gpio_mode(GPIO18_RDY_MD); -+ mdelay(1); -+ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND); -+ mdelay(10); -+ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ mdelay(10); -+ -+ return 0; -+} -+ -+static int tosa_tc6393xb_suspend(struct platform_device *dev) -+{ -+ -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND); -+ pxa_gpio_mode(GPIO11_3_6MHz_MD|GPIO_OUT); -+ GPSR0 = GPIO_bit(GPIO11_3_6MHz); -+ -+ return 0; -+} -+ -+static struct mtd_partition tosa_nand_partition[] = { -+ { -+ .name = "smf", -+ .offset = 0, -+ .size = 7 * 1024 * 1024, -+ }, -+ { -+ .name = "root", -+ .offset = MTDPART_OFS_APPEND, -+ .size = 28 * 1024 * 1024, -+ }, -+ { -+ .name = "home", -+ .offset = MTDPART_OFS_APPEND, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; -+ -+static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { -+ .options = 0, -+ .offs = 4, -+ .len = 2, -+ .pattern = scan_ff_pattern -+}; -+ -+static struct tmio_nand_data tosa_tc6393xb_nand_config = { -+ .num_partitions = ARRAY_SIZE(tosa_nand_partition), -+ .partition = tosa_nand_partition, -+ .badblock_pattern = &tosa_tc6393xb_nand_bbt, -+}; -+ -+static struct fb_videomode tosa_tc6393xb_lcd_mode[] = { -+ { -+ .xres = 480, -+ .yres = 640, -+ .pixclock = 0x002cdf00,/* PLL divisor */ -+ .left_margin = 0x004c, -+ .right_margin = 0x005b, -+ .upper_margin = 0x0001, -+ .lower_margin = 0x000d, -+ .hsync_len = 0x0002, -+ .vsync_len = 0x0001, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .vmode = FB_VMODE_NONINTERLACED, -+ },{ -+ .xres = 240, -+ .yres = 320, -+ .pixclock = 0x00e7f203,/* PLL divisor */ -+ .left_margin = 0x0024, -+ .right_margin = 0x002f, -+ .upper_margin = 0x0001, -+ .lower_margin = 0x000d, -+ .hsync_len = 0x0002, -+ .vsync_len = 0x0001, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .vmode = FB_VMODE_NONINTERLACED, -+ } -+}; -+ -+static struct tmio_fb_data tosa_tc6393xb_fb_config = { -+ .lcd_set_power = tc6393xb_lcd_set_power, -+ .lcd_mode = tc6393xb_lcd_mode, -+ .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode), -+ .modes = &tosa_tc6393xb_lcd_mode[0], -+}; -+ -+static struct tc6393xb_platform_data tosa_tc6393xb_setup = { -+ .scr_pll2cr = 0x0cc1, -+ .scr_ccr = TC6393XB_CCR_UNK1 | TC6393XB_CCR_HCLK_48, -+ .scr_gper = 0x3300, -+ .scr_gpo_dsr = TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF_JC, -+ .scr_gpo_doecr = TOSA_TC6393XB_GPO_OE, -+ -+ .irq_base = IRQ_BOARD_START, -+ -+ .enable = tosa_tc6393xb_enable, -+ .disable = tosa_tc6393xb_disable, -+ .suspend = tosa_tc6393xb_suspend, -+ .resume = tosa_tc6393xb_resume, -+ -+ .nand_data = &tosa_tc6393xb_nand_config, -+ .fb_data = &tosa_tc6393xb_fb_config, -+}; -+ -+ -+struct platform_device tc6393xb_device = { -+ .name = "tc6393xb", -+ .id = -1, -+ .dev = { -+ .platform_data = &tosa_tc6393xb_setup, -+ }, -+ .num_resources = ARRAY_SIZE(tc6393xb_resources), -+ .resource = tc6393xb_resources, -+}; -+EXPORT_SYMBOL(tc6393xb_device); -+ - static struct platform_device *devices[] __initdata = { - &tosascoop_device, - &tosascoop_jc_device, - &tosakbd_device, - &tosa_gpio_keys_device, - &tosaled_device, -+ &tc6393xb_device, - }; - - static void tosa_poweroff(void) -@@ -332,7 +509,7 @@ static void __init tosa_init(void) - arm_pm_restart = tosa_restart; - - pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); -- pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); -+ pxa_gpio_mode(TOSA_GPIO_TC6393XB_INT | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); - - /* setup sleep mode values */ -diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h -index b76ee6d..bf622d8 100644 ---- a/include/asm-arm/arch-pxa/irqs.h -+++ b/include/asm-arm/arch-pxa/irqs.h -@@ -180,6 +180,7 @@ - #define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1) - #elif defined(CONFIG_ARCH_LUBBOCK) || \ - defined(CONFIG_MACH_LOGICPD_PXA270) || \ -+ defined(CONFIG_MACH_TOSA) || \ - defined(CONFIG_MACH_MAINSTONE) - #define NR_IRQS (IRQ_BOARD_END) - #else -diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h -index c05e4fa..1b202b2 100644 ---- a/include/asm-arm/arch-pxa/tosa.h -+++ b/include/asm-arm/arch-pxa/tosa.h -@@ -20,11 +20,35 @@ - /* Jacket Scoop */ - #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000) - -+#define TC6393XB_GPIO(i) (1 << (i)) -+/* -+ * TC6393 GPIOs -+ */ -+#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0) -+#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1) -+#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3) -+#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4) -+#define TOSA_TC6393XB_CHARGE_OFF TC6393XB_GPIO(6) -+#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7) -+#define TOSA_TC6393XB_BAT0_V_ON TC6393XB_GPIO(9) -+#define TOSA_TC6393XB_BAT1_V_ON TC6393XB_GPIO(10) -+#define TOSA_TC6393XB_BU_CHRG_ON TC6393XB_GPIO(11) -+#define TOSA_TC6393XB_BAT_SW_ON TC6393XB_GPIO(12) -+#define TOSA_TC6393XB_BAT0_TH_ON TC6393XB_GPIO(14) -+#define TOSA_TC6393XB_BAT1_TH_ON TC6393XB_GPIO(15) -+ -+#define TOSA_TC6393XB_GPO_OE (TOSA_TC6393XB_TG_ON | TOSA_TC6393XB_L_MUTE | TOSA_TC6393XB_BL_C20MA | \ -+ TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF | \ -+ TOSA_TC6393XB_CHARGE_OFF_JC | TOSA_TC6393XB_BAT0_V_ON | \ -+ TOSA_TC6393XB_BAT1_V_ON | TOSA_TC6393XB_BU_CHRG_ON | \ -+ TOSA_TC6393XB_BAT_SW_ON | TOSA_TC6393XB_BAT0_TH_ON | \ -+ TOSA_TC6393XB_BAT1_TH_ON) -+ - /* - * SCOOP2 internal GPIOs - */ - #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 --#define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12 -+#define TOSA_SCOOP_TC6393XB_REST_IN SCOOP_GPCR_PA12 - #define TOSA_SCOOP_IR_POWERDWN SCOOP_GPCR_PA13 - #define TOSA_SCOOP_SD_WP SCOOP_GPCR_PA14 - #define TOSA_SCOOP_PWR_ON SCOOP_GPCR_PA15 -@@ -34,11 +58,11 @@ - #define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19 - - /* GPIO Direction 1 : output mode / 0:input mode */ --#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \ -+#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393XB_REST_IN | \ - TOSA_SCOOP_IR_POWERDWN | TOSA_SCOOP_PWR_ON | TOSA_SCOOP_AUD_PWR_ON |\ - TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN ) - /* GPIO out put level when init 1: Hi */ --#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN ) -+#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393XB_REST_IN ) - - /* - * SCOOP2 jacket GPIOs -@@ -47,8 +71,8 @@ - #define TOSA_SCOOP_JC_NOTE_LED SCOOP_GPCR_PA12 - #define TOSA_SCOOP_JC_CHRG_ERR_LED SCOOP_GPCR_PA13 - #define TOSA_SCOOP_JC_USB_PULLUP SCOOP_GPCR_PA14 --#define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15 --#define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16 -+#define TOSA_SCOOP_JC_TC6393XB_SUSPEND SCOOP_GPCR_PA15 -+#define TOSA_SCOOP_JC_TC6393XB_L3V_ON SCOOP_GPCR_PA16 - #define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17 - #define TOSA_SCOOP_JC_WLAN_LED SCOOP_GPCR_PA18 - #define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19 -@@ -56,7 +80,7 @@ - /* GPIO Direction 1 : output mode / 0:input mode */ - #define TOSA_SCOOP_JC_IO_DIR ( TOSA_SCOOP_JC_BT_LED | TOSA_SCOOP_JC_NOTE_LED | \ - TOSA_SCOOP_JC_CHRG_ERR_LED | TOSA_SCOOP_JC_USB_PULLUP | \ -- TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \ -+ TOSA_SCOOP_JC_TC6393XB_SUSPEND | TOSA_SCOOP_JC_TC6393XB_L3V_ON | \ - TOSA_SCOOP_JC_WLAN_LED | TOSA_SCOOP_JC_CARD_LIMIT_SEL ) - /* GPIO out put level when init 1: Hi */ - #define TOSA_SCOOP_JC_IO_OUT ( 0 ) -@@ -94,13 +118,13 @@ - #define TOSA_GPIO_JACKET_DETECT (7) - #define TOSA_GPIO_nSD_DETECT (9) - #define TOSA_GPIO_nSD_INT (10) --#define TOSA_GPIO_TC6393_CLK (11) -+#define TOSA_GPIO_TC6393XB_CLK (11) - #define TOSA_GPIO_BAT1_CRG (12) - #define TOSA_GPIO_CF_CD (13) - #define TOSA_GPIO_BAT0_CRG (14) --#define TOSA_GPIO_TC6393_INT (15) -+#define TOSA_GPIO_TC6393XB_INT (15) - #define TOSA_GPIO_BAT0_LOW (17) --#define TOSA_GPIO_TC6393_RDY (18) -+#define TOSA_GPIO_TC6393XB_RDY (18) - #define TOSA_GPIO_ON_RESET (19) - #define TOSA_GPIO_EAR_IN (20) - #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ -@@ -147,7 +171,7 @@ - #define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) - #define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) - #define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) --#define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT) -+#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) - #define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) - #define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) - #define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ) -@@ -161,6 +185,7 @@ - - #define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW) - -+extern struct platform_device tc6393xb_device; - extern struct platform_device tosascoop_jc_device; - extern struct platform_device tosascoop_device; - -diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c -index 5504e30..21c51b5 100644 ---- a/sound/soc/pxa/tosa.c -+++ b/sound/soc/pxa/tosa.c -@@ -32,7 +32,6 @@ - #include <sound/soc-dapm.h> - - #include <asm/mach-types.h> --#include <asm/hardware/tmio.h> - #include <asm/arch/pxa-regs.h> - #include <asm/arch/hardware.h> - #include <asm/arch/audio.h> -@@ -138,10 +137,12 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol, - /* tosa dapm event handlers */ - static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) - { -+#if 0 - if (SND_SOC_DAPM_EVENT_ON(event)) - set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); - else - reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); -+#endif - return 0; - } - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch b/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch deleted file mode 100644 index c9b5ac29d4..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch +++ /dev/null @@ -1,99 +0,0 @@ -From f24c23ba56cdd072b332e8de3e0cff8a31e7e36a Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:03:19 +0300 -Subject: [PATCH 50/64] tosa update for tc6393xb gpio - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 6 +++++- - include/asm-arm/arch-pxa/tosa.h | 36 ++++++++++++++++++++++++------------ - 2 files changed, 29 insertions(+), 13 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index e2eec0f..3e832dc 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -35,6 +35,7 @@ - #include <asm/mach-types.h> - #include <asm/hardware.h> - #include <asm/irq.h> -+#include <asm/gpio.h> - #include <asm/system.h> - #include <asm/arch/pxa-regs.h> - #include <asm/arch/irda.h> -@@ -448,10 +449,13 @@ static struct tc6393xb_platform_data tosa_tc6393xb_setup = { - .scr_pll2cr = 0x0cc1, - .scr_ccr = TC6393XB_CCR_UNK1 | TC6393XB_CCR_HCLK_48, - .scr_gper = 0x3300, -- .scr_gpo_dsr = TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF_JC, -+ .scr_gpo_dsr = -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CARD_VCC_ON) | -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF_JC), - .scr_gpo_doecr = TOSA_TC6393XB_GPO_OE, - - .irq_base = IRQ_BOARD_START, -+ .gpio_base = TOSA_TC6393XB_GPIO_BASE, - - .enable = tosa_tc6393xb_enable, - .disable = tosa_tc6393xb_disable, -diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h -index 1b202b2..410fa9a 100644 ---- a/include/asm-arm/arch-pxa/tosa.h -+++ b/include/asm-arm/arch-pxa/tosa.h -@@ -20,16 +20,21 @@ - /* Jacket Scoop */ - #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000) - --#define TC6393XB_GPIO(i) (1 << (i)) - /* - * TC6393 GPIOs - */ --#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0) --#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1) --#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3) --#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4) -+ -+#define TOSA_TC6393XB_GPIO_BASE NR_BUILTIN_GPIO -+ -+#define TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i)) -+#define TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE)) -+ -+#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0) -+#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1) -+#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3) -+#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4) - #define TOSA_TC6393XB_CHARGE_OFF TC6393XB_GPIO(6) --#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7) -+#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7) - #define TOSA_TC6393XB_BAT0_V_ON TC6393XB_GPIO(9) - #define TOSA_TC6393XB_BAT1_V_ON TC6393XB_GPIO(10) - #define TOSA_TC6393XB_BU_CHRG_ON TC6393XB_GPIO(11) -@@ -37,12 +42,19 @@ - #define TOSA_TC6393XB_BAT0_TH_ON TC6393XB_GPIO(14) - #define TOSA_TC6393XB_BAT1_TH_ON TC6393XB_GPIO(15) - --#define TOSA_TC6393XB_GPO_OE (TOSA_TC6393XB_TG_ON | TOSA_TC6393XB_L_MUTE | TOSA_TC6393XB_BL_C20MA | \ -- TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF | \ -- TOSA_TC6393XB_CHARGE_OFF_JC | TOSA_TC6393XB_BAT0_V_ON | \ -- TOSA_TC6393XB_BAT1_V_ON | TOSA_TC6393XB_BU_CHRG_ON | \ -- TOSA_TC6393XB_BAT_SW_ON | TOSA_TC6393XB_BAT0_TH_ON | \ -- TOSA_TC6393XB_BAT1_TH_ON) -+#define TOSA_TC6393XB_GPO_OE ( \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_TG_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_L_MUTE) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BL_C20MA) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CARD_VCC_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF_JC) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT0_V_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT1_V_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BU_CHRG_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT_SW_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT0_TH_ON) | \ -+ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT1_TH_ON)) - - /* - * SCOOP2 internal GPIOs --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch b/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch deleted file mode 100644 index 585f1af288..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 38ef1b452cc3138157b92d02b31cad439d12d0ca Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:03:34 +0300 -Subject: [PATCH 51/64] fix sound/soc/pxa/tosa.c to new gpio api - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - sound/soc/pxa/tosa.c | 33 ++++++++++++++++++++++++++------- - 1 files changed, 26 insertions(+), 7 deletions(-) - -diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c -index 21c51b5..b758de8 100644 ---- a/sound/soc/pxa/tosa.c -+++ b/sound/soc/pxa/tosa.c -@@ -36,6 +36,7 @@ - #include <asm/arch/hardware.h> - #include <asm/arch/audio.h> - #include <asm/arch/tosa.h> -+#include <asm/gpio.h> - - #include "../codecs/wm9712.h" - #include "pxa2xx-pcm.h" -@@ -137,11 +138,11 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol, - /* tosa dapm event handlers */ - static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) - { --#if 0 -+#ifdef CONFIG_MFD_TC6393XB - if (SND_SOC_DAPM_EVENT_ON(event)) -- set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); -+ gpio_set_value(TOSA_TC6393XB_L_MUTE, 1); - else -- reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); -+ gpio_set_value(TOSA_TC6393XB_L_MUTE, 0); - #endif - return 0; - } -@@ -262,16 +263,31 @@ static int __init tosa_init(void) - if (!machine_is_tosa()) - return -ENODEV; - -+#ifdef CONFIG_MFD_TC6393XB -+ ret = gpio_request(TOSA_TC6393XB_L_MUTE, "Headphone Jack"); -+ if (ret) -+ return ret; -+ gpio_direction_output(TOSA_TC6393XB_L_MUTE, 0); -+#endif - tosa_snd_device = platform_device_alloc("soc-audio", -1); -- if (!tosa_snd_device) -- return -ENOMEM; -+ if (!tosa_snd_device) { -+ ret = -ENOMEM; -+ goto err_alloc; -+ } - - platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata); - tosa_snd_devdata.dev = &tosa_snd_device->dev; - ret = platform_device_add(tosa_snd_device); - -- if (ret) -- platform_device_put(tosa_snd_device); -+ if (!ret) -+ return 0; -+ -+ platform_device_put(tosa_snd_device); -+ -+err_alloc: -+#ifdef CONFIG_MFD_TC6393XB -+ gpio_free(TOSA_TC6393XB_L_MUTE); -+#endif - - return ret; - } -@@ -279,6 +295,9 @@ static int __init tosa_init(void) - static void __exit tosa_exit(void) - { - platform_device_unregister(tosa_snd_device); -+#ifdef CONFIG_MFD_TC6393XB -+ gpio_free(TOSA_TC6393XB_L_MUTE); -+#endif - } - - module_init(tosa_init); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch deleted file mode 100644 index ef5263c18e..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch +++ /dev/null @@ -1,400 +0,0 @@ -From c7537657bc33d4ee1616accd0259e160d57c5c1b Mon Sep 17 00:00:00 2001 -From: Ian Molton <spyro@f2s.com> -Date: Wed, 9 Jan 2008 02:05:40 +0300 -Subject: [PATCH 52/64] tosa platform backlight support - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/video/backlight/Kconfig | 10 + - drivers/video/backlight/Makefile | 1 + - drivers/video/backlight/tosa_bl.c | 345 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 356 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/backlight/tosa_bl.c - -diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig -index 9609a6c..f47a601 100644 ---- a/drivers/video/backlight/Kconfig -+++ b/drivers/video/backlight/Kconfig -@@ -59,6 +59,16 @@ config BACKLIGHT_CORGI - known as the Corgi backlight driver. If you have a Sharp Zaurus - SL-C7xx, SL-Cxx00 or SL-6000x say y. Most users can say n. - -+config BACKLIGHT_TOSA -+ tristate "Sharp Tosa LCD/Backlight Driver (SL-6000)" -+ depends on BACKLIGHT_CLASS_DEVICE && MACH_TOSA -+ default y -+ select I2C -+ select I2C_PXA -+ select PXA_SSP -+ help -+ If you have a Sharp Zaurus SL-6000y enable this driver. -+ - config BACKLIGHT_LOCOMO - tristate "Sharp LOCOMO LCD/Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && SHARP_LOCOMO -diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile -index 965a78b..e8a6a7c 100644 ---- a/drivers/video/backlight/Makefile -+++ b/drivers/video/backlight/Makefile -@@ -5,6 +5,7 @@ obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o - - obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o - obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o -+obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o - obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o - obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o - obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o -diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c -new file mode 100644 -index 0000000..11a89c6 ---- /dev/null -+++ b/drivers/video/backlight/tosa_bl.c -@@ -0,0 +1,345 @@ -+/* -+ * LCD / Backlight control code for Sharp SL-6000x (tosa) -+ * -+ * Copyright (c) 2005 Dirk Opfer -+ * Copyright (c) 2007 Dmitry Baryshkov -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/i2c.h> -+#include <linux/backlight.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/fb.h> -+#include <linux/mfd/tc6393xb.h> -+ -+#include <asm/hardware/scoop.h> -+#include <asm/mach/sharpsl_param.h> -+#include <asm/arch/ssp.h> -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/tosa.h> -+#include <asm/gpio.h> -+ -+#define DAC_BASE 0x4e -+#define DAC_CH1 0 -+#define DAC_CH2 1 -+ -+#define TG_REG0_VQV 0x0001 -+#define TG_REG0_COLOR 0x0002 -+#define TG_REG0_UD 0x0004 -+#define TG_REG0_LR 0x0008 -+#define COMADJ_DEFAULT 97 -+ -+static unsigned short normal_i2c[] = { DAC_BASE, I2C_CLIENT_END }; -+I2C_CLIENT_INSMOD; -+ -+struct tosa_bl_data { -+ struct i2c_client client; -+ -+ int comadj; -+ spinlock_t nssp_lock; -+ struct ssp_dev nssp_dev; -+ struct ssp_state nssp_state; -+ -+ struct backlight_device *bl_dev; -+}; -+ -+static struct i2c_driver tosa_bl_driver; -+ -+static void pxa_nssp_output(struct tosa_bl_data *data, unsigned char reg, unsigned char value) -+{ -+ unsigned long flag; -+ u32 dummy; -+ u32 dat = ( ((reg << 5) & 0xe0) | (value & 0x1f) ); -+ spin_lock_irqsave(&data->nssp_lock, flag); -+ -+ ssp_config(&data->nssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(128)); -+ ssp_enable(&data->nssp_dev); -+ -+ ssp_write_word(&data->nssp_dev,dat); -+ -+ /* Read null data back from device to prevent SSP overflow */ -+ ssp_read_word(&data->nssp_dev, &dummy); -+ ssp_disable(&data->nssp_dev); -+ spin_unlock_irqrestore(&data->nssp_lock, flag); -+ -+} -+ -+static void tosa_set_backlight(struct tosa_bl_data *data, int brightness) -+{ -+ /* SetBacklightDuty */ -+ i2c_smbus_write_byte_data(&data->client, DAC_CH2, (unsigned char)brightness); -+ -+ /* SetBacklightVR */ -+ if (brightness) -+ gpio_set_value(TOSA_TC6393XB_BL_C20MA, 1); -+ else -+ gpio_set_value(TOSA_TC6393XB_BL_C20MA, 0); -+ -+ /* bl_enable GP04=1 otherwise GP04=0*/ -+ pxa_nssp_output(data, TG_GPODR2, brightness ? 0x01 : 0x00); -+} -+ -+static void tosa_lcd_tg_init(struct tosa_bl_data *data) -+{ -+ dev_dbg(&data->bl_dev->dev, "tosa_lcd_init\n"); -+ -+ /* L3V On */ -+ set_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+ mdelay(60); -+ -+ /* TG On */ -+ gpio_set_value(TOSA_TC6393XB_TG_ON, 0); -+ mdelay(60); -+ -+ pxa_nssp_output(data, TG_TPOSCTL,0x00); /* delayed 0clk TCTL signal for VGA */ -+ pxa_nssp_output(data, TG_GPOSR,0x02); /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ -+} -+ -+static void tosa_lcd_tg_on(struct tosa_bl_data *data/*, const struct fb_videomode *mode*/) -+{ -+ const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; -+ -+ tosa_lcd_tg_init(data); -+ -+ dev_dbg(&data->bl_dev->dev, "tosa_lcd_on\n"); -+ pxa_nssp_output(data, TG_PNLCTL, value | (/*mode->yres == 320 ? 0 : */ TG_REG0_VQV)); -+ -+ /* TG LCD pannel power up */ -+ pxa_nssp_output(data, TG_PINICTL,0x4); -+ mdelay(50); -+ -+ /* TG LCD GVSS */ -+ pxa_nssp_output(data, TG_PINICTL,0x0); -+ mdelay(50); -+ -+ /* set common voltage */ -+ i2c_smbus_write_byte_data(&data->client, DAC_CH1, data->comadj); -+} -+ -+static void tosa_lcd_tg_off(struct tosa_bl_data *data) -+{ -+ tosa_set_backlight(data, 0); -+ dev_dbg(&data->bl_dev->dev, "tosa_lcd_off\n"); -+ /* TG LCD VHSA off */ -+ pxa_nssp_output(data, TG_PINICTL,0x4); -+ mdelay(50); -+ -+ /* TG LCD signal off */ -+ pxa_nssp_output(data, TG_PINICTL,0x6); -+ mdelay(50); -+ -+ /* TG Off */ -+ gpio_set_value(TOSA_TC6393XB_TG_ON, 1); -+ mdelay(100); -+ -+ /* L3V Off */ -+ reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393XB_L3V_ON); -+} -+ -+ -+static int tosa_bl_update_status(struct backlight_device *dev) -+{ -+ struct backlight_properties *props = &dev->props; -+ struct tosa_bl_data *data = dev_get_drvdata(&dev->dev); -+ int new_power = max(props->power, props->fb_blank); -+ -+ tosa_set_backlight(data, props->brightness); -+ -+ if (new_power) -+ tosa_lcd_tg_off(data); -+ else -+ tosa_lcd_tg_on(data); -+ -+ return 0; -+} -+ -+static int tosa_bl_get_brightness(struct backlight_device *dev) -+{ -+ struct backlight_properties *props = &dev->props; -+ -+ return props->brightness; -+} -+ -+static struct backlight_ops tosa_bl_ops = { -+ .get_brightness = tosa_bl_get_brightness, -+ .update_status = tosa_bl_update_status, -+}; -+ -+static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address, -+ int kind) -+{ -+ int err = 0; -+ struct i2c_client *client; -+ struct tosa_bl_data *data; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA )) -+ goto out; -+ -+ if (!(data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL))) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ client = &data->client; -+ i2c_set_clientdata(client, data); -+ -+ client->addr = address; -+ client->adapter = adapter; -+ client->driver = &tosa_bl_driver; -+ -+ strlcpy(client->name, "tosa_bl", I2C_NAME_SIZE); -+ -+ spin_lock_init(&data->nssp_lock); -+ data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; -+ -+ err = gpio_request(TOSA_TC6393XB_BL_C20MA, "backlight"); -+ if (err) { -+ dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n"); -+ goto err_gpio_bl; -+ } -+ -+ err = gpio_request(TOSA_TC6393XB_TG_ON, "tg"); -+ if (err) { -+ dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n"); -+ goto err_gpio_tg; -+ } -+ -+ err = ssp_init(&data->nssp_dev,2,0); -+ if (err) { -+ dev_err(&data->bl_dev->dev, "Unable to register NSSP handler!\n"); -+ goto err_ssp_init; -+ } -+ -+ /* Tell the i2c layer a new client has arrived */ -+ err = i2c_attach_client(client); -+ if (err) -+ goto err_i2c_attach; -+ -+ gpio_direction_output(TOSA_TC6393XB_BL_C20MA, 0); -+ gpio_direction_output(TOSA_TC6393XB_TG_ON, 1); -+ -+ tosa_lcd_tg_init(data); -+ -+ data->bl_dev = backlight_device_register("tosa_bl", -+ &client->dev, data, &tosa_bl_ops); -+ if (err) -+ goto err_bl_register; -+ -+ data->bl_dev->props.brightness = 69; -+ data->bl_dev->props.max_brightness = 255; -+ data->bl_dev->props.power = FB_BLANK_UNBLANK; -+ backlight_update_status(data->bl_dev); -+ -+ -+ return 0; -+ -+err_bl_register: -+ tosa_set_backlight(data, 0); -+ tosa_lcd_tg_off(data); -+ -+ err = i2c_detach_client(client); -+ if (err) -+ return err; -+err_i2c_attach: -+ ssp_exit(&data->nssp_dev); -+err_ssp_init: -+ gpio_free(TOSA_TC6393XB_TG_ON); -+err_gpio_tg: -+ gpio_free(TOSA_TC6393XB_BL_C20MA); -+err_gpio_bl: -+ kfree(data); -+out: -+ return err; -+} -+ -+static int tosa_bl_detach_client(struct i2c_client *client) -+{ -+ int err = 0; -+ struct tosa_bl_data *data = i2c_get_clientdata(client); -+ -+ backlight_device_unregister(data->bl_dev); -+ -+ tosa_set_backlight(data, 0); -+ tosa_lcd_tg_off(data); -+ -+ /* Try to detach the client from i2c space */ -+ if ((err = i2c_detach_client(client))) -+ return err; -+ -+ ssp_exit(&data->nssp_dev); -+ -+ gpio_free(TOSA_TC6393XB_TG_ON); -+ gpio_free(TOSA_TC6393XB_BL_C20MA); -+ -+ kfree(data); -+ -+ return err; -+} -+ -+#ifdef CONFIG_PM -+static int tosa_bl_suspend(struct i2c_client *client, pm_message_t mesg) -+{ -+ struct tosa_bl_data *data = i2c_get_clientdata(client); -+ -+ tosa_lcd_tg_off(data); -+ ssp_flush(&data->nssp_dev); -+ ssp_save_state(&data->nssp_dev,&data->nssp_state); -+ -+ return 0; -+} -+ -+static int tosa_bl_resume(struct i2c_client *client) -+{ -+ struct tosa_bl_data *data = i2c_get_clientdata(client); -+ -+ ssp_restore_state(&data->nssp_dev,&data->nssp_state); -+ ssp_enable(&data->nssp_dev); -+ tosa_bl_update_status(data->bl_dev); -+ -+ return 0; -+} -+#else -+#define tosa_bl_suspend NULL -+#define tosa_bl_resume NULL -+#endif -+ -+static int tosa_bl_attach_adapter(struct i2c_adapter *adapter) -+{ -+ return i2c_probe(adapter, &addr_data, &tosa_bl_detect_client); -+} -+ -+static struct i2c_driver tosa_bl_driver = { -+ .driver = { -+ .name = "tosa_bl", -+ }, -+ -+ .attach_adapter = tosa_bl_attach_adapter, -+ .detach_client = tosa_bl_detach_client, -+ -+ .suspend = tosa_bl_suspend, -+ .resume = tosa_bl_resume, -+}; -+ -+static int __init tosa_bl_init(void) -+{ -+ return i2c_add_driver(&tosa_bl_driver); -+} -+ -+static void __exit tosa_bl_cleanup (void) -+{ -+ i2c_del_driver(&tosa_bl_driver); -+} -+ -+module_init(tosa_bl_init); -+module_exit(tosa_bl_cleanup); -+ -+MODULE_DESCRIPTION("Tosa LCD device"); -+MODULE_AUTHOR("Dirk Opfer, Dmitry Baryshkov"); -+MODULE_LICENSE("GPL v2"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch b/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch deleted file mode 100644 index 0675342508..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 47616d22f8f303dfd66cf3b9125af212194a0f3c Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:08:17 +0300 -Subject: [PATCH 53/64] sound/soc/codecs/wm9712.c | 28 ++++++++++++++++++---------- - 1 file changed, 18 insertions(+), 10 deletions(-) - -Index: git/sound/soc/codecs/wm9712.c -=================================================================== ---- - sound/soc/codecs/wm9712.c | 28 ++++++++++++++++++---------- - 1 files changed, 18 insertions(+), 10 deletions(-) - -diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c -index 986b5d5..dfb31e1 100644 ---- a/sound/soc/codecs/wm9712.c -+++ b/sound/soc/codecs/wm9712.c -@@ -606,18 +606,26 @@ static int wm9712_dapm_event(struct snd_soc_codec *codec, int event) - - static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) - { -- if (try_warm && soc_ac97_ops.warm_reset) { -- soc_ac97_ops.warm_reset(codec->ac97); -- if (!(ac97_read(codec, 0) & 0x8000)) -- return 1; -- } -+ int retry = 3; - -- soc_ac97_ops.reset(codec->ac97); -- if (ac97_read(codec, 0) & 0x8000) -- goto err; -- return 0; -+ while (retry--) -+ { -+ if(try_warm && soc_ac97_ops.warm_reset) { -+ soc_ac97_ops.warm_reset(codec->ac97); -+ if(ac97_read(codec, 0) & 0x8000) -+ continue; -+ else -+ return 1; -+ } -+ -+ soc_ac97_ops.reset(codec->ac97); -+ if(ac97_read(codec, 0) & 0x8000) -+ continue; -+ else -+ return 0; -+ -+ } - --err: - printk(KERN_ERR "WM9712 AC97 reset failed\n"); - return -EIO; - } --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch b/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch deleted file mode 100644 index be7300ab24..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 08fbae2307163b3f0c3b704c4b00a9447752a45e Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Thu, 10 Jan 2008 17:56:58 +0300 -Subject: [PATCH 54/64] sound/soc/codecs/wm9712.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: git/sound/soc/codecs/wm9712.c -=================================================================== ---- - sound/soc/codecs/wm9712.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c -index dfb31e1..a3d9f96 100644 ---- a/sound/soc/codecs/wm9712.c -+++ b/sound/soc/codecs/wm9712.c -@@ -647,7 +647,7 @@ static int wm9712_soc_resume(struct platform_device *pdev) - int i, ret; - u16 *cache = codec->reg_cache; - -- ret = wm9712_reset(codec, 1); -+ ret = wm9712_reset(codec, 0); - if (ret < 0){ - printk(KERN_ERR "could not reset AC97 codec\n"); - return ret; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch b/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch deleted file mode 100644 index 5bf691cbda..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch +++ /dev/null @@ -1,30 +0,0 @@ -From bee8b808445a53a7dbb6c15a27064f14dec410c5 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sun, 20 Jan 2008 03:01:41 +0300 -Subject: [PATCH 55/64] Add GPIO_POWERON to the list of devices that we support resume on. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 6 +++--- - 1 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index 3e832dc..d1cf3dc 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -517,9 +517,9 @@ static void __init tosa_init(void) - pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); - - /* setup sleep mode values */ -- PWER = 0x00000002; -- PFER = 0x00000000; -- PRER = 0x00000002; -+ PWER = BIT(TOSA_GPIO_POWERON) | BIT(TOSA_GPIO_RESET); -+ PFER = 0; -+ PRER = BIT(TOSA_GPIO_POWERON) | BIT(TOSA_GPIO_RESET); - PGSR0 = 0x00000000; - PGSR1 = 0x00FF0002; - PGSR2 = 0x00014000; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch b/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch deleted file mode 100644 index 99220f9200..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch +++ /dev/null @@ -1,126 +0,0 @@ -From e039614a0ce6df645f8fa4cbe32e4b21fe46a288 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sun, 20 Jan 2008 02:44:03 +0300 -Subject: [PATCH 56/64] Support resetting by asserting GPIO pin - -This adds support for resetting via assertion of GPIO pin. -This e.g. is used on Sharp Zaurus SL-6000. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/gpio.c | 43 +++++++++++++++++++++++++++++++++++++ - arch/arm/mach-pxa/pm.c | 4 +- - include/asm-arm/arch-pxa/system.h | 10 ++++++++ - 3 files changed, 55 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c -index 8638dd7..589da3b 100644 ---- a/arch/arm/mach-pxa/gpio.c -+++ b/arch/arm/mach-pxa/gpio.c -@@ -19,6 +19,7 @@ - #include <asm/hardware.h> - #include <asm/io.h> - #include <asm/arch/pxa-regs.h> -+#include <asm/arch/system.h> - - #include "generic.h" - -@@ -194,4 +195,46 @@ void __init pxa_init_gpio(int gpio_nr) - pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i; - gpiochip_add(&pxa_gpio_chip[i/32].chip); - } -+ -+ if (reset_gpio < gpio_nr) -+ init_reset_gpio(); -+} -+ -+int reset_gpio = -1; -+static int __init reset_gpio_setup(char *str) -+{ -+ if (get_option(&str, &reset_gpio) != 1) { -+ printk(KERN_ERR "reset_gpio: bad value secified"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+__setup("reset_gpio=", reset_gpio_setup); -+ -+int init_reset_gpio(void) -+{ -+ int rc = 0; -+ if (reset_gpio == -1) -+ goto out; -+ -+ rc = gpio_request(reset_gpio, "reset generator"); -+ if (rc) { -+ printk(KERN_ERR "Can't request reset_gpio\n"); -+ goto out; -+ } -+ -+ rc = gpio_direction_input(reset_gpio); -+ if (rc) { -+ printk(KERN_ERR "Can't configure reset_gpio for input\n"); -+ gpio_free(reset_gpio); -+ goto out; -+ } -+ -+out: -+ if (rc) -+ reset_gpio = -1; -+ -+ return rc; - } -diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c -index a941c71..64f37e5 100644 ---- a/arch/arm/mach-pxa/pm.c -+++ b/arch/arm/mach-pxa/pm.c -@@ -40,8 +40,8 @@ int pxa_pm_enter(suspend_state_t state) - - pxa_cpu_pm_fns->save(sleep_save); - -- /* Clear sleep reset status */ -- RCSR = RCSR_SMR; -+ /* Clear reset status */ -+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - - /* before sleeping, calculate and save a checksum */ - for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) -diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h -index 1d56a3e..c075018 100644 ---- a/include/asm-arm/arch-pxa/system.h -+++ b/include/asm-arm/arch-pxa/system.h -@@ -11,6 +11,7 @@ - */ - - #include <asm/proc-fns.h> -+#include <asm/gpio.h> - #include "hardware.h" - #include "pxa-regs.h" - -@@ -19,12 +20,21 @@ static inline void arch_idle(void) - cpu_do_idle(); - } - -+extern int reset_gpio; -+ -+int init_reset_gpio(void); - - static inline void arch_reset(char mode) - { -+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; -+ - if (mode == 's') { - /* Jump into ROM at address 0 */ - cpu_reset(0); -+ } else if (mode == 'g' && reset_gpio != -1) { -+ /* Use GPIO reset */ -+ gpio_direction_output(reset_gpio, 0); -+ gpio_set_value(reset_gpio, 1); - } else { - /* Initialize the watchdog and let it fire */ - OWER = OWER_WME; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch b/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch deleted file mode 100644 index 441e1bba75..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch +++ /dev/null @@ -1,70 +0,0 @@ -From a6f03929fa4d20cef339dbed7ef5cd1e040d0548 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sun, 20 Jan 2008 02:48:07 +0300 -Subject: [PATCH 57/64] Clean up tosa resetting - -Use new gpio-assertion reset. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 16 +++++++--------- - 1 files changed, 7 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index d1cf3dc..2b4aef7 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -41,6 +41,8 @@ - #include <asm/arch/irda.h> - #include <asm/arch/mmc.h> - #include <asm/arch/udc.h> -+#include <asm/arch/pm.h> -+#include <asm/arch/system.h> - - #include <asm/mach/arch.h> - #include <asm/mach/map.h> -@@ -489,13 +491,7 @@ static struct platform_device *devices[] __initdata = { - - static void tosa_poweroff(void) - { -- RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; -- -- pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT); -- GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET); -- -- mdelay(1000); -- arm_machine_restart('h'); -+ arm_machine_restart('g'); - } - - static void tosa_restart(char mode) -@@ -504,7 +500,7 @@ static void tosa_restart(char mode) - if((MSC0 & 0xffff0000) == 0x7ff00000) - MSC0 = (MSC0 & 0xffff) | 0x7ee00000; - -- tosa_poweroff(); -+ arm_machine_restart('g'); - } - - static void __init tosa_init(void) -@@ -512,7 +508,6 @@ static void __init tosa_init(void) - pm_power_off = tosa_poweroff; - arm_pm_restart = tosa_restart; - -- pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_TC6393XB_INT | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); - -@@ -544,6 +539,9 @@ static void __init fixup_tosa(struct machine_desc *desc, - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (64*1024*1024); -+ -+ if (reset_gpio == -1) -+ reset_gpio = TOSA_GPIO_ON_RESET; - } - - MACHINE_START(TOSA, "SHARP Tosa") --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch b/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch deleted file mode 100644 index e965857dff..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 8b57c409802e5feef64c4bb7659570e06558c0f2 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Sun, 20 Jan 2008 02:24:43 +0300 -Subject: [PATCH 58/64] Fix tosakbd suspend - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/input/keyboard/tosakbd.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c -index 3884d1e..306cbe8 100644 ---- a/drivers/input/keyboard/tosakbd.c -+++ b/drivers/input/keyboard/tosakbd.c -@@ -210,6 +210,9 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) - - del_timer_sync(&tosakbd->timer); - -+ PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT); -+ PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); -+ - return 0; - } - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch b/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch deleted file mode 100644 index 812b5bad41..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 00f6e9b946d1f653fc776d71c86a1f6a7534cd1d Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 25 Jan 2008 19:16:20 +0300 -Subject: [PATCH 59/64] patch tosa-wakeup-test - ---- - arch/arm/mach-pxa/tosa.c | 18 +++++++++++++++++- - 1 files changed, 17 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index 2b4aef7..7008919 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -260,12 +260,28 @@ static struct platform_device tosakbd_device = { - }; - - static struct gpio_keys_button tosa_gpio_keys[] = { -+ /* -+ * Two following keys are directly tied to "ON" button of tosa. Why? -+ * The first one can be used as a wakeup source, the second can't: -+ * it's outside of permitted area. -+ */ -+ { -+ .type = EV_PWR, -+ .code = KEY_RESERVED, -+ .gpio = TOSA_GPIO_POWERON, -+ .desc = "Poweron", -+ .wakeup = 1, -+ .active_low = 1, -+ }, - { - .type = EV_PWR, - .code = KEY_SUSPEND, - .gpio = TOSA_GPIO_ON_KEY, - .desc = "On key", -- .wakeup = 1, -+ /* -+ * can't be used as wakeup -+ * .wakeup = 1, -+ */ - .active_low = 1, - }, - { --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch b/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch deleted file mode 100644 index f7420de040..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch +++ /dev/null @@ -1,623 +0,0 @@ -From f6ec15733eb55e851c8ad19c2143d425558f6044 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Mon, 4 Feb 2008 20:11:58 +0300 -Subject: [PATCH 60/64] Add support for power_supply on tosa - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/Makefile | 2 +- - arch/arm/mach-pxa/tosa_power.c | 82 +++++++ - drivers/leds/leds-tosa.c | 2 +- - drivers/power/Kconfig | 7 + - drivers/power/Makefile | 1 + - drivers/power/tosa_battery.c | 458 ++++++++++++++++++++++++++++++++++++++++ - 6 files changed, 550 insertions(+), 2 deletions(-) - create mode 100644 arch/arm/mach-pxa/tosa_power.c - create mode 100644 drivers/power/tosa_battery.c - -diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile -index f276d24..2b68254 100644 ---- a/arch/arm/mach-pxa/Makefile -+++ b/arch/arm/mach-pxa/Makefile -@@ -21,7 +21,7 @@ obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o cor - obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o - obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o - obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o --obj-$(CONFIG_MACH_TOSA) += tosa.o -+obj-$(CONFIG_MACH_TOSA) += tosa.o tosa_power.o - obj-$(CONFIG_MACH_EM_X270) += em-x270.o - - ifeq ($(CONFIG_MACH_ZYLONITE),y) -diff --git a/arch/arm/mach-pxa/tosa_power.c b/arch/arm/mach-pxa/tosa_power.c -new file mode 100644 -index 0000000..61ca7dc ---- /dev/null -+++ b/arch/arm/mach-pxa/tosa_power.c -@@ -0,0 +1,82 @@ -+/* -+ * Battery and Power Management code for the Sharp SL-6000x -+ * -+ * Copyright (c) 2005 Dirk Opfer -+ * Copyright (c) 2008 Dmitry Baryshkov -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/power_supply.h> -+#include <linux/pda_power.h> -+#include <linux/platform_device.h> -+#include <linux/interrupt.h> -+ -+#include <asm/arch/tosa.h> -+#include <asm/gpio.h> -+ -+static int tosa_power_ac_online(void) -+{ -+ return gpio_get_value(TOSA_GPIO_AC_IN) == 0; -+} -+ -+static char *tosa_ac_supplied_to[] = { -+ "main-battery", -+ "backup-battery", -+ "jacket-battery", -+}; -+ -+static struct pda_power_pdata tosa_power_data = { -+ .is_ac_online = tosa_power_ac_online, -+ .supplied_to = tosa_ac_supplied_to, -+ .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), -+}; -+ -+static struct resource tosa_power_resource[] = { -+ { -+ .name = "ac", -+ .start = gpio_to_irq(TOSA_GPIO_AC_IN), -+ .end = gpio_to_irq(TOSA_GPIO_AC_IN), -+ .flags = IORESOURCE_IRQ | -+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ }, -+}; -+ -+static struct platform_device tosa_power_device = { -+ .name = "pda-power", -+ .id = -1, -+ .dev.platform_data = &tosa_power_data, -+ .resource = tosa_power_resource, -+ .num_resources = ARRAY_SIZE(tosa_power_resource), -+}; -+ -+static int __init tosa_power_init(void) -+{ -+ int ret = gpio_request(TOSA_GPIO_AC_IN, "ac"); -+ if (ret) -+ goto err_gpio_req; -+ -+ ret = gpio_direction_input(TOSA_GPIO_AC_IN); -+ if (ret) -+ goto err_gpio_in; -+ -+ return platform_device_register(&tosa_power_device); -+ -+err_gpio_in: -+ gpio_free(TOSA_GPIO_AC_IN); -+err_gpio_req: -+ return ret; -+} -+ -+static void __exit tosa_power_exit(void) -+{ -+ platform_device_unregister(&tosa_power_device); -+ gpio_free(TOSA_GPIO_AC_IN); -+} -+ -+module_init(tosa_power_init); -+module_exit(tosa_power_exit); -diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c -index fb2416a..b4498b5 100644 ---- a/drivers/leds/leds-tosa.c -+++ b/drivers/leds/leds-tosa.c -@@ -46,7 +46,7 @@ static void tosaled_green_set(struct led_classdev *led_cdev, - - static struct led_classdev tosa_amber_led = { - .name = "tosa:amber", -- .default_trigger = "sharpsl-charge", -+ .default_trigger = "main-battery-charging", - .brightness_set = tosaled_amber_set, - }; - -diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig -index 58c806e..e3a9c37 100644 ---- a/drivers/power/Kconfig -+++ b/drivers/power/Kconfig -@@ -49,4 +49,11 @@ config BATTERY_OLPC - help - Say Y to enable support for the battery on the OLPC laptop. - -+config BATTERY_TOSA -+ tristate "Sharp SL-6000 (tosa) battery" -+ depends on MACH_TOSA && MFD_TC6393XB -+ help -+ Say Y to enable support for the battery on the Sharp Zaurus -+ SL-6000 (tosa) models. -+ - endif # POWER_SUPPLY -diff --git a/drivers/power/Makefile b/drivers/power/Makefile -index 6413ded..1e408fa 100644 ---- a/drivers/power/Makefile -+++ b/drivers/power/Makefile -@@ -20,3 +20,4 @@ obj-$(CONFIG_APM_POWER) += apm_power.o - obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o - obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o - obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o -+obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o -diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c -new file mode 100644 -index 0000000..b0fd2f2 ---- /dev/null -+++ b/drivers/power/tosa_battery.c -@@ -0,0 +1,458 @@ -+/* -+ * Battery and Power Management code for the Sharp SL-6000x -+ * -+ * Copyright (c) 2005 Dirk Opfer -+ * Copyright (c) 2008 Dmitry Baryshkov -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/power_supply.h> -+#include <linux/wm97xx.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> -+#include <linux/interrupt.h> -+ -+#include <asm/mach-types.h> -+#include <asm/gpio.h> -+#include <asm/arch/tosa.h> -+ -+#define BAT_TO_VOLTS(v) ((v) * 1000000 / 414) -+#define BU_TO_VOLTS(v) ((v) * 1000000 / 1266) -+/* -+ * It's pretty strange value, but that's roughly what I get from -+ * zaurus maintainer menu -+ */ -+//#define BAT_TO_TEMP(t) ((t) * 10000/2000) -+#define BAT_TO_TEMP(t) (t) -+ -+static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ -+static struct work_struct bat_work; -+ -+struct tosa_bat { -+ int status; -+ struct power_supply psy; -+ int full_chrg; -+ -+ struct mutex work_lock; /* protects data */ -+ bool (*is_present)(struct tosa_bat *bat); -+ int gpio_full; -+ int gpio_charge_off; -+ int gpio_bat; -+ int adc_bat; -+ int gpio_temp; -+ int adc_temp; -+}; -+ -+static struct tosa_bat tosa_bat_main; -+static struct tosa_bat tosa_bat_jacket; -+ -+static enum power_supply_property tosa_bat_main_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_TEMP, -+ POWER_SUPPLY_PROP_PRESENT, -+}; -+ -+static enum power_supply_property tosa_bat_bu_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -+ POWER_SUPPLY_PROP_PRESENT, -+}; -+ -+static unsigned long tosa_read_bat(struct tosa_bat *bat) -+{ -+ unsigned long value = 0; -+ -+ if (bat->gpio_bat < 0 || bat->adc_bat < 0) -+ return 0; -+ -+ mutex_lock(&bat_lock); -+ gpio_set_value(bat->gpio_bat, 1); -+ mdelay(5); -+ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_bat); -+ gpio_set_value(bat->gpio_bat, 0); -+ mutex_unlock(&bat_lock); -+ return value; -+} -+ -+static unsigned long tosa_read_temp(struct tosa_bat *bat) -+{ -+ unsigned long value = 0; -+ -+ if (bat->gpio_temp < 0 || bat->adc_temp < 0) -+ return 0; -+ -+ mutex_lock(&bat_lock); -+ gpio_set_value(bat->gpio_temp, 1); -+ mdelay(5); -+ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_temp); -+ gpio_set_value(bat->gpio_temp, 0); -+ mutex_unlock(&bat_lock); -+ return value; -+} -+ -+static int tosa_bat_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ int ret = 0; -+ struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy); -+ -+ if (bat->is_present && !bat->is_present(bat) -+ && psp != POWER_SUPPLY_PROP_PRESENT) { -+ return -ENODEV; -+ } -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = bat->status; -+ break; -+ case POWER_SUPPLY_PROP_TECHNOLOGY: -+ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ val->intval = BAT_TO_VOLTS(tosa_read_bat(bat)); -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX: -+ if (bat->full_chrg == -1) -+ val->intval = -1; -+ else -+ val->intval = BAT_TO_VOLTS(bat->full_chrg); -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -+ val->intval = BAT_TO_VOLTS(1551); -+ break; -+ case POWER_SUPPLY_PROP_TEMP: -+ val->intval = BAT_TO_TEMP(tosa_read_temp(bat)); -+ break; -+ case POWER_SUPPLY_PROP_PRESENT: -+ val->intval = bat->is_present ? bat->is_present(bat) : 1; -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static int tosa_bu_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ int ret = 0; -+ struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy); -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN; -+ break; -+ case POWER_SUPPLY_PROP_TECHNOLOGY: -+ val->intval = POWER_SUPPLY_TECHNOLOGY_LiMn; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -+ val->intval = 0; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -+ val->intval = 3 * 1000000; /* 3 V */ -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ /* I think so */ -+ val->intval = BU_TO_VOLTS(tosa_read_bat(bat)); -+ break; -+ case POWER_SUPPLY_PROP_PRESENT: -+ val->intval = 1; -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) { -+ // FIXME -+ return 1; -+} -+ -+static void tosa_bat_external_power_changed(struct power_supply *psy) -+{ -+ schedule_work(&bat_work); -+} -+ -+static irqreturn_t tosa_bat_full_isr(int irq, void *data) -+{ -+ printk(KERN_ERR "bat_full irq: %d\n", gpio_get_value(irq_to_gpio(irq))); -+ schedule_work(&bat_work); -+ return IRQ_HANDLED; -+} -+ -+static void tosa_bat_update(struct tosa_bat *bat) -+{ -+ int old = bat->status; -+ struct power_supply *psy = &bat->psy; -+ -+ mutex_lock(&bat->work_lock); -+ -+ if (bat->is_present && !bat->is_present(bat)) { -+ printk(KERN_DEBUG "%s not present\n", psy->name); -+ bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; -+ bat->full_chrg = -1; -+ } else if (power_supply_am_i_supplied(psy)) { -+ if (gpio_get_value(bat->gpio_full)) { -+ printk(KERN_DEBUG "%s full\n", psy->name); -+ -+ if (old == POWER_SUPPLY_STATUS_CHARGING || bat->full_chrg == -1) -+ bat->full_chrg = tosa_read_bat(bat); -+ -+ gpio_set_value(bat->gpio_charge_off, 1); -+ bat->status = POWER_SUPPLY_STATUS_FULL; -+ } else { -+ printk(KERN_ERR "%s charge\n", psy->name); -+ gpio_set_value(bat->gpio_charge_off, 0); -+ bat->status = POWER_SUPPLY_STATUS_CHARGING; -+ } -+ } else { -+ printk(KERN_ERR "%s discharge\n", psy->name); -+ gpio_set_value(bat->gpio_charge_off, 1); -+ bat->status = POWER_SUPPLY_STATUS_DISCHARGING; -+ } -+ -+ if (old != bat->status) -+ power_supply_changed(psy); -+ -+ mutex_unlock(&bat->work_lock); -+} -+ -+static void tosa_bat_work(struct work_struct *work) -+{ -+ tosa_bat_update(&tosa_bat_main); -+ tosa_bat_update(&tosa_bat_jacket); -+} -+ -+ -+static struct tosa_bat tosa_bat_main = { -+ .status = POWER_SUPPLY_STATUS_UNKNOWN, -+ .full_chrg = -1, -+ .psy = { -+ .name = "main-battery", -+ .type = POWER_SUPPLY_TYPE_BATTERY, -+ .properties = tosa_bat_main_props, -+ .num_properties = ARRAY_SIZE(tosa_bat_main_props), -+ .get_property = tosa_bat_get_property, -+ .external_power_changed = tosa_bat_external_power_changed, -+ .use_for_apm = 1, -+ }, -+ -+ .gpio_full = TOSA_GPIO_BAT0_CRG, -+ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF, -+ .gpio_bat = TOSA_TC6393XB_BAT0_V_ON, -+ .adc_bat = WM97XX_AUX_ID3, -+ .gpio_temp = TOSA_TC6393XB_BAT1_TH_ON, -+ .adc_temp = WM97XX_AUX_ID2, -+}; -+ -+static struct tosa_bat tosa_bat_jacket = { -+ .status = POWER_SUPPLY_STATUS_UNKNOWN, -+ .full_chrg = -1, -+ .psy = { -+ .name = "jacket-battery", -+ .type = POWER_SUPPLY_TYPE_BATTERY, -+ .properties = tosa_bat_main_props, -+ .num_properties = ARRAY_SIZE(tosa_bat_main_props), -+ .get_property = tosa_bat_get_property, -+ .external_power_changed = tosa_bat_external_power_changed, -+// .use_for_apm = 1, -+ }, -+ -+ .is_present = tosa_jacket_bat_is_present, -+ .gpio_full = TOSA_GPIO_BAT1_CRG, -+ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF_JC, -+ .gpio_bat = TOSA_TC6393XB_BAT1_V_ON, -+ .adc_bat = WM97XX_AUX_ID3, -+ .gpio_temp = TOSA_TC6393XB_BAT0_TH_ON, -+ .adc_temp = WM97XX_AUX_ID2, -+}; -+ -+static struct tosa_bat tosa_bat_bu = { -+ .status = POWER_SUPPLY_STATUS_UNKNOWN, -+ .full_chrg = -1, -+ -+ .psy = { -+ .name = "backup-battery", -+ .type = POWER_SUPPLY_TYPE_BATTERY, -+ .properties = tosa_bat_bu_props, -+ .num_properties = ARRAY_SIZE(tosa_bat_bu_props), -+ .get_property = tosa_bu_get_property, -+ .external_power_changed = tosa_bat_external_power_changed, -+ }, -+ -+ .gpio_full = -1, -+ .gpio_charge_off = -1, -+ .gpio_bat = TOSA_TC6393XB_BU_CHRG_ON, -+ .adc_bat = WM97XX_AUX_ID4, -+ .gpio_temp = -1, -+ .adc_temp = -1, -+}; -+ -+static struct { -+ int gpio; -+ char *name; -+ bool output; -+ int value; -+} gpios[] = { -+ { TOSA_TC6393XB_CHARGE_OFF, "main charge off", 1, 1 }, -+ { TOSA_TC6393XB_CHARGE_OFF_JC, "jacket charge off", 1, 1 }, -+ { TOSA_TC6393XB_BAT_SW_ON, "battery switch", 1, 0 }, -+ { TOSA_TC6393XB_BAT0_V_ON, "main battery", 1, 0 }, -+ { TOSA_TC6393XB_BAT1_V_ON, "jacket battery", 1, 0 }, -+ { TOSA_TC6393XB_BAT1_TH_ON, "main battery temp", 1, 0 }, -+ { TOSA_TC6393XB_BAT0_TH_ON, "jacket battery temp", 1, 0 }, -+ { TOSA_TC6393XB_BU_CHRG_ON, "backup battery", 1, 0 }, -+ { TOSA_GPIO_BAT0_CRG, "main battery full", 0, 0 }, -+ { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 }, -+ { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 }, -+ { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 }, -+}; -+ -+#ifdef CONFIG_PM -+static int tosa_bat_suspend(struct device *dev, pm_message_t state) -+{ -+ /* do nothing */ -+ return 0; -+} -+ -+static int tosa_bat_resume(struct device *dev) -+{ -+ schedule_work(&bat_work); -+ return 0; -+} -+#else -+#define tosa_bat_suspend NULL -+#define tosa_bat_resume NULL -+#endif -+ -+static int __devinit tosa_bat_probe(struct device *dev) -+{ -+ int ret; -+ int i; -+ -+ if (!machine_is_tosa()) -+ return -ENODEV; -+ -+ for (i = 0; i < ARRAY_SIZE(gpios); i++) { -+ ret = gpio_request(gpios[i].gpio, gpios[i].name); -+ if (ret) { -+ i --; -+ goto err_gpio; -+ } -+ -+ if (gpios[i].output) -+ ret = gpio_direction_output(gpios[i].gpio, -+ gpios[i].value); -+ else -+ ret = gpio_direction_input(gpios[i].gpio); -+ -+ if (ret) -+ goto err_gpio; -+ } -+ -+ mutex_init(&tosa_bat_main.work_lock); -+ mutex_init(&tosa_bat_jacket.work_lock); -+ -+ INIT_WORK(&bat_work, tosa_bat_work); -+ -+ ret = power_supply_register(dev, &tosa_bat_main.psy); -+ if (ret) -+ goto err_psy_reg_main; -+ ret = power_supply_register(dev, &tosa_bat_jacket.psy); -+ if (ret) -+ goto err_psy_reg_jacket; -+ ret = power_supply_register(dev, &tosa_bat_bu.psy); -+ if (ret) -+ goto err_psy_reg_bu; -+ -+ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), -+ tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ "main full", &tosa_bat_main); -+ if (ret) -+ goto err_req_main; -+ -+ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), -+ tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ "jacket full", &tosa_bat_jacket); -+ if (!ret) { -+ schedule_work(&bat_work); -+ return 0; -+ } -+ -+ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); -+err_req_main: -+ power_supply_unregister(&tosa_bat_bu.psy); -+err_psy_reg_bu: -+ power_supply_unregister(&tosa_bat_jacket.psy); -+err_psy_reg_jacket: -+ power_supply_unregister(&tosa_bat_main.psy); -+err_psy_reg_main: -+ -+ i --; -+err_gpio: -+ for (; i >= 0; i --) -+ gpio_free(gpios[i].gpio); -+ -+ return ret; -+} -+ -+static int __devexit tosa_bat_remove(struct device *dev) -+{ -+ int i; -+ -+ free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); -+ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); -+ -+ power_supply_unregister(&tosa_bat_bu.psy); -+ power_supply_unregister(&tosa_bat_jacket.psy); -+ power_supply_unregister(&tosa_bat_main.psy); -+ -+ for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i --) -+ gpio_free(gpios[i].gpio); -+ -+ return 0; -+} -+ -+static struct device_driver tosa_bat_driver = { -+ .name = "wm97xx-battery", -+ .bus = &wm97xx_bus_type, -+ .owner = THIS_MODULE, -+ .probe = tosa_bat_probe, -+ .remove = __devexit_p(tosa_bat_remove), -+ .suspend = tosa_bat_suspend, -+ .resume = tosa_bat_resume, -+}; -+ -+static int __init tosa_bat_init(void) -+{ -+ return driver_register(&tosa_bat_driver); -+} -+ -+static void __exit tosa_bat_exit(void) -+{ -+ driver_unregister(&tosa_bat_driver); -+} -+ -+module_init(tosa_bat_init); -+module_exit(tosa_bat_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dmitry Baryshkov"); -+MODULE_DESCRIPTION("Tosa battery driver"); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch b/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch deleted file mode 100644 index 2bcede36a9..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch +++ /dev/null @@ -1,342 +0,0 @@ -From f05aa38af5bd5962ae04c4b128644e7f55451527 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 8 Feb 2008 01:14:48 +0300 -Subject: [PATCH 61/64] tosa-bat-unify - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/power/tosa_battery.c | 161 ++++++++++++++++++++--------------------- - 1 files changed, 79 insertions(+), 82 deletions(-) - -diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c -index b0fd2f2..008e791 100644 ---- a/drivers/power/tosa_battery.c -+++ b/drivers/power/tosa_battery.c -@@ -21,15 +21,6 @@ - #include <asm/gpio.h> - #include <asm/arch/tosa.h> - --#define BAT_TO_VOLTS(v) ((v) * 1000000 / 414) --#define BU_TO_VOLTS(v) ((v) * 1000000 / 1266) --/* -- * It's pretty strange value, but that's roughly what I get from -- * zaurus maintainer menu -- */ --//#define BAT_TO_TEMP(t) ((t) * 10000/2000) --#define BAT_TO_TEMP(t) (t) -- - static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ - static struct work_struct bat_work; - -@@ -39,37 +30,27 @@ struct tosa_bat { - int full_chrg; - - struct mutex work_lock; /* protects data */ -+ - bool (*is_present)(struct tosa_bat *bat); - int gpio_full; - int gpio_charge_off; -+ -+ int technology; -+ - int gpio_bat; - int adc_bat; -+ int adc_bat_divider; -+ int bat_max; -+ int bat_min; -+ - int gpio_temp; - int adc_temp; -+ int adc_temp_divider; - }; - - static struct tosa_bat tosa_bat_main; - static struct tosa_bat tosa_bat_jacket; - --static enum power_supply_property tosa_bat_main_props[] = { -- POWER_SUPPLY_PROP_STATUS, -- POWER_SUPPLY_PROP_TECHNOLOGY, -- POWER_SUPPLY_PROP_VOLTAGE_NOW, -- POWER_SUPPLY_PROP_VOLTAGE_MAX, -- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -- POWER_SUPPLY_PROP_TEMP, -- POWER_SUPPLY_PROP_PRESENT, --}; -- --static enum power_supply_property tosa_bat_bu_props[] = { -- POWER_SUPPLY_PROP_STATUS, -- POWER_SUPPLY_PROP_TECHNOLOGY, -- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -- POWER_SUPPLY_PROP_VOLTAGE_NOW, -- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -- POWER_SUPPLY_PROP_PRESENT, --}; -- - static unsigned long tosa_read_bat(struct tosa_bat *bat) - { - unsigned long value = 0; -@@ -83,6 +64,9 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat) - value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_bat); - gpio_set_value(bat->gpio_bat, 0); - mutex_unlock(&bat_lock); -+ -+ value = value * 1000000 / bat->adc_bat_divider; -+ - return value; - } - -@@ -99,6 +83,9 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat) - value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_temp); - gpio_set_value(bat->gpio_temp, 0); - mutex_unlock(&bat_lock); -+ -+ value = value * 10000 / bat->adc_temp_divider; -+ - return value; - } - -@@ -119,22 +106,25 @@ static int tosa_bat_get_property(struct power_supply *psy, - val->intval = bat->status; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: -- val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; -+ val->intval = bat->technology; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: -- val->intval = BAT_TO_VOLTS(tosa_read_bat(bat)); -+ val->intval = tosa_read_bat(bat); - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - if (bat->full_chrg == -1) -- val->intval = -1; -+ val->intval = bat->bat_max; - else -- val->intval = BAT_TO_VOLTS(bat->full_chrg); -+ val->intval = bat->full_chrg; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -+ val->intval = bat->bat_max; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -- val->intval = BAT_TO_VOLTS(1551); -+ val->intval = bat->bat_min; - break; - case POWER_SUPPLY_PROP_TEMP: -- val->intval = BAT_TO_TEMP(tosa_read_temp(bat)); -+ val->intval = tosa_read_temp(bat); - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = bat->is_present ? bat->is_present(bat) : 1; -@@ -146,40 +136,6 @@ static int tosa_bat_get_property(struct power_supply *psy, - return ret; - } - --static int tosa_bu_get_property(struct power_supply *psy, -- enum power_supply_property psp, -- union power_supply_propval *val) --{ -- int ret = 0; -- struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy); -- -- switch (psp) { -- case POWER_SUPPLY_PROP_STATUS: -- val->intval = POWER_SUPPLY_STATUS_UNKNOWN; -- break; -- case POWER_SUPPLY_PROP_TECHNOLOGY: -- val->intval = POWER_SUPPLY_TECHNOLOGY_LiMn; -- break; -- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -- val->intval = 0; -- break; -- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -- val->intval = 3 * 1000000; /* 3 V */ -- break; -- case POWER_SUPPLY_PROP_VOLTAGE_NOW: -- /* I think so */ -- val->intval = BU_TO_VOLTS(tosa_read_bat(bat)); -- break; -- case POWER_SUPPLY_PROP_PRESENT: -- val->intval = 1; -- break; -- default: -- ret = -EINVAL; -- break; -- } -- return ret; --} -- - static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) { - // FIXME - return 1; -@@ -241,6 +197,25 @@ static void tosa_bat_work(struct work_struct *work) - } - - -+static enum power_supply_property tosa_bat_main_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_TEMP, -+ POWER_SUPPLY_PROP_PRESENT, -+}; -+ -+static enum power_supply_property tosa_bat_bu_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -+ POWER_SUPPLY_PROP_PRESENT, -+}; -+ - static struct tosa_bat tosa_bat_main = { - .status = POWER_SUPPLY_STATUS_UNKNOWN, - .full_chrg = -1, -@@ -256,10 +231,18 @@ static struct tosa_bat tosa_bat_main = { - - .gpio_full = TOSA_GPIO_BAT0_CRG, - .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF, -+ -+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, -+ - .gpio_bat = TOSA_TC6393XB_BAT0_V_ON, - .adc_bat = WM97XX_AUX_ID3, -+ .adc_bat_divider = 414, -+ .bat_max = 4310000, -+ .bat_min = 1551 * 100000 / 414, -+ - .gpio_temp = TOSA_TC6393XB_BAT1_TH_ON, - .adc_temp = WM97XX_AUX_ID2, -+ .adc_temp_divider = 10000, - }; - - static struct tosa_bat tosa_bat_jacket = { -@@ -278,10 +261,18 @@ static struct tosa_bat tosa_bat_jacket = { - .is_present = tosa_jacket_bat_is_present, - .gpio_full = TOSA_GPIO_BAT1_CRG, - .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF_JC, -+ -+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, -+ - .gpio_bat = TOSA_TC6393XB_BAT1_V_ON, - .adc_bat = WM97XX_AUX_ID3, -+ .adc_bat_divider = 414, -+ .bat_max = 4310000, -+ .bat_min = 1551 * 100000 / 414, -+ - .gpio_temp = TOSA_TC6393XB_BAT0_TH_ON, - .adc_temp = WM97XX_AUX_ID2, -+ .adc_temp_divider = 10000, - }; - - static struct tosa_bat tosa_bat_bu = { -@@ -293,16 +284,22 @@ static struct tosa_bat tosa_bat_bu = { - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = tosa_bat_bu_props, - .num_properties = ARRAY_SIZE(tosa_bat_bu_props), -- .get_property = tosa_bu_get_property, -+ .get_property = tosa_bat_get_property, - .external_power_changed = tosa_bat_external_power_changed, - }, - - .gpio_full = -1, - .gpio_charge_off = -1, -+ -+ .technology = POWER_SUPPLY_TECHNOLOGY_LiMn, -+ - .gpio_bat = TOSA_TC6393XB_BU_CHRG_ON, - .adc_bat = WM97XX_AUX_ID4, -+ .adc_bat_divider = 1266, -+ - .gpio_temp = -1, - .adc_temp = -1, -+ .adc_temp_divider = -1, - }; - - static struct { -@@ -326,13 +323,14 @@ static struct { - }; - - #ifdef CONFIG_PM --static int tosa_bat_suspend(struct device *dev, pm_message_t state) -+static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) - { - /* do nothing */ -+ flush_scheduled_work(); - return 0; - } - --static int tosa_bat_resume(struct device *dev) -+static int tosa_bat_resume(struct platform_device *dev) - { - schedule_work(&bat_work); - return 0; -@@ -342,7 +340,7 @@ static int tosa_bat_resume(struct device *dev) - #define tosa_bat_resume NULL - #endif - --static int __devinit tosa_bat_probe(struct device *dev) -+static int __devinit tosa_bat_probe(struct platform_device *dev) - { - int ret; - int i; -@@ -372,13 +370,13 @@ static int __devinit tosa_bat_probe(struct device *dev) - - INIT_WORK(&bat_work, tosa_bat_work); - -- ret = power_supply_register(dev, &tosa_bat_main.psy); -+ ret = power_supply_register(&dev->dev, &tosa_bat_main.psy); - if (ret) - goto err_psy_reg_main; -- ret = power_supply_register(dev, &tosa_bat_jacket.psy); -+ ret = power_supply_register(&dev->dev, &tosa_bat_jacket.psy); - if (ret) - goto err_psy_reg_jacket; -- ret = power_supply_register(dev, &tosa_bat_bu.psy); -+ ret = power_supply_register(&dev->dev, &tosa_bat_bu.psy); - if (ret) - goto err_psy_reg_bu; - -@@ -413,7 +411,7 @@ err_gpio: - return ret; - } - --static int __devexit tosa_bat_remove(struct device *dev) -+static int __devexit tosa_bat_remove(struct platform_device *dev) - { - int i; - -@@ -430,10 +428,9 @@ static int __devexit tosa_bat_remove(struct device *dev) - return 0; - } - --static struct device_driver tosa_bat_driver = { -- .name = "wm97xx-battery", -- .bus = &wm97xx_bus_type, -- .owner = THIS_MODULE, -+static struct platform_driver tosa_bat_driver = { -+ .driver.name = "wm97xx-battery", -+ .driver.owner = THIS_MODULE, - .probe = tosa_bat_probe, - .remove = __devexit_p(tosa_bat_remove), - .suspend = tosa_bat_suspend, -@@ -442,12 +439,12 @@ static struct device_driver tosa_bat_driver = { - - static int __init tosa_bat_init(void) - { -- return driver_register(&tosa_bat_driver); -+ return platform_driver_register(&tosa_bat_driver); - } - - static void __exit tosa_bat_exit(void) - { -- driver_unregister(&tosa_bat_driver); -+ platform_driver_unregister(&tosa_bat_driver); - } - - module_init(tosa_bat_init); --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch b/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch deleted file mode 100644 index e3a6b74772..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0b9f80ab540b2e51f6e86f6a1adec67761f9368d Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 8 Feb 2008 00:50:03 +0300 -Subject: [PATCH 62/64] tosa-bat-fix-charging - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/power/tosa_battery.c | 28 +++++++++++++++++++++------- - 1 files changed, 21 insertions(+), 7 deletions(-) - -diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c -index 008e791..2db9116 100644 ---- a/drivers/power/tosa_battery.c -+++ b/drivers/power/tosa_battery.c -@@ -153,39 +153,53 @@ static irqreturn_t tosa_bat_full_isr(int irq, void *data) - return IRQ_HANDLED; - } - -+static char *status_text[] = { -+ [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown", -+ [POWER_SUPPLY_STATUS_CHARGING] = "Charging", -+ [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging", -+ [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging", -+ [POWER_SUPPLY_STATUS_FULL] = "Full", -+}; -+ - static void tosa_bat_update(struct tosa_bat *bat) - { -- int old = bat->status; -+ int old; - struct power_supply *psy = &bat->psy; - - mutex_lock(&bat->work_lock); - -+ old = bat->status; -+ - if (bat->is_present && !bat->is_present(bat)) { -- printk(KERN_DEBUG "%s not present\n", psy->name); -+ printk(KERN_NOTICE "%s not present\n", psy->name); - bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; - bat->full_chrg = -1; - } else if (power_supply_am_i_supplied(psy)) { -+ if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) { -+ gpio_set_value(bat->gpio_charge_off, 0); -+ mdelay(15); -+ } - if (gpio_get_value(bat->gpio_full)) { -- printk(KERN_DEBUG "%s full\n", psy->name); -- - if (old == POWER_SUPPLY_STATUS_CHARGING || bat->full_chrg == -1) - bat->full_chrg = tosa_read_bat(bat); - - gpio_set_value(bat->gpio_charge_off, 1); - bat->status = POWER_SUPPLY_STATUS_FULL; - } else { -- printk(KERN_ERR "%s charge\n", psy->name); - gpio_set_value(bat->gpio_charge_off, 0); - bat->status = POWER_SUPPLY_STATUS_CHARGING; - } - } else { -- printk(KERN_ERR "%s discharge\n", psy->name); - gpio_set_value(bat->gpio_charge_off, 1); - bat->status = POWER_SUPPLY_STATUS_DISCHARGING; - } - -- if (old != bat->status) -+ if (old != bat->status) { -+ printk(KERN_NOTICE "%s %s -> %s\n", psy->name, -+ status_text[old], -+ status_text[bat->status]); - power_supply_changed(psy); -+ } - - mutex_unlock(&bat->work_lock); - } --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch b/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch deleted file mode 100644 index 416cae44ec..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 4ef7289137132959e3db5a1e77580ff9db185d90 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 8 Feb 2008 01:13:54 +0300 -Subject: [PATCH 63/64] patch tosa-bat-jacket-detect - ---- - drivers/power/tosa_battery.c | 21 +++++++++++++++------ - 1 files changed, 15 insertions(+), 6 deletions(-) - -diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c -index 2db9116..70beed2 100644 ---- a/drivers/power/tosa_battery.c -+++ b/drivers/power/tosa_battery.c -@@ -137,8 +137,7 @@ static int tosa_bat_get_property(struct power_supply *psy, - } - - static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) { -- // FIXME -- return 1; -+ return gpio_get_value(TOSA_GPIO_JACKET_DETECT) == 0; - } - - static void tosa_bat_external_power_changed(struct power_supply *psy) -@@ -146,9 +145,9 @@ static void tosa_bat_external_power_changed(struct power_supply *psy) - schedule_work(&bat_work); - } - --static irqreturn_t tosa_bat_full_isr(int irq, void *data) -+static irqreturn_t tosa_bat_gpio_isr(int irq, void *data) - { -- printk(KERN_ERR "bat_full irq: %d\n", gpio_get_value(irq_to_gpio(irq))); -+ printk(KERN_ERR "bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq))); - schedule_work(&bat_work); - return IRQ_HANDLED; - } -@@ -334,6 +333,7 @@ static struct { - { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 }, - { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 }, - { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 }, -+ { TOSA_GPIO_JACKET_DETECT, "jacket detect", 0, 0 }, - }; - - #ifdef CONFIG_PM -@@ -395,19 +395,27 @@ static int __devinit tosa_bat_probe(struct platform_device *dev) - goto err_psy_reg_bu; - - ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), -- tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "main full", &tosa_bat_main); - if (ret) - goto err_req_main; - - ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), -- tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "jacket full", &tosa_bat_jacket); -+ if (ret) -+ goto err_req_jacket; -+ -+ ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), -+ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ "jacket detect", &tosa_bat_jacket); - if (!ret) { - schedule_work(&bat_work); - return 0; - } - -+ free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); -+err_req_jacket: - free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); - err_req_main: - power_supply_unregister(&tosa_bat_bu.psy); -@@ -429,6 +437,7 @@ static int __devexit tosa_bat_remove(struct platform_device *dev) - { - int i; - -+ free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket); - free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); - free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); - --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch b/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch deleted file mode 100644 index eeb92cfdd5..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch +++ /dev/null @@ -1,27 +0,0 @@ -From feeee5d22c00d9d1e2e06eb5610740be238749b9 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Thu, 7 Feb 2008 22:27:38 +0300 -Subject: [PATCH 64/64] Export modes via sysfs - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/video/tmiofb.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c -index 6b963a1..9389a77 100644 ---- a/drivers/video/tmiofb.c -+++ b/drivers/video/tmiofb.c -@@ -800,6 +800,9 @@ static int tmiofb_probe(struct platform_device *dev) - if (retval) - goto err_set_par;*/ - -+ fb_videomode_to_modelist(data->modes, data->num_modes, -+ &info->modelist); -+ - retval = register_framebuffer(info); - if (retval < 0) - goto err_register_framebuffer; --- -1.5.3.8 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch b/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch deleted file mode 100644 index 5db0cc6ba0..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2544412fc47dc13f4f3935cb4c2fd500d217e905 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 13 Feb 2008 02:00:15 +0300 -Subject: [PATCH] wm97xx-core fixes - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/input/touchscreen/wm97xx-core.c | 8 ++++---- - include/linux/wm97xx.h | 1 - - 2 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c -index 840d9ff..4cbb9e5 100644 ---- a/drivers/input/touchscreen/wm97xx-core.c -+++ b/drivers/input/touchscreen/wm97xx-core.c -@@ -596,7 +596,7 @@ static int wm97xx_probe(struct device *dev) - } - platform_set_drvdata(wm->battery_dev, wm); - wm->battery_dev->dev.parent = dev; -- ret = platform_device_register(wm->battery_dev); -+ ret = platform_device_add(wm->battery_dev); - if (ret < 0) - goto batt_reg_err; - -@@ -609,7 +609,7 @@ static int wm97xx_probe(struct device *dev) - } - platform_set_drvdata(wm->touch_dev, wm); - wm->touch_dev->dev.parent = dev; -- ret = platform_device_register(wm->touch_dev); -+ ret = platform_device_add(wm->touch_dev); - if (ret < 0) - goto touch_reg_err; - -@@ -619,10 +619,12 @@ static int wm97xx_probe(struct device *dev) - platform_device_put(wm->touch_dev); - touch_err: - platform_device_unregister(wm->battery_dev); -+ wm->battery_dev = NULL; - batt_reg_err: - platform_device_put(wm->battery_dev); - batt_err: - input_unregister_device(wm->input_dev); -+ wm->input_dev = NULL; - kfree(wm); - return ret; - } --- -1.5.4.1 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch b/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch deleted file mode 100644 index 42320be50b..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b6a63ad546cc26519a342f3fdd7b1def49ca33ee Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 13 Feb 2008 02:00:14 +0300 -Subject: [PATCH] tmiofb_probe should be __devinit - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/video/tmiofb.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c -index 9389a77..958ee8a 100644 ---- a/drivers/video/tmiofb.c -+++ b/drivers/video/tmiofb.c -@@ -704,7 +704,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info) - return IRQ_HANDLED; - } - --static int tmiofb_probe(struct platform_device *dev) -+static int __devinit tmiofb_probe(struct platform_device *dev) - { - struct mfd_cell *cell = mfd_get_cell(dev); - struct tmio_fb_data *data = cell->driver_data; --- -1.5.4.1 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch b/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch deleted file mode 100644 index 42b69d9377..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch +++ /dev/null @@ -1,225 +0,0 @@ -From aded2e51a7a2113dae6431c858df1d95fb312851 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 13 Feb 2008 19:34:08 +0300 -Subject: [PATCH] modeswitching - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - arch/arm/mach-pxa/tosa.c | 33 +++++++++++++++++++++++++++++++- - drivers/mfd/tc6393xb.c | 2 +- - drivers/video/backlight/tosa_bl.c | 38 +++++++++++++++++++++++++++++++++--- - drivers/video/tmiofb.c | 8 +++--- - include/asm-arm/arch-pxa/tosa.h | 2 + - include/linux/mfd/tc6393xb.h | 2 +- - include/linux/mfd/tmio.h | 2 +- - 7 files changed, 75 insertions(+), 12 deletions(-) - -diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c -index 94c9915..6631de2 100644 ---- a/arch/arm/mach-pxa/tosa.c -+++ b/arch/arm/mach-pxa/tosa.c -@@ -455,9 +455,40 @@ static struct fb_videomode tosa_tc6393xb_lcd_mode[] = { - } - }; - -+static DEFINE_SPINLOCK(tosa_lcd_mode_lock); -+ -+static const struct fb_videomode *tosa_lcd_mode = &tosa_tc6393xb_lcd_mode[0]; -+ -+static int tosa_lcd_set_mode(struct platform_device *fb_dev, -+ const struct fb_videomode *mode) -+{ -+ int rc; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tosa_lcd_mode_lock, flags); -+ rc = tc6393xb_lcd_mode(fb_dev, mode); -+ if (!rc) -+ tosa_lcd_mode = mode; -+ spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags); -+ -+ return rc; -+} -+ -+const struct fb_videomode *tosa_lcd_get_mode(void) -+{ -+ unsigned long flags; -+ const struct fb_videomode *mode; -+ -+ spin_lock_irqsave(&tosa_lcd_mode_lock, flags); -+ mode = tosa_lcd_mode; -+ spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags); -+ -+ return mode; -+} -+ - static struct tmio_fb_data tosa_tc6393xb_fb_config = { - .lcd_set_power = tc6393xb_lcd_set_power, -- .lcd_mode = tc6393xb_lcd_mode, -+ .lcd_mode = tosa_lcd_set_mode, - .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode), - .modes = &tosa_tc6393xb_lcd_mode[0], - }; -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index 9001687..21190f3 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -196,7 +196,7 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) - EXPORT_SYMBOL(tc6393xb_lcd_set_power); - - int tc6393xb_lcd_mode(struct platform_device *fb_dev, -- struct fb_videomode *mode) { -+ const struct fb_videomode *mode) { - struct tc6393xb *tc6393xb = - platform_get_drvdata(to_platform_device(fb_dev->dev.parent)); - struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c -index 9ef0bfb..45fc6ae 100644 ---- a/drivers/video/backlight/tosa_bl.c -+++ b/drivers/video/backlight/tosa_bl.c -@@ -48,6 +48,9 @@ struct tosa_bl_data { - struct ssp_dev nssp_dev; - struct ssp_state nssp_state; - -+ /* listen for mode changes */ -+ struct notifier_block fb_notif; -+ - struct backlight_device *bl_dev; - }; - -@@ -103,14 +106,19 @@ static void tosa_lcd_tg_init(struct tosa_bl_data *data) - pxa_nssp_output(data, TG_GPOSR,0x02); /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ - } - --static void tosa_lcd_tg_on(struct tosa_bl_data *data/*, const struct fb_videomode *mode*/) -+static void tosa_lcd_tg_on(struct tosa_bl_data *data) - { -- const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; -+ const struct fb_videomode *mode = tosa_lcd_get_mode(); -+ -+ int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; -+ -+ if (mode->yres == 640) -+ value |= TG_REG0_VQV; - - tosa_lcd_tg_init(data); - -- dev_dbg(&data->bl_dev->dev, "tosa_lcd_on\n"); -- pxa_nssp_output(data, TG_PNLCTL, value | (/*mode->yres == 320 ? 0 : */ TG_REG0_VQV)); -+ dev_dbg(&data->bl_dev->dev, "tosa_lcd_on: %04x (%d)\n", value, mode->yres); -+ pxa_nssp_output(data, TG_PNLCTL, value); - - /* TG LCD pannel power up */ - pxa_nssp_output(data, TG_PINICTL,0x4); -@@ -173,6 +181,20 @@ static struct backlight_ops tosa_bl_ops = { - .update_status = tosa_bl_update_status, - }; - -+static int fb_notifier_callback(struct notifier_block *self, -+ unsigned long event, void *_data) -+{ -+ struct tosa_bl_data *bl_data = -+ container_of(self, struct tosa_bl_data, fb_notif); -+ -+ if (event != FB_EVENT_MODE_CHANGE && event != FB_EVENT_MODE_CHANGE_ALL) -+ return 0; -+ -+ tosa_bl_update_status(bl_data->bl_dev); -+ -+ return 0; -+} -+ - static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address, - int kind) - { -@@ -238,9 +260,15 @@ static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address, - data->bl_dev->props.power = FB_BLANK_UNBLANK; - backlight_update_status(data->bl_dev); - -+ data->fb_notif.notifier_call = fb_notifier_callback; -+ err = fb_register_client(&data->fb_notif); -+ if (err) -+ goto err_fb_register; - - return 0; - -+err_fb_register: -+ backlight_device_unregister(data->bl_dev); - err_bl_register: - tosa_set_backlight(data, 0); - tosa_lcd_tg_off(data); -@@ -265,6 +293,8 @@ static int tosa_bl_detach_client(struct i2c_client *client) - int err = 0; - struct tosa_bl_data *data = i2c_get_clientdata(client); - -+ fb_unregister_client(&data->fb_notif); -+ - backlight_device_unregister(data->bl_dev); - - tosa_set_backlight(data, 0); -diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c -index 958ee8a..cc75df9 100644 ---- a/drivers/video/tmiofb.c -+++ b/drivers/video/tmiofb.c -@@ -618,17 +618,17 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) - - static int tmiofb_set_par(struct fb_info *info) - { --/* struct fb_var_screeninfo *var = &info->var; -+ struct fb_var_screeninfo *var = &info->var; - struct fb_videomode *mode; - - mode = tmiofb_find_mode(info, var); - if (!mode) - return -EINVAL; - -- if (info->mode == mode) -- return 0; -+/* if (info->mode == mode) -+ return 0;*/ - -- info->mode = mode; */ -+ info->mode = mode; - info->fix.line_length = info->mode->xres * 2; - - tmiofb_hw_mode(to_platform_device(info->device)); -diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h -index 410fa9a..624c636 100644 ---- a/include/asm-arm/arch-pxa/tosa.h -+++ b/include/asm-arm/arch-pxa/tosa.h -@@ -230,4 +230,6 @@ extern struct platform_device tosascoop_device; - #define TOSA_KEY_MAIL KEY_MAIL - #endif - -+const struct fb_videomode *tosa_lcd_get_mode(void); -+ - #endif /* _ASM_ARCH_TOSA_H_ */ -diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h -index 97c4c7c..8ab9e91 100644 ---- a/include/linux/mfd/tc6393xb.h -+++ b/include/linux/mfd/tc6393xb.h -@@ -53,7 +53,7 @@ struct tc6393xb_platform_data { - - extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on); - extern int tc6393xb_lcd_mode(struct platform_device *fb_dev, -- struct fb_videomode *mode); -+ const struct fb_videomode *mode); - - /* - * Relative to irq_base -diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h -index b6d4aac..fe7ff2d 100644 ---- a/include/linux/mfd/tmio.h -+++ b/include/linux/mfd/tmio.h -@@ -19,7 +19,7 @@ struct tmio_fb_data { - int (*lcd_set_power)(struct platform_device *fb_dev, - bool on); - int (*lcd_mode)(struct platform_device *fb_dev, -- struct fb_videomode *mode); -+ const struct fb_videomode *mode); - int num_modes; - struct fb_videomode *modes; - }; --- -1.5.4.1 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch b/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch deleted file mode 100644 index e90e3751c0..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch +++ /dev/null @@ -1,239 +0,0 @@ -From f7dad1cd9c1bd3fce5d228e0b644a51baea50cd9 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Fri, 15 Feb 2008 15:35:07 +0300 -Subject: [PATCH] Preliminary tosa denoiser - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/input/touchscreen/Kconfig | 12 ++ - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/tosa-wm97xx.c | 182 +++++++++++++++++++++++++++++++ - 3 files changed, 195 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/tosa-wm97xx.c - -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 0be05a2..938aed2 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -210,6 +210,18 @@ config TOUCHSCREEN_WM97XX_MAINSTONE - To compile this driver as a module, choose M here: the - module will be called mainstone-wm97xx - -+config TOUCHSCREEN_WM97XX_TOSA -+ tristate "WM97xx Tosa denoiser" -+ depends on TOUCHSCREEN_WM97XX && MACH_TOSA -+ help -+ Say Y here for support for touchscreen denoising on -+ Sharl Zaurus SL-6000 (tosa) system. -+ -+ If unsure, say N -+ -+ To compile this driver as a module, choose M here: the -+ module will be called tosa-wm97xx -+ - config TOUCHSCREEN_TOUCHWIN - tristate "Touchwin serial touchscreen" - select SERIO -diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index d38156e..d86278b 100644 ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o - obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o - obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o - obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o -+obj-$(CONFIG_TOUCHSCREEN_WM97XX_TOSA) += tosa-wm97xx.o - wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o - wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o - wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o -diff --git a/drivers/input/touchscreen/tosa-wm97xx.c b/drivers/input/touchscreen/tosa-wm97xx.c -new file mode 100644 -index 0000000..8fd542b ---- /dev/null -+++ b/drivers/input/touchscreen/tosa-wm97xx.c -@@ -0,0 +1,182 @@ -+/* -+ * tosa_ts.c -- Touchscreen driver for Sharp SL-6000 (Tosa). -+ * -+ * Copyright 2008 Dmitry Baryshkov -+ * Copyright 2006 Wolfson Microelectronics PLC. -+ * Author: Mike Arthur -+ * linux@wolfsonmicro.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. -+ * -+ * Revision history -+ * 1st Sep 2006 Initial version. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/wm97xx.h> -+#include <linux/fb.h> -+ -+#include <asm/arch/tosa.h> -+#include <asm/gpio.h> -+ -+static unsigned long hsync_time = 0; -+ -+static void calc_hsync_time(const struct fb_videomode *mode) -+{ -+ /* The 25 and 44 'magic numbers' are from Sharp's 2.4 patches */ -+ if (mode->yres == 640) { -+ hsync_time = 25; -+ } else if (mode->yres == 320) { -+ hsync_time = 44; -+ } else { -+ printk(KERN_ERR "unknown video mode res specified: %dx%d!", mode->xres, mode->yres); -+ WARN_ON(1); -+ } -+ -+ printk(KERN_ERR "tosa-wm97xx: using %lu hsync time\n", hsync_time); -+} -+ -+static int fb_notifier_callback(struct notifier_block *self, -+ unsigned long event, void *_data) -+{ -+ if (event != FB_EVENT_MODE_CHANGE && event != FB_EVENT_MODE_CHANGE_ALL) -+ return 0; -+ -+ calc_hsync_time(tosa_lcd_get_mode()); -+ -+ return 0; -+} -+ -+static void tosa_lcd_wait_hsync(void) -+{ -+ /* Waits for a rising edge on the VGA line */ -+ while (gpio_get_value(TOSA_GPIO_VGA_LINE) == 0); -+ while (gpio_get_value(TOSA_GPIO_VGA_LINE) != 0); -+} -+ -+/* Taken from the Sharp 2.4 kernel code */ -+#define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a)) -+#define CCNT_ON() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1)) -+#define CCNT_OFF() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(0)) -+ -+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait -+ * before sampling the Y axis of the touchscreen */ -+static void tosa_lcd_sync_on(int adcsel) -+{ -+ unsigned long timer1 = 0, timer2 = 0, wait_time = 0; -+ if (adcsel & WM97XX_ADCSEL_Y) { -+ CCNT_ON(); -+ wait_time = hsync_time; -+ -+ if (wait_time) { -+ -+ /* wait for LCD rising edge */ -+ tosa_lcd_wait_hsync(); -+ /* get clock */ -+ CCNT(timer1); -+ CCNT(timer2); -+ -+ while ((timer2 - timer1) < wait_time) { -+ CCNT(timer2); -+ } -+ } -+ } -+} -+ -+static void tosa_lcd_sync_off(int adcsel) -+{ -+ if (adcsel & WM97XX_ADCSEL_Y) -+ CCNT_OFF(); -+} -+ -+static struct wm97xx_mach_ops tosa_mach_ops = { -+ .pre_sample = tosa_lcd_sync_on, -+ .post_sample = tosa_lcd_sync_off, -+}; -+ -+static int __devinit tosa_ts_probe(struct platform_device *dev) { -+ struct wm97xx *wm = platform_get_drvdata(dev); -+ struct notifier_block *notif; -+ int err = -ENOMEM; -+ -+ notif = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); -+ if (!notif) -+ goto err_alloc; -+ -+ notif->notifier_call = fb_notifier_callback; -+ -+ err = gpio_request(TOSA_GPIO_VGA_LINE, "hsync"); -+ if (err) -+ goto err_gpio; -+ -+ err = gpio_direction_input(TOSA_GPIO_VGA_LINE); -+ if (err) -+ goto err_gpio; -+ -+ platform_set_drvdata(dev, notif); -+ -+ err = fb_register_client(notif); -+ if (err) -+ goto err_register; -+ -+ err = wm97xx_register_mach_ops(wm, &tosa_mach_ops); -+ if (err) -+ goto err_wm97xx; -+ -+ calc_hsync_time(tosa_lcd_get_mode()); -+ -+ return 0; -+ -+err_wm97xx: -+ fb_unregister_client(notif); -+err_register: -+ gpio_free(TOSA_GPIO_VGA_LINE); -+err_gpio: -+ kfree(notif); -+err_alloc: -+ return err; -+} -+ -+ -+static int __devexit tosa_ts_remove(struct platform_device *dev) { -+ struct wm97xx *wm = platform_get_drvdata(dev); -+ -+ wm97xx_unregister_mach_ops(wm); -+ -+ fb_unregister_client(platform_get_drvdata(dev)); -+ gpio_free(TOSA_GPIO_VGA_LINE); -+ kfree(platform_get_drvdata(dev)); -+ -+ return 0; -+} -+ -+static struct platform_driver tosa_ts_driver = { -+ .driver.name = "wm97xx-touch", -+ .driver.owner = THIS_MODULE, -+ .probe = tosa_ts_probe, -+ .remove = __devexit_p(tosa_ts_remove), -+}; -+ -+static int __init tosa_ts_init(void) -+{ -+ return platform_driver_register(&tosa_ts_driver); -+} -+ -+static void __exit tosa_ts_exit(void) -+{ -+ platform_driver_unregister(&tosa_ts_driver); -+} -+ -+module_init(tosa_ts_init); -+module_exit(tosa_ts_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("Dmitry Baryshkov, Mike Arthur, mike@mikearthur.co.uk, www.wolfsonmicro.com"); -+MODULE_DESCRIPTION("Sharp SL6000 Tosa Touch Screen Denoiser"); -+MODULE_LICENSE("GPL"); --- -1.5.4.1 - diff --git a/packages/linux/linux-rp-2.6.24/tosa/tosa-bl-fixup.diff b/packages/linux/linux-rp-2.6.24/tosa/tosa-bl-fixup.diff deleted file mode 100644 index c4a23d1f49..0000000000 --- a/packages/linux/linux-rp-2.6.24/tosa/tosa-bl-fixup.diff +++ /dev/null @@ -1,103 +0,0 @@ -Index: linux-2.6.24/drivers/video/backlight/tosa_bl.c -=================================================================== ---- linux-2.6.24.orig/drivers/video/backlight/tosa_bl.c 2008-11-15 22:59:51.592985003 +0300 -+++ linux-2.6.24/drivers/video/backlight/tosa_bl.c 2008-11-18 04:08:13.021416618 +0300 -@@ -76,6 +76,8 @@ static void pxa_nssp_output(struct tosa_ - - static void tosa_set_backlight(struct tosa_bl_data *data, int brightness) - { -+ pr_debug("tosa_set_backlight\n"); -+ - /* SetBacklightDuty */ - i2c_smbus_write_byte_data(&data->client, DAC_CH2, (unsigned char)brightness); - -@@ -91,7 +93,7 @@ static void tosa_set_backlight(struct to - - static void tosa_lcd_tg_init(struct tosa_bl_data *data) - { -- dev_dbg(&data->bl_dev->dev, "tosa_lcd_init\n"); -+ pr_debug("tosa_lcd_init\n"); - - /* L3V On */ - set_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393XB_L3V_ON); -@@ -116,7 +118,7 @@ static void tosa_lcd_tg_on(struct tosa_b - - tosa_lcd_tg_init(data); - -- dev_dbg(&data->bl_dev->dev, "tosa_lcd_on: %04x (%d)\n", value, mode->yres); -+ pr_debug("tosa_lcd_on: %04x (%d)\n", value, mode->yres); - pxa_nssp_output(data, TG_PNLCTL, value); - - /* TG LCD pannel power up */ -@@ -129,12 +131,15 @@ static void tosa_lcd_tg_on(struct tosa_b - - /* set common voltage */ - i2c_smbus_write_byte_data(&data->client, DAC_CH1, data->comadj); -+ -+ tosa_set_backlight(data, data->bl_dev->props.brightness); -+ - } - - static void tosa_lcd_tg_off(struct tosa_bl_data *data) - { - tosa_set_backlight(data, 0); -- dev_dbg(&data->bl_dev->dev, "tosa_lcd_off\n"); -+ pr_debug("tosa_lcd_off\n"); - /* TG LCD VHSA off */ - pxa_nssp_output(data, TG_PINICTL,0x4); - mdelay(50); -@@ -158,8 +163,6 @@ static int tosa_bl_update_status(struct - struct tosa_bl_data *data = dev_get_drvdata(&dev->dev); - int new_power = max(props->power, props->fb_blank); - -- tosa_set_backlight(data, props->brightness); -- - if (new_power) - tosa_lcd_tg_off(data); - else -@@ -223,22 +226,26 @@ static int tosa_bl_detect_client(struct - - err = gpio_request(TOSA_TC6393XB_BL_C20MA, "backlight"); - if (err) { -- dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n"); -+ printk(KERN_ERR "tosa-bl; Unable to request gpio!\n"); - goto err_gpio_bl; - } - - err = gpio_request(TOSA_TC6393XB_TG_ON, "tg"); - if (err) { -- dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n"); -+ printk(KERN_ERR "tosa-bl: Unable to request gpio!\n"); - goto err_gpio_tg; - } - - err = ssp_init(&data->nssp_dev,2,0); - if (err) { -- dev_err(&data->bl_dev->dev, "Unable to register NSSP handler!\n"); -+ printk(KERN_ERR "tosa-bl: Unable to register NSSP handler!\n"); - goto err_ssp_init; - } - -+ pxa_gpio_mode(GPIO83_NSSP_TX); -+ pxa_gpio_mode(GPIO81_NSSP_CLK_OUT); -+ pxa_gpio_mode(GPIO82_NSSP_FRM_OUT); -+ - /* Tell the i2c layer a new client has arrived */ - err = i2c_attach_client(client); - if (err) -@@ -269,7 +276,6 @@ static int tosa_bl_detect_client(struct - err_fb_register: - backlight_device_unregister(data->bl_dev); - err_bl_register: -- tosa_set_backlight(data, 0); - tosa_lcd_tg_off(data); - - err = i2c_detach_client(client); -@@ -296,7 +302,6 @@ static int tosa_bl_detach_client(struct - - backlight_device_unregister(data->bl_dev); - -- tosa_set_backlight(data, 0); - tosa_lcd_tg_off(data); - - /* Try to detach the client from i2c space */ |