aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-01-02 14:58:30 -0500
committerOlof Johansson <olof@lixom.net>2014-01-02 14:58:30 -0500
commitc01f97387ea4fa2fd57a22d38f22bcfe364b1b6f (patch)
tree061f8c30d69d454b2a2b4ec124222832bf37dc87
parent55e0b071892c9112ab49496e924f7310843afb67 (diff)
parent6a79799d5654bb7800614e8b7a009252be7ff90e (diff)
Merge tag 'u300-for-arm-soc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/fixes-non-critical
From Linus Walleij: Misc U300 development for the v3.14 series: - Timekeeping patch from Uwe. - DT 0x0 cleanup from Lee. - Return value check from Wei. * tag 'u300-for-arm-soc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson: ARM: u300: fix timekeeping when periodic mode is used ARM: u300: Remove '0x's from U300 DTS file ARM: u300: fix return value check in __u300_init_boardpower() Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--arch/arm/boot/dts/ste-u300.dts6
-rw-r--r--arch/arm/mach-u300/regulator.c4
-rw-r--r--arch/arm/mach-u300/timer.c38
3 files changed, 29 insertions, 19 deletions
diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts
index 8a1032c1ffc9..a9da4800daf0 100644
--- a/arch/arm/boot/dts/ste-u300.dts
+++ b/arch/arm/boot/dts/ste-u300.dts
@@ -307,7 +307,7 @@
307 clocks = <&i2c0_clk>; 307 clocks = <&i2c0_clk>;
308 #address-cells = <1>; 308 #address-cells = <1>;
309 #size-cells = <0>; 309 #size-cells = <0>;
310 ab3100: ab3100@0x48 { 310 ab3100: ab3100@48 {
311 compatible = "stericsson,ab3100"; 311 compatible = "stericsson,ab3100";
312 reg = <0x48>; 312 reg = <0x48>;
313 interrupt-parent = <&vica>; 313 interrupt-parent = <&vica>;
@@ -385,10 +385,10 @@
385 clocks = <&i2c1_clk>; 385 clocks = <&i2c1_clk>;
386 #address-cells = <1>; 386 #address-cells = <1>;
387 #size-cells = <0>; 387 #size-cells = <0>;
388 fwcam0: fwcam@0x10 { 388 fwcam0: fwcam@10 {
389 reg = <0x10>; 389 reg = <0x10>;
390 }; 390 };
391 fwcam1: fwcam@0x5d { 391 fwcam1: fwcam@5d {
392 reg = <0x5d>; 392 reg = <0x5d>;
393 }; 393 };
394 }; 394 };
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c
index bf40cd478fe9..0493a845b6bc 100644
--- a/arch/arm/mach-u300/regulator.c
+++ b/arch/arm/mach-u300/regulator.c
@@ -69,9 +69,9 @@ static int __init __u300_init_boardpower(struct platform_device *pdev)
69 return -ENODEV; 69 return -ENODEV;
70 } 70 }
71 regmap = syscon_node_to_regmap(syscon_np); 71 regmap = syscon_node_to_regmap(syscon_np);
72 if (!regmap) { 72 if (IS_ERR(regmap)) {
73 pr_crit("U300: could not locate syscon regmap\n"); 73 pr_crit("U300: could not locate syscon regmap\n");
74 return -ENODEV; 74 return PTR_ERR(regmap);
75 } 75 }
76 76
77 main_power_15 = regulator_get(&pdev->dev, "vana15"); 77 main_power_15 = regulator_get(&pdev->dev, "vana15");
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 9a5f9fb352ce..5226162fac69 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -184,11 +184,13 @@
184#define U300_TIMER_APP_CRC (0x100) 184#define U300_TIMER_APP_CRC (0x100)
185#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001) 185#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
186 186
187#define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
188#define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
189
190static void __iomem *u300_timer_base; 187static void __iomem *u300_timer_base;
191 188
189struct u300_clockevent_data {
190 struct clock_event_device cevd;
191 unsigned ticks_per_jiffy;
192};
193
192/* 194/*
193 * The u300_set_mode() function is always called first, if we 195 * The u300_set_mode() function is always called first, if we
194 * have oneshot timer active, the oneshot scheduling function 196 * have oneshot timer active, the oneshot scheduling function
@@ -197,6 +199,9 @@ static void __iomem *u300_timer_base;
197static void u300_set_mode(enum clock_event_mode mode, 199static void u300_set_mode(enum clock_event_mode mode,
198 struct clock_event_device *evt) 200 struct clock_event_device *evt)
199{ 201{
202 struct u300_clockevent_data *cevdata =
203 container_of(evt, struct u300_clockevent_data, cevd);
204
200 switch (mode) { 205 switch (mode) {
201 case CLOCK_EVT_MODE_PERIODIC: 206 case CLOCK_EVT_MODE_PERIODIC:
202 /* Disable interrupts on GPT1 */ 207 /* Disable interrupts on GPT1 */
@@ -209,7 +214,7 @@ static void u300_set_mode(enum clock_event_mode mode,
209 * Set the periodic mode to a certain number of ticks per 214 * Set the periodic mode to a certain number of ticks per
210 * jiffy. 215 * jiffy.
211 */ 216 */
212 writel(TICKS_PER_JIFFY, 217 writel(cevdata->ticks_per_jiffy,
213 u300_timer_base + U300_TIMER_APP_GPT1TC); 218 u300_timer_base + U300_TIMER_APP_GPT1TC);
214 /* 219 /*
215 * Set continuous mode, so the timer keeps triggering 220 * Set continuous mode, so the timer keeps triggering
@@ -305,20 +310,23 @@ static int u300_set_next_event(unsigned long cycles,
305 return 0; 310 return 0;
306} 311}
307 312
308 313static struct u300_clockevent_data u300_clockevent_data = {
309/* Use general purpose timer 1 as clock event */ 314 /* Use general purpose timer 1 as clock event */
310static struct clock_event_device clockevent_u300_1mhz = { 315 .cevd = {
311 .name = "GPT1", 316 .name = "GPT1",
312 .rating = 300, /* Reasonably fast and accurate clock event */ 317 /* Reasonably fast and accurate clock event */
313 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 318 .rating = 300,
314 .set_next_event = u300_set_next_event, 319 .features = CLOCK_EVT_FEAT_PERIODIC |
315 .set_mode = u300_set_mode, 320 CLOCK_EVT_FEAT_ONESHOT,
321 .set_next_event = u300_set_next_event,
322 .set_mode = u300_set_mode,
323 },
316}; 324};
317 325
318/* Clock event timer interrupt handler */ 326/* Clock event timer interrupt handler */
319static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) 327static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
320{ 328{
321 struct clock_event_device *evt = &clockevent_u300_1mhz; 329 struct clock_event_device *evt = &u300_clockevent_data.cevd;
322 /* ACK/Clear timer IRQ for the APP GPT1 Timer */ 330 /* ACK/Clear timer IRQ for the APP GPT1 Timer */
323 331
324 writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, 332 writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
@@ -379,6 +387,8 @@ static void __init u300_timer_init_of(struct device_node *np)
379 clk_prepare_enable(clk); 387 clk_prepare_enable(clk);
380 rate = clk_get_rate(clk); 388 rate = clk_get_rate(clk);
381 389
390 u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
391
382 setup_sched_clock(u300_read_sched_clock, 32, rate); 392 setup_sched_clock(u300_read_sched_clock, 32, rate);
383 393
384 u300_delay_timer.read_current_timer = &u300_read_current_timer; 394 u300_delay_timer.read_current_timer = &u300_read_current_timer;
@@ -428,7 +438,7 @@ static void __init u300_timer_init_of(struct device_node *np)
428 pr_err("timer: failed to initialize U300 clock source\n"); 438 pr_err("timer: failed to initialize U300 clock source\n");
429 439
430 /* Configure and register the clockevent */ 440 /* Configure and register the clockevent */
431 clockevents_config_and_register(&clockevent_u300_1mhz, rate, 441 clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
432 1, 0xffffffff); 442 1, 0xffffffff);
433 443
434 /* 444 /*