aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/arm/plat-nomadik
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/Kconfig7
-rw-r--r--arch/arm/plat-nomadik/Makefile1
-rw-r--r--arch/arm/plat-nomadik/gpio.c643
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h11
-rw-r--r--arch/arm/plat-nomadik/include/plat/i2c.h8
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h80
-rw-r--r--arch/arm/plat-nomadik/include/plat/ske.h50
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h165
-rw-r--r--arch/arm/plat-nomadik/timer.c60
9 files changed, 239 insertions, 786 deletions
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index 5da3f97c537b..ce659015535e 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -5,6 +5,7 @@
5config PLAT_NOMADIK 5config PLAT_NOMADIK
6 bool 6 bool
7 depends on ARCH_NOMADIK || ARCH_U8500 7 depends on ARCH_NOMADIK || ARCH_U8500
8 select CLKSRC_MMIO
8 default y 9 default y
9 help 10 help
10 Common platform code for Nomadik and other ST-Ericsson 11 Common platform code for Nomadik and other ST-Ericsson
@@ -14,14 +15,10 @@ if PLAT_NOMADIK
14 15
15config HAS_MTU 16config HAS_MTU
16 bool 17 bool
18 select HAVE_SCHED_CLOCK
17 help 19 help
18 Support for Multi Timer Unit. MTU provides access 20 Support for Multi Timer Unit. MTU provides access
19 to multiple interrupt generating programmable 21 to multiple interrupt generating programmable
20 32-bit free running decrementing counters. 22 32-bit free running decrementing counters.
21 23
22config NOMADIK_GPIO
23 bool
24 help
25 Support for the Nomadik GPIO controller.
26
27endif 24endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
index c33547361bd7..37c7cdd0f8f0 100644
--- a/arch/arm/plat-nomadik/Makefile
+++ b/arch/arm/plat-nomadik/Makefile
@@ -3,4 +3,3 @@
3# Licensed under GPLv2 3# Licensed under GPLv2
4 4
5obj-$(CONFIG_HAS_MTU) += timer.o 5obj-$(CONFIG_HAS_MTU) += timer.o
6obj-$(CONFIG_NOMADIK_GPIO) += gpio.o
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
deleted file mode 100644
index 977c8f9a07a2..000000000000
--- a/arch/arm/plat-nomadik/gpio.c
+++ /dev/null
@@ -1,643 +0,0 @@
1/*
2 * Generic GPIO driver for logic cells found in the Nomadik SoC
3 *
4 * Copyright (C) 2008,2009 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
6 * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
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#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20#include <linux/gpio.h>
21#include <linux/spinlock.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25
26#include <plat/pincfg.h>
27#include <mach/hardware.h>
28#include <mach/gpio.h>
29
30/*
31 * The GPIO module in the Nomadik family of Systems-on-Chip is an
32 * AMBA device, managing 32 pins and alternate functions. The logic block
33 * is currently only used in the Nomadik.
34 *
35 * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
36 */
37
38#define NMK_GPIO_PER_CHIP 32
39struct nmk_gpio_chip {
40 struct gpio_chip chip;
41 void __iomem *addr;
42 struct clk *clk;
43 unsigned int parent_irq;
44 spinlock_t lock;
45 /* Keep track of configured edges */
46 u32 edge_rising;
47 u32 edge_falling;
48};
49
50static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
51 unsigned offset, int gpio_mode)
52{
53 u32 bit = 1 << offset;
54 u32 afunc, bfunc;
55
56 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
57 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
58 if (gpio_mode & NMK_GPIO_ALT_A)
59 afunc |= bit;
60 if (gpio_mode & NMK_GPIO_ALT_B)
61 bfunc |= bit;
62 writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
63 writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
64}
65
66static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
67 unsigned offset, enum nmk_gpio_slpm mode)
68{
69 u32 bit = 1 << offset;
70 u32 slpm;
71
72 slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
73 if (mode == NMK_GPIO_SLPM_NOCHANGE)
74 slpm |= bit;
75 else
76 slpm &= ~bit;
77 writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
78}
79
80static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
81 unsigned offset, enum nmk_gpio_pull pull)
82{
83 u32 bit = 1 << offset;
84 u32 pdis;
85
86 pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
87 if (pull == NMK_GPIO_PULL_NONE)
88 pdis |= bit;
89 else
90 pdis &= ~bit;
91 writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
92
93 if (pull == NMK_GPIO_PULL_UP)
94 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
95 else if (pull == NMK_GPIO_PULL_DOWN)
96 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
97}
98
99static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
100 unsigned offset)
101{
102 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
103}
104
105static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
106 pin_cfg_t cfg)
107{
108 static const char *afnames[] = {
109 [NMK_GPIO_ALT_GPIO] = "GPIO",
110 [NMK_GPIO_ALT_A] = "A",
111 [NMK_GPIO_ALT_B] = "B",
112 [NMK_GPIO_ALT_C] = "C"
113 };
114 static const char *pullnames[] = {
115 [NMK_GPIO_PULL_NONE] = "none",
116 [NMK_GPIO_PULL_UP] = "up",
117 [NMK_GPIO_PULL_DOWN] = "down",
118 [3] /* illegal */ = "??"
119 };
120 static const char *slpmnames[] = {
121 [NMK_GPIO_SLPM_INPUT] = "input",
122 [NMK_GPIO_SLPM_NOCHANGE] = "no-change",
123 };
124
125 int pin = PIN_NUM(cfg);
126 int pull = PIN_PULL(cfg);
127 int af = PIN_ALT(cfg);
128 int slpm = PIN_SLPM(cfg);
129
130 dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n",
131 pin, afnames[af], pullnames[pull], slpmnames[slpm]);
132
133 __nmk_gpio_make_input(nmk_chip, offset);
134 __nmk_gpio_set_pull(nmk_chip, offset, pull);
135 __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
136 __nmk_gpio_set_mode(nmk_chip, offset, af);
137}
138
139/**
140 * nmk_config_pin - configure a pin's mux attributes
141 * @cfg: pin confguration
142 *
143 * Configures a pin's mode (alternate function or GPIO), its pull up status,
144 * and its sleep mode based on the specified configuration. The @cfg is
145 * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
146 * are constructed using, and can be further enhanced with, the macros in
147 * plat/pincfg.h.
148 *
149 * If a pin's mode is set to GPIO, it is configured as an input to avoid
150 * side-effects. The gpio can be manipulated later using standard GPIO API
151 * calls.
152 */
153int nmk_config_pin(pin_cfg_t cfg)
154{
155 struct nmk_gpio_chip *nmk_chip;
156 int gpio = PIN_NUM(cfg);
157 unsigned long flags;
158
159 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
160 if (!nmk_chip)
161 return -EINVAL;
162
163 spin_lock_irqsave(&nmk_chip->lock, flags);
164 __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg);
165 spin_unlock_irqrestore(&nmk_chip->lock, flags);
166
167 return 0;
168}
169EXPORT_SYMBOL(nmk_config_pin);
170
171/**
172 * nmk_config_pins - configure several pins at once
173 * @cfgs: array of pin configurations
174 * @num: number of elments in the array
175 *
176 * Configures several pins using nmk_config_pin(). Refer to that function for
177 * further information.
178 */
179int nmk_config_pins(pin_cfg_t *cfgs, int num)
180{
181 int ret = 0;
182 int i;
183
184 for (i = 0; i < num; i++) {
185 int ret = nmk_config_pin(cfgs[i]);
186 if (ret)
187 break;
188 }
189
190 return ret;
191}
192EXPORT_SYMBOL(nmk_config_pins);
193
194/**
195 * nmk_gpio_set_slpm() - configure the sleep mode of a pin
196 * @gpio: pin number
197 * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
198 *
199 * Sets the sleep mode of a pin. If @mode is NMK_GPIO_SLPM_INPUT, the pin is
200 * changed to an input (with pullup/down enabled) in sleep and deep sleep. If
201 * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
202 * configured even when in sleep and deep sleep.
203 */
204int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
205{
206 struct nmk_gpio_chip *nmk_chip;
207 unsigned long flags;
208
209 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
210 if (!nmk_chip)
211 return -EINVAL;
212
213 spin_lock_irqsave(&nmk_chip->lock, flags);
214 __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
215 spin_unlock_irqrestore(&nmk_chip->lock, flags);
216
217 return 0;
218}
219
220/**
221 * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
222 * @gpio: pin number
223 * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
224 *
225 * Enables/disables pull up/down on a specified pin. This only takes effect if
226 * the pin is configured as an input (either explicitly or by the alternate
227 * function).
228 *
229 * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
230 * configured as an input. Otherwise, due to the way the controller registers
231 * work, this function will change the value output on the pin.
232 */
233int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
234{
235 struct nmk_gpio_chip *nmk_chip;
236 unsigned long flags;
237
238 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
239 if (!nmk_chip)
240 return -EINVAL;
241
242 spin_lock_irqsave(&nmk_chip->lock, flags);
243 __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
244 spin_unlock_irqrestore(&nmk_chip->lock, flags);
245
246 return 0;
247}
248
249/* Mode functions */
250int nmk_gpio_set_mode(int gpio, int gpio_mode)
251{
252 struct nmk_gpio_chip *nmk_chip;
253 unsigned long flags;
254
255 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
256 if (!nmk_chip)
257 return -EINVAL;
258
259 spin_lock_irqsave(&nmk_chip->lock, flags);
260 __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
261 spin_unlock_irqrestore(&nmk_chip->lock, flags);
262
263 return 0;
264}
265EXPORT_SYMBOL(nmk_gpio_set_mode);
266
267int nmk_gpio_get_mode(int gpio)
268{
269 struct nmk_gpio_chip *nmk_chip;
270 u32 afunc, bfunc, bit;
271
272 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
273 if (!nmk_chip)
274 return -EINVAL;
275
276 bit = 1 << (gpio - nmk_chip->chip.base);
277
278 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
279 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
280
281 return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
282}
283EXPORT_SYMBOL(nmk_gpio_get_mode);
284
285
286/* IRQ functions */
287static inline int nmk_gpio_get_bitmask(int gpio)
288{
289 return 1 << (gpio % 32);
290}
291
292static void nmk_gpio_irq_ack(unsigned int irq)
293{
294 int gpio;
295 struct nmk_gpio_chip *nmk_chip;
296
297 gpio = NOMADIK_IRQ_TO_GPIO(irq);
298 nmk_chip = get_irq_chip_data(irq);
299 if (!nmk_chip)
300 return;
301 writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
302}
303
304enum nmk_gpio_irq_type {
305 NORMAL,
306 WAKE,
307};
308
309static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
310 int gpio, enum nmk_gpio_irq_type which,
311 bool enable)
312{
313 u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
314 u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
315 u32 bitmask = nmk_gpio_get_bitmask(gpio);
316 u32 reg;
317
318 /* we must individually set/clear the two edges */
319 if (nmk_chip->edge_rising & bitmask) {
320 reg = readl(nmk_chip->addr + rimsc);
321 if (enable)
322 reg |= bitmask;
323 else
324 reg &= ~bitmask;
325 writel(reg, nmk_chip->addr + rimsc);
326 }
327 if (nmk_chip->edge_falling & bitmask) {
328 reg = readl(nmk_chip->addr + fimsc);
329 if (enable)
330 reg |= bitmask;
331 else
332 reg &= ~bitmask;
333 writel(reg, nmk_chip->addr + fimsc);
334 }
335}
336
337static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which,
338 bool enable)
339{
340 int gpio;
341 struct nmk_gpio_chip *nmk_chip;
342 unsigned long flags;
343 u32 bitmask;
344
345 gpio = NOMADIK_IRQ_TO_GPIO(irq);
346 nmk_chip = get_irq_chip_data(irq);
347 bitmask = nmk_gpio_get_bitmask(gpio);
348 if (!nmk_chip)
349 return -EINVAL;
350
351 spin_lock_irqsave(&nmk_chip->lock, flags);
352 __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable);
353 spin_unlock_irqrestore(&nmk_chip->lock, flags);
354
355 return 0;
356}
357
358static void nmk_gpio_irq_mask(unsigned int irq)
359{
360 nmk_gpio_irq_modify(irq, NORMAL, false);
361}
362
363static void nmk_gpio_irq_unmask(unsigned int irq)
364{
365 nmk_gpio_irq_modify(irq, NORMAL, true);
366}
367
368static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
369{
370 return nmk_gpio_irq_modify(irq, WAKE, on);
371}
372
373static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
374{
375 struct irq_desc *desc = irq_to_desc(irq);
376 bool enabled = !(desc->status & IRQ_DISABLED);
377 bool wake = desc->wake_depth;
378 int gpio;
379 struct nmk_gpio_chip *nmk_chip;
380 unsigned long flags;
381 u32 bitmask;
382
383 gpio = NOMADIK_IRQ_TO_GPIO(irq);
384 nmk_chip = get_irq_chip_data(irq);
385 bitmask = nmk_gpio_get_bitmask(gpio);
386 if (!nmk_chip)
387 return -EINVAL;
388
389 if (type & IRQ_TYPE_LEVEL_HIGH)
390 return -EINVAL;
391 if (type & IRQ_TYPE_LEVEL_LOW)
392 return -EINVAL;
393
394 spin_lock_irqsave(&nmk_chip->lock, flags);
395
396 if (enabled)
397 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
398
399 if (wake)
400 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
401
402 nmk_chip->edge_rising &= ~bitmask;
403 if (type & IRQ_TYPE_EDGE_RISING)
404 nmk_chip->edge_rising |= bitmask;
405
406 nmk_chip->edge_falling &= ~bitmask;
407 if (type & IRQ_TYPE_EDGE_FALLING)
408 nmk_chip->edge_falling |= bitmask;
409
410 if (enabled)
411 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
412
413 if (wake)
414 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
415
416 spin_unlock_irqrestore(&nmk_chip->lock, flags);
417
418 return 0;
419}
420
421static struct irq_chip nmk_gpio_irq_chip = {
422 .name = "Nomadik-GPIO",
423 .ack = nmk_gpio_irq_ack,
424 .mask = nmk_gpio_irq_mask,
425 .unmask = nmk_gpio_irq_unmask,
426 .set_type = nmk_gpio_irq_set_type,
427 .set_wake = nmk_gpio_irq_set_wake,
428};
429
430static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
431{
432 struct nmk_gpio_chip *nmk_chip;
433 struct irq_chip *host_chip = get_irq_chip(irq);
434 unsigned int gpio_irq;
435 u32 pending;
436 unsigned int first_irq;
437
438 if (host_chip->mask_ack)
439 host_chip->mask_ack(irq);
440 else {
441 host_chip->mask(irq);
442 if (host_chip->ack)
443 host_chip->ack(irq);
444 }
445
446 nmk_chip = get_irq_data(irq);
447 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
448 while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
449 gpio_irq = first_irq + __ffs(pending);
450 generic_handle_irq(gpio_irq);
451 }
452
453 host_chip->unmask(irq);
454}
455
456static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
457{
458 unsigned int first_irq;
459 int i;
460
461 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
462 for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
463 set_irq_chip(i, &nmk_gpio_irq_chip);
464 set_irq_handler(i, handle_edge_irq);
465 set_irq_flags(i, IRQF_VALID);
466 set_irq_chip_data(i, nmk_chip);
467 set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
468 }
469 set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
470 set_irq_data(nmk_chip->parent_irq, nmk_chip);
471 return 0;
472}
473
474/* I/O Functions */
475static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
476{
477 struct nmk_gpio_chip *nmk_chip =
478 container_of(chip, struct nmk_gpio_chip, chip);
479
480 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
481 return 0;
482}
483
484static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
485{
486 struct nmk_gpio_chip *nmk_chip =
487 container_of(chip, struct nmk_gpio_chip, chip);
488 u32 bit = 1 << offset;
489
490 return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
491}
492
493static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
494 int val)
495{
496 struct nmk_gpio_chip *nmk_chip =
497 container_of(chip, struct nmk_gpio_chip, chip);
498 u32 bit = 1 << offset;
499
500 if (val)
501 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
502 else
503 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
504}
505
506static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
507 int val)
508{
509 struct nmk_gpio_chip *nmk_chip =
510 container_of(chip, struct nmk_gpio_chip, chip);
511
512 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
513 nmk_gpio_set_output(chip, offset, val);
514
515 return 0;
516}
517
518static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
519{
520 struct nmk_gpio_chip *nmk_chip =
521 container_of(chip, struct nmk_gpio_chip, chip);
522
523 return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
524}
525
526/* This structure is replicated for each GPIO block allocated at probe time */
527static struct gpio_chip nmk_gpio_template = {
528 .direction_input = nmk_gpio_make_input,
529 .get = nmk_gpio_get_input,
530 .direction_output = nmk_gpio_make_output,
531 .set = nmk_gpio_set_output,
532 .to_irq = nmk_gpio_to_irq,
533 .ngpio = NMK_GPIO_PER_CHIP,
534 .can_sleep = 0,
535};
536
537static int __init nmk_gpio_probe(struct platform_device *dev)
538{
539 struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
540 struct nmk_gpio_chip *nmk_chip;
541 struct gpio_chip *chip;
542 struct resource *res;
543 struct clk *clk;
544 int irq;
545 int ret;
546
547 if (!pdata)
548 return -ENODEV;
549
550 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
551 if (!res) {
552 ret = -ENOENT;
553 goto out;
554 }
555
556 irq = platform_get_irq(dev, 0);
557 if (irq < 0) {
558 ret = irq;
559 goto out;
560 }
561
562 if (request_mem_region(res->start, resource_size(res),
563 dev_name(&dev->dev)) == NULL) {
564 ret = -EBUSY;
565 goto out;
566 }
567
568 clk = clk_get(&dev->dev, NULL);
569 if (IS_ERR(clk)) {
570 ret = PTR_ERR(clk);
571 goto out_release;
572 }
573
574 clk_enable(clk);
575
576 nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
577 if (!nmk_chip) {
578 ret = -ENOMEM;
579 goto out_clk;
580 }
581 /*
582 * The virt address in nmk_chip->addr is in the nomadik register space,
583 * so we can simply convert the resource address, without remapping
584 */
585 nmk_chip->clk = clk;
586 nmk_chip->addr = io_p2v(res->start);
587 nmk_chip->chip = nmk_gpio_template;
588 nmk_chip->parent_irq = irq;
589 spin_lock_init(&nmk_chip->lock);
590
591 chip = &nmk_chip->chip;
592 chip->base = pdata->first_gpio;
593 chip->label = pdata->name;
594 chip->dev = &dev->dev;
595 chip->owner = THIS_MODULE;
596
597 ret = gpiochip_add(&nmk_chip->chip);
598 if (ret)
599 goto out_free;
600
601 platform_set_drvdata(dev, nmk_chip);
602
603 nmk_gpio_init_irq(nmk_chip);
604
605 dev_info(&dev->dev, "Bits %i-%i at address %p\n",
606 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
607 return 0;
608
609out_free:
610 kfree(nmk_chip);
611out_clk:
612 clk_disable(clk);
613 clk_put(clk);
614out_release:
615 release_mem_region(res->start, resource_size(res));
616out:
617 dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
618 pdata->first_gpio, pdata->first_gpio+31);
619 return ret;
620}
621
622static struct platform_driver nmk_gpio_driver = {
623 .driver = {
624 .owner = THIS_MODULE,
625 .name = "gpio",
626 },
627 .probe = nmk_gpio_probe,
628 .suspend = NULL, /* to be done */
629 .resume = NULL,
630};
631
632static int __init nmk_gpio_init(void)
633{
634 return platform_driver_register(&nmk_gpio_driver);
635}
636
637core_initcall(nmk_gpio_init);
638
639MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
640MODULE_DESCRIPTION("Nomadik GPIO Driver");
641MODULE_LICENSE("GPL");
642
643
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
index aba355101f49..d5d7e651269c 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -65,7 +65,9 @@ enum nmk_gpio_pull {
65/* Sleep mode */ 65/* Sleep mode */
66enum nmk_gpio_slpm { 66enum nmk_gpio_slpm {
67 NMK_GPIO_SLPM_INPUT, 67 NMK_GPIO_SLPM_INPUT,
68 NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
68 NMK_GPIO_SLPM_NOCHANGE, 69 NMK_GPIO_SLPM_NOCHANGE,
70 NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
69}; 71};
70 72
71extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); 73extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
@@ -73,6 +75,11 @@ extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
73extern int nmk_gpio_set_mode(int gpio, int gpio_mode); 75extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
74extern int nmk_gpio_get_mode(int gpio); 76extern int nmk_gpio_get_mode(int gpio);
75 77
78extern void nmk_gpio_wakeups_suspend(void);
79extern void nmk_gpio_wakeups_resume(void);
80
81extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
82
76/* 83/*
77 * Platform data to register a block: only the initial gpio/irq number. 84 * Platform data to register a block: only the initial gpio/irq number.
78 */ 85 */
@@ -80,6 +87,10 @@ struct nmk_gpio_platform_data {
80 char *name; 87 char *name;
81 int first_gpio; 88 int first_gpio;
82 int first_irq; 89 int first_irq;
90 int num_gpio;
91 u32 (*get_secondary_status)(unsigned int bank);
92 void (*set_ioforce)(bool enable);
93 bool supports_sleepmode;
83}; 94};
84 95
85#endif /* __ASM_PLAT_GPIO_H */ 96#endif /* __ASM_PLAT_GPIO_H */
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h
index 1621db67a53d..8ba70ffc31ec 100644
--- a/arch/arm/plat-nomadik/include/plat/i2c.h
+++ b/arch/arm/plat-nomadik/include/plat/i2c.h
@@ -11,8 +11,8 @@
11enum i2c_freq_mode { 11enum i2c_freq_mode {
12 I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */ 12 I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
13 I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */ 13 I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
14 I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
14 I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */ 15 I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
15 I2C_FREQ_MODE_HIGH_SPEED /* up to 3.4 Mb/s */
16}; 16};
17 17
18/** 18/**
@@ -24,13 +24,15 @@ enum i2c_freq_mode {
24 * to the values of 14, 6, 2 for a 48 MHz i2c clk 24 * to the values of 14, 6, 2 for a 48 MHz i2c clk
25 * @tft: Tx FIFO Threshold in bytes 25 * @tft: Tx FIFO Threshold in bytes
26 * @rft: Rx FIFO Threshold in bytes 26 * @rft: Rx FIFO Threshold in bytes
27 * @timeout Slave response timeout(ms)
27 * @sm: speed mode 28 * @sm: speed mode
28 */ 29 */
29struct nmk_i2c_controller { 30struct nmk_i2c_controller {
30 unsigned long clk_freq; 31 unsigned long clk_freq;
31 unsigned short slsu; 32 unsigned short slsu;
32 unsigned char tft; 33 unsigned char tft;
33 unsigned char rft; 34 unsigned char rft;
35 int timeout;
34 enum i2c_freq_mode sm; 36 enum i2c_freq_mode sm;
35}; 37};
36 38
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 7eed11c1038d..05a3936ae6d1 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -19,12 +19,22 @@
19 * bit 9..10 - Alternate Function Selection 19 * bit 9..10 - Alternate Function Selection
20 * bit 11..12 - Pull up/down state 20 * bit 11..12 - Pull up/down state
21 * bit 13 - Sleep mode behaviour 21 * bit 13 - Sleep mode behaviour
22 * bit 14 - Direction
23 * bit 15 - Value (if output)
24 * bit 16..18 - SLPM pull up/down state
25 * bit 19..20 - SLPM direction
26 * bit 21..22 - SLPM Value (if output)
22 * 27 *
23 * to facilitate the definition, the following macros are provided 28 * to facilitate the definition, the following macros are provided
24 * 29 *
25 * PIN_CFG_DEFAULT - default config (0): 30 * PIN_CFG_DEFAULT - default config (0):
26 * pull up/down = disabled 31 * pull up/down = disabled
27 * sleep mode = input 32 * sleep mode = input/wakeup
33 * direction = input
34 * value = low
35 * SLPM direction = same as normal
36 * SLPM pull = same as normal
37 * SLPM value = same as normal
28 * 38 *
29 * PIN_CFG - default config with alternate function 39 * PIN_CFG - default config with alternate function
30 * PIN_CFG_PULL - default config with alternate function and pull up/down 40 * PIN_CFG_PULL - default config with alternate function and pull up/down
@@ -53,20 +63,82 @@ typedef unsigned long pin_cfg_t;
53#define PIN_SLPM_SHIFT 13 63#define PIN_SLPM_SHIFT 13
54#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) 64#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
55#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) 65#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
56#define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) 66#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
57#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) 67#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
68/* These two replace the above in DB8500v2+ */
69#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
70#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
58 71
59#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) 72#define PIN_DIR_SHIFT 14
73#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
74#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
75#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
76#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
77
78#define PIN_VAL_SHIFT 15
79#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
80#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
81#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
82#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
83
84#define PIN_SLPM_PULL_SHIFT 16
85#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
86#define PIN_SLPM_PULL(x) \
87 (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
88#define PIN_SLPM_PULL_NONE \
89 ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
90#define PIN_SLPM_PULL_UP \
91 ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
92#define PIN_SLPM_PULL_DOWN \
93 ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
94
95#define PIN_SLPM_DIR_SHIFT 19
96#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
97#define PIN_SLPM_DIR(x) \
98 (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
99#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
100#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
101
102#define PIN_SLPM_VAL_SHIFT 21
103#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
104#define PIN_SLPM_VAL(x) \
105 (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
106#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
107#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
108
109/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
110#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
111#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
112#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
113#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
114#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
115
116#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
117#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
118#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
119#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
120#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
121
122#define PIN_CFG_DEFAULT (0)
60 123
61#define PIN_CFG(num, alt) \ 124#define PIN_CFG(num, alt) \
62 (PIN_CFG_DEFAULT |\ 125 (PIN_CFG_DEFAULT |\
63 (PIN_NUM(num) | PIN_##alt)) 126 (PIN_NUM(num) | PIN_##alt))
64 127
128#define PIN_CFG_INPUT(num, alt, pull) \
129 (PIN_CFG_DEFAULT |\
130 (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
131
132#define PIN_CFG_OUTPUT(num, alt, val) \
133 (PIN_CFG_DEFAULT |\
134 (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
135
65#define PIN_CFG_PULL(num, alt, pull) \ 136#define PIN_CFG_PULL(num, alt, pull) \
66 ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ 137 ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
67 (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) 138 (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
68 139
69extern int nmk_config_pin(pin_cfg_t cfg); 140extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
70extern int nmk_config_pins(pin_cfg_t *cfgs, int num); 141extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
142extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
71 143
72#endif 144#endif
diff --git a/arch/arm/plat-nomadik/include/plat/ske.h b/arch/arm/plat-nomadik/include/plat/ske.h
new file mode 100644
index 000000000000..31382fbc07dc
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/ske.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 * Author: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
6 *
7 * ux500 Scroll key and Keypad Encoder (SKE) header
8 */
9
10#ifndef __SKE_H
11#define __SKE_H
12
13#include <linux/input/matrix_keypad.h>
14
15/* register definitions for SKE peripheral */
16#define SKE_CR 0x00
17#define SKE_VAL0 0x04
18#define SKE_VAL1 0x08
19#define SKE_DBCR 0x0C
20#define SKE_IMSC 0x10
21#define SKE_RIS 0x14
22#define SKE_MIS 0x18
23#define SKE_ICR 0x1C
24
25/*
26 * Keypad module
27 */
28
29/**
30 * struct keypad_platform_data - structure for platform specific data
31 * @init: pointer to keypad init function
32 * @exit: pointer to keypad deinitialisation function
33 * @keymap_data: matrix scan code table for keycodes
34 * @krow: maximum number of rows
35 * @kcol: maximum number of columns
36 * @debounce_ms: platform specific debounce time
37 * @no_autorepeat: flag for auto repetition
38 * @wakeup_enable: allow waking up the system
39 */
40struct ske_keypad_platform_data {
41 int (*init)(void);
42 int (*exit)(void);
43 const struct matrix_keymap_data *keymap_data;
44 u8 krow;
45 u8 kcol;
46 u8 debounce_ms;
47 bool no_autorepeat;
48 bool wakeup_enable;
49};
50#endif /*__SKE_KPD_H*/
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
index 5fbde4b8dc12..c44886062f8e 100644
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -1,10 +1,8 @@
1/* 1/*
2 * arch/arm/plat-nomadik/include/plat/ste_dma40.h 2 * Copyright (C) ST-Ericsson SA 2007-2010
3 * 3 * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson
4 * Copyright (C) ST-Ericsson 2007-2010 4 * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
5 * License terms: GNU General Public License (GPL) version 2 5 * License terms: GNU General Public License (GPL) version 2
6 * Author: Per Friden <per.friden@stericsson.com>
7 * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
8 */ 6 */
9 7
10 8
@@ -14,43 +12,33 @@
14#include <linux/dmaengine.h> 12#include <linux/dmaengine.h>
15#include <linux/workqueue.h> 13#include <linux/workqueue.h>
16#include <linux/interrupt.h> 14#include <linux/interrupt.h>
17#include <linux/dmaengine.h> 15
16/*
17 * Maxium size for a single dma descriptor
18 * Size is limited to 16 bits.
19 * Size is in the units of addr-widths (1,2,4,8 bytes)
20 * Larger transfers will be split up to multiple linked desc
21 */
22#define STEDMA40_MAX_SEG_SIZE 0xFFFF
18 23
19/* dev types for memcpy */ 24/* dev types for memcpy */
20#define STEDMA40_DEV_DST_MEMORY (-1) 25#define STEDMA40_DEV_DST_MEMORY (-1)
21#define STEDMA40_DEV_SRC_MEMORY (-1) 26#define STEDMA40_DEV_SRC_MEMORY (-1)
22 27
23/* 28enum stedma40_mode {
24 * Description of bitfields of channel_type variable is available in 29 STEDMA40_MODE_LOGICAL = 0,
25 * the info structure. 30 STEDMA40_MODE_PHYSICAL,
26 */ 31 STEDMA40_MODE_OPERATION,
32};
27 33
28/* Priority */ 34enum stedma40_mode_opt {
29#define STEDMA40_INFO_PRIO_TYPE_POS 2 35 STEDMA40_PCHAN_BASIC_MODE = 0,
30#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS) 36 STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0,
31#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS) 37 STEDMA40_PCHAN_MODULO_MODE,
32 38 STEDMA40_PCHAN_DOUBLE_DST_MODE,
33/* Mode */ 39 STEDMA40_LCHAN_SRC_PHY_DST_LOG,
34#define STEDMA40_INFO_CH_MODE_TYPE_POS 6 40 STEDMA40_LCHAN_SRC_LOG_DST_PHY,
35#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS) 41};
36#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS)
37#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS)
38
39/* Mode options */
40#define STEDMA40_INFO_CH_MODE_OPT_POS 8
41#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
42#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
43#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
44#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
45#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
46#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
47
48/* Interrupt */
49#define STEDMA40_INFO_TIM_POS 10
50#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS)
51#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS)
52
53/* End of channel_type configuration */
54 42
55#define STEDMA40_ESIZE_8_BIT 0x0 43#define STEDMA40_ESIZE_8_BIT 0x0
56#define STEDMA40_ESIZE_16_BIT 0x1 44#define STEDMA40_ESIZE_16_BIT 0x1
@@ -73,16 +61,14 @@
73#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 61#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8
74#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 62#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16
75 63
64/* Maximum number of possible physical channels */
65#define STEDMA40_MAX_PHYS 32
66
76enum stedma40_flow_ctrl { 67enum stedma40_flow_ctrl {
77 STEDMA40_NO_FLOW_CTRL, 68 STEDMA40_NO_FLOW_CTRL,
78 STEDMA40_FLOW_CTRL, 69 STEDMA40_FLOW_CTRL,
79}; 70};
80 71
81enum stedma40_endianess {
82 STEDMA40_LITTLE_ENDIAN,
83 STEDMA40_BIG_ENDIAN
84};
85
86enum stedma40_periph_data_width { 72enum stedma40_periph_data_width {
87 STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, 73 STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
88 STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, 74 STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
@@ -90,15 +76,8 @@ enum stedma40_periph_data_width {
90 STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT 76 STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT
91}; 77};
92 78
93struct stedma40_half_channel_info {
94 enum stedma40_endianess endianess;
95 enum stedma40_periph_data_width data_width;
96 int psize;
97 enum stedma40_flow_ctrl flow_ctrl;
98};
99
100enum stedma40_xfer_dir { 79enum stedma40_xfer_dir {
101 STEDMA40_MEM_TO_MEM, 80 STEDMA40_MEM_TO_MEM = 1,
102 STEDMA40_MEM_TO_PERIPH, 81 STEDMA40_MEM_TO_PERIPH,
103 STEDMA40_PERIPH_TO_MEM, 82 STEDMA40_PERIPH_TO_MEM,
104 STEDMA40_PERIPH_TO_PERIPH 83 STEDMA40_PERIPH_TO_PERIPH
@@ -106,18 +85,33 @@ enum stedma40_xfer_dir {
106 85
107 86
108/** 87/**
88 * struct stedma40_chan_cfg - dst/src channel configuration
89 *
90 * @big_endian: true if the src/dst should be read as big endian
91 * @data_width: Data width of the src/dst hardware
92 * @p_size: Burst size
93 * @flow_ctrl: Flow control on/off.
94 */
95struct stedma40_half_channel_info {
96 bool big_endian;
97 enum stedma40_periph_data_width data_width;
98 int psize;
99 enum stedma40_flow_ctrl flow_ctrl;
100};
101
102/**
109 * struct stedma40_chan_cfg - Structure to be filled by client drivers. 103 * struct stedma40_chan_cfg - Structure to be filled by client drivers.
110 * 104 *
111 * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH 105 * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
112 * @channel_type: priority, mode, mode options and interrupt configuration. 106 * @high_priority: true if high-priority
107 * @realtime: true if realtime mode is to be enabled. Only available on DMA40
108 * version 3+, i.e DB8500v2+
109 * @mode: channel mode: physical, logical, or operation
110 * @mode_opt: options for the chosen channel mode
113 * @src_dev_type: Src device type 111 * @src_dev_type: Src device type
114 * @dst_dev_type: Dst device type 112 * @dst_dev_type: Dst device type
115 * @src_info: Parameters for dst half channel 113 * @src_info: Parameters for dst half channel
116 * @dst_info: Parameters for dst half channel 114 * @dst_info: Parameters for dst half channel
117 * @pre_transfer_data: Data to be passed on to the pre_transfer() function.
118 * @pre_transfer: Callback used if needed before preparation of transfer.
119 * Only called if device is set. size of bytes to transfer
120 * (in case of multiple element transfer size is size of the first element).
121 * 115 *
122 * 116 *
123 * This structure has to be filled by the client drivers. 117 * This structure has to be filled by the client drivers.
@@ -126,15 +120,14 @@ enum stedma40_xfer_dir {
126 */ 120 */
127struct stedma40_chan_cfg { 121struct stedma40_chan_cfg {
128 enum stedma40_xfer_dir dir; 122 enum stedma40_xfer_dir dir;
129 unsigned int channel_type; 123 bool high_priority;
124 bool realtime;
125 enum stedma40_mode mode;
126 enum stedma40_mode_opt mode_opt;
130 int src_dev_type; 127 int src_dev_type;
131 int dst_dev_type; 128 int dst_dev_type;
132 struct stedma40_half_channel_info src_info; 129 struct stedma40_half_channel_info src_info;
133 struct stedma40_half_channel_info dst_info; 130 struct stedma40_half_channel_info dst_info;
134 void *pre_transfer_data;
135 int (*pre_transfer) (struct dma_chan *chan,
136 void *data,
137 int size);
138}; 131};
139 132
140/** 133/**
@@ -147,7 +140,6 @@ struct stedma40_chan_cfg {
147 * @memcpy_len: length of memcpy 140 * @memcpy_len: length of memcpy
148 * @memcpy_conf_phy: default configuration of physical channel memcpy 141 * @memcpy_conf_phy: default configuration of physical channel memcpy
149 * @memcpy_conf_log: default configuration of logical channel memcpy 142 * @memcpy_conf_log: default configuration of logical channel memcpy
150 * @llis_per_log: number of max linked list items per logical channel
151 * @disabled_channels: A vector, ending with -1, that marks physical channels 143 * @disabled_channels: A vector, ending with -1, that marks physical channels
152 * that are for different reasons not available for the driver. 144 * that are for different reasons not available for the driver.
153 */ 145 */
@@ -159,23 +151,10 @@ struct stedma40_platform_data {
159 u32 memcpy_len; 151 u32 memcpy_len;
160 struct stedma40_chan_cfg *memcpy_conf_phy; 152 struct stedma40_chan_cfg *memcpy_conf_phy;
161 struct stedma40_chan_cfg *memcpy_conf_log; 153 struct stedma40_chan_cfg *memcpy_conf_log;
162 unsigned int llis_per_log; 154 int disabled_channels[STEDMA40_MAX_PHYS];
163 int disabled_channels[8];
164}; 155};
165 156
166/** 157#ifdef CONFIG_STE_DMA40
167 * setdma40_set_psize() - Used for changing the package size of an
168 * already configured dma channel.
169 *
170 * @chan: dmaengine handle
171 * @src_psize: new package side for src. (STEDMA40_PSIZE*)
172 * @src_psize: new package side for dst. (STEDMA40_PSIZE*)
173 *
174 * returns 0 on ok, otherwise negative error number.
175 */
176int stedma40_set_psize(struct dma_chan *chan,
177 int src_psize,
178 int dst_psize);
179 158
180/** 159/**
181 * stedma40_filter() - Provides stedma40_chan_cfg to the 160 * stedma40_filter() - Provides stedma40_chan_cfg to the
@@ -193,25 +172,6 @@ int stedma40_set_psize(struct dma_chan *chan,
193bool stedma40_filter(struct dma_chan *chan, void *data); 172bool stedma40_filter(struct dma_chan *chan, void *data);
194 173
195/** 174/**
196 * stedma40_memcpy_sg() - extension of the dma framework, memcpy to/from
197 * scattergatter lists.
198 *
199 * @chan: dmaengine handle
200 * @sgl_dst: Destination scatter list
201 * @sgl_src: Source scatter list
202 * @sgl_len: The length of each scatterlist. Both lists must be of equal length
203 * and each element must match the corresponding element in the other scatter
204 * list.
205 * @flags: is actually enum dma_ctrl_flags. See dmaengine.h
206 */
207
208struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan,
209 struct scatterlist *sgl_dst,
210 struct scatterlist *sgl_src,
211 unsigned int sgl_len,
212 unsigned long flags);
213
214/**
215 * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave 175 * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave
216 * (=device) 176 * (=device)
217 * 177 *
@@ -238,4 +198,21 @@ dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
238 direction, flags); 198 direction, flags);
239} 199}
240 200
201#else
202static inline bool stedma40_filter(struct dma_chan *chan, void *data)
203{
204 return false;
205}
206
207static inline struct
208dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
209 dma_addr_t addr,
210 unsigned int size,
211 enum dma_data_direction direction,
212 unsigned long flags)
213{
214 return NULL;
215}
216#endif
217
241#endif 218#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index aedf9c1d645e..ef74e157a9d5 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2008 STMicroelectronics 4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2010 Alessandro Rubini 5 * Copyright (C) 2010 Alessandro Rubini
6 * Copyright (C) 2010 Linus Walleij for ST-Ericsson
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as 9 * it under the terms of the GNU General Public License version 2, as
@@ -16,48 +17,36 @@
16#include <linux/clk.h> 17#include <linux/clk.h>
17#include <linux/jiffies.h> 18#include <linux/jiffies.h>
18#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/sched.h>
19#include <asm/mach/time.h> 21#include <asm/mach/time.h>
22#include <asm/sched_clock.h>
20 23
21#include <plat/mtu.h> 24#include <plat/mtu.h>
22 25
23void __iomem *mtu_base; /* ssigned by machine code */ 26void __iomem *mtu_base; /* Assigned by machine code */
24 27
25/* 28/*
26 * Kernel assumes that sched_clock can be called early 29 * Override the global weak sched_clock symbol with this
27 * but the MTU may not yet be initialized. 30 * local implementation which uses the clocksource to get some
31 * better resolution when scheduling the kernel.
28 */ 32 */
29static cycle_t nmdk_read_timer_dummy(struct clocksource *cs) 33static DEFINE_CLOCK_DATA(cd);
30{
31 return 0;
32}
33 34
34/* clocksource: MTU decrements, so we negate the value being read. */ 35unsigned long long notrace sched_clock(void)
35static cycle_t nmdk_read_timer(struct clocksource *cs)
36{ 36{
37 return -readl(mtu_base + MTU_VAL(0)); 37 u32 cyc;
38}
39 38
40static struct clocksource nmdk_clksrc = { 39 if (unlikely(!mtu_base))
41 .name = "mtu_0", 40 return 0;
42 .rating = 200,
43 .read = nmdk_read_timer_dummy,
44 .mask = CLOCKSOURCE_MASK(32),
45 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
46};
47 41
48/* 42 cyc = -readl(mtu_base + MTU_VAL(0));
49 * Override the global weak sched_clock symbol with this 43 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
50 * local implementation which uses the clocksource to get some 44}
51 * better resolution when scheduling the kernel. We accept that 45
52 * this wraps around for now, since it is just a relative time 46static void notrace nomadik_update_sched_clock(void)
53 * stamp. (Inspired by OMAP implementation.)
54 */
55unsigned long long notrace sched_clock(void)
56{ 47{
57 return clocksource_cyc2ns(nmdk_clksrc.read( 48 u32 cyc = -readl(mtu_base + MTU_VAL(0));
58 &nmdk_clksrc), 49 update_sched_clock(&cd, cyc, (u32)~0);
59 nmdk_clksrc.mult,
60 nmdk_clksrc.shift);
61} 50}
62 51
63/* Clockevent device: use one-shot mode */ 52/* Clockevent device: use one-shot mode */
@@ -153,7 +142,6 @@ void __init nmdk_timer_init(void)
153 } else { 142 } else {
154 cr |= MTU_CRn_PRESCALE_1; 143 cr |= MTU_CRn_PRESCALE_1;
155 } 144 }
156 clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
157 145
158 /* Timer 0 is the free running clocksource */ 146 /* Timer 0 is the free running clocksource */
159 writel(cr, mtu_base + MTU_CR(0)); 147 writel(cr, mtu_base + MTU_CR(0));
@@ -161,12 +149,12 @@ void __init nmdk_timer_init(void)
161 writel(0, mtu_base + MTU_BGLR(0)); 149 writel(0, mtu_base + MTU_BGLR(0));
162 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); 150 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
163 151
164 /* Now the scheduling clock is ready */ 152 if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
165 nmdk_clksrc.read = nmdk_read_timer; 153 rate, 200, 32, clocksource_mmio_readl_down))
166
167 if (clocksource_register(&nmdk_clksrc))
168 pr_err("timer: failed to initialize clock source %s\n", 154 pr_err("timer: failed to initialize clock source %s\n",
169 nmdk_clksrc.name); 155 "mtu_0");
156
157 init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
170 158
171 /* Timer 1 is used for events */ 159 /* Timer 1 is used for events */
172 160