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

Pull ARM SoC specific changes from Arnd Bergmann:
 "These changes are all to SoC-specific code, a total of 33 branches on
  17 platforms were pulled into this.  Like last time, Renesas sh-mobile
  is now the platform with the most changes, followed by OMAP and
  EXYNOS.

  Two new platforms, TI Keystone and Rockchips RK3xxx are added in this
  branch, both containing almost no platform specific code at all, since
  they are using generic subsystem interfaces for clocks, pinctrl,
  interrupts etc.  The device drivers are getting merged through the
  respective subsystem maintainer trees.

  One more SoC (u300) is now multiplatform capable and several others
  (shmobile, exynos, msm, integrator, kirkwood, clps711x) are moving
  towards that goal with this series but need more work.

  Also noteworthy is the work on PCI here, which is traditionally part
  of the SoC specific code.  With the changes done by Thomas Petazzoni,
  we can now more easily have PCI host controller drivers as loadable
  modules and keep them separate from the platform code in
  drivers/pci/host.  This has already led to the discovery that three
  platforms (exynos, spear and imx) are actually using an identical PCIe
  host controller and will be able to share a driver once support for
  spear and imx is added."

* tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (480 commits)
  ARM: integrator: let pciv3 use mem/premem from device tree
  ARM: integrator: set local side PCI addresses right
  ARM: dts: Add pcie controller node for exynos5440-ssdk5440
  ARM: dts: Add pcie controller node for Samsung EXYNOS5440 SoC
  ARM: EXYNOS: Enable PCIe support for Exynos5440
  pci: Add PCIe driver for Samsung Exynos
  ARM: OMAP5: voltagedomain data: remove temporary OMAP4 voltage data
  ARM: keystone: Move CPU bringup code to dedicated asm file
  ARM: multiplatform: always pick one CPU type
  ARM: imx: select syscon for IMX6SL
  ARM: keystone: select ARM_ERRATA_798181 only for SMP
  ARM: imx: Synertronixx scb9328 needs to select SOC_IMX1
  ARM: OMAP2+: AM43x: resolve SMP related build error
  dmaengine: edma: enable build for AM33XX
  ARM: edma: Add EDMA crossbar event mux support
  ARM: edma: Add DT and runtime PM support to the private EDMA API
  dmaengine: edma: Add TI EDMA device tree binding
  arm: add basic support for Rockchip RK3066a boards
  arm: add debug uarts for rockchip rk29xx and rk3xxx series
  arm: Add basic clocks for Rockchip rk3066a SoCs
  ...
This commit is contained in:
Linus Torvalds
2013-07-02 13:43:38 -07:00
482 changed files with 34854 additions and 19533 deletions

View File

@@ -21,6 +21,8 @@ config DW_APB_TIMER
config DW_APB_TIMER_OF
bool
select DW_APB_TIMER
select CLKSRC_OF
config ARMADA_370_XP_TIMER
bool

View File

