mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
arm-soc: mvebu platform changes
This series contains changes for the Marvell EBU platforms (mvebu,
orion, kirkwood, dove) that were not part of the first set of pull
requests because of dependencies on the MMC tree, and being submitted
a little late.
Notable changes are:
* More devices get moved out of board files into device tree
descriptions. The remaining devices listed in there have patches
that will get sent for 3.10, after which we can remove a lot of the
board files entirely. We are doing the pinctrl and mmc drivers here,
ethernet and PCI still remain.
* SMP support for mvebu is improved with support for the
local interrupt controller.
* The Guruplug board file gets replaced with a DT description.
Unfortunately, the dependency on the MMC tree turned out to be a much
larger problem than expected, when the MMC maintainer rebased the patches
in his tree that all of the patches in this branch are based on, which
caused merge conflicts between the new and old versions of those patches.
To work around the merge conflicts, this branch rebases all patches
on top of the respective MMC patches that did get merged into 3.9.
The patches are all identical to the versions that were part of
linux-next, but have a new commit date.
Merge conflicts:
* in board-nsa310.c, the gpio.h inclusion was removed prematurely and
put back as a bug fix earlier. With this series it is really not needed
any more.
* The patch to add rtc support was already applied by Andrew Morton,
and conflicts with a second copy that was in this series, which adds
a lot of other devices to arch/arm/boot/dts/armada-370-xp.dtsi.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iQIVAwUAUS+/hWCrR//JCVInAQK/eBAA0RskNuX3dL4Tn0FUBQfA11hMXyNLSLdY
mwNE91jJO0Q6NIjSlZCMV0pqEhoVlWlKnHcD76ID68qxNHiU4XMyxT/NkwTQAdOC
lKry+X8B5yt4kYiQp5adpME0rTHqtCQ9pNswU7j40ENNiOfwNk34O+PfNvh+FDkn
s2mmLjyAbJgO1n5SGVETaVCGAW1/1dcCSxOV2BqUzn2AecTHmZb1lS8W+y761+Yi
1V+Y3Xp4EJngN/OGtCNNfJ3H627MERfUF80xeijE2elhrdmynkBN1oOb4H+1AX6w
Tsi4BUYd5BkeETgsskOeZevkbRq4LZGHueaofh9i11enjgVE09Z/P3eL2K6/UbBA
mVA7+i1UujTcrEOUNO+EJ/AKvz7BU9trI4gR/RDHEkg2vzIHtsqMnDf44cQESxTn
7AgLo+G5nG10hucgcTNse3Ev2k4wQpdev5QX3uGKVNW7PPoxY/abSYKtWek6TjGd
nMGMI0+Re17Ej83SCXEJOvHmaA5IQDJJQOVLz/IxNuHE8HjEwJmguQy/YFzyZ0dQ
Rha3iaLXrWBLt5jIYOIdI0K6S4KUp5mZCax2MK/c6D18Tiuk4iIA9yD1doL4a3g8
AWoRL23ajabVa+Pg+EHqOsSUCfNI4+teMuio8vsJifudxZ6R8vYgJqdzIklwCkl3
0l2Xvnf55Ks=
=7l0+
-----END PGP SIGNATURE-----
Merge tag 'late-mvebu-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC mvebu platform changes from Olof Johansson:
"This series contains changes for the Marvell EBU platforms (mvebu,
orion, kirkwood, dove) that were not part of the first set of pull
requests because of dependencies on the MMC tree, and being submitted
a little late.
Notable changes are:
- More devices get moved out of board files into device tree
descriptions. The remaining devices listed in there have patches
that will get sent for 3.10, after which we can remove a lot of the
board files entirely. We are doing the pinctrl and mmc drivers
here, ethernet and PCI still remain.
- SMP support for mvebu is improved with support for the local
interrupt controller.
- The Guruplug board file gets replaced with a DT description.
Unfortunately, the dependency on the MMC tree turned out to be a much
larger problem than expected, when the MMC maintainer rebased the
patches in his tree that all of the patches in this branch are based
on, which caused merge conflicts between the new and old versions of
those patches.
To work around the merge conflicts, this branch rebases all patches on
top of the respective MMC patches that did get merged into 3.9. The
patches are all identical to the versions that were part of
linux-next, but have a new commit date."
* tag 'late-mvebu-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (90 commits)
arm: mvebu: enable the SD card slot on Armada 370 Reference Design board
ARM: kirkwood: topkick: init mvsdio via DT
ARM: kirkwood: nsa310: convert to pinctrl
ARM: Kirkwood: topkick: Enable i2c bus.
ARM: kirkwood: topkick: convert to pinctrl
ARM: dove: convert serial DT nodes to clocks property
arm: mvebu: Add SPI flash on Armada 370 DB board
arm: mvebu: Add SPI flash on Armada XP-DB board
arm: mvebu: Add SPI flash on Armada XP-GP board
arm: mvebu: Add support for SPI controller in Armada 370/XP
clocksource: update and move armada-370-xp-timer documentation to timer directory
arm: mvebu: update DT to support local timers
ARM: Dove: convert usb host controller to DT
arm: mvebu: Enable USB controllers on Armada 370/XP boards
arm: mvebu: Add support for USB host controllers in Armada 370/XP
arm: mvebu: add button for OpenBlocks AX3-4
ARM: Kirkwood: Convert NS2 to gpio-poweroff.
ARM: Kirkwood: Convert NSA310 I2C to device tree
ARM: Kirkwood: Convert NSA310 to use gpio-poweroff driver
ARM: Kirkwood: Convert NSA310 to DT based regulators.
...
This commit is contained in:
commit
1a32c58bb9
44 changed files with 1314 additions and 371 deletions
|
|
@ -27,8 +27,10 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
#include <asm/sched_clock.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <linux/percpu.h>
|
||||
/*
|
||||
* Timer block registers.
|
||||
*/
|
||||
|
|
@ -49,6 +51,7 @@
|
|||
#define TIMER1_RELOAD_OFF 0x0018
|
||||
#define TIMER1_VAL_OFF 0x001c
|
||||
|
||||
#define LCL_TIMER_EVENTS_STATUS 0x0028
|
||||
/* Global timers are connected to the coherency fabric clock, and the
|
||||
below divider reduces their incrementing frequency. */
|
||||
#define TIMER_DIVIDER_SHIFT 5
|
||||
|
|
@ -57,14 +60,17 @@
|
|||
/*
|
||||
* SoC-specific data.
|
||||
*/
|
||||
static void __iomem *timer_base;
|
||||
static int timer_irq;
|
||||
static void __iomem *timer_base, *local_base;
|
||||
static unsigned int timer_clk;
|
||||
static bool timer25Mhz = true;
|
||||
|
||||
/*
|
||||
* Number of timer ticks per jiffy.
|
||||
*/
|
||||
static u32 ticks_per_jiffy;
|
||||
|
||||
static struct clock_event_device __percpu **percpu_armada_370_xp_evt;
|
||||
|
||||
static u32 notrace armada_370_xp_read_sched_clock(void)
|
||||
{
|
||||
return ~readl(timer_base + TIMER0_VAL_OFF);
|
||||
|
|
@ -78,24 +84,23 @@ armada_370_xp_clkevt_next_event(unsigned long delta,
|
|||
struct clock_event_device *dev)
|
||||
{
|
||||
u32 u;
|
||||
|
||||
/*
|
||||
* Clear clockevent timer interrupt.
|
||||
*/
|
||||
writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS);
|
||||
writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
|
||||
|
||||
/*
|
||||
* Setup new clockevent timer value.
|
||||
*/
|
||||
writel(delta, timer_base + TIMER1_VAL_OFF);
|
||||
writel(delta, local_base + TIMER0_VAL_OFF);
|
||||
|
||||
/*
|
||||
* Enable the timer.
|
||||
*/
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
u = ((u & ~TIMER1_RELOAD_EN) | TIMER1_EN |
|
||||
TIMER1_DIV(TIMER_DIVIDER_SHIFT));
|
||||
writel(u, timer_base + TIMER_CTRL_OFF);
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN |
|
||||
TIMER0_DIV(TIMER_DIVIDER_SHIFT));
|
||||
writel(u, local_base + TIMER_CTRL_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -107,37 +112,38 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode,
|
|||
u32 u;
|
||||
|
||||
if (mode == CLOCK_EVT_MODE_PERIODIC) {
|
||||
|
||||
/*
|
||||
* Setup timer to fire at 1/HZ intervals.
|
||||
*/
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
|
||||
writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF);
|
||||
writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF);
|
||||
|
||||
/*
|
||||
* Enable timer.
|
||||
*/
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
writel((u | TIMER1_EN | TIMER1_RELOAD_EN |
|
||||
TIMER1_DIV(TIMER_DIVIDER_SHIFT)),
|
||||
timer_base + TIMER_CTRL_OFF);
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
|
||||
writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
|
||||
TIMER0_DIV(TIMER_DIVIDER_SHIFT)),
|
||||
local_base + TIMER_CTRL_OFF);
|
||||
} else {
|
||||
/*
|
||||
* Disable timer.
|
||||
*/
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF);
|
||||
|
||||
/*
|
||||
* ACK pending timer interrupt.
|
||||
*/
|
||||
writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS);
|
||||
|
||||
writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
static struct clock_event_device armada_370_xp_clkevt = {
|
||||
.name = "armada_370_xp_tick",
|
||||
.name = "armada_370_xp_per_cpu_tick",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
|
||||
.shift = 32,
|
||||
.rating = 300,
|
||||
|
|
@ -150,32 +156,78 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id)
|
|||
/*
|
||||
* ACK timer interrupt and call event handler.
|
||||
*/
|
||||
struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
|
||||
|
||||
writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS);
|
||||
armada_370_xp_clkevt.event_handler(&armada_370_xp_clkevt);
|
||||
writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction armada_370_xp_timer_irq = {
|
||||
.name = "armada_370_xp_tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.handler = armada_370_xp_timer_interrupt
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
u32 u;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
/* Use existing clock_event for cpu 0 */
|
||||
if (!smp_processor_id())
|
||||
return 0;
|
||||
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
if (timer25Mhz)
|
||||
writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
|
||||
else
|
||||
writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
|
||||
|
||||
evt->name = armada_370_xp_clkevt.name;
|
||||
evt->irq = armada_370_xp_clkevt.irq;
|
||||
evt->features = armada_370_xp_clkevt.features;
|
||||
evt->shift = armada_370_xp_clkevt.shift;
|
||||
evt->rating = armada_370_xp_clkevt.rating,
|
||||
evt->set_next_event = armada_370_xp_clkevt_next_event,
|
||||
evt->set_mode = armada_370_xp_clkevt_mode,
|
||||
evt->cpumask = cpumask_of(cpu);
|
||||
|
||||
*__this_cpu_ptr(percpu_armada_370_xp_evt) = evt;
|
||||
|
||||
clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe);
|
||||
enable_percpu_irq(evt->irq, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void armada_370_xp_timer_stop(struct clock_event_device *evt)
|
||||
{
|
||||
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
|
||||
disable_percpu_irq(evt->irq);
|
||||
}
|
||||
|
||||
static struct local_timer_ops armada_370_xp_local_timer_ops __cpuinitdata = {
|
||||
.setup = armada_370_xp_timer_setup,
|
||||
.stop = armada_370_xp_timer_stop,
|
||||
};
|
||||
|
||||
void __init armada_370_xp_timer_init(void)
|
||||
{
|
||||
u32 u;
|
||||
struct device_node *np;
|
||||
unsigned int timer_clk;
|
||||
int res;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
|
||||
timer_base = of_iomap(np, 0);
|
||||
WARN_ON(!timer_base);
|
||||
local_base = of_iomap(np, 1);
|
||||
|
||||
if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
|
||||
/* The fixed 25MHz timer is available so let's use it */
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
writel(u | TIMER0_25MHZ,
|
||||
local_base + TIMER_CTRL_OFF);
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u | TIMER0_25MHZ | TIMER1_25MHZ,
|
||||
writel(u | TIMER0_25MHZ,
|
||||
timer_base + TIMER_CTRL_OFF);
|
||||
timer_clk = 25000000;
|
||||
} else {
|
||||
|
|
@ -183,15 +235,23 @@ void __init armada_370_xp_timer_init(void)
|
|||
struct clk *clk = of_clk_get(np, 0);
|
||||
WARN_ON(IS_ERR(clk));
|
||||
rate = clk_get_rate(clk);
|
||||
u = readl(local_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~(TIMER0_25MHZ),
|
||||
local_base + TIMER_CTRL_OFF);
|
||||
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ),
|
||||
writel(u & ~(TIMER0_25MHZ),
|
||||
timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
timer_clk = rate / TIMER_DIVIDER;
|
||||
timer25Mhz = false;
|
||||
}
|
||||
|
||||
/* We use timer 0 as clocksource, and timer 1 for
|
||||
clockevents */
|
||||
timer_irq = irq_of_parse_and_map(np, 1);
|
||||
/*
|
||||
* We use timer 0 as clocksource, and private(local) timer 0
|
||||
* for clockevents
|
||||
*/
|
||||
armada_370_xp_clkevt.irq = irq_of_parse_and_map(np, 4);
|
||||
|
||||
ticks_per_jiffy = (timer_clk + HZ / 2) / HZ;
|
||||
|
||||
|
|
@ -216,12 +276,26 @@ void __init armada_370_xp_timer_init(void)
|
|||
"armada_370_xp_clocksource",
|
||||
timer_clk, 300, 32, clocksource_mmio_readl_down);
|
||||
|
||||
/*
|
||||
* Setup clockevent timer (interrupt-driven).
|
||||
*/
|
||||
setup_irq(timer_irq, &armada_370_xp_timer_irq);
|
||||
/* Register the clockevent on the private timer of CPU 0 */
|
||||
armada_370_xp_clkevt.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&armada_370_xp_clkevt,
|
||||
timer_clk, 1, 0xfffffffe);
|
||||
}
|
||||
|
||||
percpu_armada_370_xp_evt = alloc_percpu(struct clock_event_device *);
|
||||
|
||||
|
||||
/*
|
||||
* Setup clockevent timer (interrupt-driven).
|
||||
*/
|
||||
*__this_cpu_ptr(percpu_armada_370_xp_evt) = &armada_370_xp_clkevt;
|
||||
res = request_percpu_irq(armada_370_xp_clkevt.irq,
|
||||
armada_370_xp_timer_interrupt,
|
||||
armada_370_xp_clkevt.name,
|
||||
percpu_armada_370_xp_evt);
|
||||
if (!res) {
|
||||
enable_percpu_irq(armada_370_xp_clkevt.irq, 0);
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
local_timer_register(&armada_370_xp_local_timer_ops);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue