Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC cleanup from Olof Johansson:
 "Here is a collection of cleanup patches.  Among the pieces that stand
  out are:

   - The deletion of h720x platforms
   - Split of at91 non-dt platforms to their own Kconfig file to keep
     them separate
   - General cleanups and refactoring of i.MX and MXS platforms
   - Some restructuring of clock tables for OMAP
   - Convertion of PMC driver for Tegra to dt-only
   - Some renames of sunxi -> sun4i (Allwinner A10)
   - ... plus a bunch of other stuff that I haven't mentioned"

* tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (119 commits)
  ARM: i.MX: remove unused ARCH_* configs
  ARM i.MX53: remove platform ahci support
  ARM: sunxi: Rework the restart code
  irqchip: sunxi: Rename sunxi to sun4i
  irqchip: sunxi: Make use of the IRQCHIP_DECLARE macro
  clocksource: sunxi: Rename sunxi to sun4i
  clocksource: sunxi: make use of CLKSRC_OF
  clocksource: sunxi: Cleanup the timer code
  ARM: at91: remove trailing semicolon from macros
  ARM: at91/setup: fix trivial typos
  ARM: EXYNOS: remove "config EXYNOS_DEV_DRM"
  ARM: EXYNOS: change the name of USB ohci header
  ARM: SAMSUNG: Remove unnecessary code for dma
  ARM: S3C24XX: Remove unused GPIO drive strength register definitions
  ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
  ARM: S3C24XX: Removed unneeded dependency on CPU_S3C2412
  ARM: S3C24XX: Removed unneeded dependency on CPU_S3C2410
  ARM: S3C24XX: Removed unneeded dependency on ARCH_S3C24XX for boards
  ARM: SAMSUNG: Fix typo "CONFIG_SAMSUNG_DEV_RTC"
  ARM: S5P64X0: Fix typo "CONFIG_S5P64X0_SETUP_SDHCI"
  ...
This commit is contained in:
Linus Torvalds
2013-05-02 09:03:55 -07:00
263 changed files with 2926 additions and 6566 deletions

View File

@@ -25,7 +25,7 @@ config DW_APB_TIMER_OF
config ARMADA_370_XP_TIMER
bool
config SUNXI_TIMER
config SUN4I_TIMER
bool
config VT8500_TIMER

View File

@@ -16,7 +16,8 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o
obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
obj-$(CONFIG_ARCH_BCM) += bcm_kona_timer.o

View File

@@ -95,23 +95,13 @@ static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id)
}
}
static struct of_device_id bcm2835_time_match[] __initconst = {
{ .compatible = "brcm,bcm2835-system-timer" },
{}
};
static void __init bcm2835_timer_init(void)
static void __init bcm2835_timer_init(struct device_node *node)
{
struct device_node *node;
void __iomem *base;
u32 freq;
int irq;
struct bcm2835_timer *timer;
node = of_find_matching_node(NULL, bcm2835_time_match);
if (!node)
panic("No bcm2835 timer node");
base = of_iomap(node, 0);
if (!base)
panic("Can't remap registers");

View File

@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/clocksource.h>
extern struct of_device_id __clksrc_of_table[];
@@ -26,10 +27,10 @@ void __init clocksource_of_init(void)
{
struct device_node *np;
const struct of_device_id *match;
void (*init_func)(void);
clocksource_of_init_fn init_func;
for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
init_func = match->data;
init_func();
init_func(np);
}
}

View File

