Merge tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorOlof Johansson <olof@lixom.net>
Tue, 5 Feb 2013 20:10:18 +0000 (12:10 -0800)
committerOlof Johansson <olof@lixom.net>
Tue, 5 Feb 2013 20:10:18 +0000 (12:10 -0800)
From Stephen Warren:
ARM: tegra: cleanup

This pull request contains various cleanup and minor changes to core
Tegra code:
* Tegra clocksource driver is moved to drivers/clocksource.
* Various typos, warning cleanup, statics cleanup, section mismatch
  fixes, etc.
* Various small fixes/cleanups for CPU/hotplug/SMP code.

This pull request is based on a merge of v3.8-rc3 and at least part of
arm-soc's timer/cleanup branch.

* tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
  ARM: tegra: fix compile error when disable CPU_IDLE
  ARM: tegra30: make the wait time of CPU power up to proportional to HZ
  ARM: tegra: make device can run on UP
  ARM: tegra: clean up the CPUINIT section
  ARM: tegra: moving the clock gating procedure to tegra_cpu_kill
  ARM: tegra: update the cache maintenance order for CPU shutdown
  ARM: tegra30: fix power up sequence for boot_secondary
  ARM: tegra: cpufreq: move clk_get/put out of function tegra_cpu_init/exit
  ARM: tegra: fix Kconfig warnings when !SMP
  ARM: tegra: Make variables static
  clocksource: tegra: cosmetic: Fix error message
  ARM: tegra: move timer.c to drivers/clocksource/

Signed-off-by: Olof Johansson <olof@lixom.net>
Trivial conflicts:
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
drivers/clocksource/Makefile

1  2 
arch/arm/Kconfig
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/platsmp.c
drivers/clocksource/Makefile
drivers/clocksource/tegra20_timer.c

index af74b0fc4faaf5ee417e4fbef9e2d20423bad025,eb9fc2f8acf10b2cd56a98430caf7246a9abc3a3..c2950f3e678e5434c5c54a3f45a086af618e03f7
@@@ -642,8 -642,10 +642,9 @@@ config ARCH_TEGR
        select ARCH_HAS_CPUFREQ
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
+       select CLKSRC_OF
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
 -      select GENERIC_GPIO
        select HAVE_CLK
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
index 5ed81bab2d4bb4eb6aaf561200c400cc8d1cc506,e1f87dd314ef101db3fa20618729750df9be3364..d320f7ad735038556386464f6c268854be9b57db
@@@ -200,7 -203,8 +201,7 @@@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegr
        .smp            = smp_ops(tegra_smp_ops),
        .init_early     = tegra20_init_early,
        .init_irq       = tegra_dt_init_irq,
-       .init_time      = tegra_init_timer,
 -      .handle_irq     = gic_handle_irq,
+       .init_time      = clocksource_of_init,
        .init_machine   = tegra_dt_init,
        .init_late      = tegra_dt_init_late,
        .restart        = tegra_assert_system_reset,
index 12dc2ddeca640914c694d92a0735813de37c6591,cfe5fc02be775980e11866c25cd5d7fb655a8b75..97e1f67fc31d9e9d8cb2d0f6af140e37536aa333
@@@ -111,7 -113,8 +112,7 @@@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Te
        .map_io         = tegra_map_common_io,
        .init_early     = tegra30_init_early,
        .init_irq       = tegra_dt_init_irq,
-       .init_time      = tegra_init_timer,
 -      .handle_irq     = gic_handle_irq,
+       .init_time      = clocksource_of_init,
        .init_machine   = tegra30_dt_init,
        .init_late      = tegra_init_late,
        .restart        = tegra_assert_system_reset,
Simple merge
index 18d7290cf93b63dbe592591bfb6b4ed87be76ff0,68670304d9bc3ec770892a93cfc61148b71a3254..3c4a43c892a5a09e6fbf14ac504fe118e54770ec
  #include <linux/jiffies.h>
  #include <linux/smp.h>
  #include <linux/io.h>
 +#include <linux/irqchip/arm-gic.h>
  
  #include <asm/cacheflush.h>
 -#include <asm/hardware/gic.h>
  #include <asm/mach-types.h>
  #include <asm/smp_scu.h>
+ #include <asm/smp_plat.h>
  
  #include <mach/powergate.h>
  
index 440449c1ca21e139e7c5d79e19c0feab9934e550,b5cc50796a809e80f8623a77f0b22126d7bd8fea..596c45c2f192114224f6626f786401f5b41656a6
@@@ -17,6 -17,6 +17,7 @@@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU)     += cl
  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_TEGRA)      += tegra20_timer.o
 +obj-$(CONFIG_VT8500_TIMER)    += vt8500_timer.o
  
  obj-$(CONFIG_CLKSRC_ARM_GENERIC)      += arm_generic.o
index 0000000000000000000000000000000000000000,5bc14299de3cb3a698af94f26c0ed7e16a9e5b76..0bde03feb095365602af6fe0239a5d13b26181b3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,285 +1,281 @@@
 -      clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
 -      tegra_clockevent.max_delta_ns =
 -              clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
 -      tegra_clockevent.min_delta_ns =
 -              clockevent_delta2ns(0x1, &tegra_clockevent);
