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

Pull ARM soc-specific updates from Olof Johansson:
 "Most notable here is probably the addition of basic support for the
  BCM2835, an SoC used in some of the Roku 2 players as well as the
  much-hyped Raspberry Pi, cleaned up and contributed by Stephen Warren.
  It's still early days on mainline support, with just the basics
  working.  But it has to start somewhere!

  Beyond that there's some conversions of clock infrastructure on tegra
  to common clock, misc updates for several other platforms, and OMAP
  now has its own bus (under drivers/bus) to manage its devices through.

  This branch adds two new directories outside of arch/arm:
  drivers/irqchip for new irq controllers, and drivers/bus for the above
  OMAP bus.  It's expected that some of the other platforms will migrate
  parts of their platforms to those directories over time as well."

Fix up trivial conflicts with the clk infrastructure changes.

* tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (62 commits)
  ARM: shmobile: add new __iomem annotation for new code
  ARM: LPC32xx: Support GPI 28
  ARM: LPC32xx: Platform update for devicetree completion of spi-pl022
  ARM: LPC32xx: Board cleanup
  irqchip: fill in empty Kconfig
  ARM: SAMSUNG: Add check for NULL in clock interface
  ARM: EXYNOS: Put PCM, Slimbus, Spdif clocks to off state
  ARM: EXYNOS: Add bus clock for FIMD
  ARM: SAMSUNG: Fix HDMI related warnings
  ARM: S3C24XX: Add .get_rate callback for "camif-upll" clock
  ARM: EXYNOS: Fix incorrect help text
  ARM: EXYNOS: Turn off clocks for NAND, OneNAND and TSI controllers
  ARM: OMAP: AM33xx hwmod: fixup SPI after platform_data move
  MAINTAINERS: add an entry for the BCM2835 ARM sub-architecture
  ARM: bcm2835: instantiate console UART
  ARM: bcm2835: add stub clock driver
  ARM: bcm2835: add system timer
  ARM: bcm2835: add interrupt controller driver
  ARM: add infra-structure for BCM2835 and Raspberry Pi
  ARM: tegra20: add CPU hotplug support
  ...
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 6591990..603be36 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -13,4 +13,6 @@
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.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_CLKSRC_ARM_GENERIC)	+= arm_generic.o
diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c
new file mode 100644
index 0000000..bc19f12
--- /dev/null
+++ b/drivers/clocksource/bcm2835_timer.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2012 Simon Arlott
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/bcm2835_timer.h>
+#include <linux/bitops.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/sched_clock.h>
+#include <asm/irq.h>
+
+#define REG_CONTROL	0x00
+#define REG_COUNTER_LO	0x04
+#define REG_COUNTER_HI	0x08
+#define REG_COMPARE(n)	(0x0c + (n) * 4)
+#define MAX_TIMER	3
+#define DEFAULT_TIMER	3
+
+struct bcm2835_timer {
+	void __iomem *control;
+	void __iomem *compare;
+	int match_mask;
+	struct clock_event_device evt;
+	struct irqaction act;
+};
+
+static void __iomem *system_clock __read_mostly;
+
+static u32 notrace bcm2835_sched_read(void)
+{
+	return readl_relaxed(system_clock);
+}
+
+static void bcm2835_time_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *evt_dev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	default:
+		WARN(1, "%s: unhandled event mode %d\n", __func__, mode);
+		break;
+	}
+}
+
+static int bcm2835_time_set_next_event(unsigned long event,
+	struct clock_event_device *evt_dev)
+{
+	struct bcm2835_timer *timer = container_of(evt_dev,
+		struct bcm2835_timer, evt);
+	writel_relaxed(readl_relaxed(system_clock) + event,
+		timer->compare);
+	return 0;
+}
+
+static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id)
+{
+	struct bcm2835_timer *timer = dev_id;
+	void (*event_handler)(struct clock_event_device *);
+	if (readl_relaxed(timer->control) & timer->match_mask) {
+		writel_relaxed(timer->match_mask, timer->control);
+
+		event_handler = ACCESS_ONCE(timer->evt.event_handler);
+		if (event_handler)
+			event_handler(&timer->evt);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static struct of_device_id bcm2835_time_match[] __initconst = {
+	{ .compatible = "brcm,bcm2835-system-timer" },
+	{}
+};
+
+static void __init bcm2835_time_init(void)
+{
+	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");
+
+	if (of_property_read_u32(node, "clock-frequency", &freq))
+		panic("Can't read clock-frequency");
+
+	system_clock = base + REG_COUNTER_LO;
+	setup_sched_clock(bcm2835_sched_read, 32, freq);
+
+	clocksource_mmio_init(base + REG_COUNTER_LO, node->name,
+		freq, 300, 32, clocksource_mmio_readl_up);
+
+	irq = irq_of_parse_and_map(node, DEFAULT_TIMER);
+	if (irq <= 0)
+		panic("Can't parse IRQ");
+
+	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
+	if (!timer)
+		panic("Can't allocate timer struct\n");
+
+	timer->control = base + REG_CONTROL;
+	timer->compare = base + REG_COMPARE(DEFAULT_TIMER);
+	timer->match_mask = BIT(DEFAULT_TIMER);
+	timer->evt.name = node->name;
+	timer->evt.rating = 300;
+	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
+	timer->evt.set_mode = bcm2835_time_set_mode;
+	timer->evt.set_next_event = bcm2835_time_set_next_event;
+	timer->evt.cpumask = cpumask_of(0);
+	timer->act.name = node->name;
+	timer->act.flags = IRQF_TIMER | IRQF_SHARED;
+	timer->act.dev_id = timer;
+	timer->act.handler = bcm2835_time_interrupt;
+
+	if (setup_irq(irq, &timer->act))
+		panic("Can't set up timer IRQ\n");
+
+	clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
+
+	pr_info("bcm2835: system timer (irq = %d)\n", irq);
+}
+
+struct sys_timer bcm2835_timer = {
+	.init = bcm2835_time_init,
+};