@@ -0,0 +1,304 @@
/*
* Copyright (C) 2000-2001 Deep Blue Solutions
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/stmp_device.h>
#include <asm/mach/time.h>
#include <asm/sched_clock.h>
/*
* There are 2 versions of the timrot on Freescale MXS-based SoCs.
* The v1 on MX23 only gets 16 bits counter, while v2 on MX28
* extends the counter to 32 bits.
*
* The implementation uses two timers, one for clock_event and
* another for clocksource. MX28 uses timrot 0 and 1, while MX23
* uses 0 and 2.
*/
#define MX23_TIMROT_VERSION_OFFSET 0x0a0
#define MX28_TIMROT_VERSION_OFFSET 0x120
#define BP_TIMROT_MAJOR_VERSION 24
#define BV_TIMROT_VERSION_1 0x01
#define BV_TIMROT_VERSION_2 0x02
#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
/*
* There are 4 registers for each timrotv2 instance, and 2 registers
* for each timrotv1. So address step 0x40 in macros below strides
* one instance of timrotv2 while two instances of timrotv1.
*
* As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
* on MX28 while timrot2 on MX23.
*/
/* common between v1 and v2 */
#define HW_TIMROT_ROTCTRL 0x00
#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
/* v1 only */
#define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40)
/* v2 only */
#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
#define BP_TIMROT_TIMCTRLn_SELECT 0
#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf
static struct clock_event_device mxs_clockevent_device;
static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
static void __iomem *mxs_timrot_base;
static u32 timrot_major_version;
static inline void timrot_irq_disable(void)
{
__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
}
static inline void timrot_irq_enable(void)
{
__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET);
}
static void timrot_irq_acknowledge(void)
{
__raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base +
HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
}
static cycle_t timrotv1_get_cycles(struct clocksource *cs)
{
return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
& 0xffff0000) >> 16);
}
static int timrotv1_set_next_event(unsigned long evt,
struct clock_event_device *dev)
{
/* timrot decrements the count */
__raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
return 0;
}
static int timrotv2_set_next_event(unsigned long evt,
struct clock_event_device *dev)
{
/* timrot decrements the count */
__raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
return 0;
}
static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = dev_id;
timrot_irq_acknowledge();
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction mxs_timer_irq = {
.name = "MXS Timer Tick",
.dev_id = &mxs_clockevent_device,
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = mxs_timer_interrupt,
};
#ifdef DEBUG
static const char *clock_event_mode_label[] const = {
[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
[CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
[CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
};
#endif /* DEBUG */
static void mxs_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
/* Disable interrupt in timer module */
timrot_irq_disable();
if (mode != mxs_clockevent_mode) {
/* Set event time into the furthest future */
if (timrot_is_v1())
__raw_writel(0xffff,
mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
else
__raw_writel(0xffffffff,
mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
/* Clear pending interrupt */
timrot_irq_acknowledge();
}
#ifdef DEBUG
pr_info("%s: changing mode from %s to %s\n", __func__,
clock_event_mode_label[mxs_clockevent_mode],
clock_event_mode_label[mode]);
#endif /* DEBUG */
/* Remember timer mode */
mxs_clockevent_mode = mode;
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
pr_err("%s: Periodic mode is not implemented\n", __func__);
break;
case CLOCK_EVT_MODE_ONESHOT:
timrot_irq_enable();
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_RESUME:
/* Left event sources disabled, no more interrupts appear */
break;
}
}
static struct clock_event_device mxs_clockevent_device = {
.name = "mxs_timrot",
.features = CLOCK_EVT_FEAT_ONESHOT,
.set_mode = mxs_set_mode,
.set_next_event = timrotv2_set_next_event,
.rating = 200,
};
static int __init mxs_clockevent_init(struct clk *timer_clk)
{
if (timrot_is_v1())
mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
mxs_clockevent_device.cpumask = cpumask_of(0);
clockevents_config_and_register(&mxs_clockevent_device,
clk_get_rate(timer_clk),
timrot_is_v1() ? 0xf : 0x2,
timrot_is_v1() ? 0xfffe : 0xfffffffe);
return 0;
}
static struct clocksource clocksource_mxs = {
.name = "mxs_timer",
.rating = 200,
.read = timrotv1_get_cycles,
.mask = CLOCKSOURCE_MASK(16),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static u32 notrace mxs_read_sched_clock_v2(void)
{
return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
}
static int __init mxs_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
if (timrot_is_v1())
clocksource_register_hz(&clocksource_mxs, c);
else {
clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
"mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
}
return 0;
}
static void __init mxs_timer_init(struct device_node *np)
{
struct clk *timer_clk;
int irq;
mxs_timrot_base = of_iomap(np, 0);
WARN_ON(!mxs_timrot_base);
timer_clk = of_clk_get(np, 0);
if (IS_ERR(timer_clk)) {
pr_err("%s: failed to get clk\n", __func__);
return;
}
clk_prepare_enable(timer_clk);
/*
* Initialize timers to a known state
*/
stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
/* get timrot version */
timrot_major_version = __raw_readl(mxs_timrot_base +
(of_device_is_compatible(np, "fsl,imx23-timrot") ?
MX23_TIMROT_VERSION_OFFSET :
MX28_TIMROT_VERSION_OFFSET));
timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
/* one for clock_event */
__raw_writel((timrot_is_v1() ?
BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
BM_TIMROT_TIMCTRLn_UPDATE |
BM_TIMROT_TIMCTRLn_IRQ_EN,
mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
/* another for clocksource */
__raw_writel((timrot_is_v1() ?
BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
BM_TIMROT_TIMCTRLn_RELOAD,
mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
/* set clocksource timer fixed count to the maximum */
if (timrot_is_v1())
__raw_writel(0xffff,
mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
else
__raw_writel(0xffffffff,
mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
/* init and register the timer to the framework */
mxs_clocksource_init(timer_clk);
mxs_clockevent_init(timer_clk);
/* Make irqs happen */
irq = irq_of_parse_and_map(np, 0);
setup_irq(irq, &mxs_timer_irq);
}
CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init);

View File

@@ -22,66 +22,64 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sunxi_timer.h>
#include <linux/clk/sunxi.h>
#define TIMER_CTL_REG 0x00
#define TIMER_CTL_ENABLE (1 << 0)
#define TIMER_IRQ_EN_REG 0x00
#define TIMER_IRQ_EN(val) (1 << val)
#define TIMER_IRQ_ST_REG 0x04
#define TIMER0_CTL_REG 0x10
#define TIMER0_CTL_ENABLE (1 << 0)
#define TIMER0_CTL_AUTORELOAD (1 << 1)
#define TIMER0_CTL_ONESHOT (1 << 7)
#define TIMER0_INTVAL_REG 0x14
#define TIMER0_CNTVAL_REG 0x18
#define TIMER_CTL_REG(val) (0x10 * val + 0x10)
#define TIMER_CTL_ENABLE (1 << 0)
#define TIMER_CTL_AUTORELOAD (1 << 1)
#define TIMER_CTL_ONESHOT (1 << 7)
#define TIMER_INTVAL_REG(val) (0x10 * val + 0x14)
#define TIMER_CNTVAL_REG(val) (0x10 * val + 0x18)
#define TIMER_SCAL 16
static void __iomem *timer_base;
static void sunxi_clkevt_mode(enum clock_event_mode mode,
static void sun4i_clkevt_mode(enum clock_event_mode mode,
struct clock_event_device *clk)
{
u32 u = readl(timer_base + TIMER0_CTL_REG);
u32 u = readl(timer_base + TIMER_CTL_REG(0));
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
u &= ~(TIMER0_CTL_ONESHOT);
writel(u | TIMER0_CTL_ENABLE, timer_base + TIMER0_CTL_REG);
u &= ~(TIMER_CTL_ONESHOT);
writel(u | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(0));
break;
case CLOCK_EVT_MODE_ONESHOT:
writel(u | TIMER0_CTL_ONESHOT, timer_base + TIMER0_CTL_REG);
writel(u | TIMER_CTL_ONESHOT, timer_base + TIMER_CTL_REG(0));
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
default:
writel(u & ~(TIMER0_CTL_ENABLE), timer_base + TIMER0_CTL_REG);
writel(u & ~(TIMER_CTL_ENABLE), timer_base + TIMER_CTL_REG(0));
break;
}
}
static int sunxi_clkevt_next_event(unsigned long evt,
static int sun4i_clkevt_next_event(unsigned long evt,
struct clock_event_device *unused)
{
u32 u = readl(timer_base + TIMER0_CTL_REG);
writel(evt, timer_base + TIMER0_CNTVAL_REG);
writel(u | TIMER0_CTL_ENABLE | TIMER0_CTL_AUTORELOAD,
timer_base + TIMER0_CTL_REG);
u32 u = readl(timer_base + TIMER_CTL_REG(0));
writel(evt, timer_base + TIMER_CNTVAL_REG(0));
writel(u | TIMER_CTL_ENABLE | TIMER_CTL_AUTORELOAD,
timer_base + TIMER_CTL_REG(0));
return 0;
}
static struct clock_event_device sunxi_clockevent = {
.name = "sunxi_tick",
static struct clock_event_device sun4i_clockevent = {
.name = "sun4i_tick",
.rating = 300,
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = sunxi_clkevt_mode,
.set_next_event = sunxi_clkevt_next_event,
.set_mode = sun4i_clkevt_mode,
.set_next_event = sun4i_clkevt_next_event,
};
static irqreturn_t sunxi_timer_interrupt(int irq, void *dev_id)
static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
@@ -91,30 +89,20 @@ static irqreturn_t sunxi_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
static struct irqaction sunxi_timer_irq = {
.name = "sunxi_timer0",
static struct irqaction sun4i_timer_irq = {
.name = "sun4i_timer0",
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = sunxi_timer_interrupt,
.dev_id = &sunxi_clockevent,
.handler = sun4i_timer_interrupt,
.dev_id = &sun4i_clockevent,
};
static struct of_device_id sunxi_timer_dt_ids[] = {
{ .compatible = "allwinner,sunxi-timer" },
{ }
};
void __init sunxi_timer_init(void)
static void __init sun4i_timer_init(struct device_node *node)
{
struct device_node *node;
unsigned long rate = 0;
struct clk *clk;
int ret, irq;
u32 val;
node = of_find_matching_node(NULL, sunxi_timer_dt_ids);
if (!node)
panic("No sunxi timer node");
timer_base = of_iomap(node, 0);
if (!timer_base)
panic("Can't map registers");
@@ -123,8 +111,6 @@ void __init sunxi_timer_init(void)
if (irq <= 0)
panic("Can't parse IRQ");
sunxi_init_clocks();
clk = of_clk_get(node, 0);
if (IS_ERR(clk))
panic("Can't get timer clock");
@@ -132,29 +118,31 @@ void __init sunxi_timer_init(void)
rate = clk_get_rate(clk);
writel(rate / (TIMER_SCAL * HZ),
timer_base + TIMER0_INTVAL_REG);
timer_base + TIMER_INTVAL_REG(0));
/* set clock source to HOSC, 16 pre-division */
val = readl(timer_base + TIMER0_CTL_REG);
val = readl(timer_base + TIMER_CTL_REG(0));
val &= ~(0x07 << 4);
val &= ~(0x03 << 2);
val |= (4 << 4) | (1 << 2);
writel(val, timer_base + TIMER0_CTL_REG);
writel(val, timer_base + TIMER_CTL_REG(0));
/* set mode to auto reload */
val = readl(timer_base + TIMER0_CTL_REG);
writel(val | TIMER0_CTL_AUTORELOAD, timer_base + TIMER0_CTL_REG);
val = readl(timer_base + TIMER_CTL_REG(0));
writel(val | TIMER_CTL_AUTORELOAD, timer_base + TIMER_CTL_REG(0));
ret = setup_irq(irq, &sunxi_timer_irq);
ret = setup_irq(irq, &sun4i_timer_irq);
if (ret)
pr_warn("failed to setup irq %d\n", irq);
/* Enable timer0 interrupt */
val = readl(timer_base + TIMER_CTL_REG);
writel(val | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG);
val = readl(timer_base + TIMER_IRQ_EN_REG);
writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
sunxi_clockevent.cpumask = cpumask_of(0);
sun4i_clockevent.cpumask = cpumask_of(0);
clockevents_config_and_register(&sunxi_clockevent, rate / TIMER_SCAL,
clockevents_config_and_register(&sun4i_clockevent, rate / TIMER_SCAL,
0x1, 0xff);
}
CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer",
sun4i_timer_init);

View File

@@ -154,29 +154,12 @@ static struct irqaction tegra_timer_irq = {
.dev_id = &tegra_clockevent,
};
static const struct of_device_id timer_match[] __initconst = {
{ .compatible = "nvidia,tegra20-timer" },
{}
};
static const struct of_device_id rtc_match[] __initconst = {
{ .compatible = "nvidia,tegra20-rtc" },
{}
};
static void __init tegra20_init_timer(void)
static void __init tegra20_init_timer(struct device_node *np)
{
struct device_node *np;
struct clk *clk;
unsigned long rate;
int ret;
np = of_find_matching_node(NULL, timer_match);
if (!np) {
pr_err("Failed to find timer DT node\n");
BUG();
}
timer_reg_base = of_iomap(np, 0);
if (!timer_reg_base) {
pr_err("Can't map timer registers\n");
@@ -189,7 +172,7 @@ static void __init tegra20_init_timer(void)
BUG();
}
clk = clk_get_sys("timer", NULL);
clk = of_clk_get(np, 0);
if (IS_ERR(clk)) {
pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
rate = 12000000;
@@ -200,30 +183,6 @@ static void __init tegra20_init_timer(void)
of_node_put(np);
np = of_find_matching_node(NULL, rtc_match);
if (!np) {
pr_err("Failed to find RTC DT node\n");
BUG();
}
rtc_base = of_iomap(np, 0);
if (!rtc_base) {
pr_err("Can't map RTC registers");
BUG();
}
/*
* rtc registers are used by read_persistent_clock, keep the rtc clock
* enabled
*/
clk = clk_get_sys("rtc-tegra", NULL);
if (IS_ERR(clk))
pr_warn("Unable to get rtc-tegra clock\n");
else
clk_prepare_enable(clk);
of_node_put(np);
switch (rate) {
case 12000000:
timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -259,12 +218,34 @@ static void __init tegra20_init_timer(void)
tegra_clockevent.irq = tegra_timer_irq.irq;
clockevents_config_and_register(&tegra_clockevent, 1000000,
0x1, 0x1fffffff);
#ifdef CONFIG_HAVE_ARM_TWD
twd_local_timer_of_register();
#endif
}
CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
static void __init tegra20_init_rtc(struct device_node *np)
{
struct clk *clk;
rtc_base = of_iomap(np, 0);
if (!rtc_base) {
pr_err("Can't map RTC registers");
BUG();
}
/*
* rtc registers are used by read_persistent_clock, keep the rtc clock
* enabled
*/
clk = of_clk_get(np, 0);
if (IS_ERR(clk))
pr_warn("Unable to get rtc-tegra clock\n");
else
clk_prepare_enable(clk);
of_node_put(np);
register_persistent_clock(NULL, tegra_read_persistent_clock);
}
CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
#ifdef CONFIG_PM
static u32 usec_config;

View File

@@ -129,22 +129,10 @@ static struct irqaction irq = {
.dev_id = &clockevent,
};
static struct of_device_id vt8500_timer_ids[] = {
{ .compatible = "via,vt8500-timer" },
{ }
};
static void __init vt8500_timer_init(void)
static void __init vt8500_timer_init(struct device_node *np)
{
struct device_node *np;
int timer_irq;
np = of_find_matching_node(NULL, vt8500_timer_ids);
if (!np) {
pr_err("%s: Timer description missing from Device Tree\n",
__func__);
return;
}
regbase = of_iomap(np, 0);
if (!regbase) {
pr_err("%s: Missing iobase description in Device Tree\n",
@@ -177,4 +165,4 @@ static void __init vt8500_timer_init(void)
4, 0xf0000000);
}
CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init)
CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init);