aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/gpio.c74
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h2
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h36
-rw-r--r--arch/arm/plat-nomadik/timer.c33
4 files changed, 107 insertions, 38 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 977c8f9a07a2..85e6fd212a41 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -102,6 +102,22 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
102 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); 102 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
103} 103}
104 104
105static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
106 unsigned offset, int val)
107{
108 if (val)
109 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
110 else
111 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
112}
113
114static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
115 unsigned offset, int val)
116{
117 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
118 __nmk_gpio_set_output(nmk_chip, offset, val);
119}
120
105static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, 121static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
106 pin_cfg_t cfg) 122 pin_cfg_t cfg)
107{ 123{
@@ -118,20 +134,29 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
118 [3] /* illegal */ = "??" 134 [3] /* illegal */ = "??"
119 }; 135 };
120 static const char *slpmnames[] = { 136 static const char *slpmnames[] = {
121 [NMK_GPIO_SLPM_INPUT] = "input", 137 [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
122 [NMK_GPIO_SLPM_NOCHANGE] = "no-change", 138 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
123 }; 139 };
124 140
125 int pin = PIN_NUM(cfg); 141 int pin = PIN_NUM(cfg);
126 int pull = PIN_PULL(cfg); 142 int pull = PIN_PULL(cfg);
127 int af = PIN_ALT(cfg); 143 int af = PIN_ALT(cfg);
128 int slpm = PIN_SLPM(cfg); 144 int slpm = PIN_SLPM(cfg);
145 int output = PIN_DIR(cfg);
146 int val = PIN_VAL(cfg);
129 147
130 dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n", 148 dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n",
131 pin, afnames[af], pullnames[pull], slpmnames[slpm]); 149 pin, afnames[af], pullnames[pull], slpmnames[slpm],
150 output ? "output " : "input",
151 output ? (val ? "high" : "low") : "");
152
153 if (output)
154 __nmk_gpio_make_output(nmk_chip, offset, val);
155 else {
156 __nmk_gpio_make_input(nmk_chip, offset);
157 __nmk_gpio_set_pull(nmk_chip, offset, pull);
158 }
132 159
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); 160 __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
136 __nmk_gpio_set_mode(nmk_chip, offset, af); 161 __nmk_gpio_set_mode(nmk_chip, offset, af);
137} 162}
@@ -200,6 +225,10 @@ EXPORT_SYMBOL(nmk_config_pins);
200 * changed to an input (with pullup/down enabled) in sleep and deep sleep. If 225 * 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 226 * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
202 * configured even when in sleep and deep sleep. 227 * configured even when in sleep and deep sleep.
228 *
229 * On DB8500v2 onwards, this setting loses the previous meaning and instead
230 * indicates if wakeup detection is enabled on the pin. Note that
231 * enable_irq_wake() will automatically enable wakeup detection.
203 */ 232 */
204int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) 233int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
205{ 234{
@@ -367,7 +396,27 @@ static void nmk_gpio_irq_unmask(unsigned int irq)
367 396
368static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) 397static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
369{ 398{
370 return nmk_gpio_irq_modify(irq, WAKE, on); 399 struct nmk_gpio_chip *nmk_chip;
400 unsigned long flags;
401 int gpio;
402
403 gpio = NOMADIK_IRQ_TO_GPIO(irq);
404 nmk_chip = get_irq_chip_data(irq);
405 if (!nmk_chip)
406 return -EINVAL;
407
408 spin_lock_irqsave(&nmk_chip->lock, flags);
409#ifdef CONFIG_ARCH_U8500
410 if (cpu_is_u8500v2()) {
411 __nmk_gpio_set_slpm(nmk_chip, gpio,
412 on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
413 : NMK_GPIO_SLPM_WAKEUP_DISABLE);
414 }
415#endif
416 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
417 spin_unlock_irqrestore(&nmk_chip->lock, flags);
418
419 return 0;
371} 420}
372 421
373static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) 422static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
@@ -495,12 +544,8 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
495{ 544{
496 struct nmk_gpio_chip *nmk_chip = 545 struct nmk_gpio_chip *nmk_chip =
497 container_of(chip, struct nmk_gpio_chip, chip); 546 container_of(chip, struct nmk_gpio_chip, chip);
498 u32 bit = 1 << offset;
499 547
500 if (val) 548 __nmk_gpio_set_output(nmk_chip, offset, val);
501 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
502 else
503 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
504} 549}
505 550
506static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, 551static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
@@ -509,8 +554,7 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
509 struct nmk_gpio_chip *nmk_chip = 554 struct nmk_gpio_chip *nmk_chip =
510 container_of(chip, struct nmk_gpio_chip, chip); 555 container_of(chip, struct nmk_gpio_chip, chip);
511 556
512 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); 557 __nmk_gpio_make_output(nmk_chip, offset, val);
513 nmk_gpio_set_output(chip, offset, val);
514 558
515 return 0; 559 return 0;
516} 560}
@@ -534,7 +578,7 @@ static struct gpio_chip nmk_gpio_template = {
534 .can_sleep = 0, 578 .can_sleep = 0,
535}; 579};
536 580
537static int __init nmk_gpio_probe(struct platform_device *dev) 581static int __devinit nmk_gpio_probe(struct platform_device *dev)
538{ 582{
539 struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; 583 struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
540 struct nmk_gpio_chip *nmk_chip; 584 struct nmk_gpio_chip *nmk_chip;
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
index aba355101f49..67b113d639d8 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);
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 7eed11c1038d..8c5ae3f2acf8 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -19,12 +19,16 @@
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 - (sleep mode) Direction
23 * bit 15 - (sleep mode) Value (if output)
22 * 24 *
23 * to facilitate the definition, the following macros are provided 25 * to facilitate the definition, the following macros are provided
24 * 26 *
25 * PIN_CFG_DEFAULT - default config (0): 27 * PIN_CFG_DEFAULT - default config (0):
26 * pull up/down = disabled 28 * pull up/down = disabled
27 * sleep mode = input 29 * sleep mode = input/wakeup
30 * (sleep mode) direction = input
31 * (sleep mode) value = low
28 * 32 *
29 * PIN_CFG - default config with alternate function 33 * PIN_CFG - default config with alternate function
30 * PIN_CFG_PULL - default config with alternate function and pull up/down 34 * PIN_CFG_PULL - default config with alternate function and pull up/down
@@ -53,8 +57,36 @@ typedef unsigned long pin_cfg_t;
53#define PIN_SLPM_SHIFT 13 57#define PIN_SLPM_SHIFT 13
54#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) 58#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
55#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) 59#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
56#define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) 60#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
57#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) 61#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
62/* These two replace the above in DB8500v2+ */
63#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
64#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
65
66#define PIN_DIR_SHIFT 14
67#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
68#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
69#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
70#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
71
72#define PIN_VAL_SHIFT 15
73#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
74#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
75#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
76#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
77
78/* Shortcuts. Use these instead of separate DIR and VAL. */
79#define PIN_INPUT PIN_DIR_INPUT
80#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
81#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
82
83/*
84 * These are the same as the ones above, but should make more sense to the
85 * reader when seen along with a setting a pin to AF mode.
86 */
87#define PIN_SLPM_INPUT PIN_INPUT
88#define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW
89#define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH
58 90
59#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) 91#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
60 92
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index ea3ca86c5283..aedf9c1d645e 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-nomadik/timer.c 2 * linux/arch/arm/plat-nomadik/timer.c
3 * 3 *
4 * Copyright (C) 2008 STMicroelectronics 4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2010 Alessandro Rubini 5 * Copyright (C) 2010 Alessandro Rubini
@@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode,
75 cr = readl(mtu_base + MTU_CR(1)); 75 cr = readl(mtu_base + MTU_CR(1));
76 writel(0, mtu_base + MTU_LR(1)); 76 writel(0, mtu_base + MTU_LR(1));
77 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); 77 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
78 writel(0x2, mtu_base + MTU_IMSC); 78 writel(1 << 1, mtu_base + MTU_IMSC);
79 break; 79 break;
80 case CLOCK_EVT_MODE_SHUTDOWN: 80 case CLOCK_EVT_MODE_SHUTDOWN:
81 case CLOCK_EVT_MODE_UNUSED: 81 case CLOCK_EVT_MODE_UNUSED:
@@ -131,25 +131,23 @@ void __init nmdk_timer_init(void)
131{ 131{
132 unsigned long rate; 132 unsigned long rate;
133 struct clk *clk0; 133 struct clk *clk0;
134 struct clk *clk1; 134 u32 cr = MTU_CRn_32BITS;
135 u32 cr;
136 135
137 clk0 = clk_get_sys("mtu0", NULL); 136 clk0 = clk_get_sys("mtu0", NULL);
138 BUG_ON(IS_ERR(clk0)); 137 BUG_ON(IS_ERR(clk0));
139 138
140 clk1 = clk_get_sys("mtu1", NULL);
141 BUG_ON(IS_ERR(clk1));
142
143 clk_enable(clk0); 139 clk_enable(clk0);
144 clk_enable(clk1);
145 140
146 /* 141 /*
147 * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: 142 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
148 * use a divide-by-16 counter if it's more than 16MHz 143 * for ux500.
144 * Use a divide-by-16 counter if the tick rate is more than 32MHz.
145 * At 32 MHz, the timer (with 32 bit counter) can be programmed
146 * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer
147 * with 16 gives too low timer resolution.
149 */ 148 */
150 cr = MTU_CRn_32BITS;;
151 rate = clk_get_rate(clk0); 149 rate = clk_get_rate(clk0);
152 if (rate > 16 << 20) { 150 if (rate > 32000000) {
153 rate /= 16; 151 rate /= 16;
154 cr |= MTU_CRn_PRESCALE_16; 152 cr |= MTU_CRn_PRESCALE_16;
155 } else { 153 } else {
@@ -170,15 +168,8 @@ void __init nmdk_timer_init(void)
170 pr_err("timer: failed to initialize clock source %s\n", 168 pr_err("timer: failed to initialize clock source %s\n",
171 nmdk_clksrc.name); 169 nmdk_clksrc.name);
172 170
173 /* Timer 1 is used for events, fix according to rate */ 171 /* Timer 1 is used for events */
174 cr = MTU_CRn_32BITS; 172
175 rate = clk_get_rate(clk1);
176 if (rate > 16 << 20) {
177 rate /= 16;
178 cr |= MTU_CRn_PRESCALE_16;
179 } else {
180 cr |= MTU_CRn_PRESCALE_1;
181 }
182 clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); 173 clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
183 174
184 writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ 175 writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */