aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_throttling.c10
-rw-r--r--drivers/ata/sata_mv.c31
-rw-r--r--drivers/base/cpu.c48
-rw-r--r--drivers/base/node.c29
-rw-r--r--drivers/base/topology.c41
-rw-r--r--drivers/firmware/dcdbas.c4
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c1
-rw-r--r--drivers/i2c/chips/Kconfig1
-rw-r--r--drivers/i2c/chips/tps65010.c101
-rw-r--r--drivers/input/keyboard/Kconfig9
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/corgikbd.c1
-rw-r--r--drivers/input/keyboard/sh_keysc.c280
-rw-r--r--drivers/input/keyboard/spitzkbd.c1
-rw-r--r--drivers/input/touchscreen/ads7846.c40
-rw-r--r--drivers/input/touchscreen/corgi_ts.c1
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-tosa.c132
-rw-r--r--drivers/mfd/Kconfig16
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/htc-egpio.c440
-rw-r--r--drivers/mfd/htc-pasic3.c265
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/orion_nand.c2
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/arm/at91_ether.c4
-rw-r--r--drivers/net/irda/pxaficp_ir.c11
-rw-r--r--drivers/pci/pci-driver.c9
-rw-r--r--drivers/pci/pci-sysfs.c20
-rw-r--r--drivers/pci/probe.c27
-rw-r--r--drivers/pcmcia/Kconfig1
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c1
-rw-r--r--drivers/rtc/rtc-sh.c296
-rw-r--r--drivers/serial/imx.c111
-rw-r--r--drivers/serial/sh-sci.c7
-rw-r--r--drivers/serial/sh-sci.h60
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-orion.c37
-rw-r--r--drivers/video/pxafb.c1
41 files changed, 1655 insertions, 403 deletions
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 1b8e592a8241..0bba3a914e86 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -838,10 +838,10 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
838 * Migrate task to the cpu pointed by pr. 838 * Migrate task to the cpu pointed by pr.
839 */ 839 */
840 saved_mask = current->cpus_allowed; 840 saved_mask = current->cpus_allowed;
841 set_cpus_allowed(current, cpumask_of_cpu(pr->id)); 841 set_cpus_allowed_ptr(current, &cpumask_of_cpu(pr->id));
842 ret = pr->throttling.acpi_processor_get_throttling(pr); 842 ret = pr->throttling.acpi_processor_get_throttling(pr);
843 /* restore the previous state */ 843 /* restore the previous state */
844 set_cpus_allowed(current, saved_mask); 844 set_cpus_allowed_ptr(current, &saved_mask);
845 845
846 return ret; 846 return ret;
847} 847}
@@ -1025,7 +1025,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
1025 * it can be called only for the cpu pointed by pr. 1025 * it can be called only for the cpu pointed by pr.
1026 */ 1026 */
1027 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { 1027 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
1028 set_cpus_allowed(current, cpumask_of_cpu(pr->id)); 1028 set_cpus_allowed_ptr(current, &cpumask_of_cpu(pr->id));
1029 ret = p_throttling->acpi_processor_set_throttling(pr, 1029 ret = p_throttling->acpi_processor_set_throttling(pr,
1030 t_state.target_state); 1030 t_state.target_state);
1031 } else { 1031 } else {
@@ -1056,7 +1056,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
1056 continue; 1056 continue;
1057 } 1057 }
1058 t_state.cpu = i; 1058 t_state.cpu = i;
1059 set_cpus_allowed(current, cpumask_of_cpu(i)); 1059 set_cpus_allowed_ptr(current, &cpumask_of_cpu(i));
1060 ret = match_pr->throttling. 1060 ret = match_pr->throttling.
1061 acpi_processor_set_throttling( 1061 acpi_processor_set_throttling(
1062 match_pr, t_state.target_state); 1062 match_pr, t_state.target_state);
@@ -1074,7 +1074,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
1074 &t_state); 1074 &t_state);
1075 } 1075 }
1076 /* restore the previous state */ 1076 /* restore the previous state */
1077 set_cpus_allowed(current, saved_mask); 1077 set_cpus_allowed_ptr(current, &saved_mask);
1078 return ret; 1078 return ret;
1079} 1079}
1080 1080
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 05ff8c776497..d52ce1188327 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -76,6 +76,7 @@
76#include <linux/device.h> 76#include <linux/device.h>
77#include <linux/platform_device.h> 77#include <linux/platform_device.h>
78#include <linux/ata_platform.h> 78#include <linux/ata_platform.h>
79#include <linux/mbus.h>
79#include <scsi/scsi_host.h> 80#include <scsi/scsi_host.h>
80#include <scsi/scsi_cmnd.h> 81#include <scsi/scsi_cmnd.h>
81#include <scsi/scsi_device.h> 82#include <scsi/scsi_device.h>
@@ -370,6 +371,9 @@ enum {
370#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) 371#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
371#define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) 372#define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC))
372 373
374#define WINDOW_CTRL(i) (0x20030 + ((i) << 4))
375#define WINDOW_BASE(i) (0x20034 + ((i) << 4))
376
373enum { 377enum {
374 /* DMA boundary 0xffff is required by the s/g splitting 378 /* DMA boundary 0xffff is required by the s/g splitting
375 * we need on /length/ in mv_fill-sg(). 379 * we need on /length/ in mv_fill-sg().
@@ -2769,6 +2773,27 @@ static int mv_create_dma_pools(struct mv_host_priv *hpriv, struct device *dev)
2769 return 0; 2773 return 0;
2770} 2774}
2771 2775
2776static void mv_conf_mbus_windows(struct mv_host_priv *hpriv,
2777 struct mbus_dram_target_info *dram)
2778{
2779 int i;
2780
2781 for (i = 0; i < 4; i++) {
2782 writel(0, hpriv->base + WINDOW_CTRL(i));
2783 writel(0, hpriv->base + WINDOW_BASE(i));
2784 }
2785
2786 for (i = 0; i < dram->num_cs; i++) {
2787 struct mbus_dram_window *cs = dram->cs + i;
2788
2789 writel(((cs->size - 1) & 0xffff0000) |
2790 (cs->mbus_attr << 8) |
2791 (dram->mbus_dram_target_id << 4) | 1,
2792 hpriv->base + WINDOW_CTRL(i));
2793 writel(cs->base, hpriv->base + WINDOW_BASE(i));
2794 }
2795}
2796
2772/** 2797/**
2773 * mv_platform_probe - handle a positive probe of an soc Marvell 2798 * mv_platform_probe - handle a positive probe of an soc Marvell
2774 * host 2799 * host
@@ -2823,6 +2848,12 @@ static int mv_platform_probe(struct platform_device *pdev)
2823 res->end - res->start + 1); 2848 res->end - res->start + 1);
2824 hpriv->base -= MV_SATAHC0_REG_BASE; 2849 hpriv->base -= MV_SATAHC0_REG_BASE;
2825 2850
2851 /*
2852 * (Re-)program MBUS remapping windows if we are asked to.
2853 */
2854 if (mv_platform_data->dram != NULL)
2855 mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
2856
2826 rc = mv_create_dma_pools(hpriv, &pdev->dev); 2857 rc = mv_create_dma_pools(hpriv, &pdev->dev);
2827 if (rc) 2858 if (rc)
2828 return rc; 2859 return rc;
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 499b003f9278..2c76afff3b15 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -103,6 +103,51 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
103#endif 103#endif
104 104
105/* 105/*
106 * Print cpu online, possible, present, and system maps
107 */
108static ssize_t print_cpus_map(char *buf, cpumask_t *map)
109{
110 int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *map);
111
112 buf[n++] = '\n';
113 buf[n] = '\0';
114 return n;
115}
116
117#define print_cpus_func(type) \
118static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
119{ \
120 return print_cpus_map(buf, &cpu_##type##_map); \
121} \
122struct sysdev_class_attribute attr_##type##_map = \
123 _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
124
125print_cpus_func(online);
126print_cpus_func(possible);
127print_cpus_func(present);
128
129struct sysdev_class_attribute *cpu_state_attr[] = {
130 &attr_online_map,
131 &attr_possible_map,
132 &attr_present_map,
133};
134
135static int cpu_states_init(void)
136{
137 int i;
138 int err = 0;
139
140 for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) {
141 int ret;
142 ret = sysdev_class_create_file(&cpu_sysdev_class,
143 cpu_state_attr[i]);
144 if (!err)
145 err = ret;
146 }
147 return err;
148}
149
150/*
106 * register_cpu - Setup a sysfs device for a CPU. 151 * register_cpu - Setup a sysfs device for a CPU.
107 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in 152 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
108 * sysfs for this CPU. 153 * sysfs for this CPU.
@@ -147,6 +192,9 @@ int __init cpu_dev_init(void)
147 int err; 192 int err;
148 193
149 err = sysdev_class_register(&cpu_sysdev_class); 194 err = sysdev_class_register(&cpu_sysdev_class);
195 if (!err)
196 err = cpu_states_init();
197
150#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) 198#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
151 if (!err) 199 if (!err)
152 err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); 200 err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index e59861f18ce5..12fde2d03d69 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -19,21 +19,34 @@ static struct sysdev_class node_class = {
19}; 19};
20 20
21 21
22static ssize_t node_read_cpumap(struct sys_device * dev, char * buf) 22static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
23{ 23{
24 struct node *node_dev = to_node(dev); 24 struct node *node_dev = to_node(dev);
25 cpumask_t mask = node_to_cpumask(node_dev->sysdev.id); 25 node_to_cpumask_ptr(mask, node_dev->sysdev.id);
26 int len; 26 int len;
27 27
28 /* 2004/06/03: buf currently PAGE_SIZE, need > 1 char per 4 bits. */ 28 /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
29 BUILD_BUG_ON(MAX_NUMNODES/4 > PAGE_SIZE/2); 29 BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1));
30 30
31 len = cpumask_scnprintf(buf, PAGE_SIZE-1, mask); 31 len = type?
32 len += sprintf(buf + len, "\n"); 32 cpulist_scnprintf(buf, PAGE_SIZE-2, *mask):
33 cpumask_scnprintf(buf, PAGE_SIZE-2, *mask);
34 buf[len++] = '\n';
35 buf[len] = '\0';
33 return len; 36 return len;
34} 37}
35 38
36static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumap, NULL); 39static inline ssize_t node_read_cpumask(struct sys_device *dev, char *buf)
40{
41 return node_read_cpumap(dev, 0, buf);
42}
43static inline ssize_t node_read_cpulist(struct sys_device *dev, char *buf)
44{
45 return node_read_cpumap(dev, 1, buf);
46}
47
48static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL);
49static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
37 50
38#define K(x) ((x) << (PAGE_SHIFT - 10)) 51#define K(x) ((x) << (PAGE_SHIFT - 10))
39static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) 52static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
@@ -149,6 +162,7 @@ int register_node(struct node *node, int num, struct node *parent)
149 162
150 if (!error){ 163 if (!error){
151 sysdev_create_file(&node->sysdev, &attr_cpumap); 164 sysdev_create_file(&node->sysdev, &attr_cpumap);
165 sysdev_create_file(&node->sysdev, &attr_cpulist);
152 sysdev_create_file(&node->sysdev, &attr_meminfo); 166 sysdev_create_file(&node->sysdev, &attr_meminfo);
153 sysdev_create_file(&node->sysdev, &attr_numastat); 167 sysdev_create_file(&node->sysdev, &attr_numastat);
154 sysdev_create_file(&node->sysdev, &attr_distance); 168 sysdev_create_file(&node->sysdev, &attr_distance);
@@ -166,6 +180,7 @@ int register_node(struct node *node, int num, struct node *parent)
166void unregister_node(struct node *node) 180void unregister_node(struct node *node)
167{ 181{
168 sysdev_remove_file(&node->sysdev, &attr_cpumap); 182 sysdev_remove_file(&node->sysdev, &attr_cpumap);
183 sysdev_remove_file(&node->sysdev, &attr_cpulist);
169 sysdev_remove_file(&node->sysdev, &attr_meminfo); 184 sysdev_remove_file(&node->sysdev, &attr_meminfo);
170 sysdev_remove_file(&node->sysdev, &attr_numastat); 185 sysdev_remove_file(&node->sysdev, &attr_numastat);
171 sysdev_remove_file(&node->sysdev, &attr_distance); 186 sysdev_remove_file(&node->sysdev, &attr_distance);
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index e1d3ad4db2f0..fdf4044d2e74 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -40,15 +40,38 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \
40 return sprintf(buf, "%d\n", topology_##name(cpu)); \ 40 return sprintf(buf, "%d\n", topology_##name(cpu)); \
41} 41}
42 42
43#define define_siblings_show_func(name) \ 43static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
44static ssize_t show_##name(struct sys_device *dev, char *buf) \ 44{
45 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
46 int n = 0;
47
48 if (len > 1) {
49 n = type?
50 cpulist_scnprintf(buf, len-2, *mask):
51 cpumask_scnprintf(buf, len-2, *mask);
52 buf[n++] = '\n';
53 buf[n] = '\0';
54 }
55 return n;
56}
57
58#define define_siblings_show_map(name) \
59static inline ssize_t show_##name(struct sys_device *dev, char *buf) \
45{ \ 60{ \
46 ssize_t len = -1; \
47 unsigned int cpu = dev->id; \ 61 unsigned int cpu = dev->id; \
48 len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu)); \ 62 return show_cpumap(0, &(topology_##name(cpu)), buf); \
49 return (len + sprintf(buf + len, "\n")); \
50} 63}
51 64
65#define define_siblings_show_list(name) \
66static inline ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
67{ \
68 unsigned int cpu = dev->id; \
69 return show_cpumap(1, &(topology_##name(cpu)), buf); \
70}
71
72#define define_siblings_show_func(name) \
73 define_siblings_show_map(name); define_siblings_show_list(name)
74
52#ifdef topology_physical_package_id 75#ifdef topology_physical_package_id
53define_id_show_func(physical_package_id); 76define_id_show_func(physical_package_id);
54define_one_ro(physical_package_id); 77define_one_ro(physical_package_id);
@@ -68,7 +91,9 @@ define_one_ro(core_id);
68#ifdef topology_thread_siblings 91#ifdef topology_thread_siblings
69define_siblings_show_func(thread_siblings); 92define_siblings_show_func(thread_siblings);
70define_one_ro(thread_siblings); 93define_one_ro(thread_siblings);
71#define ref_thread_siblings_attr &attr_thread_siblings.attr, 94define_one_ro(thread_siblings_list);
95#define ref_thread_siblings_attr \
96 &attr_thread_siblings.attr, &attr_thread_siblings_list.attr,
72#else 97#else
73#define ref_thread_siblings_attr 98#define ref_thread_siblings_attr
74#endif 99#endif
@@ -76,7 +101,9 @@ define_one_ro(thread_siblings);
76#ifdef topology_core_siblings 101#ifdef topology_core_siblings
77define_siblings_show_func(core_siblings); 102define_siblings_show_func(core_siblings);
78define_one_ro(core_siblings); 103define_one_ro(core_siblings);
79#define ref_core_siblings_attr &attr_core_siblings.attr, 104define_one_ro(core_siblings_list);
105#define ref_core_siblings_attr \
106 &attr_core_siblings.attr, &attr_core_siblings_list.attr,
80#else 107#else
81#define ref_core_siblings_attr 108#define ref_core_siblings_attr
82#endif 109#endif
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index d8822eedba65..f235940719e7 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -264,7 +264,7 @@ static int smi_request(struct smi_cmd *smi_cmd)
264 264
265 /* SMI requires CPU 0 */ 265 /* SMI requires CPU 0 */
266 old_mask = current->cpus_allowed; 266 old_mask = current->cpus_allowed;
267 set_cpus_allowed(current, cpumask_of_cpu(0)); 267 set_cpus_allowed_ptr(current, &cpumask_of_cpu(0));
268 if (smp_processor_id() != 0) { 268 if (smp_processor_id() != 0) {
269 dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n", 269 dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
270 __FUNCTION__); 270 __FUNCTION__);
@@ -284,7 +284,7 @@ static int smi_request(struct smi_cmd *smi_cmd)
284 ); 284 );
285 285
286out: 286out:
287 set_cpus_allowed(current, old_mask); 287 set_cpus_allowed_ptr(current, &old_mask);
288 return ret; 288 return ret;
289} 289}
290 290
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 5fa9c3c67e0c..b04c99580d0d 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -645,7 +645,7 @@ config I2C_PCA_ISA
645 645
646config I2C_MV64XXX 646config I2C_MV64XXX
647 tristate "Marvell mv64xxx I2C Controller" 647 tristate "Marvell mv64xxx I2C Controller"
648 depends on (MV64X60 || ARCH_ORION) && EXPERIMENTAL 648 depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
649 help 649 help
650 If you say yes to this option, support will be included for the 650 If you say yes to this option, support will be included for the
651 built-in I2C interface on the Marvell 64xxx line of host bridges. 651 built-in I2C interface on the Marvell 64xxx line of host bridges.
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 2d2087ad708f..6fd2d6a84eff 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -39,6 +39,7 @@
39#include <asm/io.h> 39#include <asm/io.h>
40#include <asm/arch/i2c.h> 40#include <asm/arch/i2c.h>
41#include <asm/arch/pxa-regs.h> 41#include <asm/arch/pxa-regs.h>
42#include <asm/arch/pxa2xx-gpio.h>
42 43
43struct pxa_i2c { 44struct pxa_i2c {
44 spinlock_t lock; 45 spinlock_t lock;
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index b21593f93586..2da2edfa68ec 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -93,6 +93,7 @@ config ISP1301_OMAP
93 93
94config TPS65010 94config TPS65010
95 tristate "TPS6501x Power Management chips" 95 tristate "TPS6501x Power Management chips"
96 depends on HAVE_GPIO_LIB
96 default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK 97 default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
97 help 98 help
98 If you say yes here you get support for the TPS6501x series of 99 If you say yes here you get support for the TPS6501x series of
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 4154a9108859..b67f69c2e7f3 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -30,9 +30,13 @@
30#include <linux/debugfs.h> 30#include <linux/debugfs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/platform_device.h>
33 34
34#include <linux/i2c/tps65010.h> 35#include <linux/i2c/tps65010.h>
35 36
37#include <asm/gpio.h>
38
39
36/*-------------------------------------------------------------------------*/ 40/*-------------------------------------------------------------------------*/
37 41
38#define DRIVER_VERSION "2 May 2005" 42#define DRIVER_VERSION "2 May 2005"
@@ -84,7 +88,9 @@ struct tps65010 {
84 u8 chgstatus, regstatus, chgconf; 88 u8 chgstatus, regstatus, chgconf;
85 u8 nmask1, nmask2; 89 u8 nmask1, nmask2;
86 90
87 /* not currently tracking GPIO state */ 91 u8 outmask;
92 struct gpio_chip chip;
93 struct platform_device *leds;
88}; 94};
89 95
90#define POWER_POLL_DELAY msecs_to_jiffies(5000) 96#define POWER_POLL_DELAY msecs_to_jiffies(5000)
@@ -449,12 +455,72 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
449 455
450/*-------------------------------------------------------------------------*/ 456/*-------------------------------------------------------------------------*/
451 457
458/* offsets 0..3 == GPIO1..GPIO4
459 * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes)
460 */
461static void
462tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
463{
464 if (offset < 4)
465 tps65010_set_gpio_out_value(offset + 1, value);
466 else
467 tps65010_set_led(offset - 3, value ? ON : OFF);
468}
469
470static int
471tps65010_output(struct gpio_chip *chip, unsigned offset, int value)
472{
473 /* GPIOs may be input-only */
474 if (offset < 4) {
475 struct tps65010 *tps;
476
477 tps = container_of(chip, struct tps65010, chip);
478 if (!(tps->outmask & (1 << offset)))
479 return -EINVAL;
480 tps65010_set_gpio_out_value(offset + 1, value);
481 } else
482 tps65010_set_led(offset - 3, value ? ON : OFF);
483
484 return 0;
485}
486
487static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset)
488{
489 int value;
490 struct tps65010 *tps;
491
492 tps = container_of(chip, struct tps65010, chip);
493
494 if (offset < 4) {
495 value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO);
496 if (value < 0)
497 return 0;
498 if (value & (1 << (offset + 4))) /* output */
499 return !(value & (1 << offset));
500 else /* input */
501 return (value & (1 << offset));
502 }
503
504 /* REVISIT we *could* report LED1/nPG and LED2 state ... */
505 return 0;
506}
507
508
509/*-------------------------------------------------------------------------*/
510
452static struct tps65010 *the_tps; 511static struct tps65010 *the_tps;
453 512
454static int __exit tps65010_remove(struct i2c_client *client) 513static int __exit tps65010_remove(struct i2c_client *client)
455{ 514{
456 struct tps65010 *tps = i2c_get_clientdata(client); 515 struct tps65010 *tps = i2c_get_clientdata(client);
516 struct tps65010_board *board = client->dev.platform_data;
457 517
518 if (board && board->teardown) {
519 int status = board->teardown(client, board->context);
520 if (status < 0)
521 dev_dbg(&client->dev, "board %s %s err %d\n",
522 "teardown", client->name, status);
523 }
458 if (client->irq > 0) 524 if (client->irq > 0)
459 free_irq(client->irq, tps); 525 free_irq(client->irq, tps);
460 cancel_delayed_work(&tps->work); 526 cancel_delayed_work(&tps->work);
@@ -469,6 +535,7 @@ static int tps65010_probe(struct i2c_client *client)
469{ 535{
470 struct tps65010 *tps; 536 struct tps65010 *tps;
471 int status; 537 int status;
538 struct tps65010_board *board = client->dev.platform_data;
472 539
473 if (the_tps) { 540 if (the_tps) {
474 dev_dbg(&client->dev, "only one tps6501x chip allowed\n"); 541 dev_dbg(&client->dev, "only one tps6501x chip allowed\n");
@@ -577,6 +644,38 @@ static int tps65010_probe(struct i2c_client *client)
577 644
578 tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, 645 tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
579 tps, DEBUG_FOPS); 646 tps, DEBUG_FOPS);
647
648 /* optionally register GPIOs */
649 if (board && board->base > 0) {
650 tps->outmask = board->outmask;
651
652 tps->chip.label = client->name;
653
654 tps->chip.set = tps65010_gpio_set;
655 tps->chip.direction_output = tps65010_output;
656
657 /* NOTE: only partial support for inputs; nyet IRQs */
658 tps->chip.get = tps65010_gpio_get;
659
660 tps->chip.base = board->base;
661 tps->chip.ngpio = 6;
662 tps->chip.can_sleep = 1;
663
664 status = gpiochip_add(&tps->chip);
665 if (status < 0)
666 dev_err(&client->dev, "can't add gpiochip, err %d\n",
667 status);
668 else if (board->setup) {
669 status = board->setup(client, board->context);
670 if (status < 0) {
671 dev_dbg(&client->dev,
672 "board %s %s err %d\n",
673 "setup", client->name, status);
674 status = 0;
675 }
676 }
677 }
678
580 return 0; 679 return 0;
581fail1: 680fail1:
582 kfree(tps); 681 kfree(tps);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 8ea709be3306..efd70a974591 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -314,4 +314,13 @@ config KEYBOARD_BFIN
314 To compile this driver as a module, choose M here: the 314 To compile this driver as a module, choose M here: the
315 module will be called bf54x-keys. 315 module will be called bf54x-keys.
316 316
317config KEYBOARD_SH_KEYSC
318 tristate "SuperH KEYSC keypad support"
319 depends on SUPERH
320 help
321 Say Y here if you want to use a keypad attached to the KEYSC block
322 on SuperH processors such as sh7722 and sh7343.
323
324 To compile this driver as a module, choose M here: the
325 module will be called sh_keysc.
317endif 326endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index e741f4031012..0edc8f285d1c 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
26obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o 26obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
27obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o 27obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
28obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o 28obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
29obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 790fed368aae..5d6cc7f1dc94 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -23,6 +23,7 @@
23#include <asm/arch/corgi.h> 23#include <asm/arch/corgi.h>
24#include <asm/arch/hardware.h> 24#include <asm/arch/hardware.h>
25#include <asm/arch/pxa-regs.h> 25#include <asm/arch/pxa-regs.h>
26#include <asm/arch/pxa2xx-gpio.h>
26#include <asm/hardware/scoop.h> 27#include <asm/hardware/scoop.h>
27 28
28#define KB_ROWS 8 29#define KB_ROWS 8
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
new file mode 100644
index 000000000000..8486abc457ed
--- /dev/null
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -0,0 +1,280 @@
1/*
2 * SuperH KEYSC Keypad Driver
3 *
4 * Copyright (C) 2008 Magnus Damm
5 *
6 * Based on gpio_keys.c, Copyright 2005 Phil Blundell
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/delay.h>
19#include <linux/platform_device.h>
20#include <linux/input.h>
21#include <linux/io.h>
22#include <asm/sh_keysc.h>
23
24#define KYCR1_OFFS 0x00
25#define KYCR2_OFFS 0x04
26#define KYINDR_OFFS 0x08
27#define KYOUTDR_OFFS 0x0c
28
29#define KYCR2_IRQ_LEVEL 0x10
30#define KYCR2_IRQ_DISABLED 0x00
31
32static const struct {
33 unsigned char kymd, keyout, keyin;
34} sh_keysc_mode[] = {
35 [SH_KEYSC_MODE_1] = { 0, 6, 5 },
36 [SH_KEYSC_MODE_2] = { 1, 5, 6 },
37 [SH_KEYSC_MODE_3] = { 2, 4, 7 },
38};
39
40struct sh_keysc_priv {
41 void __iomem *iomem_base;
42 unsigned long last_keys;
43 struct input_dev *input;
44 struct sh_keysc_info pdata;
45};
46
47static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
48{
49 struct platform_device *pdev = dev_id;
50 struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
51 struct sh_keysc_info *pdata = &priv->pdata;
52 unsigned long keys, keys1, keys0, mask;
53 unsigned char keyin_set, tmp;
54 int i, k;
55
56 dev_dbg(&pdev->dev, "isr!\n");
57
58 keys1 = ~0;
59 keys0 = 0;
60
61 do {
62 keys = 0;
63 keyin_set = 0;
64
65 iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS);
66
67 for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) {
68 iowrite16(0xfff ^ (3 << (i * 2)),
69 priv->iomem_base + KYOUTDR_OFFS);
70 udelay(pdata->delay);
71 tmp = ioread16(priv->iomem_base + KYINDR_OFFS);
72 keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i);
73 tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1;
74 keyin_set |= tmp;
75 }
76
77 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
78 iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8),
79 priv->iomem_base + KYCR2_OFFS);
80
81 keys ^= ~0;
82 keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
83 sh_keysc_mode[pdata->mode].keyout)) - 1;
84 keys1 &= keys;
85 keys0 |= keys;
86
87 dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys);
88
89 } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01);
90
91 dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n",
92 priv->last_keys, keys0, keys1);
93
94 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
95 k = pdata->keycodes[i];
96 if (!k)
97 continue;
98
99 mask = 1 << i;
100
101 if (!((priv->last_keys ^ keys0) & mask))
102 continue;
103
104 if ((keys1 | keys0) & mask) {
105 input_event(priv->input, EV_KEY, k, 1);
106 priv->last_keys |= mask;
107 }
108
109 if (!(keys1 & mask)) {
110 input_event(priv->input, EV_KEY, k, 0);
111 priv->last_keys &= ~mask;
112 }
113
114 }
115 input_sync(priv->input);
116
117 return IRQ_HANDLED;
118}
119
120#define res_size(res) ((res)->end - (res)->start + 1)
121
122static int __devinit sh_keysc_probe(struct platform_device *pdev)
123{
124 struct sh_keysc_priv *priv;
125 struct sh_keysc_info *pdata;
126 struct resource *res;
127 struct input_dev *input;
128 int i, k;
129 int irq, error;
130
131 if (!pdev->dev.platform_data) {
132 dev_err(&pdev->dev, "no platform data defined\n");
133 error = -EINVAL;
134 goto err0;
135 }
136
137 error = -ENXIO;
138 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
139 if (res == NULL) {
140 dev_err(&pdev->dev, "failed to get I/O memory\n");
141 goto err0;
142 }
143
144 irq = platform_get_irq(pdev, 0);
145 if (irq < 0) {
146 dev_err(&pdev->dev, "failed to get irq\n");
147 goto err0;
148 }
149
150 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
151 if (priv == NULL) {
152 dev_err(&pdev->dev, "failed to allocate driver data\n");
153 error = -ENOMEM;
154 goto err0;
155 }
156
157 platform_set_drvdata(pdev, priv);
158 memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata));
159 pdata = &priv->pdata;
160
161 res = request_mem_region(res->start, res_size(res), pdev->name);
162 if (res == NULL) {
163 dev_err(&pdev->dev, "failed to request I/O memory\n");
164 error = -EBUSY;
165 goto err1;
166 }
167
168 priv->iomem_base = ioremap_nocache(res->start, res_size(res));
169 if (priv->iomem_base == NULL) {
170 dev_err(&pdev->dev, "failed to remap I/O memory\n");
171 error = -ENXIO;
172 goto err2;
173 }
174
175 priv->input = input_allocate_device();
176 if (!priv->input) {
177 dev_err(&pdev->dev, "failed to allocate input device\n");
178 error = -ENOMEM;
179 goto err3;
180 }
181
182 input = priv->input;
183 input->evbit[0] = BIT_MASK(EV_KEY);
184
185 input->name = pdev->name;
186 input->phys = "sh-keysc-keys/input0";
187 input->dev.parent = &pdev->dev;
188
189 input->id.bustype = BUS_HOST;
190 input->id.vendor = 0x0001;
191 input->id.product = 0x0001;
192 input->id.version = 0x0100;
193
194 error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
195 if (error) {
196 dev_err(&pdev->dev, "failed to request IRQ\n");
197 goto err4;
198 }
199
200 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
201 k = pdata->keycodes[i];
202 if (k)
203 input_set_capability(input, EV_KEY, k);
204 }
205
206 error = input_register_device(input);
207 if (error) {
208 dev_err(&pdev->dev, "failed to register input device\n");
209 goto err5;
210 }
211
212 iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) |
213 pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
214 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
215 iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
216 return 0;
217 err5:
218 free_irq(irq, pdev);
219 err4:
220 input_free_device(input);
221 err3:
222 iounmap(priv->iomem_base);
223 err2:
224 release_mem_region(res->start, res_size(res));
225 err1:
226 platform_set_drvdata(pdev, NULL);
227 kfree(priv);
228 err0:
229 return error;
230}
231
232static int __devexit sh_keysc_remove(struct platform_device *pdev)
233{
234 struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
235 struct resource *res;
236
237 iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS);
238
239 input_unregister_device(priv->input);
240 free_irq(platform_get_irq(pdev, 0), pdev);
241 iounmap(priv->iomem_base);
242
243 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
244 release_mem_region(res->start, res_size(res));
245
246 platform_set_drvdata(pdev, NULL);
247 kfree(priv);
248 return 0;
249}
250
251
252#define sh_keysc_suspend NULL
253#define sh_keysc_resume NULL
254
255struct platform_driver sh_keysc_device_driver = {
256 .probe = sh_keysc_probe,
257 .remove = __devexit_p(sh_keysc_remove),
258 .suspend = sh_keysc_suspend,
259 .resume = sh_keysc_resume,
260 .driver = {
261 .name = "sh_keysc",
262 }
263};
264
265static int __init sh_keysc_init(void)
266{
267 return platform_driver_register(&sh_keysc_device_driver);
268}
269
270static void __exit sh_keysc_exit(void)
271{
272 platform_driver_unregister(&sh_keysc_device_driver);
273}
274
275module_init(sh_keysc_init);
276module_exit(sh_keysc_exit);
277
278MODULE_AUTHOR("Magnus Damm");
279MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver");
280MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 1d59a2dc3c17..0be74bfc58fe 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -23,6 +23,7 @@
23#include <asm/arch/spitz.h> 23#include <asm/arch/spitz.h>
24#include <asm/arch/hardware.h> 24#include <asm/arch/hardware.h>
25#include <asm/arch/pxa-regs.h> 25#include <asm/arch/pxa-regs.h>
26#include <asm/arch/pxa2xx-gpio.h>
26 27
27#define KB_ROWS 7 28#define KB_ROWS 7
28#define KB_COLS 11 29#define KB_COLS 11
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 57a1c28bf122..39573b91c8de 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -28,13 +28,6 @@
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <asm/irq.h> 29#include <asm/irq.h>
30 30
31#ifdef CONFIG_ARM
32#include <asm/mach-types.h>
33#ifdef CONFIG_ARCH_OMAP
34#include <asm/arch/gpio.h>
35#endif
36#endif
37
38 31
39/* 32/*
40 * This code has been heavily tested on a Nokia 770, and lightly 33 * This code has been heavily tested on a Nokia 770, and lightly
@@ -1174,31 +1167,6 @@ static struct spi_driver ads7846_driver = {
1174 1167
1175static int __init ads7846_init(void) 1168static int __init ads7846_init(void)
1176{ 1169{
1177 /* grr, board-specific init should stay out of drivers!! */
1178
1179#ifdef CONFIG_ARCH_OMAP
1180 if (machine_is_omap_osk()) {
1181 /* GPIO4 = PENIRQ; GPIO6 = BUSY */
1182 omap_request_gpio(4);
1183 omap_set_gpio_direction(4, 1);
1184 omap_request_gpio(6);
1185 omap_set_gpio_direction(6, 1);
1186 }
1187 // also TI 1510 Innovator, bitbanging through FPGA
1188 // also Nokia 770
1189 // also Palm Tungsten T2
1190#endif
1191
1192 // PXA:
1193 // also Dell Axim X50
1194 // also HP iPaq H191x/H192x/H415x/H435x
1195 // also Intel Lubbock (additional to UCB1400; as temperature sensor)
1196 // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
1197
1198 // Atmel at91sam9261-EK uses ads7843
1199
1200 // also various AMD Au1x00 devel boards
1201
1202 return spi_register_driver(&ads7846_driver); 1170 return spi_register_driver(&ads7846_driver);
1203} 1171}
1204module_init(ads7846_init); 1172module_init(ads7846_init);
@@ -1206,14 +1174,6 @@ module_init(ads7846_init);
1206static void __exit ads7846_exit(void) 1174static void __exit ads7846_exit(void)
1207{ 1175{
1208 spi_unregister_driver(&ads7846_driver); 1176 spi_unregister_driver(&ads7846_driver);
1209
1210#ifdef CONFIG_ARCH_OMAP
1211 if (machine_is_omap_osk()) {
1212 omap_free_gpio(4);
1213 omap_free_gpio(6);
1214 }
1215#endif
1216
1217} 1177}
1218module_exit(ads7846_exit); 1178module_exit(ads7846_exit);
1219 1179
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 99d92f5c93d6..a22576779acd 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -22,6 +22,7 @@
22#include <asm/arch/sharpsl.h> 22#include <asm/arch/sharpsl.h>
23#include <asm/arch/hardware.h> 23#include <asm/arch/hardware.h>
24#include <asm/arch/pxa-regs.h> 24#include <asm/arch/pxa-regs.h>
25#include <asm/arch/pxa2xx-gpio.h>
25 26
26 27
27#define PWR_MODE_ACTIVE 0 28#define PWR_MODE_ACTIVE 0
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 859814f62cb0..a3a6199639f9 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -46,13 +46,6 @@ config LEDS_SPITZ
46 This option enables support for the LEDs on Sharp Zaurus 46 This option enables support for the LEDs on Sharp Zaurus
47 SL-Cxx00 series (C1000, C3000, C3100). 47 SL-Cxx00 series (C1000, C3000, C3100).
48 48
49config LEDS_TOSA
50 tristate "LED Support for the Sharp SL-6000 series"
51 depends on LEDS_CLASS && PXA_SHARPSL
52 help
53 This option enables support for the LEDs on Sharp Zaurus
54 SL-6000 series.
55
56config LEDS_S3C24XX 49config LEDS_S3C24XX
57 tristate "LED Support for Samsung S3C24XX GPIO LEDs" 50 tristate "LED Support for Samsung S3C24XX GPIO LEDs"
58 depends on LEDS_CLASS && ARCH_S3C2410 51 depends on LEDS_CLASS && ARCH_S3C2410
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 84ced3b1a13d..e54f42da21a2 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
9obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o 9obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
10obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o 10obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
11obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o 11obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
12obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
13obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o 12obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
14obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o 13obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
15obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o 14obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c
deleted file mode 100644
index 7ebecc41a9be..000000000000
--- a/drivers/leds/leds-tosa.c
+++ /dev/null
@@ -1,132 +0,0 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005 Dirk Opfer
5 *
6 * Author: Dirk Opfer <Dirk@Opfer-Online.de>
7 * based on spitz.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <asm/hardware/scoop.h>
20#include <asm/mach-types.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h>
23#include <asm/arch/tosa.h>
24
25static void tosaled_amber_set(struct led_classdev *led_cdev,
26 enum led_brightness value)
27{
28 if (value)
29 set_scoop_gpio(&tosascoop_jc_device.dev,
30 TOSA_SCOOP_JC_CHRG_ERR_LED);
31 else
32 reset_scoop_gpio(&tosascoop_jc_device.dev,
33 TOSA_SCOOP_JC_CHRG_ERR_LED);
34}
35
36static void tosaled_green_set(struct led_classdev *led_cdev,
37 enum led_brightness value)
38{
39 if (value)
40 set_scoop_gpio(&tosascoop_jc_device.dev,
41 TOSA_SCOOP_JC_NOTE_LED);
42 else
43 reset_scoop_gpio(&tosascoop_jc_device.dev,
44 TOSA_SCOOP_JC_NOTE_LED);
45}
46
47static struct led_classdev tosa_amber_led = {
48 .name = "tosa:amber:charge",
49 .default_trigger = "sharpsl-charge",
50 .brightness_set = tosaled_amber_set,
51};
52
53static struct led_classdev tosa_green_led = {
54 .name = "tosa:green:mail",
55 .default_trigger = "nand-disk",
56 .brightness_set = tosaled_green_set,
57};
58
59#ifdef CONFIG_PM
60static int tosaled_suspend(struct platform_device *dev, pm_message_t state)
61{
62#ifdef CONFIG_LEDS_TRIGGERS
63 if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name,
64 "sharpsl-charge"))
65#endif
66 led_classdev_suspend(&tosa_amber_led);
67 led_classdev_suspend(&tosa_green_led);
68 return 0;
69}
70
71static int tosaled_resume(struct platform_device *dev)
72{
73 led_classdev_resume(&tosa_amber_led);
74 led_classdev_resume(&tosa_green_led);
75 return 0;
76}
77#else
78#define tosaled_suspend NULL
79#define tosaled_resume NULL
80#endif
81
82static int tosaled_probe(struct platform_device *pdev)
83{
84 int ret;
85
86 ret = led_classdev_register(&pdev->dev, &tosa_amber_led);
87 if (ret < 0)
88 return ret;
89
90 ret = led_classdev_register(&pdev->dev, &tosa_green_led);
91 if (ret < 0)
92 led_classdev_unregister(&tosa_amber_led);
93
94 return ret;
95}
96
97static int tosaled_remove(struct platform_device *pdev)
98{
99 led_classdev_unregister(&tosa_amber_led);
100 led_classdev_unregister(&tosa_green_led);
101
102 return 0;
103}
104
105static struct platform_driver tosaled_driver = {
106 .probe = tosaled_probe,
107 .remove = tosaled_remove,
108 .suspend = tosaled_suspend,
109 .resume = tosaled_resume,
110 .driver = {
111 .name = "tosa-led",
112 .owner = THIS_MODULE,
113 },
114};
115
116static int __init tosaled_init(void)
117{
118 return platform_driver_register(&tosaled_driver);
119}
120
121static void __exit tosaled_exit(void)
122{
123 platform_driver_unregister(&tosaled_driver);
124}
125
126module_init(tosaled_init);
127module_exit(tosaled_exit);
128
129MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
130MODULE_DESCRIPTION("Tosa LED driver");
131MODULE_LICENSE("GPL");
132MODULE_ALIAS("platform:tosa-led");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0c886c882385..2566479937c9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -22,6 +22,22 @@ config MFD_ASIC3
22 This driver supports the ASIC3 multifunction chip found on many 22 This driver supports the ASIC3 multifunction chip found on many
23 PDAs (mainly iPAQ and HTC based ones) 23 PDAs (mainly iPAQ and HTC based ones)
24 24
25config HTC_EGPIO
26 bool "HTC EGPIO support"
27 depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB
28 help
29 This driver supports the CPLD egpio chip present on
30 several HTC phones. It provides basic support for input
31 pins, output pins, and irqs.
32
33config HTC_PASIC3
34 tristate "HTC PASIC3 LED/DS1WM chip support"
35 help
36 This core driver provides register access for the LED/DS1WM
37 chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
38 HTC Magician devices, respectively. Actual functionality is
39 handled by the leds-pasic3 and ds1wm drivers.
40
25endmenu 41endmenu
26 42
27menu "Multimedia Capabilities Port drivers" 43menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 521cd5cb68af..eef4e26807df 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -5,6 +5,9 @@
5obj-$(CONFIG_MFD_SM501) += sm501.o 5obj-$(CONFIG_MFD_SM501) += sm501.o
6obj-$(CONFIG_MFD_ASIC3) += asic3.o 6obj-$(CONFIG_MFD_ASIC3) += asic3.o
7 7
8obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
9obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
10
8obj-$(CONFIG_MCP) += mcp-core.o 11obj-$(CONFIG_MCP) += mcp-core.o
9obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o 12obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
10obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o 13obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
new file mode 100644
index 000000000000..8872cc077519
--- /dev/null
+++ b/drivers/mfd/htc-egpio.c
@@ -0,0 +1,440 @@
1/*
2 * Support for the GPIO/IRQ expander chips present on several HTC phones.
3 * These are implemented in CPLD chips present on the board.
4 *
5 * Copyright (c) 2007 Kevin O'Connor <kevin@koconnor.net>
6 * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com>
7 *
8 * This file may be distributed under the terms of the GNU GPL license.
9 */
10
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <linux/spinlock.h>
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/mfd/htc-egpio.h>
20
21struct egpio_chip {
22 int reg_start;
23 int cached_values;
24 unsigned long is_out;
25 struct device *dev;
26 struct gpio_chip chip;
27};
28
29struct egpio_info {
30 spinlock_t lock;
31
32 /* iomem info */
33 void __iomem *base_addr;
34 int bus_shift; /* byte shift */
35 int reg_shift; /* bit shift */
36 int reg_mask;
37
38 /* irq info */
39 int ack_register;
40 int ack_write;
41 u16 irqs_enabled;
42 uint irq_start;
43 int nirqs;
44 uint chained_irq;
45
46 /* egpio info */
47 struct egpio_chip *chip;
48 int nchips;
49};
50
51static inline void egpio_writew(u16 value, struct egpio_info *ei, int reg)
52{
53 writew(value, ei->base_addr + (reg << ei->bus_shift));
54}
55
56static inline u16 egpio_readw(struct egpio_info *ei, int reg)
57{
58 return readw(ei->base_addr + (reg << ei->bus_shift));
59}
60
61/*
62 * IRQs
63 */
64
65static inline void ack_irqs(struct egpio_info *ei)
66{
67 egpio_writew(ei->ack_write, ei, ei->ack_register);
68 pr_debug("EGPIO ack - write %x to base+%x\n",
69 ei->ack_write, ei->ack_register << ei->bus_shift);
70}
71
72static void egpio_ack(unsigned int irq)
73{
74}
75
76/* There does not appear to be a way to proactively mask interrupts
77 * on the egpio chip itself. So, we simply ignore interrupts that
78 * aren't desired. */
79static void egpio_mask(unsigned int irq)
80{
81 struct egpio_info *ei = get_irq_chip_data(irq);
82 ei->irqs_enabled &= ~(1 << (irq - ei->irq_start));
83 pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled);
84}
85static void egpio_unmask(unsigned int irq)
86{
87 struct egpio_info *ei = get_irq_chip_data(irq);
88 ei->irqs_enabled |= 1 << (irq - ei->irq_start);
89 pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled);
90}
91
92static struct irq_chip egpio_muxed_chip = {
93 .name = "htc-egpio",
94 .ack = egpio_ack,
95 .mask = egpio_mask,
96 .unmask = egpio_unmask,
97};
98
99static void egpio_handler(unsigned int irq, struct irq_desc *desc)
100{
101 struct egpio_info *ei = get_irq_data(irq);
102 int irqpin;
103
104 /* Read current pins. */
105 unsigned long readval = egpio_readw(ei, ei->ack_register);
106 pr_debug("IRQ reg: %x\n", (unsigned int)readval);
107 /* Ack/unmask interrupts. */
108 ack_irqs(ei);
109 /* Process all set pins. */
110 readval &= ei->irqs_enabled;
111 for_each_bit(irqpin, &readval, ei->nirqs) {
112 /* Run irq handler */
113 pr_debug("got IRQ %d\n", irqpin);
114 irq = ei->irq_start + irqpin;
115 desc = &irq_desc[irq];
116 desc->handle_irq(irq, desc);
117 }
118}
119
120int htc_egpio_get_wakeup_irq(struct device *dev)
121{
122 struct egpio_info *ei = dev_get_drvdata(dev);
123
124 /* Read current pins. */
125 u16 readval = egpio_readw(ei, ei->ack_register);
126 /* Ack/unmask interrupts. */
127 ack_irqs(ei);
128 /* Return first set pin. */
129 readval &= ei->irqs_enabled;
130 return ei->irq_start + ffs(readval) - 1;
131}
132EXPORT_SYMBOL(htc_egpio_get_wakeup_irq);
133
134static inline int egpio_pos(struct egpio_info *ei, int bit)
135{
136 return bit >> ei->reg_shift;
137}
138
139static inline int egpio_bit(struct egpio_info *ei, int bit)
140{
141 return 1 << (bit & ((1 << ei->reg_shift)-1));
142}
143
144/*
145 * Input pins
146 */
147
148static int egpio_get(struct gpio_chip *chip, unsigned offset)
149{
150 struct egpio_chip *egpio;
151 struct egpio_info *ei;
152 unsigned bit;
153 int reg;
154 int value;
155
156 pr_debug("egpio_get_value(%d)\n", chip->base + offset);
157
158 egpio = container_of(chip, struct egpio_chip, chip);
159 ei = dev_get_drvdata(egpio->dev);
160 bit = egpio_bit(ei, offset);
161 reg = egpio->reg_start + egpio_pos(ei, offset);
162
163 value = egpio_readw(ei, reg);
164 pr_debug("readw(%p + %x) = %x\n",
165 ei->base_addr, reg << ei->bus_shift, value);
166 return value & bit;
167}
168
169static int egpio_direction_input(struct gpio_chip *chip, unsigned offset)
170{
171 struct egpio_chip *egpio;
172
173 egpio = container_of(chip, struct egpio_chip, chip);
174 return test_bit(offset, &egpio->is_out) ? -EINVAL : 0;
175}
176
177
178/*
179 * Output pins
180 */
181
182static void egpio_set(struct gpio_chip *chip, unsigned offset, int value)
183{
184 unsigned long flag;
185 struct egpio_chip *egpio;
186 struct egpio_info *ei;
187 unsigned bit;
188 int pos;
189 int reg;
190 int shift;
191
192 pr_debug("egpio_set(%s, %d(%d), %d)\n",
193 chip->label, offset, offset+chip->base, value);
194
195 egpio = container_of(chip, struct egpio_chip, chip);
196 ei = dev_get_drvdata(egpio->dev);
197 bit = egpio_bit(ei, offset);
198 pos = egpio_pos(ei, offset);
199 reg = egpio->reg_start + pos;
200 shift = pos << ei->reg_shift;
201
202 pr_debug("egpio %s: reg %d = 0x%04x\n", value ? "set" : "clear",
203 reg, (egpio->cached_values >> shift) & ei->reg_mask);
204
205 spin_lock_irqsave(&ei->lock, flag);
206 if (value)
207 egpio->cached_values |= (1 << offset);
208 else
209 egpio->cached_values &= ~(1 << offset);
210 egpio_writew((egpio->cached_values >> shift) & ei->reg_mask, ei, reg);
211 spin_unlock_irqrestore(&ei->lock, flag);
212}
213
214static int egpio_direction_output(struct gpio_chip *chip,
215 unsigned offset, int value)
216{
217 struct egpio_chip *egpio;
218
219 egpio = container_of(chip, struct egpio_chip, chip);
220 if (test_bit(offset, &egpio->is_out)) {
221 egpio_set(chip, offset, value);
222 return 0;
223 } else {
224 return -EINVAL;
225 }
226}
227
228static void egpio_write_cache(struct egpio_info *ei)
229{
230 int i;
231 struct egpio_chip *egpio;
232 int shift;
233
234 for (i = 0; i < ei->nchips; i++) {
235 egpio = &(ei->chip[i]);
236 if (!egpio->is_out)
237 continue;
238
239 for (shift = 0; shift < egpio->chip.ngpio;
240 shift += (1<<ei->reg_shift)) {
241
242 int reg = egpio->reg_start + egpio_pos(ei, shift);
243
244 if (!((egpio->is_out >> shift) & ei->reg_mask))
245 continue;
246
247 pr_debug("EGPIO: setting %x to %x, was %x\n", reg,
248 (egpio->cached_values >> shift) & ei->reg_mask,
249 egpio_readw(ei, reg));
250
251 egpio_writew((egpio->cached_values >> shift)
252 & ei->reg_mask, ei, reg);
253 }
254 }
255}
256
257
258/*
259 * Setup
260 */
261
262static int __init egpio_probe(struct platform_device *pdev)
263{
264 struct htc_egpio_platform_data *pdata = pdev->dev.platform_data;
265 struct resource *res;
266 struct egpio_info *ei;
267 struct gpio_chip *chip;
268 unsigned int irq, irq_end;
269 int i;
270 int ret;
271
272 /* Initialize ei data structure. */
273 ei = kzalloc(sizeof(*ei), GFP_KERNEL);
274 if (!ei)
275 return -ENOMEM;
276
277 spin_lock_init(&ei->lock);
278
279 /* Find chained irq */
280 ret = -EINVAL;
281 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
282 if (res)
283 ei->chained_irq = res->start;
284
285 /* Map egpio chip into virtual address space. */
286 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
287 if (!res)
288 goto fail;
289 ei->base_addr = ioremap_nocache(res->start, res->end - res->start);
290 if (!ei->base_addr)
291 goto fail;
292 pr_debug("EGPIO phys=%08x virt=%p\n", res->start, ei->base_addr);
293
294 if ((pdata->bus_width != 16) && (pdata->bus_width != 32))
295 goto fail;
296 ei->bus_shift = fls(pdata->bus_width - 1) - 3;
297 pr_debug("bus_shift = %d\n", ei->bus_shift);
298
299 if ((pdata->reg_width != 8) && (pdata->reg_width != 16))
300 goto fail;
301 ei->reg_shift = fls(pdata->reg_width - 1);
302 pr_debug("reg_shift = %d\n", ei->reg_shift);
303
304 ei->reg_mask = (1 << pdata->reg_width) - 1;
305
306 platform_set_drvdata(pdev, ei);
307
308 ei->nchips = pdata->num_chips;
309 ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL);
310 if (!ei) {
311 ret = -ENOMEM;
312 goto fail;
313 }
314 for (i = 0; i < ei->nchips; i++) {
315 ei->chip[i].reg_start = pdata->chip[i].reg_start;
316 ei->chip[i].cached_values = pdata->chip[i].initial_values;
317 ei->chip[i].is_out = pdata->chip[i].direction;
318 ei->chip[i].dev = &(pdev->dev);
319 chip = &(ei->chip[i].chip);
320 chip->label = "htc-egpio";
321 chip->get = egpio_get;
322 chip->set = egpio_set;
323 chip->direction_input = egpio_direction_input;
324 chip->direction_output = egpio_direction_output;
325 chip->base = pdata->chip[i].gpio_base;
326 chip->ngpio = pdata->chip[i].num_gpios;
327
328 gpiochip_add(chip);
329 }
330
331 /* Set initial pin values */
332 egpio_write_cache(ei);
333
334 ei->irq_start = pdata->irq_base;
335 ei->nirqs = pdata->num_irqs;
336 ei->ack_register = pdata->ack_register;
337
338 if (ei->chained_irq) {
339 /* Setup irq handlers */
340 ei->ack_write = 0xFFFF;
341 if (pdata->invert_acks)
342 ei->ack_write = 0;
343 irq_end = ei->irq_start + ei->nirqs;
344 for (irq = ei->irq_start; irq < irq_end; irq++) {
345 set_irq_chip(irq, &egpio_muxed_chip);
346 set_irq_chip_data(irq, ei);
347 set_irq_handler(irq, handle_simple_irq);
348 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
349 }
350 set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING);
351 set_irq_data(ei->chained_irq, ei);
352 set_irq_chained_handler(ei->chained_irq, egpio_handler);
353 ack_irqs(ei);
354
355 device_init_wakeup(&pdev->dev, 1);
356 }
357
358 return 0;
359
360fail:
361 printk(KERN_ERR "EGPIO failed to setup\n");
362 kfree(ei);
363 return ret;
364}
365
366static int __exit egpio_remove(struct platform_device *pdev)
367{
368 struct egpio_info *ei = platform_get_drvdata(pdev);
369 unsigned int irq, irq_end;
370
371 if (ei->chained_irq) {
372 irq_end = ei->irq_start + ei->nirqs;
373 for (irq = ei->irq_start; irq < irq_end; irq++) {
374 set_irq_chip(irq, NULL);
375 set_irq_handler(irq, NULL);
376 set_irq_flags(irq, 0);
377 }
378 set_irq_chained_handler(ei->chained_irq, NULL);
379 device_init_wakeup(&pdev->dev, 0);
380 }
381 iounmap(ei->base_addr);
382 kfree(ei->chip);
383 kfree(ei);
384
385 return 0;
386}
387
388#ifdef CONFIG_PM
389static int egpio_suspend(struct platform_device *pdev, pm_message_t state)
390{
391 struct egpio_info *ei = platform_get_drvdata(pdev);
392
393 if (ei->chained_irq && device_may_wakeup(&pdev->dev))
394 enable_irq_wake(ei->chained_irq);
395 return 0;
396}
397
398static int egpio_resume(struct platform_device *pdev)
399{
400 struct egpio_info *ei = platform_get_drvdata(pdev);
401
402 if (ei->chained_irq && device_may_wakeup(&pdev->dev))
403 disable_irq_wake(ei->chained_irq);
404
405 /* Update registers from the cache, in case
406 the CPLD was powered off during suspend */
407 egpio_write_cache(ei);
408 return 0;
409}
410#else
411#define egpio_suspend NULL
412#define egpio_resume NULL
413#endif
414
415
416static struct platform_driver egpio_driver = {
417 .driver = {
418 .name = "htc-egpio",
419 },
420 .remove = __exit_p(egpio_remove),
421 .suspend = egpio_suspend,
422 .resume = egpio_resume,
423};
424
425static int __init egpio_init(void)
426{
427 return platform_driver_probe(&egpio_driver, egpio_probe);
428}
429
430static void __exit egpio_exit(void)
431{
432 platform_driver_unregister(&egpio_driver);
433}
434
435/* start early for dependencies */
436subsys_initcall(egpio_init);
437module_exit(egpio_exit)
438
439MODULE_LICENSE("GPL");
440MODULE_AUTHOR("Kevin O'Connor <kevin@koconnor.net>");
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
new file mode 100644
index 000000000000..af66f4f28300
--- /dev/null
+++ b/drivers/mfd/htc-pasic3.c
@@ -0,0 +1,265 @@
1/*
2 * Core driver for HTC PASIC3 LED/DS1WM chip.
3 *
4 * Copyright (C) 2006 Philipp Zabel <philipp.zabel@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14
15#include <linux/ds1wm.h>
16#include <linux/gpio.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/interrupt.h>
20#include <linux/mfd/htc-pasic3.h>
21
22#include <asm/arch/pxa-regs.h>
23
24struct pasic3_data {
25 void __iomem *mapping;
26 unsigned int bus_shift;
27 struct platform_device *ds1wm_pdev;
28 struct platform_device *led_pdev;
29};
30
31#define REG_ADDR 5
32#define REG_DATA 6
33#define NUM_REGS 7
34
35#define READ_MODE 0x80
36
37/*
38 * write to a secondary register on the PASIC3
39 */
40void pasic3_write_register(struct device *dev, u32 reg, u8 val)
41{
42 struct pasic3_data *asic = dev->driver_data;
43 int bus_shift = asic->bus_shift;
44 void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
45 void __iomem *data = asic->mapping + (REG_DATA << bus_shift);
46
47 __raw_writeb(~READ_MODE & reg, addr);
48 __raw_writeb(val, data);
49}
50EXPORT_SYMBOL(pasic3_write_register); /* for leds-pasic3 */
51
52/*
53 * read from a secondary register on the PASIC3
54 */
55u8 pasic3_read_register(struct device *dev, u32 reg)
56{
57 struct pasic3_data *asic = dev->driver_data;
58 int bus_shift = asic->bus_shift;
59 void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
60 void __iomem *data = asic->mapping + (REG_DATA << bus_shift);
61
62 __raw_writeb(READ_MODE | reg, addr);
63 return __raw_readb(data);
64}
65EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
66
67/*
68 * LEDs
69 */
70
71static int led_device_add(struct device *pasic3_dev,
72 const struct pasic3_leds_machinfo *pdata)
73{
74 struct pasic3_data *asic = pasic3_dev->driver_data;
75 struct platform_device *pdev;
76 int ret;
77
78 pdev = platform_device_alloc("pasic3-led", -1);
79 if (!pdev) {
80 dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
81 return -ENOMEM;
82 }
83
84 ret = platform_device_add_data(pdev, pdata,
85 sizeof(struct pasic3_leds_machinfo));
86 if (ret < 0) {
87 dev_dbg(pasic3_dev, "failed to add LED platform data\n");
88 goto exit_pdev_put;
89 }
90
91 pdev->dev.parent = pasic3_dev;
92 ret = platform_device_add(pdev);
93 if (ret < 0) {
94 dev_dbg(pasic3_dev, "failed to add LED platform device\n");
95 goto exit_pdev_put;
96 }
97
98 asic->led_pdev = pdev;
99 return 0;
100
101exit_pdev_put:
102 platform_device_put(pdev);
103 return ret;
104}
105
106/*
107 * DS1WM
108 */
109
110static void ds1wm_enable(struct platform_device *pdev)
111{
112 struct device *dev = pdev->dev.parent;
113 int c;
114
115 c = pasic3_read_register(dev, 0x28);
116 pasic3_write_register(dev, 0x28, c & 0x7f);
117
118 dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
119}
120
121static void ds1wm_disable(struct platform_device *pdev)
122{
123 struct device *dev = pdev->dev.parent;
124 int c;
125
126 c = pasic3_read_register(dev, 0x28);
127 pasic3_write_register(dev, 0x28, c | 0x80);
128
129 dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
130}
131
132static struct ds1wm_platform_data ds1wm_pdata = {
133 .bus_shift = 2,
134 .enable = ds1wm_enable,
135 .disable = ds1wm_disable,
136};
137
138static int ds1wm_device_add(struct device *pasic3_dev, int bus_shift)
139{
140 struct pasic3_data *asic = pasic3_dev->driver_data;
141 struct platform_device *pdev;
142 int ret;
143
144 pdev = platform_device_alloc("ds1wm", -1);
145 if (!pdev) {
146 dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
147 return -ENOMEM;
148 }
149
150 ret = platform_device_add_resources(pdev, pdev->resource,
151 pdev->num_resources);
152 if (ret < 0) {
153 dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
154 goto exit_pdev_put;
155 }
156
157 ds1wm_pdata.bus_shift = asic->bus_shift;
158 ret = platform_device_add_data(pdev, &ds1wm_pdata,
159 sizeof(struct ds1wm_platform_data));
160 if (ret < 0) {
161 dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
162 goto exit_pdev_put;
163 }
164
165 pdev->dev.parent = pasic3_dev;
166 ret = platform_device_add(pdev);
167 if (ret < 0) {
168 dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
169 goto exit_pdev_put;
170 }
171
172 asic->ds1wm_pdev = pdev;
173 return 0;
174
175exit_pdev_put:
176 platform_device_put(pdev);
177 return ret;
178}
179
180static int __init pasic3_probe(struct platform_device *pdev)
181{
182 struct pasic3_platform_data *pdata = pdev->dev.platform_data;
183 struct device *dev = &pdev->dev;
184 struct pasic3_data *asic;
185 struct resource *r;
186 int ret;
187
188 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
189 if (!r)
190 return -ENXIO;
191
192 if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
193 return -EBUSY;
194
195 asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
196 if (!asic)
197 return -ENOMEM;
198
199 platform_set_drvdata(pdev, asic);
200
201 if (pdata && pdata->bus_shift)
202 asic->bus_shift = pdata->bus_shift;
203 else
204 asic->bus_shift = 2;
205
206 asic->mapping = ioremap(r->start, r->end - r->start + 1);
207 if (!asic->mapping) {
208 dev_err(dev, "couldn't ioremap PASIC3\n");
209 kfree(asic);
210 return -ENOMEM;
211 }
212
213 ret = ds1wm_device_add(dev, asic->bus_shift);
214 if (ret < 0)
215 dev_warn(dev, "failed to register DS1WM\n");
216
217 if (pdata->led_pdata) {
218 ret = led_device_add(dev, pdata->led_pdata);
219 if (ret < 0)
220 dev_warn(dev, "failed to register LED device\n");
221 }
222
223 return 0;
224}
225
226static int pasic3_remove(struct platform_device *pdev)
227{
228 struct pasic3_data *asic = platform_get_drvdata(pdev);
229 struct resource *r;
230
231 if (asic->led_pdev)
232 platform_device_unregister(asic->led_pdev);
233 if (asic->ds1wm_pdev)
234 platform_device_unregister(asic->ds1wm_pdev);
235
236 iounmap(asic->mapping);
237 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
238 release_mem_region(r->start, r->end - r->start + 1);
239 kfree(asic);
240 return 0;
241}
242
243static struct platform_driver pasic3_driver = {
244 .driver = {
245 .name = "pasic3",
246 },
247 .remove = pasic3_remove,
248};
249
250static int __init pasic3_base_init(void)
251{
252 return platform_driver_probe(&pasic3_driver, pasic3_probe);
253}
254
255static void __exit pasic3_base_exit(void)
256{
257 platform_driver_unregister(&pasic3_driver);
258}
259
260module_init(pasic3_base_init);
261module_exit(pasic3_base_exit);
262
263MODULE_AUTHOR("Philipp Zabel <philipp.zabel@gmail.com>");
264MODULE_DESCRIPTION("Core driver for HTC PASIC3");
265MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 4a3c6759492b..959fb86cda01 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -314,7 +314,7 @@ config MTD_ALAUDA
314 314
315config MTD_NAND_ORION 315config MTD_NAND_ORION
316 tristate "NAND Flash support for Marvell Orion SoC" 316 tristate "NAND Flash support for Marvell Orion SoC"
317 depends on ARCH_ORION && MTD_NAND 317 depends on PLAT_ORION && MTD_NAND
318 help 318 help
319 This enables the NAND flash controller on Orion machines. 319 This enables the NAND flash controller on Orion machines.
320 320
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 9162cca0182b..ec5ad28b237e 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -18,8 +18,8 @@
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/sizes.h> 20#include <asm/sizes.h>
21#include <asm/arch/platform.h>
22#include <asm/arch/hardware.h> 21#include <asm/arch/hardware.h>
22#include <asm/plat-orion/orion_nand.h>
23 23
24#ifdef CONFIG_MTD_CMDLINE_PARTS 24#ifdef CONFIG_MTD_CMDLINE_PARTS
25static const char *part_probes[] = { "cmdlinepart", NULL }; 25static const char *part_probes[] = { "cmdlinepart", NULL };
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 45c3a208d93f..2399a3796f6e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2335,7 +2335,7 @@ config UGETH_TX_ON_DEMAND
2335 2335
2336config MV643XX_ETH 2336config MV643XX_ETH
2337 tristate "Marvell Discovery (643XX) and Orion ethernet support" 2337 tristate "Marvell Discovery (643XX) and Orion ethernet support"
2338 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || ARCH_ORION 2338 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
2339 select MII 2339 select MII
2340 help 2340 help
2341 This driver supports the gigabit ethernet MACs in the 2341 This driver supports the gigabit ethernet MACs in the
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 0ae0d83e5d22..978e20a1791b 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -1043,7 +1043,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
1043 } else if (machine_is_csb337()) { 1043 } else if (machine_is_csb337()) {
1044 /* mix link activity status into LED2 link state */ 1044 /* mix link activity status into LED2 link state */
1045 write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22); 1045 write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22);
1046 } 1046 } else if (machine_is_ecbat91())
1047 write_phy(phy_address, MII_LEDCTRL_REG, 0x156A);
1048
1047 disable_mdi(); 1049 disable_mdi();
1048 spin_unlock_irq(&lp->lock); 1050 spin_unlock_irq(&lp->lock);
1049 1051
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 8c09344f58dc..8db71ab20456 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -36,6 +36,7 @@
36#include <asm/hardware.h> 36#include <asm/hardware.h>
37#include <asm/arch/irda.h> 37#include <asm/arch/irda.h>
38#include <asm/arch/pxa-regs.h> 38#include <asm/arch/pxa-regs.h>
39#include <asm/arch/pxa2xx-gpio.h>
39 40
40#ifdef CONFIG_MACH_MAINSTONE 41#ifdef CONFIG_MACH_MAINSTONE
41#include <asm/arch/mainstone.h> 42#include <asm/arch/mainstone.h>
@@ -831,6 +832,11 @@ static int pxa_irda_probe(struct platform_device *pdev)
831 if (err) 832 if (err)
832 goto err_mem_5; 833 goto err_mem_5;
833 834
835 if (si->pdata->startup)
836 err = si->pdata->startup(si->dev);
837 if (err)
838 goto err_startup;
839
834 dev->hard_start_xmit = pxa_irda_hard_xmit; 840 dev->hard_start_xmit = pxa_irda_hard_xmit;
835 dev->open = pxa_irda_start; 841 dev->open = pxa_irda_start;
836 dev->stop = pxa_irda_stop; 842 dev->stop = pxa_irda_stop;
@@ -856,6 +862,9 @@ static int pxa_irda_probe(struct platform_device *pdev)
856 dev_set_drvdata(&pdev->dev, dev); 862 dev_set_drvdata(&pdev->dev, dev);
857 863
858 if (err) { 864 if (err) {
865 if (si->pdata->shutdown)
866 si->pdata->shutdown(si->dev);
867err_startup:
859 kfree(si->tx_buff.head); 868 kfree(si->tx_buff.head);
860err_mem_5: 869err_mem_5:
861 kfree(si->rx_buff.head); 870 kfree(si->rx_buff.head);
@@ -881,6 +890,8 @@ static int pxa_irda_remove(struct platform_device *_dev)
881 if (dev) { 890 if (dev) {
882 struct pxa_irda *si = netdev_priv(dev); 891 struct pxa_irda *si = netdev_priv(dev);
883 unregister_netdev(dev); 892 unregister_netdev(dev);
893 if (si->pdata->shutdown)
894 si->pdata->shutdown(si->dev);
884 kfree(si->tx_buff.head); 895 kfree(si->tx_buff.head);
885 kfree(si->rx_buff.head); 896 kfree(si->rx_buff.head);
886 clk_put(si->fir_clk); 897 clk_put(si->fir_clk);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e571c72e6753..e8d94fafc280 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -182,15 +182,18 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
182 struct mempolicy *oldpol; 182 struct mempolicy *oldpol;
183 cpumask_t oldmask = current->cpus_allowed; 183 cpumask_t oldmask = current->cpus_allowed;
184 int node = pcibus_to_node(dev->bus); 184 int node = pcibus_to_node(dev->bus);
185 if (node >= 0 && node_online(node)) 185
186 set_cpus_allowed(current, node_to_cpumask(node)); 186 if (node >= 0) {
187 node_to_cpumask_ptr(nodecpumask, node);
188 set_cpus_allowed_ptr(current, nodecpumask);
189 }
187 /* And set default memory allocation policy */ 190 /* And set default memory allocation policy */
188 oldpol = current->mempolicy; 191 oldpol = current->mempolicy;
189 current->mempolicy = NULL; /* fall back to system default policy */ 192 current->mempolicy = NULL; /* fall back to system default policy */
190#endif 193#endif
191 error = drv->probe(dev, id); 194 error = drv->probe(dev, id);
192#ifdef CONFIG_NUMA 195#ifdef CONFIG_NUMA
193 set_cpus_allowed(current, oldmask); 196 set_cpus_allowed_ptr(current, &oldmask);
194 current->mempolicy = oldpol; 197 current->mempolicy = oldpol;
195#endif 198#endif
196 return error; 199 return error;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 8dcf1458aa2f..8d9d648daeba 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -73,8 +73,23 @@ static ssize_t local_cpus_show(struct device *dev,
73 73
74 mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); 74 mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
75 len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); 75 len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
76 strcat(buf,"\n"); 76 buf[len++] = '\n';
77 return 1+len; 77 buf[len] = '\0';
78 return len;
79}
80
81
82static ssize_t local_cpulist_show(struct device *dev,
83 struct device_attribute *attr, char *buf)
84{
85 cpumask_t mask;
86 int len;
87
88 mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
89 len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask);
90 buf[len++] = '\n';
91 buf[len] = '\0';
92 return len;
78} 93}
79 94
80/* show resources */ 95/* show resources */
@@ -201,6 +216,7 @@ struct device_attribute pci_dev_attrs[] = {
201 __ATTR_RO(class), 216 __ATTR_RO(class),
202 __ATTR_RO(irq), 217 __ATTR_RO(irq),
203 __ATTR_RO(local_cpus), 218 __ATTR_RO(local_cpus),
219 __ATTR_RO(local_cpulist),
204 __ATTR_RO(modalias), 220 __ATTR_RO(modalias),
205#ifdef CONFIG_NUMA 221#ifdef CONFIG_NUMA
206 __ATTR_RO(numa_node), 222 __ATTR_RO(numa_node),
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2db2e4bb0d1e..4b3011a23eff 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -82,6 +82,7 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; }
82 * PCI Bus Class Devices 82 * PCI Bus Class Devices
83 */ 83 */
84static ssize_t pci_bus_show_cpuaffinity(struct device *dev, 84static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
85 int type,
85 struct device_attribute *attr, 86 struct device_attribute *attr,
86 char *buf) 87 char *buf)
87{ 88{
@@ -89,12 +90,30 @@ static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
89 cpumask_t cpumask; 90 cpumask_t cpumask;
90 91
91 cpumask = pcibus_to_cpumask(to_pci_bus(dev)); 92 cpumask = pcibus_to_cpumask(to_pci_bus(dev));
92 ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); 93 ret = type?
93 if (ret < PAGE_SIZE) 94 cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask):
94 buf[ret++] = '\n'; 95 cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask);
96 buf[ret++] = '\n';
97 buf[ret] = '\0';
95 return ret; 98 return ret;
96} 99}
97DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); 100
101static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
102 struct device_attribute *attr,
103 char *buf)
104{
105 return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
106}
107
108static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
109 struct device_attribute *attr,
110 char *buf)
111{
112 return pci_bus_show_cpuaffinity(dev, 1, attr, buf);
113}
114
115DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL);
116DEVICE_ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL);
98 117
99/* 118/*
100 * PCI Bus Class 119 * PCI Bus Class
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 8b22281b087f..ed8c06904807 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -200,6 +200,7 @@ config PCMCIA_AU1X00
200config PCMCIA_SA1100 200config PCMCIA_SA1100
201 tristate "SA1100 support" 201 tristate "SA1100 support"
202 depends on ARM && ARCH_SA1100 && PCMCIA 202 depends on ARM && ARCH_SA1100 && PCMCIA
203 depends on ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL || MACH_ARMCORE
203 help 204 help
204 Say Y here to include support for SA11x0-based PCMCIA or CF 205 Say Y here to include support for SA11x0-based PCMCIA or CF
205 sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ 206 sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index fbf2f3a6984c..e7ab060ff118 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -20,6 +20,7 @@
20#include <asm/hardware.h> 20#include <asm/hardware.h>
21 21
22#include <asm/arch/pxa-regs.h> 22#include <asm/arch/pxa-regs.h>
23#include <asm/arch/pxa2xx-gpio.h>
23#include <asm/arch/cm-x270.h> 24#include <asm/arch/cm-x270.h>
24 25
25#include "soc_common.h" 26#include "soc_common.h"
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 9e9caa5d7f5f..c594b34c6767 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * SuperH On-Chip RTC Support 2 * SuperH On-Chip RTC Support
3 * 3 *
4 * Copyright (C) 2006, 2007 Paul Mundt 4 * Copyright (C) 2006, 2007, 2008 Paul Mundt
5 * Copyright (C) 2006 Jamie Lenehan 5 * Copyright (C) 2006 Jamie Lenehan
6 * Copyright (C) 2008 Angelo Castello
6 * 7 *
7 * Based on the old arch/sh/kernel/cpu/rtc.c by: 8 * Based on the old arch/sh/kernel/cpu/rtc.c by:
8 * 9 *
@@ -26,7 +27,7 @@
26#include <asm/rtc.h> 27#include <asm/rtc.h>
27 28
28#define DRV_NAME "sh-rtc" 29#define DRV_NAME "sh-rtc"
29#define DRV_VERSION "0.1.6" 30#define DRV_VERSION "0.2.0"
30 31
31#define RTC_REG(r) ((r) * rtc_reg_size) 32#define RTC_REG(r) ((r) * rtc_reg_size)
32 33
@@ -63,6 +64,13 @@
63/* ALARM Bits - or with BCD encoded value */ 64/* ALARM Bits - or with BCD encoded value */
64#define AR_ENB 0x80 /* Enable for alarm cmp */ 65#define AR_ENB 0x80 /* Enable for alarm cmp */
65 66
67/* Period Bits */
68#define PF_HP 0x100 /* Enable Half Period to support 8,32,128Hz */
69#define PF_COUNT 0x200 /* Half periodic counter */
70#define PF_OXS 0x400 /* Periodic One x Second */
71#define PF_KOU 0x800 /* Kernel or User periodic request 1=kernel */
72#define PF_MASK 0xf00
73
66/* RCR1 Bits */ 74/* RCR1 Bits */
67#define RCR1_CF 0x80 /* Carry Flag */ 75#define RCR1_CF 0x80 /* Carry Flag */
68#define RCR1_CIE 0x10 /* Carry Interrupt Enable */ 76#define RCR1_CIE 0x10 /* Carry Interrupt Enable */
@@ -84,33 +92,24 @@ struct sh_rtc {
84 unsigned int alarm_irq, periodic_irq, carry_irq; 92 unsigned int alarm_irq, periodic_irq, carry_irq;
85 struct rtc_device *rtc_dev; 93 struct rtc_device *rtc_dev;
86 spinlock_t lock; 94 spinlock_t lock;
87 int rearm_aie;
88 unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ 95 unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */
96 unsigned short periodic_freq;
89}; 97};
90 98
91static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) 99static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
92{ 100{
93 struct platform_device *pdev = to_platform_device(dev_id); 101 struct sh_rtc *rtc = dev_id;
94 struct sh_rtc *rtc = platform_get_drvdata(pdev); 102 unsigned int tmp;
95 unsigned int tmp, events = 0;
96 103
97 spin_lock(&rtc->lock); 104 spin_lock(&rtc->lock);
98 105
99 tmp = readb(rtc->regbase + RCR1); 106 tmp = readb(rtc->regbase + RCR1);
100 tmp &= ~RCR1_CF; 107 tmp &= ~RCR1_CF;
101
102 if (rtc->rearm_aie) {
103 if (tmp & RCR1_AF)
104 tmp &= ~RCR1_AF; /* try to clear AF again */
105 else {
106 tmp |= RCR1_AIE; /* AF has cleared, rearm IRQ */
107 rtc->rearm_aie = 0;
108 }
109 }
110
111 writeb(tmp, rtc->regbase + RCR1); 108 writeb(tmp, rtc->regbase + RCR1);
112 109
113 rtc_update_irq(rtc->rtc_dev, 1, events); 110 /* Users have requested One x Second IRQ */
111 if (rtc->periodic_freq & PF_OXS)
112 rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
114 113
115 spin_unlock(&rtc->lock); 114 spin_unlock(&rtc->lock);
116 115
@@ -119,47 +118,48 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
119 118
120static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) 119static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
121{ 120{
122 struct platform_device *pdev = to_platform_device(dev_id); 121 struct sh_rtc *rtc = dev_id;
123 struct sh_rtc *rtc = platform_get_drvdata(pdev); 122 unsigned int tmp;
124 unsigned int tmp, events = 0;
125 123
126 spin_lock(&rtc->lock); 124 spin_lock(&rtc->lock);
127 125
128 tmp = readb(rtc->regbase + RCR1); 126 tmp = readb(rtc->regbase + RCR1);
129 127 tmp &= ~(RCR1_AF | RCR1_AIE);
130 /*
131 * If AF is set then the alarm has triggered. If we clear AF while
132 * the alarm time still matches the RTC time then AF will
133 * immediately be set again, and if AIE is enabled then the alarm
134 * interrupt will immediately be retrigger. So we clear AIE here
135 * and use rtc->rearm_aie so that the carry interrupt will keep
136 * trying to clear AF and once it stays cleared it'll re-enable
137 * AIE.
138 */
139 if (tmp & RCR1_AF) {
140 events |= RTC_AF | RTC_IRQF;
141
142 tmp &= ~(RCR1_AF|RCR1_AIE);
143
144 writeb(tmp, rtc->regbase + RCR1); 128 writeb(tmp, rtc->regbase + RCR1);
145 129
146 rtc->rearm_aie = 1; 130 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
147
148 rtc_update_irq(rtc->rtc_dev, 1, events);
149 }
150 131
151 spin_unlock(&rtc->lock); 132 spin_unlock(&rtc->lock);
133
152 return IRQ_HANDLED; 134 return IRQ_HANDLED;
153} 135}
154 136
155static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) 137static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
156{ 138{
157 struct platform_device *pdev = to_platform_device(dev_id); 139 struct sh_rtc *rtc = dev_id;
158 struct sh_rtc *rtc = platform_get_drvdata(pdev); 140 struct rtc_device *rtc_dev = rtc->rtc_dev;
141 unsigned int tmp;
159 142
160 spin_lock(&rtc->lock); 143 spin_lock(&rtc->lock);
161 144
162 rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); 145 tmp = readb(rtc->regbase + RCR2);
146 tmp &= ~RCR2_PEF;
147 writeb(tmp, rtc->regbase + RCR2);
148
149 /* Half period enabled than one skipped and the next notified */
150 if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT))
151 rtc->periodic_freq &= ~PF_COUNT;
152 else {
153 if (rtc->periodic_freq & PF_HP)
154 rtc->periodic_freq |= PF_COUNT;
155 if (rtc->periodic_freq & PF_KOU) {
156 spin_lock(&rtc_dev->irq_task_lock);
157 if (rtc_dev->irq_task)
158 rtc_dev->irq_task->func(rtc_dev->irq_task->private_data);
159 spin_unlock(&rtc_dev->irq_task_lock);
160 } else
161 rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
162 }
163 163
164 spin_unlock(&rtc->lock); 164 spin_unlock(&rtc->lock);
165 165
@@ -176,8 +176,8 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
176 tmp = readb(rtc->regbase + RCR2); 176 tmp = readb(rtc->regbase + RCR2);
177 177
178 if (enable) { 178 if (enable) {
179 tmp &= ~RCR2_PESMASK; 179 tmp &= ~RCR2_PEF; /* Clear PES bit */
180 tmp |= RCR2_PEF | (2 << 4); 180 tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */
181 } else 181 } else
182 tmp &= ~(RCR2_PESMASK | RCR2_PEF); 182 tmp &= ~(RCR2_PESMASK | RCR2_PEF);
183 183
@@ -186,82 +186,81 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
186 spin_unlock_irq(&rtc->lock); 186 spin_unlock_irq(&rtc->lock);
187} 187}
188 188
189static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) 189static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq)
190{ 190{
191 struct sh_rtc *rtc = dev_get_drvdata(dev); 191 struct sh_rtc *rtc = dev_get_drvdata(dev);
192 unsigned int tmp; 192 int tmp, ret = 0;
193 193
194 spin_lock_irq(&rtc->lock); 194 spin_lock_irq(&rtc->lock);
195 tmp = rtc->periodic_freq & PF_MASK;
195 196
196 tmp = readb(rtc->regbase + RCR1); 197 switch (freq) {
197 198 case 0:
198 if (!enable) { 199 rtc->periodic_freq = 0x00;
199 tmp &= ~RCR1_AIE; 200 break;
200 rtc->rearm_aie = 0; 201 case 1:
201 } else if (rtc->rearm_aie == 0) 202 rtc->periodic_freq = 0x60;
202 tmp |= RCR1_AIE; 203 break;
204 case 2:
205 rtc->periodic_freq = 0x50;
206 break;
207 case 4:
208 rtc->periodic_freq = 0x40;
209 break;
210 case 8:
211 rtc->periodic_freq = 0x30 | PF_HP;
212 break;
213 case 16:
214 rtc->periodic_freq = 0x30;
215 break;
216 case 32:
217 rtc->periodic_freq = 0x20 | PF_HP;
218 break;
219 case 64:
220 rtc->periodic_freq = 0x20;
221 break;
222 case 128:
223 rtc->periodic_freq = 0x10 | PF_HP;
224 break;
225 case 256:
226 rtc->periodic_freq = 0x10;
227 break;
228 default:
229 ret = -ENOTSUPP;
230 }
203 231
204 writeb(tmp, rtc->regbase + RCR1); 232 if (ret == 0) {
233 rtc->periodic_freq |= tmp;
234 rtc->rtc_dev->irq_freq = freq;
235 }
205 236
206 spin_unlock_irq(&rtc->lock); 237 spin_unlock_irq(&rtc->lock);
238 return ret;
207} 239}
208 240
209static int sh_rtc_open(struct device *dev) 241static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
210{ 242{
211 struct sh_rtc *rtc = dev_get_drvdata(dev); 243 struct sh_rtc *rtc = dev_get_drvdata(dev);
212 unsigned int tmp; 244 unsigned int tmp;
213 int ret;
214
215 tmp = readb(rtc->regbase + RCR1);
216 tmp &= ~RCR1_CF;
217 tmp |= RCR1_CIE;
218 writeb(tmp, rtc->regbase + RCR1);
219 245
220 ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, 246 spin_lock_irq(&rtc->lock);
221 "sh-rtc period", dev);
222 if (unlikely(ret)) {
223 dev_err(dev, "request period IRQ failed with %d, IRQ %d\n",
224 ret, rtc->periodic_irq);
225 return ret;
226 }
227
228 ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
229 "sh-rtc carry", dev);
230 if (unlikely(ret)) {
231 dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n",
232 ret, rtc->carry_irq);
233 free_irq(rtc->periodic_irq, dev);
234 goto err_bad_carry;
235 }
236 247
237 ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, 248 tmp = readb(rtc->regbase + RCR1);
238 "sh-rtc alarm", dev);
239 if (unlikely(ret)) {
240 dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n",
241 ret, rtc->alarm_irq);
242 goto err_bad_alarm;
243 }
244 249
245 return 0; 250 if (!enable)
251 tmp &= ~RCR1_AIE;
252 else
253 tmp |= RCR1_AIE;
246 254
247err_bad_alarm: 255 writeb(tmp, rtc->regbase + RCR1);
248 free_irq(rtc->carry_irq, dev);
249err_bad_carry:
250 free_irq(rtc->periodic_irq, dev);
251 256
252 return ret; 257 spin_unlock_irq(&rtc->lock);
253} 258}
254 259
255static void sh_rtc_release(struct device *dev) 260static void sh_rtc_release(struct device *dev)
256{ 261{
257 struct sh_rtc *rtc = dev_get_drvdata(dev);
258
259 sh_rtc_setpie(dev, 0); 262 sh_rtc_setpie(dev, 0);
260 sh_rtc_setaie(dev, 0); 263 sh_rtc_setaie(dev, 0);
261
262 free_irq(rtc->periodic_irq, dev);
263 free_irq(rtc->carry_irq, dev);
264 free_irq(rtc->alarm_irq, dev);
265} 264}
266 265
267static int sh_rtc_proc(struct device *dev, struct seq_file *seq) 266static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
@@ -270,31 +269,44 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
270 unsigned int tmp; 269 unsigned int tmp;
271 270
272 tmp = readb(rtc->regbase + RCR1); 271 tmp = readb(rtc->regbase + RCR1);
273 seq_printf(seq, "carry_IRQ\t: %s\n", 272 seq_printf(seq, "carry_IRQ\t: %s\n", (tmp & RCR1_CIE) ? "yes" : "no");
274 (tmp & RCR1_CIE) ? "yes" : "no");
275 273
276 tmp = readb(rtc->regbase + RCR2); 274 tmp = readb(rtc->regbase + RCR2);
277 seq_printf(seq, "periodic_IRQ\t: %s\n", 275 seq_printf(seq, "periodic_IRQ\t: %s\n",
278 (tmp & RCR2_PEF) ? "yes" : "no"); 276 (tmp & RCR2_PESMASK) ? "yes" : "no");
279 277
280 return 0; 278 return 0;
281} 279}
282 280
283static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 281static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
284{ 282{
285 unsigned int ret = -ENOIOCTLCMD; 283 struct sh_rtc *rtc = dev_get_drvdata(dev);
284 unsigned int ret = 0;
286 285
287 switch (cmd) { 286 switch (cmd) {
288 case RTC_PIE_OFF: 287 case RTC_PIE_OFF:
289 case RTC_PIE_ON: 288 case RTC_PIE_ON:
290 sh_rtc_setpie(dev, cmd == RTC_PIE_ON); 289 sh_rtc_setpie(dev, cmd == RTC_PIE_ON);
291 ret = 0;
292 break; 290 break;
293 case RTC_AIE_OFF: 291 case RTC_AIE_OFF:
294 case RTC_AIE_ON: 292 case RTC_AIE_ON:
295 sh_rtc_setaie(dev, cmd == RTC_AIE_ON); 293 sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
296 ret = 0;
297 break; 294 break;
295 case RTC_UIE_OFF:
296 rtc->periodic_freq &= ~PF_OXS;
297 break;
298 case RTC_UIE_ON:
299 rtc->periodic_freq |= PF_OXS;
300 break;
301 case RTC_IRQP_READ:
302 ret = put_user(rtc->rtc_dev->irq_freq,
303 (unsigned long __user *)arg);
304 break;
305 case RTC_IRQP_SET:
306 ret = sh_rtc_setfreq(dev, arg);
307 break;
308 default:
309 ret = -ENOIOCTLCMD;
298 } 310 }
299 311
300 return ret; 312 return ret;
@@ -421,7 +433,7 @@ static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
421{ 433{
422 struct platform_device *pdev = to_platform_device(dev); 434 struct platform_device *pdev = to_platform_device(dev);
423 struct sh_rtc *rtc = platform_get_drvdata(pdev); 435 struct sh_rtc *rtc = platform_get_drvdata(pdev);
424 struct rtc_time* tm = &wkalrm->time; 436 struct rtc_time *tm = &wkalrm->time;
425 437
426 spin_lock_irq(&rtc->lock); 438 spin_lock_irq(&rtc->lock);
427 439
@@ -452,7 +464,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
452 writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); 464 writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off);
453} 465}
454 466
455static int sh_rtc_check_alarm(struct rtc_time* tm) 467static int sh_rtc_check_alarm(struct rtc_time *tm)
456{ 468{
457 /* 469 /*
458 * The original rtc says anything > 0xc0 is "don't care" or "match 470 * The original rtc says anything > 0xc0 is "don't care" or "match
@@ -503,11 +515,9 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
503 515
504 /* disable alarm interrupt and clear the alarm flag */ 516 /* disable alarm interrupt and clear the alarm flag */
505 rcr1 = readb(rtc->regbase + RCR1); 517 rcr1 = readb(rtc->regbase + RCR1);
506 rcr1 &= ~(RCR1_AF|RCR1_AIE); 518 rcr1 &= ~(RCR1_AF | RCR1_AIE);
507 writeb(rcr1, rtc->regbase + RCR1); 519 writeb(rcr1, rtc->regbase + RCR1);
508 520
509 rtc->rearm_aie = 0;
510
511 /* set alarm time */ 521 /* set alarm time */
512 sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); 522 sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR);
513 sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); 523 sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR);
@@ -529,14 +539,34 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
529 return 0; 539 return 0;
530} 540}
531 541
542static int sh_rtc_irq_set_state(struct device *dev, int enabled)
543{
544 struct platform_device *pdev = to_platform_device(dev);
545 struct sh_rtc *rtc = platform_get_drvdata(pdev);
546
547 if (enabled) {
548 rtc->periodic_freq |= PF_KOU;
549 return sh_rtc_ioctl(dev, RTC_PIE_ON, 0);
550 } else {
551 rtc->periodic_freq &= ~PF_KOU;
552 return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0);
553 }
554}
555
556static int sh_rtc_irq_set_freq(struct device *dev, int freq)
557{
558 return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
559}
560
532static struct rtc_class_ops sh_rtc_ops = { 561static struct rtc_class_ops sh_rtc_ops = {
533 .open = sh_rtc_open,
534 .release = sh_rtc_release, 562 .release = sh_rtc_release,
535 .ioctl = sh_rtc_ioctl, 563 .ioctl = sh_rtc_ioctl,
536 .read_time = sh_rtc_read_time, 564 .read_time = sh_rtc_read_time,
537 .set_time = sh_rtc_set_time, 565 .set_time = sh_rtc_set_time,
538 .read_alarm = sh_rtc_read_alarm, 566 .read_alarm = sh_rtc_read_alarm,
539 .set_alarm = sh_rtc_set_alarm, 567 .set_alarm = sh_rtc_set_alarm,
568 .irq_set_state = sh_rtc_irq_set_state,
569 .irq_set_freq = sh_rtc_irq_set_freq,
540 .proc = sh_rtc_proc, 570 .proc = sh_rtc_proc,
541}; 571};
542 572
@@ -544,6 +574,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
544{ 574{
545 struct sh_rtc *rtc; 575 struct sh_rtc *rtc;
546 struct resource *res; 576 struct resource *res;
577 unsigned int tmp;
547 int ret = -ENOENT; 578 int ret = -ENOENT;
548 579
549 rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); 580 rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
@@ -552,6 +583,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
552 583
553 spin_lock_init(&rtc->lock); 584 spin_lock_init(&rtc->lock);
554 585
586 /* get periodic/carry/alarm irqs */
555 rtc->periodic_irq = platform_get_irq(pdev, 0); 587 rtc->periodic_irq = platform_get_irq(pdev, 0);
556 if (unlikely(rtc->periodic_irq < 0)) { 588 if (unlikely(rtc->periodic_irq < 0)) {
557 dev_err(&pdev->dev, "No IRQ for period\n"); 589 dev_err(&pdev->dev, "No IRQ for period\n");
@@ -608,8 +640,48 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
608 rtc->capabilities |= pinfo->capabilities; 640 rtc->capabilities |= pinfo->capabilities;
609 } 641 }
610 642
643 rtc->rtc_dev->max_user_freq = 256;
644 rtc->rtc_dev->irq_freq = 1;
645 rtc->periodic_freq = 0x60;
646
611 platform_set_drvdata(pdev, rtc); 647 platform_set_drvdata(pdev, rtc);
612 648
649 /* register periodic/carry/alarm irqs */
650 ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
651 "sh-rtc period", rtc);
652 if (unlikely(ret)) {
653 dev_err(&pdev->dev,
654 "request period IRQ failed with %d, IRQ %d\n", ret,
655 rtc->periodic_irq);
656 goto err_badmap;
657 }
658
659 ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
660 "sh-rtc carry", rtc);
661 if (unlikely(ret)) {
662 dev_err(&pdev->dev,
663 "request carry IRQ failed with %d, IRQ %d\n", ret,
664 rtc->carry_irq);
665 free_irq(rtc->periodic_irq, rtc);
666 goto err_badmap;
667 }
668
669 ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
670 "sh-rtc alarm", rtc);
671 if (unlikely(ret)) {
672 dev_err(&pdev->dev,
673 "request alarm IRQ failed with %d, IRQ %d\n", ret,
674 rtc->alarm_irq);
675 free_irq(rtc->carry_irq, rtc);
676 free_irq(rtc->periodic_irq, rtc);
677 goto err_badmap;
678 }
679
680 tmp = readb(rtc->regbase + RCR1);
681 tmp &= ~RCR1_CF;
682 tmp |= RCR1_CIE;
683 writeb(tmp, rtc->regbase + RCR1);
684
613 return 0; 685 return 0;
614 686
615err_badmap: 687err_badmap:
@@ -630,6 +702,10 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
630 sh_rtc_setpie(&pdev->dev, 0); 702 sh_rtc_setpie(&pdev->dev, 0);
631 sh_rtc_setaie(&pdev->dev, 0); 703 sh_rtc_setaie(&pdev->dev, 0);
632 704
705 free_irq(rtc->carry_irq, rtc);
706 free_irq(rtc->periodic_irq, rtc);
707 free_irq(rtc->alarm_irq, rtc);
708
633 release_resource(rtc->res); 709 release_resource(rtc->res);
634 710
635 platform_set_drvdata(pdev, NULL); 711 platform_set_drvdata(pdev, NULL);
@@ -662,6 +738,8 @@ module_exit(sh_rtc_exit);
662 738
663MODULE_DESCRIPTION("SuperH on-chip RTC driver"); 739MODULE_DESCRIPTION("SuperH on-chip RTC driver");
664MODULE_VERSION(DRV_VERSION); 740MODULE_VERSION(DRV_VERSION);
665MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>"); 741MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
742 "Jamie Lenehan <lenehan@twibble.org>, "
743 "Angelo Castello <angelo.castello@st.com>");
666MODULE_LICENSE("GPL"); 744MODULE_LICENSE("GPL");
667MODULE_ALIAS("platform:" DRV_NAME); 745MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 16ba9ac7a566..5a375bf0ebf4 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -166,15 +166,6 @@
166#define SERIAL_IMX_MAJOR 204 166#define SERIAL_IMX_MAJOR 204
167#define MINOR_START 41 167#define MINOR_START 41
168 168
169#define NR_PORTS 2
170
171#define IMX_ISR_PASS_LIMIT 256
172
173/*
174 * This is the size of our serial port register set.
175 */
176#define UART_PORT_SIZE 0x100
177
178/* 169/*
179 * This determines how often we check the modem status signals 170 * This determines how often we check the modem status signals
180 * for any change. They generally aren't connected to an IRQ 171 * for any change. They generally aren't connected to an IRQ
@@ -358,66 +349,60 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
358 struct tty_struct *tty = sport->port.info->tty; 349 struct tty_struct *tty = sport->port.info->tty;
359 unsigned long flags, temp; 350 unsigned long flags, temp;
360 351
361 rx = readl(sport->port.membase + URXD0);
362 spin_lock_irqsave(&sport->port.lock,flags); 352 spin_lock_irqsave(&sport->port.lock,flags);
363 353
364 do { 354 while (readl(sport->port.membase + USR2) & USR2_RDR) {
365 flg = TTY_NORMAL; 355 flg = TTY_NORMAL;
366 sport->port.icount.rx++; 356 sport->port.icount.rx++;
367 357
358 rx = readl(sport->port.membase + URXD0);
359
368 temp = readl(sport->port.membase + USR2); 360 temp = readl(sport->port.membase + USR2);
369 if( temp & USR2_BRCD ) { 361 if (temp & USR2_BRCD) {
370 writel(temp | USR2_BRCD, sport->port.membase + USR2); 362 writel(temp | USR2_BRCD, sport->port.membase + USR2);
371 if(uart_handle_break(&sport->port)) 363 if (uart_handle_break(&sport->port))
372 goto ignore_char; 364 continue;
373 } 365 }
374 366
375 if (uart_handle_sysrq_char 367 if (uart_handle_sysrq_char
376 (&sport->port, (unsigned char)rx)) 368 (&sport->port, (unsigned char)rx))
377 goto ignore_char; 369 continue;
370
371 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
372 if (rx & URXD_PRERR)
373 sport->port.icount.parity++;
374 else if (rx & URXD_FRMERR)
375 sport->port.icount.frame++;
376 if (rx & URXD_OVRRUN)
377 sport->port.icount.overrun++;
378
379 if (rx & sport->port.ignore_status_mask) {
380 if (++ignored > 100)
381 goto out;
382 continue;
383 }
384
385 rx &= sport->port.read_status_mask;
386
387 if (rx & URXD_PRERR)
388 flg = TTY_PARITY;
389 else if (rx & URXD_FRMERR)
390 flg = TTY_FRAME;
391 if (rx & URXD_OVRRUN)
392 flg = TTY_OVERRUN;
378 393
379 if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) 394#ifdef SUPPORT_SYSRQ
380 goto handle_error; 395 sport->port.sysrq = 0;
396#endif
397 }
381 398
382 error_return:
383 tty_insert_flip_char(tty, rx, flg); 399 tty_insert_flip_char(tty, rx, flg);
384 400 }
385 ignore_char:
386 rx = readl(sport->port.membase + URXD0);
387 } while(rx & URXD_CHARRDY);
388 401
389out: 402out:
390 spin_unlock_irqrestore(&sport->port.lock,flags); 403 spin_unlock_irqrestore(&sport->port.lock,flags);
391 tty_flip_buffer_push(tty); 404 tty_flip_buffer_push(tty);
392 return IRQ_HANDLED; 405 return IRQ_HANDLED;
393
394handle_error:
395 if (rx & URXD_PRERR)
396 sport->port.icount.parity++;
397 else if (rx & URXD_FRMERR)
398 sport->port.icount.frame++;
399 if (rx & URXD_OVRRUN)
400 sport->port.icount.overrun++;
401
402 if (rx & sport->port.ignore_status_mask) {
403 if (++ignored > 100)
404 goto out;
405 goto ignore_char;
406 }
407
408 rx &= sport->port.read_status_mask;
409
410 if (rx & URXD_PRERR)
411 flg = TTY_PARITY;
412 else if (rx & URXD_FRMERR)
413 flg = TTY_FRAME;
414 if (rx & URXD_OVRRUN)
415 flg = TTY_OVERRUN;
416
417#ifdef SUPPORT_SYSRQ
418 sport->port.sysrq = 0;
419#endif
420 goto error_return;
421} 406}
422 407
423/* 408/*
@@ -546,7 +531,7 @@ static int imx_startup(struct uart_port *port)
546 writel(USR1_RTSD, sport->port.membase + USR1); 531 writel(USR1_RTSD, sport->port.membase + USR1);
547 532
548 temp = readl(sport->port.membase + UCR1); 533 temp = readl(sport->port.membase + UCR1);
549 temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); 534 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
550 writel(temp, sport->port.membase + UCR1); 535 writel(temp, sport->port.membase + UCR1);
551 536
552 temp = readl(sport->port.membase + UCR2); 537 temp = readl(sport->port.membase + UCR2);
@@ -731,9 +716,11 @@ static const char *imx_type(struct uart_port *port)
731 */ 716 */
732static void imx_release_port(struct uart_port *port) 717static void imx_release_port(struct uart_port *port)
733{ 718{
734 struct imx_port *sport = (struct imx_port *)port; 719 struct platform_device *pdev = to_platform_device(port->dev);
720 struct resource *mmres;
735 721
736 release_mem_region(sport->port.mapbase, UART_PORT_SIZE); 722 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
723 release_mem_region(mmres->start, mmres->end - mmres->start + 1);
737} 724}
738 725
739/* 726/*
@@ -741,10 +728,18 @@ static void imx_release_port(struct uart_port *port)
741 */ 728 */
742static int imx_request_port(struct uart_port *port) 729static int imx_request_port(struct uart_port *port)
743{ 730{
744 struct imx_port *sport = (struct imx_port *)port; 731 struct platform_device *pdev = to_platform_device(port->dev);
732 struct resource *mmres;
733 void *ret;
734
735 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
736 if (!mmres)
737 return -ENODEV;
738
739 ret = request_mem_region(mmres->start, mmres->end - mmres->start + 1,
740 "imx-uart");
745 741
746 return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, 742 return ret ? 0 : -EBUSY;
747 "imx-uart") != NULL ? 0 : -EBUSY;
748} 743}
749 744
750/* 745/*
@@ -815,7 +810,7 @@ static struct imx_port imx_ports[] = {
815 .type = PORT_IMX, 810 .type = PORT_IMX,
816 .iotype = UPIO_MEM, 811 .iotype = UPIO_MEM,
817 .membase = (void *)IMX_UART1_BASE, 812 .membase = (void *)IMX_UART1_BASE,
818 .mapbase = IMX_UART1_BASE, /* FIXME */ 813 .mapbase = 0x00206000,
819 .irq = UART1_MINT_RX, 814 .irq = UART1_MINT_RX,
820 .uartclk = 16000000, 815 .uartclk = 16000000,
821 .fifosize = 32, 816 .fifosize = 32,
@@ -831,7 +826,7 @@ static struct imx_port imx_ports[] = {
831 .type = PORT_IMX, 826 .type = PORT_IMX,
832 .iotype = UPIO_MEM, 827 .iotype = UPIO_MEM,
833 .membase = (void *)IMX_UART2_BASE, 828 .membase = (void *)IMX_UART2_BASE,
834 .mapbase = IMX_UART2_BASE, /* FIXME */ 829 .mapbase = 0x00207000,
835 .irq = UART2_MINT_RX, 830 .irq = UART2_MINT_RX,
836 .uartclk = 16000000, 831 .uartclk = 16000000,
837 .fifosize = 32, 832 .fifosize = 32,
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index eff593080d4f..c2ea5d4df44a 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -333,7 +333,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
333 } 333 }
334 sci_out(port, SCFCR, fcr_val); 334 sci_out(port, SCFCR, fcr_val);
335} 335}
336
337#elif defined(CONFIG_CPU_SH3) 336#elif defined(CONFIG_CPU_SH3)
338/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ 337/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
339static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) 338static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
@@ -384,6 +383,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
384 383
385 sci_out(port, SCFCR, fcr_val); 384 sci_out(port, SCFCR, fcr_val);
386} 385}
386#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
387static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
388{
389 /* Nothing to do here.. */
390 sci_out(port, SCFCR, 0);
391}
387#else 392#else
388/* For SH7750 */ 393/* For SH7750 */
389static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) 394static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 01a9dd715f5d..fa8700a968fc 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,20 +1,5 @@
1/* $Id: sh-sci.h,v 1.4 2004/02/19 16:43:56 lethal Exp $
2 *
3 * linux/drivers/serial/sh-sci.h
4 *
5 * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
6 * Copyright (C) 1999, 2000 Niibe Yutaka
7 * Copyright (C) 2000 Greg Banks
8 * Copyright (C) 2002, 2003 Paul Mundt
9 * Modified to support multiple serial ports. Stuart Menefy (May 2000).
10 * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003).
11 * Modified to support H8/300 Series Yoshinori Sato (Feb 2004).
12 * Removed SH7300 support (Jul 2007).
13 * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Aug 2007).
14 */
15#include <linux/serial_core.h> 1#include <linux/serial_core.h>
16#include <asm/io.h> 2#include <asm/io.h>
17
18#include <asm/gpio.h> 3#include <asm/gpio.h>
19 4
20#if defined(CONFIG_H83007) || defined(CONFIG_H83068) 5#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
@@ -102,6 +87,15 @@
102# define SCSPTR0 SCPDR0 87# define SCSPTR0 SCPDR0
103# define SCIF_ORER 0x0001 /* overrun error bit */ 88# define SCIF_ORER 0x0001 /* overrun error bit */
104# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ 89# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
90#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
91# define SCSPTR0 0xa4050160
92# define SCSPTR1 0xa405013e
93# define SCSPTR2 0xa4050160
94# define SCSPTR3 0xa405013e
95# define SCSPTR4 0xa4050128
96# define SCSPTR5 0xa4050128
97# define SCIF_ORER 0x0001 /* overrun error bit */
98# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
105# define SCIF_ONLY 99# define SCIF_ONLY
106#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) 100#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
107# define SCSPTR2 0xffe80020 /* 16 bit SCIF */ 101# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
@@ -395,6 +389,11 @@
395 h8_sci_offset, h8_sci_size) \ 389 h8_sci_offset, h8_sci_size) \
396 CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) 390 CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
397#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) 391#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size)
392#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
393 #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \
394 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size)
395 #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
396 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
398#else 397#else
399#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ 398#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
400 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ 399 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
@@ -419,6 +418,18 @@ SCIF_FNS(SCFDR, 0x1c, 16)
419SCIF_FNS(SCxTDR, 0x20, 8) 418SCIF_FNS(SCxTDR, 0x20, 8)
420SCIF_FNS(SCxRDR, 0x24, 8) 419SCIF_FNS(SCxRDR, 0x24, 8)
421SCIF_FNS(SCLSR, 0x24, 16) 420SCIF_FNS(SCLSR, 0x24, 16)
421#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
422SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
423SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8)
424SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
425SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
426SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
427SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
428SCIF_FNS(SCTDSR, 0x0c, 8)
429SCIF_FNS(SCFER, 0x10, 16)
430SCIF_FNS(SCFCR, 0x18, 16)
431SCIF_FNS(SCFDR, 0x1c, 16)
432SCIF_FNS(SCLSR, 0x24, 16)
422#else 433#else
423/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ 434/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/
424/* name off sz off sz off sz off sz off sz*/ 435/* name off sz off sz off sz off sz off sz*/
@@ -589,6 +600,23 @@ static inline int sci_rxd_in(struct uart_port *port)
589 return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ 600 return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
590 return 1; 601 return 1;
591} 602}
603#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
604static inline int sci_rxd_in(struct uart_port *port)
605{
606 if (port->mapbase == 0xffe00000)
607 return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */
608 if (port->mapbase == 0xffe10000)
609 return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */
610 if (port->mapbase == 0xffe20000)
611 return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */
612 if (port->mapbase == 0xa4e30000)
613 return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */
614 if (port->mapbase == 0xa4e40000)
615 return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */
616 if (port->mapbase == 0xa4e50000)
617 return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */
618 return 1;
619}
592#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) 620#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
593static inline int sci_rxd_in(struct uart_port *port) 621static inline int sci_rxd_in(struct uart_port *port)
594{ 622{
@@ -727,6 +755,8 @@ static inline int sci_rxd_in(struct uart_port *port)
727 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 755 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
728 defined(CONFIG_CPU_SUBTYPE_SH7721) 756 defined(CONFIG_CPU_SUBTYPE_SH7721)
729#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) 757#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
758#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
759#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1)
730#elif defined(__H8300H__) || defined(__H8300S__) 760#elif defined(__H8300H__) || defined(__H8300S__)
731#define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) 761#define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1)
732#elif defined(CONFIG_SUPERH64) 762#elif defined(CONFIG_SUPERH64)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 46ee7f4c0912..85074cb36f38 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1033,7 +1033,7 @@ MODULE_LICENSE ("GPL");
1033#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver 1033#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver
1034#endif 1034#endif
1035 1035
1036#ifdef CONFIG_ARCH_ORION 1036#ifdef CONFIG_PLAT_ORION
1037#include "ehci-orion.c" 1037#include "ehci-orion.c"
1038#define PLATFORM_DRIVER ehci_orion_driver 1038#define PLATFORM_DRIVER ehci_orion_driver
1039#endif 1039#endif
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index e129981f139f..d187d0313742 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -11,15 +11,18 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <asm/arch/orion.h> 14#include <linux/mbus.h>
15#include <asm/plat-orion/ehci-orion.h>
15 16
16#define rdl(off) __raw_readl(hcd->regs + (off)) 17#define rdl(off) __raw_readl(hcd->regs + (off))
17#define wrl(off, val) __raw_writel((val), hcd->regs + (off)) 18#define wrl(off, val) __raw_writel((val), hcd->regs + (off))
18 19
19#define USB_CAUSE 0x310
20#define USB_MASK 0x314
21#define USB_CMD 0x140 20#define USB_CMD 0x140
22#define USB_MODE 0x1a8 21#define USB_MODE 0x1a8
22#define USB_CAUSE 0x310
23#define USB_MASK 0x314
24#define USB_WINDOW_CTRL(i) (0x320 + ((i) << 4))
25#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4))
23#define USB_IPG 0x360 26#define USB_IPG 0x360
24#define USB_PHY_PWR_CTRL 0x400 27#define USB_PHY_PWR_CTRL 0x400
25#define USB_PHY_TX_CTRL 0x420 28#define USB_PHY_TX_CTRL 0x420
@@ -162,8 +165,30 @@ static const struct hc_driver ehci_orion_hc_driver = {
162 .bus_resume = ehci_bus_resume, 165 .bus_resume = ehci_bus_resume,
163}; 166};
164 167
168static void __init
169ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
170 struct mbus_dram_target_info *dram)
171{
172 int i;
173
174 for (i = 0; i < 4; i++) {
175 wrl(USB_WINDOW_CTRL(i), 0);
176 wrl(USB_WINDOW_BASE(i), 0);
177 }
178
179 for (i = 0; i < dram->num_cs; i++) {
180 struct mbus_dram_window *cs = dram->cs + i;
181
182 wrl(USB_WINDOW_CTRL(i), ((cs->size - 1) & 0xffff0000) |
183 (cs->mbus_attr << 8) |
184 (dram->mbus_dram_target_id << 4) | 1);
185 wrl(USB_WINDOW_BASE(i), cs->base);
186 }
187}
188
165static int __init ehci_orion_drv_probe(struct platform_device *pdev) 189static int __init ehci_orion_drv_probe(struct platform_device *pdev)
166{ 190{
191 struct orion_ehci_data *pd = pdev->dev.platform_data;
167 struct resource *res; 192 struct resource *res;
168 struct usb_hcd *hcd; 193 struct usb_hcd *hcd;
169 struct ehci_hcd *ehci; 194 struct ehci_hcd *ehci;
@@ -227,6 +252,12 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev)
227 ehci->sbrn = 0x20; 252 ehci->sbrn = 0x20;
228 253
229 /* 254 /*
255 * (Re-)program MBUS remapping windows if we are asked to.
256 */
257 if (pd != NULL && pd->dram != NULL)
258 ehci_orion_conf_mbus_windows(hcd, pd->dram);
259
260 /*
230 * setup Orion USB controller 261 * setup Orion USB controller
231 */ 262 */
232 orion_usb_setup(hcd); 263 orion_usb_setup(hcd);
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 97facb121c73..757651954e6c 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -45,6 +45,7 @@
45#include <asm/irq.h> 45#include <asm/irq.h>
46#include <asm/div64.h> 46#include <asm/div64.h>
47#include <asm/arch/pxa-regs.h> 47#include <asm/arch/pxa-regs.h>
48#include <asm/arch/pxa2xx-gpio.h>
48#include <asm/arch/bitfield.h> 49#include <asm/arch/bitfield.h>
49#include <asm/arch/pxafb.h> 50#include <asm/arch/pxafb.h>
50 51