Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
[linux/fpc-iii.git] / drivers / clocksource / h8300_timer16.c
blob82941c1e9e33f0d098ae4b0b7273fa263c3b9ce0
1 /*
2 * H8/300 16bit Timer driver
4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp>
5 */
7 #include <linux/errno.h>
8 #include <linux/kernel.h>
9 #include <linux/param.h>
10 #include <linux/string.h>
11 #include <linux/slab.h>
12 #include <linux/interrupt.h>
13 #include <linux/init.h>
14 #include <linux/platform_device.h>
15 #include <linux/clocksource.h>
16 #include <linux/module.h>
17 #include <linux/clk.h>
18 #include <linux/io.h>
19 #include <linux/of.h>
21 #include <asm/segment.h>
22 #include <asm/irq.h>
24 #define TSTR 0
25 #define TSNC 1
26 #define TMDR 2
27 #define TOLR 3
28 #define TISRA 4
29 #define TISRB 5
30 #define TISRC 6
32 #define TCR 0
33 #define TIOR 1
34 #define TCNT 2
35 #define GRA 4
36 #define GRB 6
38 #define FLAG_REPROGRAM (1 << 0)
39 #define FLAG_SKIPEVENT (1 << 1)
40 #define FLAG_IRQCONTEXT (1 << 2)
41 #define FLAG_STARTED (1 << 3)
43 #define ONESHOT 0
44 #define PERIODIC 1
46 #define RELATIVE 0
47 #define ABSOLUTE 1
49 struct timer16_priv {
50 struct platform_device *pdev;
51 struct clocksource cs;
52 struct irqaction irqaction;
53 unsigned long total_cycles;
54 unsigned long mapbase;
55 unsigned long mapcommon;
56 unsigned long flags;
57 unsigned short gra;
58 unsigned short cs_enabled;
59 unsigned char enb;
60 unsigned char imfa;
61 unsigned char imiea;
62 unsigned char ovf;
63 raw_spinlock_t lock;
64 struct clk *clk;
67 static unsigned long timer16_get_counter(struct timer16_priv *p)
69 unsigned long v1, v2, v3;
70 int o1, o2;
72 o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf;
74 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
75 do {
76 o2 = o1;
77 v1 = ctrl_inw(p->mapbase + TCNT);
78 v2 = ctrl_inw(p->mapbase + TCNT);
79 v3 = ctrl_inw(p->mapbase + TCNT);
80 o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf;
81 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
82 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
84 v2 |= 0x10000;
85 return v2;
89 static irqreturn_t timer16_interrupt(int irq, void *dev_id)
91 struct timer16_priv *p = (struct timer16_priv *)dev_id;
93 ctrl_outb(ctrl_inb(p->mapcommon + TISRA) & ~p->imfa,
94 p->mapcommon + TISRA);
95 p->total_cycles += 0x10000;
97 return IRQ_HANDLED;
100 static inline struct timer16_priv *cs_to_priv(struct clocksource *cs)
102 return container_of(cs, struct timer16_priv, cs);
105 static cycle_t timer16_clocksource_read(struct clocksource *cs)
107 struct timer16_priv *p = cs_to_priv(cs);
108 unsigned long flags, raw;
109 unsigned long value;
111 raw_spin_lock_irqsave(&p->lock, flags);
112 value = p->total_cycles;
113 raw = timer16_get_counter(p);
114 raw_spin_unlock_irqrestore(&p->lock, flags);
116 return value + raw;
119 static int timer16_enable(struct clocksource *cs)
121 struct timer16_priv *p = cs_to_priv(cs);
123 WARN_ON(p->cs_enabled);
125 p->total_cycles = 0;
126 ctrl_outw(0x0000, p->mapbase + TCNT);
127 ctrl_outb(0x83, p->mapbase + TCR);
128 ctrl_outb(ctrl_inb(p->mapcommon + TSTR) | p->enb,
129 p->mapcommon + TSTR);
131 p->cs_enabled = true;
132 return 0;
135 static void timer16_disable(struct clocksource *cs)
137 struct timer16_priv *p = cs_to_priv(cs);
139 WARN_ON(!p->cs_enabled);
141 ctrl_outb(ctrl_inb(p->mapcommon + TSTR) & ~p->enb,
142 p->mapcommon + TSTR);
144 p->cs_enabled = false;
147 #define REG_CH 0
148 #define REG_COMM 1
150 static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev)
152 struct resource *res[2];
153 int ret, irq;
154 unsigned int ch;
156 memset(p, 0, sizeof(*p));
157 p->pdev = pdev;
159 res[REG_CH] = platform_get_resource(p->pdev,
160 IORESOURCE_MEM, REG_CH);
161 res[REG_COMM] = platform_get_resource(p->pdev,
162 IORESOURCE_MEM, REG_COMM);
163 if (!res[REG_CH] || !res[REG_COMM]) {
164 dev_err(&p->pdev->dev, "failed to get I/O memory\n");
165 return -ENXIO;
167 irq = platform_get_irq(p->pdev, 0);
168 if (irq < 0) {
169 dev_err(&p->pdev->dev, "failed to get irq\n");
170 return irq;
173 p->clk = clk_get(&p->pdev->dev, "fck");
174 if (IS_ERR(p->clk)) {
175 dev_err(&p->pdev->dev, "can't get clk\n");
176 return PTR_ERR(p->clk);
178 of_property_read_u32(p->pdev->dev.of_node, "renesas,channel", &ch);
180 p->pdev = pdev;
181 p->mapbase = res[REG_CH]->start;
182 p->mapcommon = res[REG_COMM]->start;
183 p->enb = 1 << ch;
184 p->imfa = 1 << ch;
185 p->imiea = 1 << (4 + ch);
186 p->cs.name = pdev->name;
187 p->cs.rating = 200;
188 p->cs.read = timer16_clocksource_read;
189 p->cs.enable = timer16_enable;
190 p->cs.disable = timer16_disable;
191 p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
192 p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
194 ret = request_irq(irq, timer16_interrupt,
195 IRQF_TIMER, pdev->name, p);
196 if (ret < 0) {
197 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
198 return ret;
201 clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 8);
203 return 0;
206 static int timer16_probe(struct platform_device *pdev)
208 struct timer16_priv *p = platform_get_drvdata(pdev);
210 if (p) {
211 dev_info(&pdev->dev, "kept as earlytimer\n");
212 return 0;
215 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
216 if (!p)
217 return -ENOMEM;
219 return timer16_setup(p, pdev);
222 static int timer16_remove(struct platform_device *pdev)
224 return -EBUSY;
227 static const struct of_device_id timer16_of_table[] = {
228 { .compatible = "renesas,16bit-timer" },
231 static struct platform_driver timer16_driver = {
232 .probe = timer16_probe,
233 .remove = timer16_remove,
234 .driver = {
235 .name = "h8300h-16timer",
236 .of_match_table = of_match_ptr(timer16_of_table),
240 static int __init timer16_init(void)
242 return platform_driver_register(&timer16_driver);
245 static void __exit timer16_exit(void)
247 platform_driver_unregister(&timer16_driver);
250 subsys_initcall(timer16_init);
251 module_exit(timer16_exit);
252 MODULE_AUTHOR("Yoshinori Sato");
253 MODULE_DESCRIPTION("H8/300H 16bit Timer Driver");
254 MODULE_LICENSE("GPL v2");