| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 1 | /* | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 2 |  * Copyright (C) 2008 STMicroelectronics | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 3 |  * Copyright (C) 2010 Alessandro Rubini | 
| Linus Walleij | 8fbb97a2 | 2010-11-19 10:16:05 +0100 | [diff] [blame] | 4 |  * Copyright (C) 2010 Linus Walleij for ST-Ericsson | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 5 |  * | 
 | 6 |  * This program is free software; you can redistribute it and/or modify | 
 | 7 |  * it under the terms of the GNU General Public License version 2, as | 
 | 8 |  * published by the Free Software Foundation. | 
 | 9 |  */ | 
 | 10 | #include <linux/init.h> | 
 | 11 | #include <linux/interrupt.h> | 
 | 12 | #include <linux/irq.h> | 
 | 13 | #include <linux/io.h> | 
 | 14 | #include <linux/clockchips.h> | 
| Linus Walleij | 694e33a | 2012-10-18 14:01:25 +0200 | [diff] [blame] | 15 | #include <linux/clocksource.h> | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 16 | #include <linux/clk.h> | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 17 | #include <linux/jiffies.h> | 
| Fabio Baltieri | 6f179b7 | 2012-12-04 11:10:44 +0100 | [diff] [blame] | 18 | #include <linux/delay.h> | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 19 | #include <linux/err.h> | 
| Linus Walleij | 694e33a | 2012-10-18 14:01:25 +0200 | [diff] [blame] | 20 | #include <linux/platform_data/clocksource-nomadik-mtu.h> | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 21 | #include <asm/mach/time.h> | 
| Russell King | ec05aa1 | 2010-12-15 21:53:02 +0000 | [diff] [blame] | 22 | #include <asm/sched_clock.h> | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 23 |  | 
| Jonas Aaberg | 05387a9 | 2011-09-20 11:18:27 +0200 | [diff] [blame] | 24 | /* | 
| Jonas Aaberg | 05387a9 | 2011-09-20 11:18:27 +0200 | [diff] [blame] | 25 |  * The MTU device hosts four different counters, with 4 set of | 
 | 26 |  * registers. These are register names. | 
 | 27 |  */ | 
 | 28 |  | 
 | 29 | #define MTU_IMSC	0x00	/* Interrupt mask set/clear */ | 
 | 30 | #define MTU_RIS		0x04	/* Raw interrupt status */ | 
 | 31 | #define MTU_MIS		0x08	/* Masked interrupt status */ | 
 | 32 | #define MTU_ICR		0x0C	/* Interrupt clear register */ | 
 | 33 |  | 
 | 34 | /* per-timer registers take 0..3 as argument */ | 
 | 35 | #define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */ | 
 | 36 | #define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */ | 
 | 37 | #define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */ | 
 | 38 | #define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */ | 
 | 39 |  | 
 | 40 | /* bits for the control register */ | 
 | 41 | #define MTU_CRn_ENA		0x80 | 
 | 42 | #define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */ | 
 | 43 | #define MTU_CRn_PRESCALE_MASK	0x0c | 
 | 44 | #define MTU_CRn_PRESCALE_1		0x00 | 
 | 45 | #define MTU_CRn_PRESCALE_16		0x04 | 
 | 46 | #define MTU_CRn_PRESCALE_256		0x08 | 
 | 47 | #define MTU_CRn_32BITS		0x02 | 
 | 48 | #define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/ | 
 | 49 |  | 
 | 50 | /* Other registers are usual amba/primecell registers, currently not used */ | 
 | 51 | #define MTU_ITCR	0xff0 | 
 | 52 | #define MTU_ITOP	0xff4 | 
 | 53 |  | 
 | 54 | #define MTU_PERIPH_ID0	0xfe0 | 
 | 55 | #define MTU_PERIPH_ID1	0xfe4 | 
 | 56 | #define MTU_PERIPH_ID2	0xfe8 | 
 | 57 | #define MTU_PERIPH_ID3	0xfeC | 
 | 58 |  | 
 | 59 | #define MTU_PCELL0	0xff0 | 
 | 60 | #define MTU_PCELL1	0xff4 | 
 | 61 | #define MTU_PCELL2	0xff8 | 
 | 62 | #define MTU_PCELL3	0xffC | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 63 |  | 
| Linus Walleij | b957662 | 2012-01-11 09:46:59 +0100 | [diff] [blame] | 64 | static void __iomem *mtu_base; | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 65 | static bool clkevt_periodic; | 
 | 66 | static u32 clk_prescale; | 
 | 67 | static u32 nmdk_cycle;		/* write-once */ | 
