Misc U300 development for the v3.14 series:
- Timekeeping patch from Uwe. - DT 0x0 cleanup from Lee. - Return value check from Wei. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) iQIcBAABAgAGBQJStAGjAAoJEEEQszewGV1zDj4QAJPcM7vFsgDSCGmSvaeS6NfF bqyLnTo8JVF0FCAbUTtWWYdA1s7fpcOXsQxm/R73UJ5/2m5vqCxJf2ldXuD0rkM2 sPvVH7lfMJb0JjZK/6D7xyUQwCmrl6UULztcVvK+2vEts+cZa/kasRSI4Ea6GLiA RpD3M3Bt8NGT6/WUfLGYPDGNKFk+nzix2lQ6yQnfZWf0zg5g/0tlsf9GPN7lJNgN QQ0SKSXZt9jMcn0L/q3rSrTRL7qCcAELkNea03WPbhyhmYUucYDsZ2NWgPdYbPaL 2HMV9xwy7pPfykM8W7BPwcMsHz6YIxOuQY0oeMapz2LX5vE98IZuN/aYRI1LGYKM weEHEao8vXpUhDGLBSPUbA6REVFg9HPhUm775F9wh65Bn4N1FfoR9W1FNwQxyELj kq1VW9oUxzEdTeITyqxJ+izxhObhGY12u5D1f4TxY8RAzYNE+Nd3RHNVl2wOCoJ/ 4wa8+atDSw1TVIRI0rExBupJZ4wN1bshrYda1qvmkGv8Mmn6HQZDri15xuZdUxyG SNrENOc3jd3uXQWCcKppnViM+10xsUdOx7yvze8obZbm9gjCyD1j4zYyqr9yGCkd f5r6hmG6a7cjaTmn24wSJiuvIqWHIzl1IjeOrSsWg8ct5AjdS4R+n2SCk5O7vUFU 2WWZlaOiZ7oKOyXWviji =cBuO -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
c01f97387e
3 changed files with 29 additions and 19 deletions
|
@ -307,7 +307,7 @@
|
||||||
clocks = <&i2c0_clk>;
|
clocks = <&i2c0_clk>;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
ab3100: ab3100@0x48 {
|
ab3100: ab3100@48 {
|
||||||
compatible = "stericsson,ab3100";
|
compatible = "stericsson,ab3100";
|
||||||
reg = <0x48>;
|
reg = <0x48>;
|
||||||
interrupt-parent = <&vica>;
|
interrupt-parent = <&vica>;
|
||||||
|
@ -385,10 +385,10 @@
|
||||||
clocks = <&i2c1_clk>;
|
clocks = <&i2c1_clk>;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
fwcam0: fwcam@0x10 {
|
fwcam0: fwcam@10 {
|
||||||
reg = <0x10>;
|
reg = <0x10>;
|
||||||
};
|
};
|
||||||
fwcam1: fwcam@0x5d {
|
fwcam1: fwcam@5d {
|
||||||
reg = <0x5d>;
|
reg = <0x5d>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,9 +69,9 @@ static int __init __u300_init_boardpower(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
regmap = syscon_node_to_regmap(syscon_np);
|
regmap = syscon_node_to_regmap(syscon_np);
|
||||||
if (!regmap) {
|
if (IS_ERR(regmap)) {
|
||||||
pr_crit("U300: could not locate syscon regmap\n");
|
pr_crit("U300: could not locate syscon regmap\n");
|
||||||
return -ENODEV;
|
return PTR_ERR(regmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
main_power_15 = regulator_get(&pdev->dev, "vana15");
|
main_power_15 = regulator_get(&pdev->dev, "vana15");
|
||||||
|
|
|
@ -184,11 +184,13 @@
|
||||||
#define U300_TIMER_APP_CRC (0x100)
|
#define U300_TIMER_APP_CRC (0x100)
|
||||||
#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
|
#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
|
||||||
|
|
||||||
#define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
|
|
||||||
#define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
|
|
||||||
|
|
||||||
static void __iomem *u300_timer_base;
|
static void __iomem *u300_timer_base;
|
||||||
|
|
||||||
|
struct u300_clockevent_data {
|
||||||
|
struct clock_event_device cevd;
|
||||||
|
unsigned ticks_per_jiffy;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The u300_set_mode() function is always called first, if we
|
* The u300_set_mode() function is always called first, if we
|
||||||
* have oneshot timer active, the oneshot scheduling function
|
* have oneshot timer active, the oneshot scheduling function
|
||||||
|
@ -197,6 +199,9 @@ static void __iomem *u300_timer_base;
|
||||||
static void u300_set_mode(enum clock_event_mode mode,
|
static void u300_set_mode(enum clock_event_mode mode,
|
||||||
struct clock_event_device *evt)
|
struct clock_event_device *evt)
|
||||||
{
|
{
|
||||||
|
struct u300_clockevent_data *cevdata =
|
||||||
|
container_of(evt, struct u300_clockevent_data, cevd);
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case CLOCK_EVT_MODE_PERIODIC:
|
case CLOCK_EVT_MODE_PERIODIC:
|
||||||
/* Disable interrupts on GPT1 */
|
/* Disable interrupts on GPT1 */
|
||||||
|
@ -209,7 +214,7 @@ static void u300_set_mode(enum clock_event_mode mode,
|
||||||
* Set the periodic mode to a certain number of ticks per
|
* Set the periodic mode to a certain number of ticks per
|
||||||
* jiffy.
|
* jiffy.
|
||||||
*/
|
*/
|
||||||
writel(TICKS_PER_JIFFY,
|
writel(cevdata->ticks_per_jiffy,
|
||||||
u300_timer_base + U300_TIMER_APP_GPT1TC);
|
u300_timer_base + U300_TIMER_APP_GPT1TC);
|
||||||
/*
|
/*
|
||||||
* Set continuous mode, so the timer keeps triggering
|
* Set continuous mode, so the timer keeps triggering
|
||||||
|
@ -305,20 +310,23 @@ static int u300_set_next_event(unsigned long cycles,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct u300_clockevent_data u300_clockevent_data = {
|
||||||
/* Use general purpose timer 1 as clock event */
|
/* Use general purpose timer 1 as clock event */
|
||||||
static struct clock_event_device clockevent_u300_1mhz = {
|
.cevd = {
|
||||||
.name = "GPT1",
|
.name = "GPT1",
|
||||||
.rating = 300, /* Reasonably fast and accurate clock event */
|
/* Reasonably fast and accurate clock event */
|
||||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
.rating = 300,
|
||||||
.set_next_event = u300_set_next_event,
|
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||||
.set_mode = u300_set_mode,
|
CLOCK_EVT_FEAT_ONESHOT,
|
||||||
|
.set_next_event = u300_set_next_event,
|
||||||
|
.set_mode = u300_set_mode,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Clock event timer interrupt handler */
|
/* Clock event timer interrupt handler */
|
||||||
static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
|
static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct clock_event_device *evt = &clockevent_u300_1mhz;
|
struct clock_event_device *evt = &u300_clockevent_data.cevd;
|
||||||
/* ACK/Clear timer IRQ for the APP GPT1 Timer */
|
/* ACK/Clear timer IRQ for the APP GPT1 Timer */
|
||||||
|
|
||||||
writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
|
writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
|
||||||
|
@ -379,6 +387,8 @@ static void __init u300_timer_init_of(struct device_node *np)
|
||||||
clk_prepare_enable(clk);
|
clk_prepare_enable(clk);
|
||||||
rate = clk_get_rate(clk);
|
rate = clk_get_rate(clk);
|
||||||
|
|
||||||
|
u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
|
||||||
|
|
||||||
setup_sched_clock(u300_read_sched_clock, 32, rate);
|
setup_sched_clock(u300_read_sched_clock, 32, rate);
|
||||||
|
|
||||||
u300_delay_timer.read_current_timer = &u300_read_current_timer;
|
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)
|
||||||
pr_err("timer: failed to initialize U300 clock source\n");
|
pr_err("timer: failed to initialize U300 clock source\n");
|
||||||
|
|
||||||
/* Configure and register the clockevent */
|
/* Configure and register the clockevent */
|
||||||
clockevents_config_and_register(&clockevent_u300_1mhz, rate,
|
clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
|
||||||
1, 0xffffffff);
|
1, 0xffffffff);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue