diff options
| author | Olof Johansson <olof@lixom.net> | 2014-01-02 14:58:30 -0500 |
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2014-01-02 14:58:30 -0500 |
| commit | c01f97387ea4fa2fd57a22d38f22bcfe364b1b6f (patch) | |
| tree | 061f8c30d69d454b2a2b4ec124222832bf37dc87 | |
| parent | 55e0b071892c9112ab49496e924f7310843afb67 (diff) | |
| parent | 6a79799d5654bb7800614e8b7a009252be7ff90e (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.dts | 6 | ||||
| -rw-r--r-- | arch/arm/mach-u300/regulator.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-u300/timer.c | 38 |
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 | |||
| 190 | static void __iomem *u300_timer_base; | 187 | static void __iomem *u300_timer_base; |
| 191 | 188 | ||
| 189 | struct 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; | |||
| 197 | static void u300_set_mode(enum clock_event_mode mode, | 199 | static 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 | 313 | static 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 */ |
| 310 | static 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 */ |
| 319 | static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) | 327 | static 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 | /* |