| Fabio Baltieri | 6f179b7 | 2012-12-04 11:10:44 +0100 | [diff] [blame] | 68 | static struct delay_timer mtu_delay_timer; | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 69 |  | 
| Mattias Wallin | cba1383 | 2011-05-27 10:29:25 +0200 | [diff] [blame] | 70 | #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK | 
| Linus Walleij | 2a84751 | 2010-05-07 10:03:02 +0100 | [diff] [blame] | 71 | /* | 
| Linus Walleij | 2a84751 | 2010-05-07 10:03:02 +0100 | [diff] [blame] | 72 |  * Override the global weak sched_clock symbol with this | 
 | 73 |  * local implementation which uses the clocksource to get some | 
| Linus Walleij | 8fbb97a2 | 2010-11-19 10:16:05 +0100 | [diff] [blame] | 74 |  * better resolution when scheduling the kernel. | 
| Linus Walleij | 2a84751 | 2010-05-07 10:03:02 +0100 | [diff] [blame] | 75 |  */ | 
| Marc Zyngier | 2f0778af | 2011-12-15 12:19:23 +0100 | [diff] [blame] | 76 | static u32 notrace nomadik_read_sched_clock(void) | 
| Linus Walleij | 2a84751 | 2010-05-07 10:03:02 +0100 | [diff] [blame] | 77 | { | 
| Linus Walleij | 8fbb97a2 | 2010-11-19 10:16:05 +0100 | [diff] [blame] | 78 | 	if (unlikely(!mtu_base)) | 
 | 79 | 		return 0; | 
 | 80 |  | 
| Marc Zyngier | 2f0778af | 2011-12-15 12:19:23 +0100 | [diff] [blame] | 81 | 	return -readl(mtu_base + MTU_VAL(0)); | 
| Linus Walleij | 2a84751 | 2010-05-07 10:03:02 +0100 | [diff] [blame] | 82 | } | 
| Mattias Wallin | cba1383 | 2011-05-27 10:29:25 +0200 | [diff] [blame] | 83 | #endif | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 84 |  | 
| Fabio Baltieri | 6f179b7 | 2012-12-04 11:10:44 +0100 | [diff] [blame] | 85 | static unsigned long nmdk_timer_read_current_timer(void) | 
 | 86 | { | 
 | 87 | 	return ~readl_relaxed(mtu_base + MTU_VAL(0)); | 
 | 88 | } | 
 | 89 |  | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 90 | /* Clockevent device: use one-shot mode */ | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 91 | static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) | 
 | 92 | { | 
 | 93 | 	writel(1 << 1, mtu_base + MTU_IMSC); | 
 | 94 | 	writel(evt, mtu_base + MTU_LR(1)); | 
 | 95 | 	/* Load highest value, enable device, enable interrupts */ | 
 | 96 | 	writel(MTU_CRn_ONESHOT | clk_prescale | | 
 | 97 | 	       MTU_CRn_32BITS | MTU_CRn_ENA, | 
 | 98 | 	       mtu_base + MTU_CR(1)); | 
 | 99 |  | 
 | 100 | 	return 0; | 
 | 101 | } | 
 | 102 |  | 
| Jonas Aaberg | 05387a9 | 2011-09-20 11:18:27 +0200 | [diff] [blame] | 103 | void nmdk_clkevt_reset(void) | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 104 | { | 
 | 105 | 	if (clkevt_periodic) { | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 106 | 		/* Timer: configure load and background-load, and fire it up */ | 
 | 107 | 		writel(nmdk_cycle, mtu_base + MTU_LR(1)); | 
 | 108 | 		writel(nmdk_cycle, mtu_base + MTU_BGLR(1)); | 
 | 109 |  | 
 | 110 | 		writel(MTU_CRn_PERIODIC | clk_prescale | | 
 | 111 | 		       MTU_CRn_32BITS | MTU_CRn_ENA, | 
 | 112 | 		       mtu_base + MTU_CR(1)); | 
 | 113 | 		writel(1 << 1, mtu_base + MTU_IMSC); | 
 | 114 | 	} else { | 
 | 115 | 		/* Generate an interrupt to start the clockevent again */ | 
 | 116 | 		(void) nmdk_clkevt_next(nmdk_cycle, NULL); | 
 | 117 | 	} | 
 | 118 | } | 
 | 119 |  | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 120 | static void nmdk_clkevt_mode(enum clock_event_mode mode, | 
 | 121 | 			     struct clock_event_device *dev) | 
 | 122 | { | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 123 | 	switch (mode) { | 
 | 124 | 	case CLOCK_EVT_MODE_PERIODIC: | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 125 | 		clkevt_periodic = true; | 
 | 126 | 		nmdk_clkevt_reset(); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 127 | 		break; | 
 | 128 | 	case CLOCK_EVT_MODE_ONESHOT: | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 129 | 		clkevt_periodic = false; | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 130 | 		break; | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 131 | 	case CLOCK_EVT_MODE_SHUTDOWN: | 
 | 132 | 	case CLOCK_EVT_MODE_UNUSED: | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 133 | 		writel(0, mtu_base + MTU_IMSC); | 
| Linus Walleij | 2917947 | 2010-06-01 08:26:49 +0100 | [diff] [blame] | 134 | 		/* disable timer */ | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 135 | 		writel(0, mtu_base + MTU_CR(1)); | 
| Linus Walleij | 2917947 | 2010-06-01 08:26:49 +0100 | [diff] [blame] | 136 | 		/* load some high default value */ | 
 | 137 | 		writel(0xffffffff, mtu_base + MTU_LR(1)); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 138 | 		break; | 
 | 139 | 	case CLOCK_EVT_MODE_RESUME: | 
 | 140 | 		break; | 
 | 141 | 	} | 
 | 142 | } | 
 | 143 |  | 
