All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20121007015406.470633343@gmail.com>

diff --git a/a/1.txt b/N1/1.txt
index 1be3c73..e3c8192 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,3 +1,325 @@
-An embedded and charset-unspecified text was scrubbed...
-Name: arm-bcm476x-add-system-timer.patch
-URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121007/f50ca8e4/attachment.ksh>
+From: Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
+
+System timer implementation for the BCM476x SoCs.
+
+Signed-off-by: Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
+---
+ Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt |   22 +
+ arch/arm/boot/dts/bcm476x.dtsi                                        |    8 +
+ arch/arm/mach-bcm476x/bcm476x.c                                       |   10 -
+ drivers/clocksource/Makefile                                          |    1 +
+ drivers/clocksource/bcm476x_timer.c                                   |  188 ++++++++++
+ include/linux/bcm476x_timer.h                                         |   24 +
+ 6 files changed, 244 insertions(+), 9 deletions(-)
+
+Index: b/Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt
+===================================================================
+--- /dev/null
++++ b/Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt
+@@ -0,0 +1,22 @@
++BCM476x System Timer
++
++The System Timer peripheral provides either two or four 32-bit timer
++channels.  BCM476x has three timers at 0xba000, 0xbb000 and 0xd1000. The
++first two provide four channels, the last (in the AON - Always ON power
++domain) provides only two.
++
++Required properties:
++
++- compatible : should be "brcm,bcm476x-system-timer"
++- reg : Specifies base physical address and size of the registers.
++- interrupts : A list of 2 or 4 interrupt sinks; one per timer channel.
++- clock-frequency : The frequency of the clock that drives the counter, in Hz.
++
++Example:
++
++timer {
++	compatible = "brcm,bcm476x-system-timer";
++	reg = <0xba000 0x1000>;
++	interrupts = <4>, <11>;
++	clock-frequency = <24000000>;
++};
+Index: b/arch/arm/boot/dts/bcm476x.dtsi
+===================================================================
+--- a/arch/arm/boot/dts/bcm476x.dtsi
++++ b/arch/arm/boot/dts/bcm476x.dtsi
+@@ -14,6 +14,14 @@
+ 		#size-cells = <1>;
+ 		ranges;
+ 
++		timer {
++			compatible = "brcm,bcm476x-system-timer";
++			reg = <0xba000 0x1000>;
++			interrupt-parent = <&vic0>;
++			interrupts = <4>, <11>;
++			clock-frequency = <24000000>;
++		};
++
+ 		vic0: interrupt-controller@80000 {
+ 			compatible = "brcm,bcm476x-pl192", "arm,pl192-vic", "arm,primecell";
+ 			reg = <0x80000 0x1000>;
+Index: b/arch/arm/mach-bcm476x/bcm476x.c
+===================================================================
+--- a/arch/arm/mach-bcm476x/bcm476x.c
++++ b/arch/arm/mach-bcm476x/bcm476x.c
+@@ -17,11 +17,11 @@
+ #include <linux/init.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_platform.h>
++#include <linux/bcm476x_timer.h>
+ 
+ #include <asm/hardware/vic.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+-#include <asm/mach/time.h>
+ 
+ #define BCM476X_PERIPH_PHYS   0x00080000
+ #define BCM476X_PERIPH_VIRT   0xd0080000
+@@ -60,14 +60,6 @@ static void __init bcm476x_init_irq(void
+ 	of_irq_init(vic_of_match);
+ }
+ 
+-static void __init bcm476x_timer_init(void)
+-{
+-}
+-
+-struct sys_timer bcm476x_timer = {
+-	.init = bcm476x_timer_init
+-};
+-
+ static const char * const bcm476x_compat[] = {
+ 	"brcm,bcm476x",
+ 	NULL
+Index: b/drivers/clocksource/Makefile
+===================================================================
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -14,5 +14,6 @@ obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_
+ 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_ARCH_BCM476X)	+= bcm476x_timer.o
+ 
+ obj-$(CONFIG_CLKSRC_ARM_GENERIC)	+= arm_generic.o
+Index: b/drivers/clocksource/bcm476x_timer.c
+===================================================================
+--- /dev/null
++++ b/drivers/clocksource/bcm476x_timer.c
+@@ -0,0 +1,188 @@
++/*
++ * Broadcom BCM476x SoCs system timer
++ *
++ * Copyright (C) 2012 Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
++ *
++ * 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.
++ */
++
++#include <linux/bcm476x_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 TIMER_LOAD_OFFSET          0x00          /* load */
++#define TIMER_VALUE_OFFSET         0x04          /* value */
++#define TIMER_CONTROL_OFFSET       0x08          /* control */
++#define TIMER_INTCLR_OFFSET        0x0c          /* interrupt clear */
++#define TIMER_RIS_OFFSET           0x10          /* raw interrupt */
++#define TIMER_MIS_OFFSET           0x14          /* masked interrupt status */
++#define TIMER_BGLOAD_OFFSET        0x18          /* background load */
++
++#define TIMER_CTRL_ONESHOTMODE     BIT(0)        /* One shot mode */
++#define TIMER_CTRL_32BIT           BIT(1)        /* 32-bit counter mode */
++#define TIMER_CTRL_IE              BIT(5)        /* Interrupt enable */
++#define TIMER_CTRL_PERIODIC        BIT(6)        /* Periodic mode */
++#define TIMER_CTRL_EN              BIT(7)        /* Timer enable */
++#define TIMER_CTRL_CLK2            BIT(9)        /* Clock 2 selected */
++#define TIMER_CTRL_PREBY16         (1 << 2)      /* prescale divide by 16 */
++#define TIMER_CTRL_PREBY256        (2 << 2)      /* prescale divide by 256 */
++
++struct bcm476x_timer {
++	void __iomem *base;
++	struct clock_event_device evt;
++	struct irqaction act;
++};
++
++static inline void __iomem *to_load(struct bcm476x_timer *timer)
++{
++	return timer->base + TIMER_LOAD_OFFSET;
++}
++
++static inline void __iomem *to_control(struct bcm476x_timer *timer)
++{
++	return timer->base + TIMER_CONTROL_OFFSET;
++}
++
++static inline void __iomem *to_intclr(struct bcm476x_timer *timer)
++{
++	return timer->base + TIMER_INTCLR_OFFSET;
++}
++
++static inline void __iomem *to_ris(struct bcm476x_timer *timer)
++{
++	return timer->base + TIMER_RIS_OFFSET;
++}
++
++static inline void __iomem *to_mis(struct bcm476x_timer *timer)
++{
++	return timer->base + TIMER_MIS_OFFSET;
++}
++
++static void bcm476x_timer_set_mode(enum clock_event_mode mode,
++	struct clock_event_device *evt_dev)
++{
++	struct bcm476x_timer *timer;
++	u32 val;
++
++	timer = container_of(evt_dev, struct bcm476x_timer, evt);
++	val = TIMER_CTRL_CLK2 | TIMER_CTRL_32BIT |
++	      TIMER_CTRL_IE | TIMER_CTRL_EN;
++
++	switch (mode) {
++	case CLOCK_EVT_MODE_ONESHOT:
++		writel(val | TIMER_CTRL_ONESHOTMODE, to_control(timer));
++		break;
++	case CLOCK_EVT_MODE_RESUME:
++	case CLOCK_EVT_MODE_SHUTDOWN:
++		break;
++	default:
++		WARN(1, "%s: unhandled event mode %d\n", __func__, mode);
++		break;
++	}
++}
++
++static int bcm476x_timer_set_next_event(unsigned long event,
++	struct clock_event_device *evt_dev)
++{
++	struct bcm476x_timer *timer;
++
++	timer = container_of(evt_dev, struct bcm476x_timer, evt);
++	writel(event, to_load(timer));
++	return 0;
++}
++
++static irqreturn_t bcm476x_timer_interrupt(int irq, void *dev_id)
++{
++	struct bcm476x_timer *timer = dev_id;
++	void (*event_handler)(struct clock_event_device *);
++
++	/* check the (masked) interrupt status */
++	if (!readl_relaxed(to_mis(timer)))
++		return IRQ_NONE;
++
++	/* clear the timer interrupt */
++	writel_relaxed(1, to_intclr(timer));
++
++	event_handler = ACCESS_ONCE(timer->evt.event_handler);
++	if (event_handler)
++		event_handler(&timer->evt);
++
++	return IRQ_HANDLED;
++}
++
++static struct of_device_id bcm476x_timer_match[] __initconst = {
++	{ .compatible = "brcm,bcm476x-system-timer" },
++	{}
++};
++
++static void __init bcm476x_timer_init(void)
++{
++	struct device_node *node;
++	void __iomem *base;
++	u32 freq;
++	int irq;
++	struct bcm476x_timer *timer;
++
++	node = of_find_matching_node(NULL, bcm476x_timer_match);
++	if (!node)
++		panic("No bcm476x timer node");
++
++	base = of_iomap(node, 0);
++	if (!base)
++		panic("Can't remap timer registers");
++
++	if (of_property_read_u32(node, "clock-frequency", &freq))
++		panic("Can't read timer frequency");
++	if (freq != 32000 && freq != 24000000)
++		panic("Invalid timer frequency");
++
++	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
++	if (!timer)
++		panic("Can't allocate timer struct\n");
++
++	irq = irq_of_parse_and_map(node, 0);
++	if (irq <= 0)
++		panic("Can't parse timer IRQ");
++
++	timer->base = base;
++	timer->evt.name = node->name;
++	timer->evt.rating = 300;
++	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
++	timer->evt.set_mode = bcm476x_timer_set_mode;
++	timer->evt.set_next_event = bcm476x_timer_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 = bcm476x_timer_interrupt;
++
++	if (setup_irq(irq, &timer->act))
++		panic("Can't set up timer IRQ\n");
++
++	clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
++}
++
++struct sys_timer bcm476x_timer = {
++	.init = bcm476x_timer_init,
++};
+Index: b/include/linux/bcm476x_timer.h
+===================================================================
+--- /dev/null
++++ b/include/linux/bcm476x_timer.h
+@@ -0,0 +1,24 @@
++/*
++ * Broadcom BCM476x SoCs system timer
++ *
++ * Copyright (C) 2012 Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
++ *
++ * 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.
++ */
++
++#ifndef __BCM476X_TIMER_H
++#define __BCM476X_TIMER_H
++
++#include <asm/mach/time.h>
++
++extern struct sys_timer bcm476x_timer;
++
++#endif
diff --git a/a/content_digest b/N1/content_digest
index 2aaca5a..a00d5e1 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,12 +1,337 @@
  "ref\020121007015300.828366635@gmail.com\0"
- "From\0cavokz@gmail.com (Domenico Andreoli)\0"
+ "From\0Domenico Andreoli <cavokz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>\0"
  "Subject\0[PATCH 2/6] ARM: bcm476x: Add system timer\0"
  "Date\0Sun, 07 Oct 2012 03:53:02 +0200\0"
- "To\0linux-arm-kernel@lists.infradead.org\0"
+ "To\0linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org\0"
+ "Cc\0Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>"
+ " devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org\0"
  "\00:1\0"
+ "fn\0arm-bcm476x-add-system-timer.patch\0"
  "b\0"
- "An embedded and charset-unspecified text was scrubbed...\n"
- "Name: arm-bcm476x-add-system-timer.patch\n"
- URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121007/f50ca8e4/attachment.ksh>
+ "From: Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>\n"
+ "\n"
+ "System timer implementation for the BCM476x SoCs.\n"
+ "\n"
+ "Signed-off-by: Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>\n"
+ "---\n"
+ " Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt |   22 +\n"
+ " arch/arm/boot/dts/bcm476x.dtsi                                        |    8 +\n"
+ " arch/arm/mach-bcm476x/bcm476x.c                                       |   10 -\n"
+ " drivers/clocksource/Makefile                                          |    1 +\n"
+ " drivers/clocksource/bcm476x_timer.c                                   |  188 ++++++++++\n"
+ " include/linux/bcm476x_timer.h                                         |   24 +\n"
+ " 6 files changed, 244 insertions(+), 9 deletions(-)\n"
+ "\n"
+ "Index: b/Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt\n"
+ "===================================================================\n"
+ "--- /dev/null\n"
+ "+++ b/Documentation/devicetree/bindings/timer/brcm,bcm476x-system-timer.txt\n"
+ "@@ -0,0 +1,22 @@\n"
+ "+BCM476x System Timer\n"
+ "+\n"
+ "+The System Timer peripheral provides either two or four 32-bit timer\n"
+ "+channels.  BCM476x has three timers at 0xba000, 0xbb000 and 0xd1000. The\n"
+ "+first two provide four channels, the last (in the AON - Always ON power\n"
+ "+domain) provides only two.\n"
+ "+\n"
+ "+Required properties:\n"
+ "+\n"
+ "+- compatible : should be \"brcm,bcm476x-system-timer\"\n"
+ "+- reg : Specifies base physical address and size of the registers.\n"
+ "+- interrupts : A list of 2 or 4 interrupt sinks; one per timer channel.\n"
+ "+- clock-frequency : The frequency of the clock that drives the counter, in Hz.\n"
+ "+\n"
+ "+Example:\n"
+ "+\n"
+ "+timer {\n"
+ "+\tcompatible = \"brcm,bcm476x-system-timer\";\n"
+ "+\treg = <0xba000 0x1000>;\n"
+ "+\tinterrupts = <4>, <11>;\n"
+ "+\tclock-frequency = <24000000>;\n"
+ "+};\n"
+ "Index: b/arch/arm/boot/dts/bcm476x.dtsi\n"
+ "===================================================================\n"
+ "--- a/arch/arm/boot/dts/bcm476x.dtsi\n"
+ "+++ b/arch/arm/boot/dts/bcm476x.dtsi\n"
+ "@@ -14,6 +14,14 @@\n"
+ " \t\t#size-cells = <1>;\n"
+ " \t\tranges;\n"
+ " \n"
+ "+\t\ttimer {\n"
+ "+\t\t\tcompatible = \"brcm,bcm476x-system-timer\";\n"
+ "+\t\t\treg = <0xba000 0x1000>;\n"
+ "+\t\t\tinterrupt-parent = <&vic0>;\n"
+ "+\t\t\tinterrupts = <4>, <11>;\n"
+ "+\t\t\tclock-frequency = <24000000>;\n"
+ "+\t\t};\n"
+ "+\n"
+ " \t\tvic0: interrupt-controller@80000 {\n"
+ " \t\t\tcompatible = \"brcm,bcm476x-pl192\", \"arm,pl192-vic\", \"arm,primecell\";\n"
+ " \t\t\treg = <0x80000 0x1000>;\n"
+ "Index: b/arch/arm/mach-bcm476x/bcm476x.c\n"
+ "===================================================================\n"
+ "--- a/arch/arm/mach-bcm476x/bcm476x.c\n"
+ "+++ b/arch/arm/mach-bcm476x/bcm476x.c\n"
+ "@@ -17,11 +17,11 @@\n"
+ " #include <linux/init.h>\n"
+ " #include <linux/of_irq.h>\n"
+ " #include <linux/of_platform.h>\n"
+ "+#include <linux/bcm476x_timer.h>\n"
+ " \n"
+ " #include <asm/hardware/vic.h>\n"
+ " #include <asm/mach/arch.h>\n"
+ " #include <asm/mach/map.h>\n"
+ "-#include <asm/mach/time.h>\n"
+ " \n"
+ " #define BCM476X_PERIPH_PHYS   0x00080000\n"
+ " #define BCM476X_PERIPH_VIRT   0xd0080000\n"
+ "@@ -60,14 +60,6 @@ static void __init bcm476x_init_irq(void\n"
+ " \tof_irq_init(vic_of_match);\n"
+ " }\n"
+ " \n"
+ "-static void __init bcm476x_timer_init(void)\n"
+ "-{\n"
+ "-}\n"
+ "-\n"
+ "-struct sys_timer bcm476x_timer = {\n"
+ "-\t.init = bcm476x_timer_init\n"
+ "-};\n"
+ "-\n"
+ " static const char * const bcm476x_compat[] = {\n"
+ " \t\"brcm,bcm476x\",\n"
+ " \tNULL\n"
+ "Index: b/drivers/clocksource/Makefile\n"
+ "===================================================================\n"
+ "--- a/drivers/clocksource/Makefile\n"
+ "+++ b/drivers/clocksource/Makefile\n"
+ "@@ -14,5 +14,6 @@ obj-$(CONFIG_DW_APB_TIMER_OF)\t+= dw_apb_\n"
+ " obj-$(CONFIG_CLKSRC_DBX500_PRCMU)\t+= clksrc-dbx500-prcmu.o\n"
+ " obj-$(CONFIG_ARMADA_370_XP_TIMER)\t+= time-armada-370-xp.o\n"
+ " obj-$(CONFIG_ARCH_BCM2835)\t+= bcm2835_timer.o\n"
+ "+obj-$(CONFIG_ARCH_BCM476X)\t+= bcm476x_timer.o\n"
+ " \n"
+ " obj-$(CONFIG_CLKSRC_ARM_GENERIC)\t+= arm_generic.o\n"
+ "Index: b/drivers/clocksource/bcm476x_timer.c\n"
+ "===================================================================\n"
+ "--- /dev/null\n"
+ "+++ b/drivers/clocksource/bcm476x_timer.c\n"
+ "@@ -0,0 +1,188 @@\n"
+ "+/*\n"
+ "+ * Broadcom BCM476x SoCs system timer\n"
+ "+ *\n"
+ "+ * Copyright (C) 2012 Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>\n"
+ "+ *\n"
+ "+ * This program is free software; you can redistribute it and/or modify\n"
+ "+ * it under the terms of the GNU General Public License as published by\n"
+ "+ * the Free Software Foundation; either version 2 of the License, or\n"
+ "+ * (at your option) any later version.\n"
+ "+ *\n"
+ "+ * This program is distributed in the hope that it will be useful,\n"
+ "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+ "+ * GNU General Public License for more details.\n"
+ "+ */\n"
+ "+\n"
+ "+#include <linux/bcm476x_timer.h>\n"
+ "+#include <linux/bitops.h>\n"
+ "+#include <linux/clockchips.h>\n"
+ "+#include <linux/clocksource.h>\n"
+ "+#include <linux/interrupt.h>\n"
+ "+#include <linux/irqreturn.h>\n"
+ "+#include <linux/kernel.h>\n"
+ "+#include <linux/module.h>\n"
+ "+#include <linux/of_address.h>\n"
+ "+#include <linux/of_irq.h>\n"
+ "+#include <linux/of_platform.h>\n"
+ "+#include <linux/slab.h>\n"
+ "+#include <linux/string.h>\n"
+ "+\n"
+ "+#include <asm/sched_clock.h>\n"
+ "+#include <asm/irq.h>\n"
+ "+\n"
+ "+#define TIMER_LOAD_OFFSET          0x00          /* load */\n"
+ "+#define TIMER_VALUE_OFFSET         0x04          /* value */\n"
+ "+#define TIMER_CONTROL_OFFSET       0x08          /* control */\n"
+ "+#define TIMER_INTCLR_OFFSET        0x0c          /* interrupt clear */\n"
+ "+#define TIMER_RIS_OFFSET           0x10          /* raw interrupt */\n"
+ "+#define TIMER_MIS_OFFSET           0x14          /* masked interrupt status */\n"
+ "+#define TIMER_BGLOAD_OFFSET        0x18          /* background load */\n"
+ "+\n"
+ "+#define TIMER_CTRL_ONESHOTMODE     BIT(0)        /* One shot mode */\n"
+ "+#define TIMER_CTRL_32BIT           BIT(1)        /* 32-bit counter mode */\n"
+ "+#define TIMER_CTRL_IE              BIT(5)        /* Interrupt enable */\n"
+ "+#define TIMER_CTRL_PERIODIC        BIT(6)        /* Periodic mode */\n"
+ "+#define TIMER_CTRL_EN              BIT(7)        /* Timer enable */\n"
+ "+#define TIMER_CTRL_CLK2            BIT(9)        /* Clock 2 selected */\n"
+ "+#define TIMER_CTRL_PREBY16         (1 << 2)      /* prescale divide by 16 */\n"
+ "+#define TIMER_CTRL_PREBY256        (2 << 2)      /* prescale divide by 256 */\n"
+ "+\n"
+ "+struct bcm476x_timer {\n"
+ "+\tvoid __iomem *base;\n"
+ "+\tstruct clock_event_device evt;\n"
+ "+\tstruct irqaction act;\n"
+ "+};\n"
+ "+\n"
+ "+static inline void __iomem *to_load(struct bcm476x_timer *timer)\n"
+ "+{\n"
+ "+\treturn timer->base + TIMER_LOAD_OFFSET;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void __iomem *to_control(struct bcm476x_timer *timer)\n"
+ "+{\n"
+ "+\treturn timer->base + TIMER_CONTROL_OFFSET;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void __iomem *to_intclr(struct bcm476x_timer *timer)\n"
+ "+{\n"
+ "+\treturn timer->base + TIMER_INTCLR_OFFSET;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void __iomem *to_ris(struct bcm476x_timer *timer)\n"
+ "+{\n"
+ "+\treturn timer->base + TIMER_RIS_OFFSET;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void __iomem *to_mis(struct bcm476x_timer *timer)\n"
+ "+{\n"
+ "+\treturn timer->base + TIMER_MIS_OFFSET;\n"
+ "+}\n"
+ "+\n"
+ "+static void bcm476x_timer_set_mode(enum clock_event_mode mode,\n"
+ "+\tstruct clock_event_device *evt_dev)\n"
+ "+{\n"
+ "+\tstruct bcm476x_timer *timer;\n"
+ "+\tu32 val;\n"
+ "+\n"
+ "+\ttimer = container_of(evt_dev, struct bcm476x_timer, evt);\n"
+ "+\tval = TIMER_CTRL_CLK2 | TIMER_CTRL_32BIT |\n"
+ "+\t      TIMER_CTRL_IE | TIMER_CTRL_EN;\n"
+ "+\n"
+ "+\tswitch (mode) {\n"
+ "+\tcase CLOCK_EVT_MODE_ONESHOT:\n"
+ "+\t\twritel(val | TIMER_CTRL_ONESHOTMODE, to_control(timer));\n"
+ "+\t\tbreak;\n"
+ "+\tcase CLOCK_EVT_MODE_RESUME:\n"
+ "+\tcase CLOCK_EVT_MODE_SHUTDOWN:\n"
+ "+\t\tbreak;\n"
+ "+\tdefault:\n"
+ "+\t\tWARN(1, \"%s: unhandled event mode %d\\n\", __func__, mode);\n"
+ "+\t\tbreak;\n"
+ "+\t}\n"
+ "+}\n"
+ "+\n"
+ "+static int bcm476x_timer_set_next_event(unsigned long event,\n"
+ "+\tstruct clock_event_device *evt_dev)\n"
+ "+{\n"
+ "+\tstruct bcm476x_timer *timer;\n"
+ "+\n"
+ "+\ttimer = container_of(evt_dev, struct bcm476x_timer, evt);\n"
+ "+\twritel(event, to_load(timer));\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+static irqreturn_t bcm476x_timer_interrupt(int irq, void *dev_id)\n"
+ "+{\n"
+ "+\tstruct bcm476x_timer *timer = dev_id;\n"
+ "+\tvoid (*event_handler)(struct clock_event_device *);\n"
+ "+\n"
+ "+\t/* check the (masked) interrupt status */\n"
+ "+\tif (!readl_relaxed(to_mis(timer)))\n"
+ "+\t\treturn IRQ_NONE;\n"
+ "+\n"
+ "+\t/* clear the timer interrupt */\n"
+ "+\twritel_relaxed(1, to_intclr(timer));\n"
+ "+\n"
+ "+\tevent_handler = ACCESS_ONCE(timer->evt.event_handler);\n"
+ "+\tif (event_handler)\n"
+ "+\t\tevent_handler(&timer->evt);\n"
+ "+\n"
+ "+\treturn IRQ_HANDLED;\n"
+ "+}\n"
+ "+\n"
+ "+static struct of_device_id bcm476x_timer_match[] __initconst = {\n"
+ "+\t{ .compatible = \"brcm,bcm476x-system-timer\" },\n"
+ "+\t{}\n"
+ "+};\n"
+ "+\n"
+ "+static void __init bcm476x_timer_init(void)\n"
+ "+{\n"
+ "+\tstruct device_node *node;\n"
+ "+\tvoid __iomem *base;\n"
+ "+\tu32 freq;\n"
+ "+\tint irq;\n"
+ "+\tstruct bcm476x_timer *timer;\n"
+ "+\n"
+ "+\tnode = of_find_matching_node(NULL, bcm476x_timer_match);\n"
+ "+\tif (!node)\n"
+ "+\t\tpanic(\"No bcm476x timer node\");\n"
+ "+\n"
+ "+\tbase = of_iomap(node, 0);\n"
+ "+\tif (!base)\n"
+ "+\t\tpanic(\"Can't remap timer registers\");\n"
+ "+\n"
+ "+\tif (of_property_read_u32(node, \"clock-frequency\", &freq))\n"
+ "+\t\tpanic(\"Can't read timer frequency\");\n"
+ "+\tif (freq != 32000 && freq != 24000000)\n"
+ "+\t\tpanic(\"Invalid timer frequency\");\n"
+ "+\n"
+ "+\ttimer = kzalloc(sizeof(*timer), GFP_KERNEL);\n"
+ "+\tif (!timer)\n"
+ "+\t\tpanic(\"Can't allocate timer struct\\n\");\n"
+ "+\n"
+ "+\tirq = irq_of_parse_and_map(node, 0);\n"
+ "+\tif (irq <= 0)\n"
+ "+\t\tpanic(\"Can't parse timer IRQ\");\n"
+ "+\n"
+ "+\ttimer->base = base;\n"
+ "+\ttimer->evt.name = node->name;\n"
+ "+\ttimer->evt.rating = 300;\n"
+ "+\ttimer->evt.features = CLOCK_EVT_FEAT_ONESHOT;\n"
+ "+\ttimer->evt.set_mode = bcm476x_timer_set_mode;\n"
+ "+\ttimer->evt.set_next_event = bcm476x_timer_set_next_event;\n"
+ "+\ttimer->evt.cpumask = cpumask_of(0);\n"
+ "+\ttimer->act.name = node->name;\n"
+ "+\ttimer->act.flags = IRQF_TIMER | IRQF_SHARED;\n"
+ "+\ttimer->act.dev_id = timer;\n"
+ "+\ttimer->act.handler = bcm476x_timer_interrupt;\n"
+ "+\n"
+ "+\tif (setup_irq(irq, &timer->act))\n"
+ "+\t\tpanic(\"Can't set up timer IRQ\\n\");\n"
+ "+\n"
+ "+\tclockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);\n"
+ "+}\n"
+ "+\n"
+ "+struct sys_timer bcm476x_timer = {\n"
+ "+\t.init = bcm476x_timer_init,\n"
+ "+};\n"
+ "Index: b/include/linux/bcm476x_timer.h\n"
+ "===================================================================\n"
+ "--- /dev/null\n"
+ "+++ b/include/linux/bcm476x_timer.h\n"
+ "@@ -0,0 +1,24 @@\n"
+ "+/*\n"
+ "+ * Broadcom BCM476x SoCs system timer\n"
+ "+ *\n"
+ "+ * Copyright (C) 2012 Domenico Andreoli <domenico.andreoli-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>\n"
+ "+ *\n"
+ "+ * This program is free software; you can redistribute it and/or modify\n"
+ "+ * it under the terms of the GNU General Public License as published by\n"
+ "+ * the Free Software Foundation; either version 2 of the License, or\n"
+ "+ * (at your option) any later version.\n"
+ "+ *\n"
+ "+ * This program is distributed in the hope that it will be useful,\n"
+ "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+ "+ * GNU General Public License for more details.\n"
+ "+ */\n"
+ "+\n"
+ "+#ifndef __BCM476X_TIMER_H\n"
+ "+#define __BCM476X_TIMER_H\n"
+ "+\n"
+ "+#include <asm/mach/time.h>\n"
+ "+\n"
+ "+extern struct sys_timer bcm476x_timer;\n"
+ "+\n"
+ +#endif
 
-fc487edac843927d57608ce0699835e20c9793c82d11c6d2f315ea06d1d7938b
+efc9651a2517dfe1b8a459d9c6bea506917457290d8f8496b84a161e8bd9957b

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.