+ /*
+  * Copyright (C) 2010 Google, Inc.
+  *
+  * Author:
+  *    Colin Cross <ccross@google.com>
+  *
+  * This software is licensed under the terms of the GNU General Public
+  * License version 2, as published by the Free Software Foundation, and
+  * may be copied, distributed, and modified under those terms.
+  *
+  * 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.
+  *
+  */
+ #include <linux/init.h>
+ #include <linux/err.h>
+ #include <linux/time.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/clockchips.h>
+ #include <linux/clocksource.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <asm/mach/time.h>
+ #include <asm/smp_twd.h>
+ #include <asm/sched_clock.h>
+ #define RTC_SECONDS            0x08
+ #define RTC_SHADOW_SECONDS     0x0c
+ #define RTC_MILLISECONDS       0x10
+ #define TIMERUS_CNTR_1US 0x10
+ #define TIMERUS_USEC_CFG 0x14
+ #define TIMERUS_CNTR_FREEZE 0x4c
+ #define TIMER1_BASE 0x0
+ #define TIMER2_BASE 0x8
+ #define TIMER3_BASE 0x50
+ #define TIMER4_BASE 0x58
+ #define TIMER_PTV 0x0
+ #define TIMER_PCR 0x4
+ static void __iomem *timer_reg_base;
+ static void __iomem *rtc_base;
+ static struct timespec persistent_ts;
+ static u64 persistent_ms, last_persistent_ms;
+ #define timer_writel(value, reg) \
+       __raw_writel(value, timer_reg_base + (reg))
+ #define timer_readl(reg) \
+       __raw_readl(timer_reg_base + (reg))
+ static int tegra_timer_set_next_event(unsigned long cycles,
+                                        struct clock_event_device *evt)
+ {
+       u32 reg;
+       reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
+       timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+       return 0;
+ }
+ static void tegra_timer_set_mode(enum clock_event_mode mode,
+                                   struct clock_event_device *evt)
+ {
+       u32 reg;
+       timer_writel(0, TIMER3_BASE + TIMER_PTV);
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               reg = 0xC0000000 | ((1000000/HZ)-1);
+               timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+ }
+ static struct clock_event_device tegra_clockevent = {
+       .name           = "timer0",
+       .rating         = 300,
+       .features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+       .set_next_event = tegra_timer_set_next_event,
+       .set_mode       = tegra_timer_set_mode,
+ };
+ static u32 notrace tegra_read_sched_clock(void)
+ {
+       return timer_readl(TIMERUS_CNTR_1US);
+ }
+ /*
+  * tegra_rtc_read - Reads the Tegra RTC registers
+  * Care must be taken that this funciton is not called while the
+  * tegra_rtc driver could be executing to avoid race conditions
+  * on the RTC shadow register
+  */
+ static u64 tegra_rtc_read_ms(void)
+ {
+       u32 ms = readl(rtc_base + RTC_MILLISECONDS);
+       u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
+       return (u64)s * MSEC_PER_SEC + ms;
+ }
+ /*
+  * tegra_read_persistent_clock -  Return time from a persistent clock.
+  *
+  * Reads the time from a source which isn't disabled during PM, the
+  * 32k sync timer.  Convert the cycles elapsed since last read into
+  * nsecs and adds to a monotonically increasing timespec.
+  * Care must be taken that this funciton is not called while the
+  * tegra_rtc driver could be executing to avoid race conditions
+  * on the RTC shadow register
+  */
+ static void tegra_read_persistent_clock(struct timespec *ts)
+ {
+       u64 delta;
+       struct timespec *tsp = &persistent_ts;
+       last_persistent_ms = persistent_ms;
+       persistent_ms = tegra_rtc_read_ms();
+       delta = persistent_ms - last_persistent_ms;
+       timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
+       *ts = *tsp;
+ }
+ static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
+ {
+       struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+       timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
+       evt->event_handler(evt);
+       return IRQ_HANDLED;
+ }
+ static struct irqaction tegra_timer_irq = {
+       .name           = "timer0",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
+       .handler        = tegra_timer_interrupt,
+       .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)
+ {
+       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");
+               BUG();
+       }
+       tegra_timer_irq.irq = irq_of_parse_and_map(np, 2);
+       if (tegra_timer_irq.irq <= 0) {
+               pr_err("Failed to map timer IRQ\n");
+               BUG();
+       }
+       clk = clk_get_sys("timer", NULL);
+       if (IS_ERR(clk)) {
+               pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
+               rate = 12000000;
+       } else {
+               clk_prepare_enable(clk);
+               rate = clk_get_rate(clk);
+       }
+       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);
+               break;
+       case 13000000:
+               timer_writel(0x000c, TIMERUS_USEC_CFG);
+               break;
+       case 19200000:
+               timer_writel(0x045f, TIMERUS_USEC_CFG);
+               break;
+       case 26000000:
+               timer_writel(0x0019, TIMERUS_USEC_CFG);
+               break;
+       default:
+               WARN(1, "Unknown clock rate");
+       }
+       setup_sched_clock(tegra_read_sched_clock, 32, 1000000);
+       if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
+               "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
+               pr_err("Failed to register clocksource\n");
+               BUG();
+       }
+       ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
+       if (ret) {
+               pr_err("Failed to register timer IRQ: %d\n", ret);
+               BUG();
+       }
 -      clockevents_register_device(&tegra_clockevent);
+       tegra_clockevent.cpumask = cpu_all_mask;
+       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
+       register_persistent_clock(NULL, tegra_read_persistent_clock);
+ }
+ CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
+ #ifdef CONFIG_PM
+ static u32 usec_config;
+ void tegra_timer_suspend(void)
+ {
+       usec_config = timer_readl(TIMERUS_USEC_CFG);
+ }
+ void tegra_timer_resume(void)
+ {
+       timer_writel(usec_config, TIMERUS_USEC_CFG);
+ }
+ #endif