aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2010-03-26 10:55:59 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-03-26 10:55:59 -0400
commit329f9052dbadf6f4afe2231668bd00c579a4aa10 (patch)
treee080a5c70df40f3ae8cf28a95a3267757668ab97 /arch/arm/mach-ep93xx
parent395b228858778d3c44f7c413693a6acaa8bb62dc (diff)
parent220bf991b0366cc50a94feede3d7341fa5710ee4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/mtd/nand/sh_flctl.c Maxim's patch to initialise sysfs attributes depends on the patch which actually adds sysfs_attr_init().
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/Kconfig14
-rw-r--r--arch/arm/mach-ep93xx/Makefile2
-rw-r--r--arch/arm/mach-ep93xx/clock.c32
-rw-r--r--arch/arm/mach-ep93xx/core.c277
-rw-r--r--arch/arm/mach-ep93xx/dma-m2p.c6
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c21
-rw-r--r--arch/arm/mach-ep93xx/gpio.c235
-rw-r--r--arch/arm/mach-ep93xx/include/mach/debug-macro.S2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h22
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h14
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-ep93xx/micro9.c2
-rw-r--r--arch/arm/mach-ep93xx/simone.c97
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c172
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c21
16 files changed, 642 insertions, 279 deletions
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 9167c3d2a5ed..3a08b18f6433 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -161,6 +161,20 @@ config MACH_MICRO9S
161 Say 'Y' here if you want your kernel to support the 161 Say 'Y' here if you want your kernel to support the
162 Contec Micro9-Slim board. 162 Contec Micro9-Slim board.
163 163
164config MACH_SIM_ONE
165 bool "Support Simplemachines Sim.One board"
166 depends on EP93XX_SDCE0_PHYS_OFFSET
167 help
168 Say 'Y' here if you want your kernel to support the
169 Simplemachines Sim.One board.
170
171config MACH_SNAPPER_CL15
172 bool "Support Bluewater Systems Snapper CL15 Module"
173 depends on EP93XX_SDCE0_PHYS_OFFSET
174 help
175 Say 'Y' here if you want your kernel to support the Bluewater
176 Systems Snapper CL15 Module.
177
164config MACH_TS72XX 178config MACH_TS72XX
165 bool "Support Technologic Systems TS-72xx SBC" 179 bool "Support Technologic Systems TS-72xx SBC"
166 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET 180 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index eae6199a9891..33ee2c863d18 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -10,4 +10,6 @@ obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
10obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o 10obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
11obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o 11obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
12obj-$(CONFIG_MACH_MICRO9) += micro9.o 12obj-$(CONFIG_MACH_MICRO9) += micro9.o
13obj-$(CONFIG_MACH_SIM_ONE) += simone.o
14obj-$(CONFIG_MACH_SNAPPER_CL15) += snappercl15.o
13obj-$(CONFIG_MACH_TS72XX) += ts72xx.o 15obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 1d0f9d8aff2e..5f80092b6ace 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -10,6 +10,8 @@
10 * your option) any later version. 10 * your option) any later version.
11 */ 11 */
12 12
13#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
14
13#include <linux/kernel.h> 15#include <linux/kernel.h>
14#include <linux/clk.h> 16#include <linux/clk.h>
15#include <linux/err.h> 17#include <linux/err.h>
@@ -445,37 +447,39 @@ static void __init ep93xx_dma_clock_init(void)
445static int __init ep93xx_clock_init(void) 447static int __init ep93xx_clock_init(void)
446{ 448{
447 u32 value; 449 u32 value;
448 int i;
449 450
450 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); 451 /* Determine the bootloader configured pll1 rate */
451 if (!(value & 0x00800000)) { /* PLL1 bypassed? */ 452 value = __raw_readl(EP93XX_SYSCON_CLKSET1);
453 if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
452 clk_pll1.rate = clk_xtali.rate; 454 clk_pll1.rate = clk_xtali.rate;
453 } else { 455 else
454 clk_pll1.rate = calc_pll_rate(value); 456 clk_pll1.rate = calc_pll_rate(value);
455 } 457
458 /* Initialize the pll1 derived clocks */
456 clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7]; 459 clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
457 clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7]; 460 clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
458 clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3]; 461 clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
459 ep93xx_dma_clock_init(); 462 ep93xx_dma_clock_init();
460 463
461 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); 464 /* Determine the bootloader configured pll2 rate */
462 if (!(value & 0x00080000)) { /* PLL2 bypassed? */ 465 value = __raw_readl(EP93XX_SYSCON_CLKSET2);
466 if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
463 clk_pll2.rate = clk_xtali.rate; 467 clk_pll2.rate = clk_xtali.rate;
464 } else if (value & 0x00040000) { /* PLL2 enabled? */ 468 else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
465 clk_pll2.rate = calc_pll_rate(value); 469 clk_pll2.rate = calc_pll_rate(value);
466 } else { 470 else
467 clk_pll2.rate = 0; 471 clk_pll2.rate = 0;
468 } 472
473 /* Initialize the pll2 derived clocks */
469 clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1); 474 clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
470 475
471 printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n", 476 pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
472 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000); 477 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
473 printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", 478 pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
474 clk_f.rate / 1000000, clk_h.rate / 1000000, 479 clk_f.rate / 1000000, clk_h.rate / 1000000,
475 clk_p.rate / 1000000); 480 clk_p.rate / 1000000);
476 481
477 for (i = 0; i < ARRAY_SIZE(clocks); i++) 482 clkdev_add_table(clocks, ARRAY_SIZE(clocks));
478 clkdev_add(&clocks[i]);
479 return 0; 483 return 0;
480} 484}
481arch_initcall(ep93xx_clock_init); 485arch_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 1f0d66561bbe..90fb591cbffa 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -14,12 +14,15 @@
14 * your option) any later version. 14 * your option) any later version.
15 */ 15 */
16 16
17#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
18
17#include <linux/kernel.h> 19#include <linux/kernel.h>
18#include <linux/init.h> 20#include <linux/init.h>
19#include <linux/platform_device.h> 21#include <linux/platform_device.h>
20#include <linux/interrupt.h> 22#include <linux/interrupt.h>
21#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
22#include <linux/timex.h> 24#include <linux/timex.h>
25#include <linux/irq.h>
23#include <linux/io.h> 26#include <linux/io.h>
24#include <linux/gpio.h> 27#include <linux/gpio.h>
25#include <linux/leds.h> 28#include <linux/leds.h>
@@ -35,7 +38,6 @@
35 38
36#include <asm/mach/map.h> 39#include <asm/mach/map.h>
37#include <asm/mach/time.h> 40#include <asm/mach/time.h>
38#include <asm/mach/irq.h>
39 41
40#include <asm/hardware/vic.h> 42#include <asm/hardware/vic.h>
41 43
@@ -82,13 +84,40 @@ void __init ep93xx_map_io(void)
82 * to use this timer for something else. We also use timer 4 for keeping 84 * to use this timer for something else. We also use timer 4 for keeping
83 * track of lost jiffies. 85 * track of lost jiffies.
84 */ 86 */
85static unsigned int last_jiffy_time; 87#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
86 88#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
89#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
90#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
91#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
92#define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
93#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
94#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
95#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
96#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
97#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
98#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
99#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
100#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
101#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
102#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
103#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
104#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
105#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
106
107#define EP93XX_TIMER123_CLOCK 508469
108#define EP93XX_TIMER4_CLOCK 983040
109
110#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1)
87#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ) 111#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
88 112
113static unsigned int last_jiffy_time;
114
89static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) 115static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
90{ 116{
117 /* Writing any value clears the timer interrupt */
91 __raw_writel(1, EP93XX_TIMER1_CLEAR); 118 __raw_writel(1, EP93XX_TIMER1_CLEAR);
119
120 /* Recover lost jiffies */
92 while ((signed long) 121 while ((signed long)
93 (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) 122 (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
94 >= TIMER4_TICKS_PER_JIFFY) { 123 >= TIMER4_TICKS_PER_JIFFY) {
@@ -107,13 +136,18 @@ static struct irqaction ep93xx_timer_irq = {
107 136
108static void __init ep93xx_timer_init(void) 137static void __init ep93xx_timer_init(void)
109{ 138{
139 u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
140 EP93XX_TIMER123_CONTROL_CLKSEL;
141
110 /* Enable periodic HZ timer. */ 142 /* Enable periodic HZ timer. */
111 __raw_writel(0x48, EP93XX_TIMER1_CONTROL); 143 __raw_writel(tmode, EP93XX_TIMER1_CONTROL);
112 __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD); 144 __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
113 __raw_writel(0xc8, EP93XX_TIMER1_CONTROL); 145 __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
146 EP93XX_TIMER1_CONTROL);
114 147
115 /* Enable lost jiffy timer. */ 148 /* Enable lost jiffy timer. */
116 __raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH); 149 __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
150 EP93XX_TIMER4_VALUE_HIGH);
117 151
118 setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); 152 setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
119} 153}
@@ -135,237 +169,16 @@ struct sys_timer ep93xx_timer = {
135 169
136 170
137/************************************************************************* 171/*************************************************************************
138 * GPIO handling for EP93xx
139 *************************************************************************/
140static unsigned char gpio_int_unmasked[3];
141static unsigned char gpio_int_enabled[3];
142static unsigned char gpio_int_type1[3];
143static unsigned char gpio_int_type2[3];
144static unsigned char gpio_int_debounce[3];
145
146/* Port ordering is: A B F */
147static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
148static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
149static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
150static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
151static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
152
153void ep93xx_gpio_update_int_params(unsigned port)
154{
155 BUG_ON(port > 2);
156
157 __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
158
159 __raw_writeb(gpio_int_type2[port],
160 EP93XX_GPIO_REG(int_type2_register_offset[port]));
161
162 __raw_writeb(gpio_int_type1[port],
163 EP93XX_GPIO_REG(int_type1_register_offset[port]));
164
165 __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
166 EP93XX_GPIO_REG(int_en_register_offset[port]));
167}
168
169void ep93xx_gpio_int_mask(unsigned line)
170{
171 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
172}
173
174void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
175{
176 int line = irq_to_gpio(irq);
177 int port = line >> 3;
178 int port_mask = 1 << (line & 7);
179
180 if (enable)
181 gpio_int_debounce[port] |= port_mask;
182 else
183 gpio_int_debounce[port] &= ~port_mask;
184
185 __raw_writeb(gpio_int_debounce[port],
186 EP93XX_GPIO_REG(int_debounce_register_offset[port]));
187}
188EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
189
190/*************************************************************************
191 * EP93xx IRQ handling 172 * EP93xx IRQ handling
192 *************************************************************************/ 173 *************************************************************************/
193static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) 174extern void ep93xx_gpio_init_irq(void);
194{
195 unsigned char status;
196 int i;
197
198 status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
199 for (i = 0; i < 8; i++) {
200 if (status & (1 << i)) {
201 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
202 generic_handle_irq(gpio_irq);
203 }
204 }
205
206 status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
207 for (i = 0; i < 8; i++) {
208 if (status & (1 << i)) {
209 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
210 generic_handle_irq(gpio_irq);
211 }
212 }
213}
214
215static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
216{
217 /*
218 * map discontiguous hw irq range to continous sw irq range:
219 *
220 * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
221 */
222 int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
223 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
224
225 generic_handle_irq(gpio_irq);
226}
227
228static void ep93xx_gpio_irq_ack(unsigned int irq)
229{
230 int line = irq_to_gpio(irq);
231 int port = line >> 3;
232 int port_mask = 1 << (line & 7);
233
234 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
235 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
236 ep93xx_gpio_update_int_params(port);
237 }
238
239 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
240}
241
242static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
243{
244 int line = irq_to_gpio(irq);
245 int port = line >> 3;
246 int port_mask = 1 << (line & 7);
247
248 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
249 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
250
251 gpio_int_unmasked[port] &= ~port_mask;
252 ep93xx_gpio_update_int_params(port);
253
254 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
255}
256
257static void ep93xx_gpio_irq_mask(unsigned int irq)
258{
259 int line = irq_to_gpio(irq);
260 int port = line >> 3;
261
262 gpio_int_unmasked[port] &= ~(1 << (line & 7));
263 ep93xx_gpio_update_int_params(port);
264}
265
266static void ep93xx_gpio_irq_unmask(unsigned int irq)
267{
268 int line = irq_to_gpio(irq);
269 int port = line >> 3;
270
271 gpio_int_unmasked[port] |= 1 << (line & 7);
272 ep93xx_gpio_update_int_params(port);
273}
274
275
276/*
277 * gpio_int_type1 controls whether the interrupt is level (0) or
278 * edge (1) triggered, while gpio_int_type2 controls whether it
279 * triggers on low/falling (0) or high/rising (1).
280 */
281static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
282{
283 struct irq_desc *desc = irq_desc + irq;
284 const int gpio = irq_to_gpio(irq);
285 const int port = gpio >> 3;
286 const int port_mask = 1 << (gpio & 7);
287
288 gpio_direction_input(gpio);
289
290 switch (type) {
291 case IRQ_TYPE_EDGE_RISING:
292 gpio_int_type1[port] |= port_mask;
293 gpio_int_type2[port] |= port_mask;
294 desc->handle_irq = handle_edge_irq;
295 break;
296 case IRQ_TYPE_EDGE_FALLING:
297 gpio_int_type1[port] |= port_mask;
298 gpio_int_type2[port] &= ~port_mask;
299 desc->handle_irq = handle_edge_irq;
300 break;
301 case IRQ_TYPE_LEVEL_HIGH:
302 gpio_int_type1[port] &= ~port_mask;
303 gpio_int_type2[port] |= port_mask;
304 desc->handle_irq = handle_level_irq;
305 break;
306 case IRQ_TYPE_LEVEL_LOW:
307 gpio_int_type1[port] &= ~port_mask;
308 gpio_int_type2[port] &= ~port_mask;
309 desc->handle_irq = handle_level_irq;
310 break;
311 case IRQ_TYPE_EDGE_BOTH:
312 gpio_int_type1[port] |= port_mask;
313 /* set initial polarity based on current input level */
314 if (gpio_get_value(gpio))
315 gpio_int_type2[port] &= ~port_mask; /* falling */
316 else
317 gpio_int_type2[port] |= port_mask; /* rising */
318 desc->handle_irq = handle_edge_irq;
319 break;
320 default:
321 pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
322 type, gpio);
323 return -EINVAL;
324 }
325
326 gpio_int_enabled[port] |= port_mask;
327
328 desc->status &= ~IRQ_TYPE_SENSE_MASK;
329 desc->status |= type & IRQ_TYPE_SENSE_MASK;
330
331 ep93xx_gpio_update_int_params(port);
332
333 return 0;
334}
335
336static struct irq_chip ep93xx_gpio_irq_chip = {
337 .name = "GPIO",
338 .ack = ep93xx_gpio_irq_ack,
339 .mask_ack = ep93xx_gpio_irq_mask_ack,
340 .mask = ep93xx_gpio_irq_mask,
341 .unmask = ep93xx_gpio_irq_unmask,
342 .set_type = ep93xx_gpio_irq_type,
343};
344
345 175
346void __init ep93xx_init_irq(void) 176void __init ep93xx_init_irq(void)
347{ 177{
348 int gpio_irq;
349
350 vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); 178 vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
351 vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); 179 vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
352 180
353 for (gpio_irq = gpio_to_irq(0); 181 ep93xx_gpio_init_irq();
354 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
355 set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
356 set_irq_handler(gpio_irq, handle_level_irq);
357 set_irq_flags(gpio_irq, IRQF_VALID);
358 }
359
360 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
361 set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
362 set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
363 set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
364 set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
365 set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
366 set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
367 set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
368 set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
369} 182}
370 183
371 184
@@ -572,9 +385,9 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
572 * CMOS driver. 385 * CMOS driver.
573 */ 386 */
574 if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT) 387 if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
575 pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n"); 388 pr_warning("sda != EEDAT, open drain has no effect\n");
576 if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK) 389 if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
577 pr_warning("ep93xx: scl != EECLK, open drain has no effect\n"); 390 pr_warning("scl != EECLK, open drain has no effect\n");
578 391
579 __raw_writel((data->sda_is_open_drain << 1) | 392 __raw_writel((data->sda_is_open_drain << 1) |
580 (data->scl_is_open_drain << 0), 393 (data->scl_is_open_drain << 0),
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c
index dbcac9c40a28..8904ca4e2e24 100644
--- a/arch/arm/mach-ep93xx/dma-m2p.c
+++ b/arch/arm/mach-ep93xx/dma-m2p.c
@@ -28,6 +28,8 @@
28 * with this implementation. 28 * with this implementation.
29 */ 29 */
30 30
31#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
32
31#include <linux/kernel.h> 33#include <linux/kernel.h>
32#include <linux/clk.h> 34#include <linux/clk.h>
33#include <linux/err.h> 35#include <linux/err.h>
@@ -173,7 +175,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
173 175
174 switch (m2p_channel_state(ch)) { 176 switch (m2p_channel_state(ch)) {
175 case STATE_IDLE: 177 case STATE_IDLE:
176 pr_crit("m2p_irq: dma interrupt without a dma buffer\n"); 178 pr_crit("dma interrupt without a dma buffer\n");
177 BUG(); 179 BUG();
178 break; 180 break;
179 181
@@ -197,7 +199,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
197 break; 199 break;
198 200
199 case STATE_NEXT: 201 case STATE_NEXT:
200 pr_crit("m2p_irq: dma interrupt while next\n"); 202 pr_crit("dma interrupt while next\n");
201 BUG(); 203 BUG();
202 break; 204 break;
203 } 205 }
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index a4a7be308000..d22d67ac8b99 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -118,12 +118,33 @@ static void __init edb93xx_register_i2c(void)
118 } 118 }
119} 119}
120 120
121
122/*************************************************************************
123 * EDB93xx pwm
124 *************************************************************************/
125static void __init edb93xx_register_pwm(void)
126{
127 if (machine_is_edb9301() ||
128 machine_is_edb9302() || machine_is_edb9302a()) {
129 /* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
130 ep93xx_register_pwm(0, 1);
131 } else if (machine_is_edb9307() || machine_is_edb9307a()) {
132 /* EP9307 only has pwm.0 (PWMOUT) */
133 ep93xx_register_pwm(1, 0);
134 } else {
135 /* EP9312 and EP9315 have both */
136 ep93xx_register_pwm(1, 1);
137 }
138}
139
140
121static void __init edb93xx_init_machine(void) 141static void __init edb93xx_init_machine(void)
122{ 142{
123 ep93xx_init_devices(); 143 ep93xx_init_devices();
124 edb93xx_register_flash(); 144 edb93xx_register_flash();
125 ep93xx_register_eth(&edb93xx_eth_data, 1); 145 ep93xx_register_eth(&edb93xx_eth_data, 1);
126 edb93xx_register_i2c(); 146 edb93xx_register_i2c();
147 edb93xx_register_pwm();
127} 148}
128 149
129 150
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 1ea8871e03a9..cc377ae8c428 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -13,6 +13,8 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15 15
16#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
17
16#include <linux/init.h> 18#include <linux/init.h>
17#include <linux/module.h> 19#include <linux/module.h>
18#include <linux/seq_file.h> 20#include <linux/seq_file.h>
@@ -22,6 +24,235 @@
22 24
23#include <mach/hardware.h> 25#include <mach/hardware.h>
24 26
27/*************************************************************************
28 * GPIO handling for EP93xx
29 *************************************************************************/
30static unsigned char gpio_int_unmasked[3];
31static unsigned char gpio_int_enabled[3];
32static unsigned char gpio_int_type1[3];
33static unsigned char gpio_int_type2[3];
34static unsigned char gpio_int_debounce[3];
35
36/* Port ordering is: A B F */
37static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
38static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
39static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
40static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
41static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
42
43void ep93xx_gpio_update_int_params(unsigned port)
44{
45 BUG_ON(port > 2);
46
47 __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
48
49 __raw_writeb(gpio_int_type2[port],
50 EP93XX_GPIO_REG(int_type2_register_offset[port]));
51
52 __raw_writeb(gpio_int_type1[port],
53 EP93XX_GPIO_REG(int_type1_register_offset[port]));
54
55 __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
56 EP93XX_GPIO_REG(int_en_register_offset[port]));
57}
58
59void ep93xx_gpio_int_mask(unsigned line)
60{
61 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
62}
63
64void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
65{
66 int line = irq_to_gpio(irq);
67 int port = line >> 3;
68 int port_mask = 1 << (line & 7);
69
70 if (enable)
71 gpio_int_debounce[port] |= port_mask;
72 else
73 gpio_int_debounce[port] &= ~port_mask;
74
75 __raw_writeb(gpio_int_debounce[port],
76 EP93XX_GPIO_REG(int_debounce_register_offset[port]));
77}
78EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
79
80static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
81{
82 unsigned char status;
83 int i;
84
85 status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
86 for (i = 0; i < 8; i++) {
87 if (status & (1 << i)) {
88 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
89 generic_handle_irq(gpio_irq);
90 }
91 }
92
93 status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
94 for (i = 0; i < 8; i++) {
95 if (status & (1 << i)) {
96 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
97 generic_handle_irq(gpio_irq);
98 }
99 }
100}
101
102static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
103{
104 /*
105 * map discontiguous hw irq range to continous sw irq range:
106 *
107 * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
108 */
109 int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
110 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
111
112 generic_handle_irq(gpio_irq);
113}
114
115static void ep93xx_gpio_irq_ack(unsigned int irq)
116{
117 int line = irq_to_gpio(irq);
118 int port = line >> 3;
119 int port_mask = 1 << (line & 7);
120
121 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
122 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
123 ep93xx_gpio_update_int_params(port);
124 }
125
126 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
127}
128
129static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
130{
131 int line = irq_to_gpio(irq);
132 int port = line >> 3;
133 int port_mask = 1 << (line & 7);
134
135 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
136 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
137
138 gpio_int_unmasked[port] &= ~port_mask;
139 ep93xx_gpio_update_int_params(port);
140
141 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
142}
143
144static void ep93xx_gpio_irq_mask(unsigned int irq)
145{
146 int line = irq_to_gpio(irq);
147 int port = line >> 3;
148
149 gpio_int_unmasked[port] &= ~(1 << (line & 7));
150 ep93xx_gpio_update_int_params(port);
151}
152
153static void ep93xx_gpio_irq_unmask(unsigned int irq)
154{
155 int line = irq_to_gpio(irq);
156 int port = line >> 3;
157
158 gpio_int_unmasked[port] |= 1 << (line & 7);
159 ep93xx_gpio_update_int_params(port);
160}
161
162/*
163 * gpio_int_type1 controls whether the interrupt is level (0) or
164 * edge (1) triggered, while gpio_int_type2 controls whether it
165 * triggers on low/falling (0) or high/rising (1).
166 */
167static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
168{
169 struct irq_desc *desc = irq_desc + irq;
170 const int gpio = irq_to_gpio(irq);
171 const int port = gpio >> 3;
172 const int port_mask = 1 << (gpio & 7);
173
174 gpio_direction_input(gpio);
175
176 switch (type) {
177 case IRQ_TYPE_EDGE_RISING:
178 gpio_int_type1[port] |= port_mask;
179 gpio_int_type2[port] |= port_mask;
180 desc->handle_irq = handle_edge_irq;
181 break;
182 case IRQ_TYPE_EDGE_FALLING:
183 gpio_int_type1[port] |= port_mask;
184 gpio_int_type2[port] &= ~port_mask;
185 desc->handle_irq = handle_edge_irq;
186 break;
187 case IRQ_TYPE_LEVEL_HIGH:
188 gpio_int_type1[port] &= ~port_mask;
189 gpio_int_type2[port] |= port_mask;
190 desc->handle_irq = handle_level_irq;
191 break;
192 case IRQ_TYPE_LEVEL_LOW:
193 gpio_int_type1[port] &= ~port_mask;
194 gpio_int_type2[port] &= ~port_mask;
195 desc->handle_irq = handle_level_irq;
196 break;
197 case IRQ_TYPE_EDGE_BOTH:
198 gpio_int_type1[port] |= port_mask;
199 /* set initial polarity based on current input level */
200 if (gpio_get_value(gpio))
201 gpio_int_type2[port] &= ~port_mask; /* falling */
202 else
203 gpio_int_type2[port] |= port_mask; /* rising */
204 desc->handle_irq = handle_edge_irq;
205 break;
206 default:
207 pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
208 return -EINVAL;
209 }
210
211 gpio_int_enabled[port] |= port_mask;
212
213 desc->status &= ~IRQ_TYPE_SENSE_MASK;
214 desc->status |= type & IRQ_TYPE_SENSE_MASK;
215
216 ep93xx_gpio_update_int_params(port);
217
218 return 0;
219}
220
221static struct irq_chip ep93xx_gpio_irq_chip = {
222 .name = "GPIO",
223 .ack = ep93xx_gpio_irq_ack,
224 .mask_ack = ep93xx_gpio_irq_mask_ack,
225 .mask = ep93xx_gpio_irq_mask,
226 .unmask = ep93xx_gpio_irq_unmask,
227 .set_type = ep93xx_gpio_irq_type,
228};
229
230void __init ep93xx_gpio_init_irq(void)
231{
232 int gpio_irq;
233
234 for (gpio_irq = gpio_to_irq(0);
235 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
236 set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
237 set_irq_handler(gpio_irq, handle_level_irq);
238 set_irq_flags(gpio_irq, IRQF_VALID);
239 }
240
241 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
242 set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
243 set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
244 set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
245 set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
246 set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
247 set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
248 set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
249 set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
250}
251
252
253/*************************************************************************
254 * gpiolib interface for EP93xx on-chip GPIOs
255 *************************************************************************/
25struct ep93xx_gpio_chip { 256struct ep93xx_gpio_chip {
26 struct gpio_chip chip; 257 struct gpio_chip chip;
27 258
@@ -31,10 +262,6 @@ struct ep93xx_gpio_chip {
31 262
32#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) 263#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
33 264
34/* From core.c */
35extern void ep93xx_gpio_int_mask(unsigned line);
36extern void ep93xx_gpio_update_int_params(unsigned port);
37
38static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 265static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
39{ 266{
40 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 267 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
index 802858bc8095..5cd22444e223 100644
--- a/arch/arm/mach-ep93xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
@@ -11,7 +11,7 @@
11 */ 11 */
12#include <mach/ep93xx-regs.h> 12#include <mach/ep93xx-regs.h>
13 13
14 .macro addruart,rx 14 .macro addruart, rx, tmp
15 mrc p15, 0, \rx, c1, c0 15 mrc p15, 0, \rx, c1, c0
16 tst \rx, #1 @ MMU enabled? 16 tst \rx, #1 @ MMU enabled?
17 ldreq \rx, =EP93XX_APB_PHYS_BASE @ Physical base 17 ldreq \rx, =EP93XX_APB_PHYS_BASE @ Physical base
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index d55194a4c093..93e2ecc79ceb 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -92,21 +92,6 @@
92 92
93/* APB peripherals */ 93/* APB peripherals */
94#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) 94#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
95#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
96#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
97#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
98#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
99#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
100#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
101#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
102#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
103#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
104#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
105#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
106#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
107#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
108#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
109#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
110 95
111#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) 96#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
112 97
@@ -167,8 +152,11 @@
167#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16) 152#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16)
168#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08) 153#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
169#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) 154#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
170#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) 155#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20)
171#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) 156#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23)
157#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24)
158#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19)
159#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18)
172#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) 160#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
173#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) 161#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
174#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) 162#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
index 62d17421e48c..1e2f4e97f428 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
@@ -5,6 +5,8 @@
5#ifndef __ASM_ARCH_EP93XX_KEYPAD_H 5#ifndef __ASM_ARCH_EP93XX_KEYPAD_H
6#define __ASM_ARCH_EP93XX_KEYPAD_H 6#define __ASM_ARCH_EP93XX_KEYPAD_H
7 7
8struct matrix_keymap_data;
9
8/* flags for the ep93xx_keypad driver */ 10/* flags for the ep93xx_keypad driver */
9#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */ 11#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */
10#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */ 12#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */
@@ -15,15 +17,13 @@
15 17
16/** 18/**
17 * struct ep93xx_keypad_platform_data - platform specific device structure 19 * struct ep93xx_keypad_platform_data - platform specific device structure
18 * @matrix_key_map: array of keycodes defining the keypad matrix 20 * @keymap_data: pointer to &matrix_keymap_data
19 * @matrix_key_map_size: ARRAY_SIZE(matrix_key_map) 21 * @debounce: debounce start count; terminal count is 0xff
20 * @debounce: debounce start count; terminal count is 0xff 22 * @prescale: row/column counter pre-scaler load value
21 * @prescale: row/column counter pre-scaler load value 23 * @flags: see above
22 * @flags: see above
23 */ 24 */
24struct ep93xx_keypad_platform_data { 25struct ep93xx_keypad_platform_data {
25 unsigned int *matrix_key_map; 26 struct matrix_keymap_data *keymap_data;
26 int matrix_key_map_size;
27 unsigned int debounce; 27 unsigned int debounce;
28 unsigned int prescale; 28 unsigned int prescale;
29 unsigned int flags; 29 unsigned int flags;
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 61c0e132c63e..0eabec62cd9d 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -46,6 +46,8 @@
46#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000 46#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
47#define TS72XX_RTC_DATA_SIZE 0x00001000 47#define TS72XX_RTC_DATA_SIZE 0x00001000
48 48
49#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
50#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
49 51
50#ifndef __ASSEMBLY__ 52#ifndef __ASSEMBLY__
51 53
diff --git a/arch/arm/mach-ep93xx/include/mach/vmalloc.h b/arch/arm/mach-ep93xx/include/mach/vmalloc.h
index aed21cd3fe2d..1b3f25d03d39 100644
--- a/arch/arm/mach-ep93xx/include/mach/vmalloc.h
+++ b/arch/arm/mach-ep93xx/include/mach/vmalloc.h
@@ -2,4 +2,4 @@
2 * arch/arm/mach-ep93xx/include/mach/vmalloc.h 2 * arch/arm/mach-ep93xx/include/mach/vmalloc.h
3 */ 3 */
4 4
5#define VMALLOC_END 0xfe800000 5#define VMALLOC_END 0xfe800000UL
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index f3757a1c5a10..c33360e82868 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -28,7 +28,7 @@
28 * 28 *
29 * Micro9-High has up to 64MB of 32-bit flash on CS1 29 * Micro9-High has up to 64MB of 32-bit flash on CS1
30 * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1 30 * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
31 * Micro9-Lite uses a seperate MTD map driver for flash support 31 * Micro9-Lite uses a separate MTD map driver for flash support
32 * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1 32 * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
33 *************************************************************************/ 33 *************************************************************************/
34static struct physmap_flash_data micro9_flash_data; 34static struct physmap_flash_data micro9_flash_data;
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
new file mode 100644
index 000000000000..cd93990f1b99
--- /dev/null
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -0,0 +1,97 @@
1/*
2 * arch/arm/mach-ep93xx/simone.c
3 * Simplemachines Sim.One support.
4 *
5 * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
6 *
7 * Based on the 2.6.24.7 support:
8 * Copyright (C) 2009 Simplemachines
9 * MMC support by Peter Ivanov <ivanovp@gmail.com>, 2007
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21#include <linux/mtd/physmap.h>
22#include <linux/gpio.h>
23#include <linux/i2c.h>
24#include <linux/i2c-gpio.h>
25
26#include <mach/hardware.h>
27#include <mach/fb.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31
32static struct physmap_flash_data simone_flash_data = {
33 .width = 2,
34};
35
36static struct resource simone_flash_resource = {
37 .start = EP93XX_CS6_PHYS_BASE,
38 .end = EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
39 .flags = IORESOURCE_MEM,
40};
41
42static struct platform_device simone_flash = {
43 .name = "physmap-flash",
44 .id = 0,
45 .num_resources = 1,
46 .resource = &simone_flash_resource,
47 .dev = {
48 .platform_data = &simone_flash_data,
49 },
50};
51
52static struct ep93xx_eth_data simone_eth_data = {
53 .phy_id = 1,
54};
55
56static struct ep93xxfb_mach_info simone_fb_info = {
57 .num_modes = EP93XXFB_USE_MODEDB,
58 .bpp = 16,
59 .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
60};
61
62static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
63 .sda_pin = EP93XX_GPIO_LINE_EEDAT,
64 .sda_is_open_drain = 0,
65 .scl_pin = EP93XX_GPIO_LINE_EECLK,
66 .scl_is_open_drain = 0,
67 .udelay = 0,
68 .timeout = 0,
69};
70
71static struct i2c_board_info __initdata simone_i2c_board_info[] = {
72 {
73 I2C_BOARD_INFO("ds1337", 0x68),
74 },
75};
76
77static void __init simone_init_machine(void)
78{
79 ep93xx_init_devices();
80
81 platform_device_register(&simone_flash);
82 ep93xx_register_eth(&simone_eth_data, 1);
83 ep93xx_register_fb(&simone_fb_info);
84 ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
85 ARRAY_SIZE(simone_i2c_board_info));
86}
87
88MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
89/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
90 .phys_io = EP93XX_APB_PHYS_BASE,
91 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
92 .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
93 .map_io = ep93xx_map_io,
94 .init_irq = ep93xx_init_irq,
95 .timer = &ep93xx_timer,
96 .init_machine = simone_init_machine,
97MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
new file mode 100644
index 000000000000..51134b0382ca
--- /dev/null
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -0,0 +1,172 @@
1/*
2 * arch/arm/mach-ep93xx/snappercl15.c
3 * Bluewater Systems Snapper CL15 system module
4 *
5 * Copyright (C) 2009 Bluewater Systems Ltd
6 * Author: Ryan Mallon <ryan@bluewatersys.com>
7 *
8 * NAND code adapted from driver by:
9 * Andre Renaud <andre@bluewatersys.com>
10 * James R. McKaskill
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 */
18
19#include <linux/platform_device.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/io.h>
23#include <linux/gpio.h>
24#include <linux/i2c.h>
25#include <linux/i2c-gpio.h>
26#include <linux/fb.h>
27
28#include <linux/mtd/partitions.h>
29#include <linux/mtd/nand.h>
30
31#include <mach/hardware.h>
32#include <mach/fb.h>
33
34#include <asm/mach-types.h>
35#include <asm/mach/arch.h>
36
37#define SNAPPERCL15_NAND_BASE (EP93XX_CS7_PHYS_BASE + SZ_16M)
38
39#define SNAPPERCL15_NAND_WPN (1 << 8) /* Write protect (active low) */
40#define SNAPPERCL15_NAND_ALE (1 << 9) /* Address latch */
41#define SNAPPERCL15_NAND_CLE (1 << 10) /* Command latch */
42#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
43#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
44
45#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
46
47static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
48 unsigned int ctrl)
49{
50 struct nand_chip *chip = mtd->priv;
51 static u16 nand_state = SNAPPERCL15_NAND_WPN;
52 u16 set;
53
54 if (ctrl & NAND_CTRL_CHANGE) {
55 set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
56
57 if (ctrl & NAND_NCE)
58 set &= ~SNAPPERCL15_NAND_CEN;
59 if (ctrl & NAND_CLE)
60 set |= SNAPPERCL15_NAND_CLE;
61 if (ctrl & NAND_ALE)
62 set |= SNAPPERCL15_NAND_ALE;
63
64 nand_state &= ~(SNAPPERCL15_NAND_CEN |
65 SNAPPERCL15_NAND_CLE |
66 SNAPPERCL15_NAND_ALE);
67 nand_state |= set;
68 __raw_writew(nand_state, NAND_CTRL_ADDR(chip));
69 }
70
71 if (cmd != NAND_CMD_NONE)
72 __raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
73}
74
75static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
76{
77 struct nand_chip *chip = mtd->priv;
78
79 return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
80}
81
82static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL};
83
84static struct mtd_partition snappercl15_nand_parts[] = {
85 {
86 .name = "Kernel",
87 .offset = 0,
88 .size = SZ_2M,
89 },
90 {
91 .name = "Filesystem",
92 .offset = MTDPART_OFS_APPEND,
93 .size = MTDPART_SIZ_FULL,
94 },
95};
96
97static struct platform_nand_data snappercl15_nand_data = {
98 .chip = {
99 .nr_chips = 1,
100 .part_probe_types = snappercl15_nand_part_probes,
101 .partitions = snappercl15_nand_parts,
102 .nr_partitions = ARRAY_SIZE(snappercl15_nand_parts),
103 .options = NAND_NO_AUTOINCR,
104 .chip_delay = 25,
105 },
106 .ctrl = {
107 .dev_ready = snappercl15_nand_dev_ready,
108 .cmd_ctrl = snappercl15_nand_cmd_ctrl,
109 },
110};
111
112static struct resource snappercl15_nand_resource[] = {
113 {
114 .start = SNAPPERCL15_NAND_BASE,
115 .end = SNAPPERCL15_NAND_BASE + SZ_4K - 1,
116 .flags = IORESOURCE_MEM,
117 },
118};
119
120static struct platform_device snappercl15_nand_device = {
121 .name = "gen_nand",
122 .id = -1,
123 .dev.platform_data = &snappercl15_nand_data,
124 .resource = snappercl15_nand_resource,
125 .num_resources = ARRAY_SIZE(snappercl15_nand_resource),
126};
127
128static struct ep93xx_eth_data snappercl15_eth_data = {
129 .phy_id = 1,
130};
131
132static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
133 .sda_pin = EP93XX_GPIO_LINE_EEDAT,
134 .sda_is_open_drain = 0,
135 .scl_pin = EP93XX_GPIO_LINE_EECLK,
136 .scl_is_open_drain = 0,
137 .udelay = 0,
138 .timeout = 0,
139};
140
141static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
142 {
143 /* Audio codec */
144 I2C_BOARD_INFO("tlv320aic23", 0x1a),
145 },
146};
147
148static struct ep93xxfb_mach_info snappercl15_fb_info = {
149 .num_modes = EP93XXFB_USE_MODEDB,
150 .bpp = 16,
151};
152
153static void __init snappercl15_init_machine(void)
154{
155 ep93xx_init_devices();
156 ep93xx_register_eth(&snappercl15_eth_data, 1);
157 ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
158 ARRAY_SIZE(snappercl15_i2c_data));
159 ep93xx_register_fb(&snappercl15_fb_info);
160 platform_device_register(&snappercl15_nand_device);
161}
162
163MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
164 /* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
165 .phys_io = EP93XX_APB_PHYS_BASE,
166 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
167 .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
168 .map_io = ep93xx_map_io,
169 .init_irq = ep93xx_init_irq,
170 .timer = &ep93xx_timer,
171 .init_machine = snappercl15_init_machine,
172MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 47a86f07831d..333d259b79d5 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -240,6 +240,26 @@ static struct platform_device ts72xx_rtc_device = {
240 .num_resources = 0, 240 .num_resources = 0,
241}; 241};
242 242
243static struct resource ts72xx_wdt_resources[] = {
244 {
245 .start = TS72XX_WDT_CONTROL_PHYS_BASE,
246 .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
247 .flags = IORESOURCE_MEM,
248 },
249 {
250 .start = TS72XX_WDT_FEED_PHYS_BASE,
251 .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
252 .flags = IORESOURCE_MEM,
253 },
254};
255
256static struct platform_device ts72xx_wdt_device = {
257 .name = "ts72xx-wdt",
258 .id = -1,
259 .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
260 .resource = ts72xx_wdt_resources,
261};
262
243static struct ep93xx_eth_data ts72xx_eth_data = { 263static struct ep93xx_eth_data ts72xx_eth_data = {
244 .phy_id = 1, 264 .phy_id = 1,
245}; 265};
@@ -249,6 +269,7 @@ static void __init ts72xx_init_machine(void)
249 ep93xx_init_devices(); 269 ep93xx_init_devices();
250 ts72xx_register_flash(); 270 ts72xx_register_flash();
251 platform_device_register(&ts72xx_rtc_device); 271 platform_device_register(&ts72xx_rtc_device);
272 platform_device_register(&ts72xx_wdt_device);
252 273
253 ep93xx_register_eth(&ts72xx_eth_data, 1); 274 ep93xx_register_eth(&ts72xx_eth_data, 1);
254} 275}