1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * SuperH Timer Support - CMT
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2008 Magnus Damm
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/clk.h>
9*4882a593Smuzhiyun #include <linux/clockchips.h>
10*4882a593Smuzhiyun #include <linux/clocksource.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/err.h>
13*4882a593Smuzhiyun #include <linux/init.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/io.h>
16*4882a593Smuzhiyun #include <linux/ioport.h>
17*4882a593Smuzhiyun #include <linux/irq.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/of.h>
20*4882a593Smuzhiyun #include <linux/of_device.h>
21*4882a593Smuzhiyun #include <linux/platform_device.h>
22*4882a593Smuzhiyun #include <linux/pm_domain.h>
23*4882a593Smuzhiyun #include <linux/pm_runtime.h>
24*4882a593Smuzhiyun #include <linux/sh_timer.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/spinlock.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #ifdef CONFIG_SUPERH
29*4882a593Smuzhiyun #include <asm/platform_early.h>
30*4882a593Smuzhiyun #endif
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun struct sh_cmt_device;
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun * The CMT comes in 5 different identified flavours, depending not only on the
36*4882a593Smuzhiyun * SoC but also on the particular instance. The following table lists the main
37*4882a593Smuzhiyun * characteristics of those flavours.
38*4882a593Smuzhiyun *
39*4882a593Smuzhiyun * 16B 32B 32B-F 48B R-Car Gen2
40*4882a593Smuzhiyun * -----------------------------------------------------------------------------
41*4882a593Smuzhiyun * Channels 2 1/4 1 6 2/8
42*4882a593Smuzhiyun * Control Width 16 16 16 16 32
43*4882a593Smuzhiyun * Counter Width 16 32 32 32/48 32/48
44*4882a593Smuzhiyun * Shared Start/Stop Y Y Y Y N
45*4882a593Smuzhiyun *
46*4882a593Smuzhiyun * The r8a73a4 / R-Car Gen2 version has a per-channel start/stop register
47*4882a593Smuzhiyun * located in the channel registers block. All other versions have a shared
48*4882a593Smuzhiyun * start/stop register located in the global space.
49*4882a593Smuzhiyun *
50*4882a593Smuzhiyun * Channels are indexed from 0 to N-1 in the documentation. The channel index
51*4882a593Smuzhiyun * infers the start/stop bit position in the control register and the channel
52*4882a593Smuzhiyun * registers block address. Some CMT instances have a subset of channels
53*4882a593Smuzhiyun * available, in which case the index in the documentation doesn't match the
54*4882a593Smuzhiyun * "real" index as implemented in hardware. This is for instance the case with
55*4882a593Smuzhiyun * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
56*4882a593Smuzhiyun * in the documentation but using start/stop bit 5 and having its registers
57*4882a593Smuzhiyun * block at 0x60.
58*4882a593Smuzhiyun *
59*4882a593Smuzhiyun * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
60*4882a593Smuzhiyun * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
61*4882a593Smuzhiyun */
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun enum sh_cmt_model {
64*4882a593Smuzhiyun SH_CMT_16BIT,
65*4882a593Smuzhiyun SH_CMT_32BIT,
66*4882a593Smuzhiyun SH_CMT_48BIT,
67*4882a593Smuzhiyun SH_CMT0_RCAR_GEN2,
68*4882a593Smuzhiyun SH_CMT1_RCAR_GEN2,
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun struct sh_cmt_info {
72*4882a593Smuzhiyun enum sh_cmt_model model;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun unsigned int channels_mask;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun unsigned long width; /* 16 or 32 bit version of hardware block */
77*4882a593Smuzhiyun u32 overflow_bit;
78*4882a593Smuzhiyun u32 clear_bits;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /* callbacks for CMSTR and CMCSR access */
81*4882a593Smuzhiyun u32 (*read_control)(void __iomem *base, unsigned long offs);
82*4882a593Smuzhiyun void (*write_control)(void __iomem *base, unsigned long offs,
83*4882a593Smuzhiyun u32 value);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /* callbacks for CMCNT and CMCOR access */
86*4882a593Smuzhiyun u32 (*read_count)(void __iomem *base, unsigned long offs);
87*4882a593Smuzhiyun void (*write_count)(void __iomem *base, unsigned long offs, u32 value);
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun struct sh_cmt_channel {
91*4882a593Smuzhiyun struct sh_cmt_device *cmt;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun unsigned int index; /* Index in the documentation */
94*4882a593Smuzhiyun unsigned int hwidx; /* Real hardware index */
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun void __iomem *iostart;
97*4882a593Smuzhiyun void __iomem *ioctrl;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun unsigned int timer_bit;
100*4882a593Smuzhiyun unsigned long flags;
101*4882a593Smuzhiyun u32 match_value;
102*4882a593Smuzhiyun u32 next_match_value;
103*4882a593Smuzhiyun u32 max_match_value;
104*4882a593Smuzhiyun raw_spinlock_t lock;
105*4882a593Smuzhiyun struct clock_event_device ced;
106*4882a593Smuzhiyun struct clocksource cs;
107*4882a593Smuzhiyun u64 total_cycles;
108*4882a593Smuzhiyun bool cs_enabled;
109*4882a593Smuzhiyun };
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun struct sh_cmt_device {
112*4882a593Smuzhiyun struct platform_device *pdev;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun const struct sh_cmt_info *info;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun void __iomem *mapbase;
117*4882a593Smuzhiyun struct clk *clk;
118*4882a593Smuzhiyun unsigned long rate;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun raw_spinlock_t lock; /* Protect the shared start/stop register */
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun struct sh_cmt_channel *channels;
123*4882a593Smuzhiyun unsigned int num_channels;
124*4882a593Smuzhiyun unsigned int hw_channels;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun bool has_clockevent;
127*4882a593Smuzhiyun bool has_clocksource;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CMF (1 << 7)
131*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CMIE (1 << 6)
132*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CKS8 (0 << 0)
133*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CKS32 (1 << 0)
134*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CKS128 (2 << 0)
135*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CKS512 (3 << 0)
136*4882a593Smuzhiyun #define SH_CMT16_CMCSR_CKS_MASK (3 << 0)
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMF (1 << 15)
139*4882a593Smuzhiyun #define SH_CMT32_CMCSR_OVF (1 << 14)
140*4882a593Smuzhiyun #define SH_CMT32_CMCSR_WRFLG (1 << 13)
141*4882a593Smuzhiyun #define SH_CMT32_CMCSR_STTF (1 << 12)
142*4882a593Smuzhiyun #define SH_CMT32_CMCSR_STPF (1 << 11)
143*4882a593Smuzhiyun #define SH_CMT32_CMCSR_SSIE (1 << 10)
144*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMS (1 << 9)
145*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMM (1 << 8)
146*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMTOUT_IE (1 << 7)
147*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMR_NONE (0 << 4)
148*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMR_DMA (1 << 4)
149*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMR_IRQ (2 << 4)
150*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CMR_MASK (3 << 4)
151*4882a593Smuzhiyun #define SH_CMT32_CMCSR_DBGIVD (1 << 3)
152*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CKS_RCLK8 (4 << 0)
153*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CKS_RCLK32 (5 << 0)
154*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CKS_RCLK128 (6 << 0)
155*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CKS_RCLK1 (7 << 0)
156*4882a593Smuzhiyun #define SH_CMT32_CMCSR_CKS_MASK (7 << 0)
157*4882a593Smuzhiyun
sh_cmt_read16(void __iomem * base,unsigned long offs)158*4882a593Smuzhiyun static u32 sh_cmt_read16(void __iomem *base, unsigned long offs)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun return ioread16(base + (offs << 1));
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
sh_cmt_read32(void __iomem * base,unsigned long offs)163*4882a593Smuzhiyun static u32 sh_cmt_read32(void __iomem *base, unsigned long offs)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun return ioread32(base + (offs << 2));
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
sh_cmt_write16(void __iomem * base,unsigned long offs,u32 value)168*4882a593Smuzhiyun static void sh_cmt_write16(void __iomem *base, unsigned long offs, u32 value)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun iowrite16(value, base + (offs << 1));
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
sh_cmt_write32(void __iomem * base,unsigned long offs,u32 value)173*4882a593Smuzhiyun static void sh_cmt_write32(void __iomem *base, unsigned long offs, u32 value)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun iowrite32(value, base + (offs << 2));
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun static const struct sh_cmt_info sh_cmt_info[] = {
179*4882a593Smuzhiyun [SH_CMT_16BIT] = {
180*4882a593Smuzhiyun .model = SH_CMT_16BIT,
181*4882a593Smuzhiyun .width = 16,
182*4882a593Smuzhiyun .overflow_bit = SH_CMT16_CMCSR_CMF,
183*4882a593Smuzhiyun .clear_bits = ~SH_CMT16_CMCSR_CMF,
184*4882a593Smuzhiyun .read_control = sh_cmt_read16,
185*4882a593Smuzhiyun .write_control = sh_cmt_write16,
186*4882a593Smuzhiyun .read_count = sh_cmt_read16,
187*4882a593Smuzhiyun .write_count = sh_cmt_write16,
188*4882a593Smuzhiyun },
189*4882a593Smuzhiyun [SH_CMT_32BIT] = {
190*4882a593Smuzhiyun .model = SH_CMT_32BIT,
191*4882a593Smuzhiyun .width = 32,
192*4882a593Smuzhiyun .overflow_bit = SH_CMT32_CMCSR_CMF,
193*4882a593Smuzhiyun .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
194*4882a593Smuzhiyun .read_control = sh_cmt_read16,
195*4882a593Smuzhiyun .write_control = sh_cmt_write16,
196*4882a593Smuzhiyun .read_count = sh_cmt_read32,
197*4882a593Smuzhiyun .write_count = sh_cmt_write32,
198*4882a593Smuzhiyun },
199*4882a593Smuzhiyun [SH_CMT_48BIT] = {
200*4882a593Smuzhiyun .model = SH_CMT_48BIT,
201*4882a593Smuzhiyun .channels_mask = 0x3f,
202*4882a593Smuzhiyun .width = 32,
203*4882a593Smuzhiyun .overflow_bit = SH_CMT32_CMCSR_CMF,
204*4882a593Smuzhiyun .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
205*4882a593Smuzhiyun .read_control = sh_cmt_read32,
206*4882a593Smuzhiyun .write_control = sh_cmt_write32,
207*4882a593Smuzhiyun .read_count = sh_cmt_read32,
208*4882a593Smuzhiyun .write_count = sh_cmt_write32,
209*4882a593Smuzhiyun },
210*4882a593Smuzhiyun [SH_CMT0_RCAR_GEN2] = {
211*4882a593Smuzhiyun .model = SH_CMT0_RCAR_GEN2,
212*4882a593Smuzhiyun .channels_mask = 0x60,
213*4882a593Smuzhiyun .width = 32,
214*4882a593Smuzhiyun .overflow_bit = SH_CMT32_CMCSR_CMF,
215*4882a593Smuzhiyun .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
216*4882a593Smuzhiyun .read_control = sh_cmt_read32,
217*4882a593Smuzhiyun .write_control = sh_cmt_write32,
218*4882a593Smuzhiyun .read_count = sh_cmt_read32,
219*4882a593Smuzhiyun .write_count = sh_cmt_write32,
220*4882a593Smuzhiyun },
221*4882a593Smuzhiyun [SH_CMT1_RCAR_GEN2] = {
222*4882a593Smuzhiyun .model = SH_CMT1_RCAR_GEN2,
223*4882a593Smuzhiyun .channels_mask = 0xff,
224*4882a593Smuzhiyun .width = 32,
225*4882a593Smuzhiyun .overflow_bit = SH_CMT32_CMCSR_CMF,
226*4882a593Smuzhiyun .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
227*4882a593Smuzhiyun .read_control = sh_cmt_read32,
228*4882a593Smuzhiyun .write_control = sh_cmt_write32,
229*4882a593Smuzhiyun .read_count = sh_cmt_read32,
230*4882a593Smuzhiyun .write_count = sh_cmt_write32,
231*4882a593Smuzhiyun },
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun #define CMCSR 0 /* channel register */
235*4882a593Smuzhiyun #define CMCNT 1 /* channel register */
236*4882a593Smuzhiyun #define CMCOR 2 /* channel register */
237*4882a593Smuzhiyun
sh_cmt_read_cmstr(struct sh_cmt_channel * ch)238*4882a593Smuzhiyun static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun if (ch->iostart)
241*4882a593Smuzhiyun return ch->cmt->info->read_control(ch->iostart, 0);
242*4882a593Smuzhiyun else
243*4882a593Smuzhiyun return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
sh_cmt_write_cmstr(struct sh_cmt_channel * ch,u32 value)246*4882a593Smuzhiyun static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun if (ch->iostart)
249*4882a593Smuzhiyun ch->cmt->info->write_control(ch->iostart, 0, value);
250*4882a593Smuzhiyun else
251*4882a593Smuzhiyun ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
sh_cmt_read_cmcsr(struct sh_cmt_channel * ch)254*4882a593Smuzhiyun static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
sh_cmt_write_cmcsr(struct sh_cmt_channel * ch,u32 value)259*4882a593Smuzhiyun static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun
sh_cmt_read_cmcnt(struct sh_cmt_channel * ch)264*4882a593Smuzhiyun static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
sh_cmt_write_cmcnt(struct sh_cmt_channel * ch,u32 value)269*4882a593Smuzhiyun static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
sh_cmt_write_cmcor(struct sh_cmt_channel * ch,u32 value)274*4882a593Smuzhiyun static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
sh_cmt_get_counter(struct sh_cmt_channel * ch,u32 * has_wrapped)279*4882a593Smuzhiyun static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun u32 v1, v2, v3;
282*4882a593Smuzhiyun u32 o1, o2;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun /* Make sure the timer value is stable. Stolen from acpi_pm.c */
287*4882a593Smuzhiyun do {
288*4882a593Smuzhiyun o2 = o1;
289*4882a593Smuzhiyun v1 = sh_cmt_read_cmcnt(ch);
290*4882a593Smuzhiyun v2 = sh_cmt_read_cmcnt(ch);
291*4882a593Smuzhiyun v3 = sh_cmt_read_cmcnt(ch);
292*4882a593Smuzhiyun o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
293*4882a593Smuzhiyun } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
294*4882a593Smuzhiyun || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun *has_wrapped = o1;
297*4882a593Smuzhiyun return v2;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
sh_cmt_start_stop_ch(struct sh_cmt_channel * ch,int start)300*4882a593Smuzhiyun static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun unsigned long flags;
303*4882a593Smuzhiyun u32 value;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun /* start stop register shared by multiple timer channels */
306*4882a593Smuzhiyun raw_spin_lock_irqsave(&ch->cmt->lock, flags);
307*4882a593Smuzhiyun value = sh_cmt_read_cmstr(ch);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (start)
310*4882a593Smuzhiyun value |= 1 << ch->timer_bit;
311*4882a593Smuzhiyun else
312*4882a593Smuzhiyun value &= ~(1 << ch->timer_bit);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun sh_cmt_write_cmstr(ch, value);
315*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&ch->cmt->lock, flags);
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
sh_cmt_enable(struct sh_cmt_channel * ch)318*4882a593Smuzhiyun static int sh_cmt_enable(struct sh_cmt_channel *ch)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun int k, ret;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun pm_runtime_get_sync(&ch->cmt->pdev->dev);
323*4882a593Smuzhiyun dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /* enable clock */
326*4882a593Smuzhiyun ret = clk_enable(ch->cmt->clk);
327*4882a593Smuzhiyun if (ret) {
328*4882a593Smuzhiyun dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
329*4882a593Smuzhiyun ch->index);
330*4882a593Smuzhiyun goto err0;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /* make sure channel is disabled */
334*4882a593Smuzhiyun sh_cmt_start_stop_ch(ch, 0);
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* configure channel, periodic mode and maximum timeout */
337*4882a593Smuzhiyun if (ch->cmt->info->width == 16) {
338*4882a593Smuzhiyun sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
339*4882a593Smuzhiyun SH_CMT16_CMCSR_CKS512);
340*4882a593Smuzhiyun } else {
341*4882a593Smuzhiyun sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
342*4882a593Smuzhiyun SH_CMT32_CMCSR_CMTOUT_IE |
343*4882a593Smuzhiyun SH_CMT32_CMCSR_CMR_IRQ |
344*4882a593Smuzhiyun SH_CMT32_CMCSR_CKS_RCLK8);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun sh_cmt_write_cmcor(ch, 0xffffffff);
348*4882a593Smuzhiyun sh_cmt_write_cmcnt(ch, 0);
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /*
351*4882a593Smuzhiyun * According to the sh73a0 user's manual, as CMCNT can be operated
352*4882a593Smuzhiyun * only by the RCLK (Pseudo 32 kHz), there's one restriction on
353*4882a593Smuzhiyun * modifying CMCNT register; two RCLK cycles are necessary before
354*4882a593Smuzhiyun * this register is either read or any modification of the value
355*4882a593Smuzhiyun * it holds is reflected in the LSI's actual operation.
356*4882a593Smuzhiyun *
357*4882a593Smuzhiyun * While at it, we're supposed to clear out the CMCNT as of this
358*4882a593Smuzhiyun * moment, so make sure it's processed properly here. This will
359*4882a593Smuzhiyun * take RCLKx2 at maximum.
360*4882a593Smuzhiyun */
361*4882a593Smuzhiyun for (k = 0; k < 100; k++) {
362*4882a593Smuzhiyun if (!sh_cmt_read_cmcnt(ch))
363*4882a593Smuzhiyun break;
364*4882a593Smuzhiyun udelay(1);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun if (sh_cmt_read_cmcnt(ch)) {
368*4882a593Smuzhiyun dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
369*4882a593Smuzhiyun ch->index);
370*4882a593Smuzhiyun ret = -ETIMEDOUT;
371*4882a593Smuzhiyun goto err1;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun /* enable channel */
375*4882a593Smuzhiyun sh_cmt_start_stop_ch(ch, 1);
376*4882a593Smuzhiyun return 0;
377*4882a593Smuzhiyun err1:
378*4882a593Smuzhiyun /* stop clock */
379*4882a593Smuzhiyun clk_disable(ch->cmt->clk);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun err0:
382*4882a593Smuzhiyun return ret;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
sh_cmt_disable(struct sh_cmt_channel * ch)385*4882a593Smuzhiyun static void sh_cmt_disable(struct sh_cmt_channel *ch)
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun /* disable channel */
388*4882a593Smuzhiyun sh_cmt_start_stop_ch(ch, 0);
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun /* disable interrupts in CMT block */
391*4882a593Smuzhiyun sh_cmt_write_cmcsr(ch, 0);
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun /* stop clock */
394*4882a593Smuzhiyun clk_disable(ch->cmt->clk);
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
397*4882a593Smuzhiyun pm_runtime_put(&ch->cmt->pdev->dev);
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun /* private flags */
401*4882a593Smuzhiyun #define FLAG_CLOCKEVENT (1 << 0)
402*4882a593Smuzhiyun #define FLAG_CLOCKSOURCE (1 << 1)
403*4882a593Smuzhiyun #define FLAG_REPROGRAM (1 << 2)
404*4882a593Smuzhiyun #define FLAG_SKIPEVENT (1 << 3)
405*4882a593Smuzhiyun #define FLAG_IRQCONTEXT (1 << 4)
406*4882a593Smuzhiyun
sh_cmt_clock_event_program_verify(struct sh_cmt_channel * ch,int absolute)407*4882a593Smuzhiyun static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
408*4882a593Smuzhiyun int absolute)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun u32 value = ch->next_match_value;
411*4882a593Smuzhiyun u32 new_match;
412*4882a593Smuzhiyun u32 delay = 0;
413*4882a593Smuzhiyun u32 now = 0;
414*4882a593Smuzhiyun u32 has_wrapped;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun now = sh_cmt_get_counter(ch, &has_wrapped);
417*4882a593Smuzhiyun ch->flags |= FLAG_REPROGRAM; /* force reprogram */
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun if (has_wrapped) {
420*4882a593Smuzhiyun /* we're competing with the interrupt handler.
421*4882a593Smuzhiyun * -> let the interrupt handler reprogram the timer.
422*4882a593Smuzhiyun * -> interrupt number two handles the event.
423*4882a593Smuzhiyun */
424*4882a593Smuzhiyun ch->flags |= FLAG_SKIPEVENT;
425*4882a593Smuzhiyun return;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun if (absolute)
429*4882a593Smuzhiyun now = 0;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun do {
432*4882a593Smuzhiyun /* reprogram the timer hardware,
433*4882a593Smuzhiyun * but don't save the new match value yet.
434*4882a593Smuzhiyun */
435*4882a593Smuzhiyun new_match = now + value + delay;
436*4882a593Smuzhiyun if (new_match > ch->max_match_value)
437*4882a593Smuzhiyun new_match = ch->max_match_value;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun sh_cmt_write_cmcor(ch, new_match);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun now = sh_cmt_get_counter(ch, &has_wrapped);
442*4882a593Smuzhiyun if (has_wrapped && (new_match > ch->match_value)) {
443*4882a593Smuzhiyun /* we are changing to a greater match value,
444*4882a593Smuzhiyun * so this wrap must be caused by the counter
445*4882a593Smuzhiyun * matching the old value.
446*4882a593Smuzhiyun * -> first interrupt reprograms the timer.
447*4882a593Smuzhiyun * -> interrupt number two handles the event.
448*4882a593Smuzhiyun */
449*4882a593Smuzhiyun ch->flags |= FLAG_SKIPEVENT;
450*4882a593Smuzhiyun break;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun if (has_wrapped) {
454*4882a593Smuzhiyun /* we are changing to a smaller match value,
455*4882a593Smuzhiyun * so the wrap must be caused by the counter
456*4882a593Smuzhiyun * matching the new value.
457*4882a593Smuzhiyun * -> save programmed match value.
458*4882a593Smuzhiyun * -> let isr handle the event.
459*4882a593Smuzhiyun */
460*4882a593Smuzhiyun ch->match_value = new_match;
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /* be safe: verify hardware settings */
465*4882a593Smuzhiyun if (now < new_match) {
466*4882a593Smuzhiyun /* timer value is below match value, all good.
467*4882a593Smuzhiyun * this makes sure we won't miss any match events.
468*4882a593Smuzhiyun * -> save programmed match value.
469*4882a593Smuzhiyun * -> let isr handle the event.
470*4882a593Smuzhiyun */
471*4882a593Smuzhiyun ch->match_value = new_match;
472*4882a593Smuzhiyun break;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* the counter has reached a value greater
476*4882a593Smuzhiyun * than our new match value. and since the
477*4882a593Smuzhiyun * has_wrapped flag isn't set we must have
478*4882a593Smuzhiyun * programmed a too close event.
479*4882a593Smuzhiyun * -> increase delay and retry.
480*4882a593Smuzhiyun */
481*4882a593Smuzhiyun if (delay)
482*4882a593Smuzhiyun delay <<= 1;
483*4882a593Smuzhiyun else
484*4882a593Smuzhiyun delay = 1;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun if (!delay)
487*4882a593Smuzhiyun dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
488*4882a593Smuzhiyun ch->index);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun } while (delay);
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
__sh_cmt_set_next(struct sh_cmt_channel * ch,unsigned long delta)493*4882a593Smuzhiyun static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun if (delta > ch->max_match_value)
496*4882a593Smuzhiyun dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
497*4882a593Smuzhiyun ch->index);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun ch->next_match_value = delta;
500*4882a593Smuzhiyun sh_cmt_clock_event_program_verify(ch, 0);
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
sh_cmt_set_next(struct sh_cmt_channel * ch,unsigned long delta)503*4882a593Smuzhiyun static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun unsigned long flags;
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun raw_spin_lock_irqsave(&ch->lock, flags);
508*4882a593Smuzhiyun __sh_cmt_set_next(ch, delta);
509*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&ch->lock, flags);
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun
sh_cmt_interrupt(int irq,void * dev_id)512*4882a593Smuzhiyun static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun struct sh_cmt_channel *ch = dev_id;
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun /* clear flags */
517*4882a593Smuzhiyun sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
518*4882a593Smuzhiyun ch->cmt->info->clear_bits);
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /* update clock source counter to begin with if enabled
521*4882a593Smuzhiyun * the wrap flag should be cleared by the timer specific
522*4882a593Smuzhiyun * isr before we end up here.
523*4882a593Smuzhiyun */
524*4882a593Smuzhiyun if (ch->flags & FLAG_CLOCKSOURCE)
525*4882a593Smuzhiyun ch->total_cycles += ch->match_value + 1;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun if (!(ch->flags & FLAG_REPROGRAM))
528*4882a593Smuzhiyun ch->next_match_value = ch->max_match_value;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun ch->flags |= FLAG_IRQCONTEXT;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun if (ch->flags & FLAG_CLOCKEVENT) {
533*4882a593Smuzhiyun if (!(ch->flags & FLAG_SKIPEVENT)) {
534*4882a593Smuzhiyun if (clockevent_state_oneshot(&ch->ced)) {
535*4882a593Smuzhiyun ch->next_match_value = ch->max_match_value;
536*4882a593Smuzhiyun ch->flags |= FLAG_REPROGRAM;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun ch->ced.event_handler(&ch->ced);
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun ch->flags &= ~FLAG_SKIPEVENT;
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun if (ch->flags & FLAG_REPROGRAM) {
546*4882a593Smuzhiyun ch->flags &= ~FLAG_REPROGRAM;
547*4882a593Smuzhiyun sh_cmt_clock_event_program_verify(ch, 1);
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun if (ch->flags & FLAG_CLOCKEVENT)
550*4882a593Smuzhiyun if ((clockevent_state_shutdown(&ch->ced))
551*4882a593Smuzhiyun || (ch->match_value == ch->next_match_value))
552*4882a593Smuzhiyun ch->flags &= ~FLAG_REPROGRAM;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun ch->flags &= ~FLAG_IRQCONTEXT;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun return IRQ_HANDLED;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
sh_cmt_start(struct sh_cmt_channel * ch,unsigned long flag)560*4882a593Smuzhiyun static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun int ret = 0;
563*4882a593Smuzhiyun unsigned long flags;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun raw_spin_lock_irqsave(&ch->lock, flags);
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
568*4882a593Smuzhiyun ret = sh_cmt_enable(ch);
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun if (ret)
571*4882a593Smuzhiyun goto out;
572*4882a593Smuzhiyun ch->flags |= flag;
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* setup timeout if no clockevent */
575*4882a593Smuzhiyun if (ch->cmt->num_channels == 1 &&
576*4882a593Smuzhiyun flag == FLAG_CLOCKSOURCE && (!(ch->flags & FLAG_CLOCKEVENT)))
577*4882a593Smuzhiyun __sh_cmt_set_next(ch, ch->max_match_value);
578*4882a593Smuzhiyun out:
579*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&ch->lock, flags);
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun return ret;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
sh_cmt_stop(struct sh_cmt_channel * ch,unsigned long flag)584*4882a593Smuzhiyun static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun unsigned long flags;
587*4882a593Smuzhiyun unsigned long f;
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun raw_spin_lock_irqsave(&ch->lock, flags);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
592*4882a593Smuzhiyun ch->flags &= ~flag;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
595*4882a593Smuzhiyun sh_cmt_disable(ch);
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun /* adjust the timeout to maximum if only clocksource left */
598*4882a593Smuzhiyun if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
599*4882a593Smuzhiyun __sh_cmt_set_next(ch, ch->max_match_value);
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&ch->lock, flags);
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun
cs_to_sh_cmt(struct clocksource * cs)604*4882a593Smuzhiyun static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
605*4882a593Smuzhiyun {
606*4882a593Smuzhiyun return container_of(cs, struct sh_cmt_channel, cs);
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun
sh_cmt_clocksource_read(struct clocksource * cs)609*4882a593Smuzhiyun static u64 sh_cmt_clocksource_read(struct clocksource *cs)
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
612*4882a593Smuzhiyun u32 has_wrapped;
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun if (ch->cmt->num_channels == 1) {
615*4882a593Smuzhiyun unsigned long flags;
616*4882a593Smuzhiyun u64 value;
617*4882a593Smuzhiyun u32 raw;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun raw_spin_lock_irqsave(&ch->lock, flags);
620*4882a593Smuzhiyun value = ch->total_cycles;
621*4882a593Smuzhiyun raw = sh_cmt_get_counter(ch, &has_wrapped);
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun if (unlikely(has_wrapped))
624*4882a593Smuzhiyun raw += ch->match_value + 1;
625*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&ch->lock, flags);
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun return value + raw;
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun return sh_cmt_get_counter(ch, &has_wrapped);
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun
sh_cmt_clocksource_enable(struct clocksource * cs)633*4882a593Smuzhiyun static int sh_cmt_clocksource_enable(struct clocksource *cs)
634*4882a593Smuzhiyun {
635*4882a593Smuzhiyun int ret;
636*4882a593Smuzhiyun struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun WARN_ON(ch->cs_enabled);
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun ch->total_cycles = 0;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
643*4882a593Smuzhiyun if (!ret)
644*4882a593Smuzhiyun ch->cs_enabled = true;
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun return ret;
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
sh_cmt_clocksource_disable(struct clocksource * cs)649*4882a593Smuzhiyun static void sh_cmt_clocksource_disable(struct clocksource *cs)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun WARN_ON(!ch->cs_enabled);
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
656*4882a593Smuzhiyun ch->cs_enabled = false;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun
sh_cmt_clocksource_suspend(struct clocksource * cs)659*4882a593Smuzhiyun static void sh_cmt_clocksource_suspend(struct clocksource *cs)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun if (!ch->cs_enabled)
664*4882a593Smuzhiyun return;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
667*4882a593Smuzhiyun dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
sh_cmt_clocksource_resume(struct clocksource * cs)670*4882a593Smuzhiyun static void sh_cmt_clocksource_resume(struct clocksource *cs)
671*4882a593Smuzhiyun {
672*4882a593Smuzhiyun struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun if (!ch->cs_enabled)
675*4882a593Smuzhiyun return;
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun dev_pm_genpd_resume(&ch->cmt->pdev->dev);
678*4882a593Smuzhiyun sh_cmt_start(ch, FLAG_CLOCKSOURCE);
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun
sh_cmt_register_clocksource(struct sh_cmt_channel * ch,const char * name)681*4882a593Smuzhiyun static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
682*4882a593Smuzhiyun const char *name)
683*4882a593Smuzhiyun {
684*4882a593Smuzhiyun struct clocksource *cs = &ch->cs;
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun cs->name = name;
687*4882a593Smuzhiyun cs->rating = 125;
688*4882a593Smuzhiyun cs->read = sh_cmt_clocksource_read;
689*4882a593Smuzhiyun cs->enable = sh_cmt_clocksource_enable;
690*4882a593Smuzhiyun cs->disable = sh_cmt_clocksource_disable;
691*4882a593Smuzhiyun cs->suspend = sh_cmt_clocksource_suspend;
692*4882a593Smuzhiyun cs->resume = sh_cmt_clocksource_resume;
693*4882a593Smuzhiyun cs->mask = CLOCKSOURCE_MASK(ch->cmt->info->width);
694*4882a593Smuzhiyun cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
697*4882a593Smuzhiyun ch->index);
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun clocksource_register_hz(cs, ch->cmt->rate);
700*4882a593Smuzhiyun return 0;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
ced_to_sh_cmt(struct clock_event_device * ced)703*4882a593Smuzhiyun static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
704*4882a593Smuzhiyun {
705*4882a593Smuzhiyun return container_of(ced, struct sh_cmt_channel, ced);
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
sh_cmt_clock_event_start(struct sh_cmt_channel * ch,int periodic)708*4882a593Smuzhiyun static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun sh_cmt_start(ch, FLAG_CLOCKEVENT);
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun if (periodic)
713*4882a593Smuzhiyun sh_cmt_set_next(ch, ((ch->cmt->rate + HZ/2) / HZ) - 1);
714*4882a593Smuzhiyun else
715*4882a593Smuzhiyun sh_cmt_set_next(ch, ch->max_match_value);
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun
sh_cmt_clock_event_shutdown(struct clock_event_device * ced)718*4882a593Smuzhiyun static int sh_cmt_clock_event_shutdown(struct clock_event_device *ced)
719*4882a593Smuzhiyun {
720*4882a593Smuzhiyun struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun sh_cmt_stop(ch, FLAG_CLOCKEVENT);
723*4882a593Smuzhiyun return 0;
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
sh_cmt_clock_event_set_state(struct clock_event_device * ced,int periodic)726*4882a593Smuzhiyun static int sh_cmt_clock_event_set_state(struct clock_event_device *ced,
727*4882a593Smuzhiyun int periodic)
728*4882a593Smuzhiyun {
729*4882a593Smuzhiyun struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun /* deal with old setting first */
732*4882a593Smuzhiyun if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
733*4882a593Smuzhiyun sh_cmt_stop(ch, FLAG_CLOCKEVENT);
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun dev_info(&ch->cmt->pdev->dev, "ch%u: used for %s clock events\n",
736*4882a593Smuzhiyun ch->index, periodic ? "periodic" : "oneshot");
737*4882a593Smuzhiyun sh_cmt_clock_event_start(ch, periodic);
738*4882a593Smuzhiyun return 0;
739*4882a593Smuzhiyun }
740*4882a593Smuzhiyun
sh_cmt_clock_event_set_oneshot(struct clock_event_device * ced)741*4882a593Smuzhiyun static int sh_cmt_clock_event_set_oneshot(struct clock_event_device *ced)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun return sh_cmt_clock_event_set_state(ced, 0);
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun
sh_cmt_clock_event_set_periodic(struct clock_event_device * ced)746*4882a593Smuzhiyun static int sh_cmt_clock_event_set_periodic(struct clock_event_device *ced)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun return sh_cmt_clock_event_set_state(ced, 1);
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun
sh_cmt_clock_event_next(unsigned long delta,struct clock_event_device * ced)751*4882a593Smuzhiyun static int sh_cmt_clock_event_next(unsigned long delta,
752*4882a593Smuzhiyun struct clock_event_device *ced)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun BUG_ON(!clockevent_state_oneshot(ced));
757*4882a593Smuzhiyun if (likely(ch->flags & FLAG_IRQCONTEXT))
758*4882a593Smuzhiyun ch->next_match_value = delta - 1;
759*4882a593Smuzhiyun else
760*4882a593Smuzhiyun sh_cmt_set_next(ch, delta - 1);
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun return 0;
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun
sh_cmt_clock_event_suspend(struct clock_event_device * ced)765*4882a593Smuzhiyun static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
766*4882a593Smuzhiyun {
767*4882a593Smuzhiyun struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
770*4882a593Smuzhiyun clk_unprepare(ch->cmt->clk);
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun
sh_cmt_clock_event_resume(struct clock_event_device * ced)773*4882a593Smuzhiyun static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
774*4882a593Smuzhiyun {
775*4882a593Smuzhiyun struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun clk_prepare(ch->cmt->clk);
778*4882a593Smuzhiyun dev_pm_genpd_resume(&ch->cmt->pdev->dev);
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun
sh_cmt_register_clockevent(struct sh_cmt_channel * ch,const char * name)781*4882a593Smuzhiyun static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
782*4882a593Smuzhiyun const char *name)
783*4882a593Smuzhiyun {
784*4882a593Smuzhiyun struct clock_event_device *ced = &ch->ced;
785*4882a593Smuzhiyun int irq;
786*4882a593Smuzhiyun int ret;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun irq = platform_get_irq(ch->cmt->pdev, ch->index);
789*4882a593Smuzhiyun if (irq < 0)
790*4882a593Smuzhiyun return irq;
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun ret = request_irq(irq, sh_cmt_interrupt,
793*4882a593Smuzhiyun IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
794*4882a593Smuzhiyun dev_name(&ch->cmt->pdev->dev), ch);
795*4882a593Smuzhiyun if (ret) {
796*4882a593Smuzhiyun dev_err(&ch->cmt->pdev->dev, "ch%u: failed to request irq %d\n",
797*4882a593Smuzhiyun ch->index, irq);
798*4882a593Smuzhiyun return ret;
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun ced->name = name;
802*4882a593Smuzhiyun ced->features = CLOCK_EVT_FEAT_PERIODIC;
803*4882a593Smuzhiyun ced->features |= CLOCK_EVT_FEAT_ONESHOT;
804*4882a593Smuzhiyun ced->rating = 125;
805*4882a593Smuzhiyun ced->cpumask = cpu_possible_mask;
806*4882a593Smuzhiyun ced->set_next_event = sh_cmt_clock_event_next;
807*4882a593Smuzhiyun ced->set_state_shutdown = sh_cmt_clock_event_shutdown;
808*4882a593Smuzhiyun ced->set_state_periodic = sh_cmt_clock_event_set_periodic;
809*4882a593Smuzhiyun ced->set_state_oneshot = sh_cmt_clock_event_set_oneshot;
810*4882a593Smuzhiyun ced->suspend = sh_cmt_clock_event_suspend;
811*4882a593Smuzhiyun ced->resume = sh_cmt_clock_event_resume;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun /* TODO: calculate good shift from rate and counter bit width */
814*4882a593Smuzhiyun ced->shift = 32;
815*4882a593Smuzhiyun ced->mult = div_sc(ch->cmt->rate, NSEC_PER_SEC, ced->shift);
816*4882a593Smuzhiyun ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
817*4882a593Smuzhiyun ced->max_delta_ticks = ch->max_match_value;
818*4882a593Smuzhiyun ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
819*4882a593Smuzhiyun ced->min_delta_ticks = 0x1f;
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
822*4882a593Smuzhiyun ch->index);
823*4882a593Smuzhiyun clockevents_register_device(ced);
824*4882a593Smuzhiyun
825*4882a593Smuzhiyun return 0;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
sh_cmt_register(struct sh_cmt_channel * ch,const char * name,bool clockevent,bool clocksource)828*4882a593Smuzhiyun static int sh_cmt_register(struct sh_cmt_channel *ch, const char *name,
829*4882a593Smuzhiyun bool clockevent, bool clocksource)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun int ret;
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun if (clockevent) {
834*4882a593Smuzhiyun ch->cmt->has_clockevent = true;
835*4882a593Smuzhiyun ret = sh_cmt_register_clockevent(ch, name);
836*4882a593Smuzhiyun if (ret < 0)
837*4882a593Smuzhiyun return ret;
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun if (clocksource) {
841*4882a593Smuzhiyun ch->cmt->has_clocksource = true;
842*4882a593Smuzhiyun sh_cmt_register_clocksource(ch, name);
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun return 0;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun
sh_cmt_setup_channel(struct sh_cmt_channel * ch,unsigned int index,unsigned int hwidx,bool clockevent,bool clocksource,struct sh_cmt_device * cmt)848*4882a593Smuzhiyun static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
849*4882a593Smuzhiyun unsigned int hwidx, bool clockevent,
850*4882a593Smuzhiyun bool clocksource, struct sh_cmt_device *cmt)
851*4882a593Smuzhiyun {
852*4882a593Smuzhiyun int ret;
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun /* Skip unused channels. */
855*4882a593Smuzhiyun if (!clockevent && !clocksource)
856*4882a593Smuzhiyun return 0;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun ch->cmt = cmt;
859*4882a593Smuzhiyun ch->index = index;
860*4882a593Smuzhiyun ch->hwidx = hwidx;
861*4882a593Smuzhiyun ch->timer_bit = hwidx;
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun /*
864*4882a593Smuzhiyun * Compute the address of the channel control register block. For the
865*4882a593Smuzhiyun * timers with a per-channel start/stop register, compute its address
866*4882a593Smuzhiyun * as well.
867*4882a593Smuzhiyun */
868*4882a593Smuzhiyun switch (cmt->info->model) {
869*4882a593Smuzhiyun case SH_CMT_16BIT:
870*4882a593Smuzhiyun ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
871*4882a593Smuzhiyun break;
872*4882a593Smuzhiyun case SH_CMT_32BIT:
873*4882a593Smuzhiyun case SH_CMT_48BIT:
874*4882a593Smuzhiyun ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
875*4882a593Smuzhiyun break;
876*4882a593Smuzhiyun case SH_CMT0_RCAR_GEN2:
877*4882a593Smuzhiyun case SH_CMT1_RCAR_GEN2:
878*4882a593Smuzhiyun ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
879*4882a593Smuzhiyun ch->ioctrl = ch->iostart + 0x10;
880*4882a593Smuzhiyun ch->timer_bit = 0;
881*4882a593Smuzhiyun break;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
885*4882a593Smuzhiyun ch->max_match_value = ~0;
886*4882a593Smuzhiyun else
887*4882a593Smuzhiyun ch->max_match_value = (1 << cmt->info->width) - 1;
888*4882a593Smuzhiyun
889*4882a593Smuzhiyun ch->match_value = ch->max_match_value;
890*4882a593Smuzhiyun raw_spin_lock_init(&ch->lock);
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev),
893*4882a593Smuzhiyun clockevent, clocksource);
894*4882a593Smuzhiyun if (ret) {
895*4882a593Smuzhiyun dev_err(&cmt->pdev->dev, "ch%u: registration failed\n",
896*4882a593Smuzhiyun ch->index);
897*4882a593Smuzhiyun return ret;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun ch->cs_enabled = false;
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun return 0;
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun
sh_cmt_map_memory(struct sh_cmt_device * cmt)904*4882a593Smuzhiyun static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
905*4882a593Smuzhiyun {
906*4882a593Smuzhiyun struct resource *mem;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun mem = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
909*4882a593Smuzhiyun if (!mem) {
910*4882a593Smuzhiyun dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
911*4882a593Smuzhiyun return -ENXIO;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun cmt->mapbase = ioremap(mem->start, resource_size(mem));
915*4882a593Smuzhiyun if (cmt->mapbase == NULL) {
916*4882a593Smuzhiyun dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
917*4882a593Smuzhiyun return -ENXIO;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun return 0;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun static const struct platform_device_id sh_cmt_id_table[] = {
924*4882a593Smuzhiyun { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
925*4882a593Smuzhiyun { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
926*4882a593Smuzhiyun { }
927*4882a593Smuzhiyun };
928*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun static const struct of_device_id sh_cmt_of_table[] __maybe_unused = {
931*4882a593Smuzhiyun {
932*4882a593Smuzhiyun /* deprecated, preserved for backward compatibility */
933*4882a593Smuzhiyun .compatible = "renesas,cmt-48",
934*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT_48BIT]
935*4882a593Smuzhiyun },
936*4882a593Smuzhiyun {
937*4882a593Smuzhiyun /* deprecated, preserved for backward compatibility */
938*4882a593Smuzhiyun .compatible = "renesas,cmt-48-gen2",
939*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
940*4882a593Smuzhiyun },
941*4882a593Smuzhiyun {
942*4882a593Smuzhiyun .compatible = "renesas,r8a7740-cmt1",
943*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT_48BIT]
944*4882a593Smuzhiyun },
945*4882a593Smuzhiyun {
946*4882a593Smuzhiyun .compatible = "renesas,sh73a0-cmt1",
947*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT_48BIT]
948*4882a593Smuzhiyun },
949*4882a593Smuzhiyun {
950*4882a593Smuzhiyun .compatible = "renesas,rcar-gen2-cmt0",
951*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
952*4882a593Smuzhiyun },
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun .compatible = "renesas,rcar-gen2-cmt1",
955*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
956*4882a593Smuzhiyun },
957*4882a593Smuzhiyun {
958*4882a593Smuzhiyun .compatible = "renesas,rcar-gen3-cmt0",
959*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
960*4882a593Smuzhiyun },
961*4882a593Smuzhiyun {
962*4882a593Smuzhiyun .compatible = "renesas,rcar-gen3-cmt1",
963*4882a593Smuzhiyun .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
964*4882a593Smuzhiyun },
965*4882a593Smuzhiyun { }
966*4882a593Smuzhiyun };
967*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
968*4882a593Smuzhiyun
sh_cmt_setup(struct sh_cmt_device * cmt,struct platform_device * pdev)969*4882a593Smuzhiyun static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
970*4882a593Smuzhiyun {
971*4882a593Smuzhiyun unsigned int mask;
972*4882a593Smuzhiyun unsigned int i;
973*4882a593Smuzhiyun int ret;
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun cmt->pdev = pdev;
976*4882a593Smuzhiyun raw_spin_lock_init(&cmt->lock);
977*4882a593Smuzhiyun
978*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
979*4882a593Smuzhiyun cmt->info = of_device_get_match_data(&pdev->dev);
980*4882a593Smuzhiyun cmt->hw_channels = cmt->info->channels_mask;
981*4882a593Smuzhiyun } else if (pdev->dev.platform_data) {
982*4882a593Smuzhiyun struct sh_timer_config *cfg = pdev->dev.platform_data;
983*4882a593Smuzhiyun const struct platform_device_id *id = pdev->id_entry;
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun cmt->info = (const struct sh_cmt_info *)id->driver_data;
986*4882a593Smuzhiyun cmt->hw_channels = cfg->channels_mask;
987*4882a593Smuzhiyun } else {
988*4882a593Smuzhiyun dev_err(&cmt->pdev->dev, "missing platform data\n");
989*4882a593Smuzhiyun return -ENXIO;
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun /* Get hold of clock. */
993*4882a593Smuzhiyun cmt->clk = clk_get(&cmt->pdev->dev, "fck");
994*4882a593Smuzhiyun if (IS_ERR(cmt->clk)) {
995*4882a593Smuzhiyun dev_err(&cmt->pdev->dev, "cannot get clock\n");
996*4882a593Smuzhiyun return PTR_ERR(cmt->clk);
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun ret = clk_prepare(cmt->clk);
1000*4882a593Smuzhiyun if (ret < 0)
1001*4882a593Smuzhiyun goto err_clk_put;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun /* Determine clock rate. */
1004*4882a593Smuzhiyun ret = clk_enable(cmt->clk);
1005*4882a593Smuzhiyun if (ret < 0)
1006*4882a593Smuzhiyun goto err_clk_unprepare;
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun if (cmt->info->width == 16)
1009*4882a593Smuzhiyun cmt->rate = clk_get_rate(cmt->clk) / 512;
1010*4882a593Smuzhiyun else
1011*4882a593Smuzhiyun cmt->rate = clk_get_rate(cmt->clk) / 8;
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun clk_disable(cmt->clk);
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun /* Map the memory resource(s). */
1016*4882a593Smuzhiyun ret = sh_cmt_map_memory(cmt);
1017*4882a593Smuzhiyun if (ret < 0)
1018*4882a593Smuzhiyun goto err_clk_unprepare;
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun /* Allocate and setup the channels. */
1021*4882a593Smuzhiyun cmt->num_channels = hweight8(cmt->hw_channels);
1022*4882a593Smuzhiyun cmt->channels = kcalloc(cmt->num_channels, sizeof(*cmt->channels),
1023*4882a593Smuzhiyun GFP_KERNEL);
1024*4882a593Smuzhiyun if (cmt->channels == NULL) {
1025*4882a593Smuzhiyun ret = -ENOMEM;
1026*4882a593Smuzhiyun goto err_unmap;
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun /*
1030*4882a593Smuzhiyun * Use the first channel as a clock event device and the second channel
1031*4882a593Smuzhiyun * as a clock source. If only one channel is available use it for both.
1032*4882a593Smuzhiyun */
1033*4882a593Smuzhiyun for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
1034*4882a593Smuzhiyun unsigned int hwidx = ffs(mask) - 1;
1035*4882a593Smuzhiyun bool clocksource = i == 1 || cmt->num_channels == 1;
1036*4882a593Smuzhiyun bool clockevent = i == 0;
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun ret = sh_cmt_setup_channel(&cmt->channels[i], i, hwidx,
1039*4882a593Smuzhiyun clockevent, clocksource, cmt);
1040*4882a593Smuzhiyun if (ret < 0)
1041*4882a593Smuzhiyun goto err_unmap;
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun mask &= ~(1 << hwidx);
1044*4882a593Smuzhiyun }
1045*4882a593Smuzhiyun
1046*4882a593Smuzhiyun platform_set_drvdata(pdev, cmt);
1047*4882a593Smuzhiyun
1048*4882a593Smuzhiyun return 0;
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun err_unmap:
1051*4882a593Smuzhiyun kfree(cmt->channels);
1052*4882a593Smuzhiyun iounmap(cmt->mapbase);
1053*4882a593Smuzhiyun err_clk_unprepare:
1054*4882a593Smuzhiyun clk_unprepare(cmt->clk);
1055*4882a593Smuzhiyun err_clk_put:
1056*4882a593Smuzhiyun clk_put(cmt->clk);
1057*4882a593Smuzhiyun return ret;
1058*4882a593Smuzhiyun }
1059*4882a593Smuzhiyun
sh_cmt_probe(struct platform_device * pdev)1060*4882a593Smuzhiyun static int sh_cmt_probe(struct platform_device *pdev)
1061*4882a593Smuzhiyun {
1062*4882a593Smuzhiyun struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
1063*4882a593Smuzhiyun int ret;
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun if (!is_sh_early_platform_device(pdev)) {
1066*4882a593Smuzhiyun pm_runtime_set_active(&pdev->dev);
1067*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
1068*4882a593Smuzhiyun }
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun if (cmt) {
1071*4882a593Smuzhiyun dev_info(&pdev->dev, "kept as earlytimer\n");
1072*4882a593Smuzhiyun goto out;
1073*4882a593Smuzhiyun }
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
1076*4882a593Smuzhiyun if (cmt == NULL)
1077*4882a593Smuzhiyun return -ENOMEM;
1078*4882a593Smuzhiyun
1079*4882a593Smuzhiyun ret = sh_cmt_setup(cmt, pdev);
1080*4882a593Smuzhiyun if (ret) {
1081*4882a593Smuzhiyun kfree(cmt);
1082*4882a593Smuzhiyun pm_runtime_idle(&pdev->dev);
1083*4882a593Smuzhiyun return ret;
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun if (is_sh_early_platform_device(pdev))
1086*4882a593Smuzhiyun return 0;
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun out:
1089*4882a593Smuzhiyun if (cmt->has_clockevent || cmt->has_clocksource)
1090*4882a593Smuzhiyun pm_runtime_irq_safe(&pdev->dev);
1091*4882a593Smuzhiyun else
1092*4882a593Smuzhiyun pm_runtime_idle(&pdev->dev);
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun return 0;
1095*4882a593Smuzhiyun }
1096*4882a593Smuzhiyun
sh_cmt_remove(struct platform_device * pdev)1097*4882a593Smuzhiyun static int sh_cmt_remove(struct platform_device *pdev)
1098*4882a593Smuzhiyun {
1099*4882a593Smuzhiyun return -EBUSY; /* cannot unregister clockevent and clocksource */
1100*4882a593Smuzhiyun }
1101*4882a593Smuzhiyun
1102*4882a593Smuzhiyun static struct platform_driver sh_cmt_device_driver = {
1103*4882a593Smuzhiyun .probe = sh_cmt_probe,
1104*4882a593Smuzhiyun .remove = sh_cmt_remove,
1105*4882a593Smuzhiyun .driver = {
1106*4882a593Smuzhiyun .name = "sh_cmt",
1107*4882a593Smuzhiyun .of_match_table = of_match_ptr(sh_cmt_of_table),
1108*4882a593Smuzhiyun },
1109*4882a593Smuzhiyun .id_table = sh_cmt_id_table,
1110*4882a593Smuzhiyun };
1111*4882a593Smuzhiyun
sh_cmt_init(void)1112*4882a593Smuzhiyun static int __init sh_cmt_init(void)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun return platform_driver_register(&sh_cmt_device_driver);
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun
sh_cmt_exit(void)1117*4882a593Smuzhiyun static void __exit sh_cmt_exit(void)
1118*4882a593Smuzhiyun {
1119*4882a593Smuzhiyun platform_driver_unregister(&sh_cmt_device_driver);
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun #ifdef CONFIG_SUPERH
1123*4882a593Smuzhiyun sh_early_platform_init("earlytimer", &sh_cmt_device_driver);
1124*4882a593Smuzhiyun #endif
1125*4882a593Smuzhiyun
1126*4882a593Smuzhiyun subsys_initcall(sh_cmt_init);
1127*4882a593Smuzhiyun module_exit(sh_cmt_exit);
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun MODULE_AUTHOR("Magnus Damm");
1130*4882a593Smuzhiyun MODULE_DESCRIPTION("SuperH CMT Timer Driver");
1131*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1132