@@ -51,6 +51,8 @@
#define TTC_CNT_CNTRL_DISABLE_MASK 0x1
#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */
/*
* Setup the timers to use pre-scaling, using a fixed value for now that will
* work across most input frequency, but it may need to be more dynamic
@@ -396,8 +398,9 @@ static void __init ttc_timer_init(struct device_node *timer)
{
unsigned int irq;
void __iomem *timer_baseaddr;
struct clk *clk;
struct clk *clk_cs, *clk_ce;
static int initialized;
int clksel;
if (initialized)
return;
@@ -421,14 +424,24 @@ static void __init ttc_timer_init(struct device_node *timer)
BUG();
}
clk = of_clk_get_by_name(timer, "cpu_1x");
if (IS_ERR(clk)) {
clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET);
clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
clk_cs = of_clk_get(timer, clksel);
if (IS_ERR(clk_cs)) {
pr_err("ERROR: timer input clock not found\n");
BUG();
}
ttc_setup_clocksource(clk, timer_baseaddr);
ttc_setup_clockevent(clk, timer_baseaddr + 4, irq);
clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET);
clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
clk_ce = of_clk_get(timer, clksel);
if (IS_ERR(clk_ce)) {
pr_err("ERROR: timer input clock not found\n");
BUG();
}
ttc_setup_clocksource(clk_cs, timer_baseaddr);
ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq);
}

View File

@@ -20,6 +20,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <asm/mach/time.h>
#include <asm/sched_clock.h>
@@ -27,14 +28,37 @@
static void timer_get_base_and_rate(struct device_node *np,
void __iomem **base, u32 *rate)
{
struct clk *timer_clk;
struct clk *pclk;
*base = of_iomap(np, 0);
if (!*base)
panic("Unable to map regs for %s", np->name);
/*
* Not all implementations use a periphal clock, so don't panic
* if it's not present
*/
pclk = of_clk_get_by_name(np, "pclk");
if (!IS_ERR(pclk))
if (clk_prepare_enable(pclk))
pr_warn("pclk for %s is present, but could not be activated\n",
np->name);
timer_clk = of_clk_get_by_name(np, "timer");
if (IS_ERR(timer_clk))
goto try_clock_freq;
if (!clk_prepare_enable(timer_clk)) {
*rate = clk_get_rate(timer_clk);
return;
}
try_clock_freq:
if (of_property_read_u32(np, "clock-freq", rate) &&
of_property_read_u32(np, "clock-frequency", rate))
panic("No clock-frequency property for %s", np->name);
panic("No clock nor clock-frequency property for %s", np->name);
}
static void add_clockevent(struct device_node *event_timer)
@@ -57,6 +81,9 @@ static void add_clockevent(struct device_node *event_timer)
dw_apb_clockevent_register(ced);
}
static void __iomem *sched_io_base;
static u32 sched_rate;
static void add_clocksource(struct device_node *source_timer)
{
void __iomem *iobase;
@@ -71,9 +98,15 @@ static void add_clocksource(struct device_node *source_timer)
dw_apb_clocksource_start(cs);
dw_apb_clocksource_register(cs);
}
static void __iomem *sched_io_base;
/*
* Fallback to use the clocksource as sched_clock if no separate
* timer is found. sched_io_base then points to the current_value
* register of the clocksource timer.
*/
sched_io_base = iobase + 0x04;
sched_rate = rate;
}
static u32 read_sched_clock(void)
{
@@ -89,39 +122,37 @@ static const struct of_device_id sptimer_ids[] __initconst = {
static void init_sched_clock(void)
{
struct device_node *sched_timer;
u32 rate;
sched_timer = of_find_matching_node(NULL, sptimer_ids);
if (!sched_timer)
panic("No RTC for sched clock to use");
if (sched_timer) {
timer_get_base_and_rate(sched_timer, &sched_io_base,
&sched_rate);
of_node_put(sched_timer);
}
timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
of_node_put(sched_timer);
setup_sched_clock(read_sched_clock, 32, rate);
setup_sched_clock(read_sched_clock, 32, sched_rate);
}
static const struct of_device_id osctimer_ids[] __initconst = {
{ .compatible = "picochip,pc3x2-timer" },
{ .compatible = "snps,dw-apb-timer-osc" },
{},
};
void __init dw_apb_timer_init(void)
static int num_called;
static void __init dw_apb_timer_init(struct device_node *timer)
{
struct device_node *event_timer, *source_timer;
switch (num_called) {
case 0:
pr_debug("%s: found clockevent timer\n", __func__);
add_clockevent(timer);
of_node_put(timer);
break;
case 1:
pr_debug("%s: found clocksource timer\n", __func__);
add_clocksource(timer);
of_node_put(timer);
init_sched_clock();
break;
default:
break;
}
event_timer = of_find_matching_node(NULL, osctimer_ids);
if (!event_timer)
panic("No timer for clockevent");
add_clockevent(event_timer);
source_timer = of_find_matching_node(event_timer, osctimer_ids);
if (!source_timer)
panic("No timer for clocksource");
add_clocksource(source_timer);
of_node_put(source_timer);
init_sched_clock();
num_called++;
}
CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init);
CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer-osc", dw_apb_timer_init);