| Stephen Warren | 8726e96 | 2012-11-07 17:07:45 -0700 | [diff] [blame] | 144 | void nmdk_clksrc_reset(void) | 
 | 145 | { | 
 | 146 | 	/* Disable */ | 
 | 147 | 	writel(0, mtu_base + MTU_CR(0)); | 
 | 148 |  | 
 | 149 | 	/* ClockSource: configure load and background-load, and fire it up */ | 
 | 150 | 	writel(nmdk_cycle, mtu_base + MTU_LR(0)); | 
 | 151 | 	writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); | 
 | 152 |  | 
 | 153 | 	writel(clk_prescale | MTU_CRn_32BITS | MTU_CRn_ENA, | 
 | 154 | 	       mtu_base + MTU_CR(0)); | 
 | 155 | } | 
 | 156 |  | 
 | 157 | static void nmdk_clkevt_resume(struct clock_event_device *cedev) | 
 | 158 | { | 
 | 159 | 	nmdk_clkevt_reset(); | 
 | 160 | 	nmdk_clksrc_reset(); | 
 | 161 | } | 
 | 162 |  | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 163 | static struct clock_event_device nmdk_clkevt = { | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 164 | 	.name		= "mtu_1", | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 165 | 	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 166 | 	.rating		= 200, | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 167 | 	.set_mode	= nmdk_clkevt_mode, | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 168 | 	.set_next_event	= nmdk_clkevt_next, | 
| Stephen Warren | 8726e96 | 2012-11-07 17:07:45 -0700 | [diff] [blame] | 169 | 	.resume		= nmdk_clkevt_resume, | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 170 | }; | 
 | 171 |  | 
 | 172 | /* | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 173 |  * IRQ Handler for timer 1 of the MTU block. | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 174 |  */ | 
 | 175 | static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) | 
 | 176 | { | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 177 | 	struct clock_event_device *evdev = dev_id; | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 178 |  | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 179 | 	writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */ | 
 | 180 | 	evdev->event_handler(evdev); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 181 | 	return IRQ_HANDLED; | 
 | 182 | } | 
 | 183 |  | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 184 | static struct irqaction nmdk_timer_irq = { | 
 | 185 | 	.name		= "Nomadik Timer Tick", | 
 | 186 | 	.flags		= IRQF_DISABLED | IRQF_TIMER, | 
 | 187 | 	.handler	= nmdk_timer_interrupt, | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 188 | 	.dev_id		= &nmdk_clkevt, | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 189 | }; | 
 | 190 |  | 
| Linus Walleij | 0813069 | 2012-10-18 11:06:02 +0200 | [diff] [blame] | 191 | void __init nmdk_timer_init(void __iomem *base, int irq) | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 192 | { | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 193 | 	unsigned long rate; | 
| Ulf Hansson | 16defa6 | 2012-10-24 14:13:41 +0200 | [diff] [blame] | 194 | 	struct clk *clk0, *pclk0; | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 195 |  | 
| Linus Walleij | b957662 | 2012-01-11 09:46:59 +0100 | [diff] [blame] | 196 | 	mtu_base = base; | 
| Ulf Hansson | 16defa6 | 2012-10-24 14:13:41 +0200 | [diff] [blame] | 197 |  | 
 | 198 | 	pclk0 = clk_get_sys("mtu0", "apb_pclk"); | 
 | 199 | 	BUG_ON(IS_ERR(pclk0)); | 
 | 200 | 	BUG_ON(clk_prepare(pclk0) < 0); | 
 | 201 | 	BUG_ON(clk_enable(pclk0) < 0); | 
 | 202 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 203 | 	clk0 = clk_get_sys("mtu0", NULL); | 
 | 204 | 	BUG_ON(IS_ERR(clk0)); | 
| Linus Walleij | d3e8b75 | 2012-01-11 09:51:14 +0100 | [diff] [blame] | 205 | 	BUG_ON(clk_prepare(clk0) < 0); | 
 | 206 | 	BUG_ON(clk_enable(clk0) < 0); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 207 |  | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 208 | 	/* | 
| Linus Walleij | a0719f5 | 2010-09-13 13:40:04 +0100 | [diff] [blame] | 209 | 	 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz | 
 | 210 | 	 * for ux500. | 
 | 211 | 	 * Use a divide-by-16 counter if the tick rate is more than 32MHz. | 
 | 212 | 	 * At 32 MHz, the timer (with 32 bit counter) can be programmed | 
 | 213 | 	 * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer | 
 | 214 | 	 * with 16 gives too low timer resolution. | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 215 | 	 */ | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 216 | 	rate = clk_get_rate(clk0); | 
| Linus Walleij | a0719f5 | 2010-09-13 13:40:04 +0100 | [diff] [blame] | 217 | 	if (rate > 32000000) { | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 218 | 		rate /= 16; | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 219 | 		clk_prescale = MTU_CRn_PRESCALE_16; | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 220 | 	} else { | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 221 | 		clk_prescale = MTU_CRn_PRESCALE_1; | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 222 | 	} | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 223 |  | 
| Linus Walleij | 2136683 | 2012-10-18 11:12:31 +0200 | [diff] [blame] | 224 | 	/* Cycles for periodic mode */ | 
 | 225 | 	nmdk_cycle = DIV_ROUND_CLOSEST(rate, HZ); | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 226 |  | 
 | 227 |  | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 228 | 	/* Timer 0 is the free running clocksource */ | 
| Jonas Aaberg | 2f73a06 | 2011-09-14 10:32:51 +0200 | [diff] [blame] | 229 | 	nmdk_clksrc_reset(); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 230 |  | 
| Russell King | bfe45e0 | 2011-05-08 15:33:30 +0100 | [diff] [blame] | 231 | 	if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", | 
 | 232 | 			rate, 200, 32, clocksource_mmio_readl_down)) | 
| Alessandro Rubini | b102c01 | 2010-03-05 12:38:51 +0100 | [diff] [blame] | 233 | 		pr_err("timer: failed to initialize clock source %s\n", | 
| Russell King | bfe45e0 | 2011-05-08 15:33:30 +0100 | [diff] [blame] | 234 | 		       "mtu_0"); | 
| Marc Zyngier | 2f0778af | 2011-12-15 12:19:23 +0100 | [diff] [blame] | 235 |  | 
| Mattias Wallin | cba1383 | 2011-05-27 10:29:25 +0200 | [diff] [blame] | 236 | #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK | 
| Marc Zyngier | 2f0778af | 2011-12-15 12:19:23 +0100 | [diff] [blame] | 237 | 	setup_sched_clock(nomadik_read_sched_clock, 32, rate); | 
| Mattias Wallin | cba1383 | 2011-05-27 10:29:25 +0200 | [diff] [blame] | 238 | #endif | 
| Marc Zyngier | 2f0778af | 2011-12-15 12:19:23 +0100 | [diff] [blame] | 239 |  | 
| Linus Walleij | a3b86a6 | 2012-01-11 09:57:56 +0100 | [diff] [blame] | 240 | 	/* Timer 1 is used for events, register irq and clockevents */ | 
| Linus Walleij | 0813069 | 2012-10-18 11:06:02 +0200 | [diff] [blame] | 241 | 	setup_irq(irq, &nmdk_timer_irq); | 
| Linus Walleij | a3b86a6 | 2012-01-11 09:57:56 +0100 | [diff] [blame] | 242 | 	nmdk_clkevt.cpumask = cpumask_of(0); | 
| Daniel Lezcano | 00f4e13 | 2013-02-22 16:44:30 +0100 | [diff] [blame] | 243 | 	nmdk_clkevt.irq = irq; | 
| Linus Walleij | a3b86a6 | 2012-01-11 09:57:56 +0100 | [diff] [blame] | 244 | 	clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU); | 
| Fabio Baltieri | 6f179b7 | 2012-12-04 11:10:44 +0100 | [diff] [blame] | 245 |  | 
 | 246 | 	mtu_delay_timer.read_current_timer = &nmdk_timer_read_current_timer; | 
 | 247 | 	mtu_delay_timer.freq = rate; | 
 | 248 | 	register_current_timer_delay(&mtu_delay_timer); | 
| Alessandro Rubini | 28ad94e | 2009-07-02 19:06:47 +0100 | [diff] [blame] | 249 | } |