~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/jz4740/time.c

Version: ~ [ linux-5.18 ] ~ [ linux-5.17.9 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.41 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.117 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.195 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.244 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.280 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.315 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
  3  *  JZ4740 platform time support
  4  *
  5  *  This program is free software; you can redistribute it and/or modify it
  6  *  under  the terms of the GNU General  Public License as published by the
  7  *  Free Software Foundation;  either version 2 of the License, or (at your
  8  *  option) any later version.
  9  *
 10  *  You should have received a copy of the GNU General Public License along
 11  *  with this program; if not, write to the Free Software Foundation, Inc.,
 12  *  675 Mass Ave, Cambridge, MA 02139, USA.
 13  *
 14  */
 15 
 16 #include <linux/clk.h>
 17 #include <linux/clk-provider.h>
 18 #include <linux/interrupt.h>
 19 #include <linux/kernel.h>
 20 #include <linux/time.h>
 21 
 22 #include <linux/clockchips.h>
 23 #include <linux/sched_clock.h>
 24 
 25 #include <asm/mach-jz4740/clock.h>
 26 #include <asm/mach-jz4740/irq.h>
 27 #include <asm/mach-jz4740/timer.h>
 28 #include <asm/time.h>
 29 
 30 #include "clock.h"
 31 
 32 #define TIMER_CLOCKEVENT 0
 33 #define TIMER_CLOCKSOURCE 1
 34 
 35 static uint16_t jz4740_jiffies_per_tick;
 36 
 37 static u64 jz4740_clocksource_read(struct clocksource *cs)
 38 {
 39         return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
 40 }
 41 
 42 static struct clocksource jz4740_clocksource = {
 43         .name = "jz4740-timer",
 44         .rating = 200,
 45         .read = jz4740_clocksource_read,
 46         .mask = CLOCKSOURCE_MASK(16),
 47         .flags = CLOCK_SOURCE_IS_CONTINUOUS,
 48 };
 49 
 50 static u64 notrace jz4740_read_sched_clock(void)
 51 {
 52         return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
 53 }
 54 
 55 static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
 56 {
 57         struct clock_event_device *cd = devid;
 58 
 59         jz4740_timer_ack_full(TIMER_CLOCKEVENT);
 60 
 61         if (!clockevent_state_periodic(cd))
 62                 jz4740_timer_disable(TIMER_CLOCKEVENT);
 63 
 64         cd->event_handler(cd);
 65 
 66         return IRQ_HANDLED;
 67 }
 68 
 69 static int jz4740_clockevent_set_periodic(struct clock_event_device *evt)
 70 {
 71         jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
 72         jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
 73         jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
 74         jz4740_timer_enable(TIMER_CLOCKEVENT);
 75 
 76         return 0;
 77 }
 78 
 79 static int jz4740_clockevent_resume(struct clock_event_device *evt)
 80 {
 81         jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
 82         jz4740_timer_enable(TIMER_CLOCKEVENT);
 83 
 84         return 0;
 85 }
 86 
 87 static int jz4740_clockevent_shutdown(struct clock_event_device *evt)
 88 {
 89         jz4740_timer_disable(TIMER_CLOCKEVENT);
 90 
 91         return 0;
 92 }
 93 
 94 static int jz4740_clockevent_set_next(unsigned long evt,
 95         struct clock_event_device *cd)
 96 {
 97         jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
 98         jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
 99         jz4740_timer_enable(TIMER_CLOCKEVENT);
100 
101         return 0;
102 }
103 
104 static struct clock_event_device jz4740_clockevent = {
105         .name = "jz4740-timer",
106         .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
107         .set_next_event = jz4740_clockevent_set_next,
108         .set_state_shutdown = jz4740_clockevent_shutdown,
109         .set_state_periodic = jz4740_clockevent_set_periodic,
110         .set_state_oneshot = jz4740_clockevent_shutdown,
111         .tick_resume = jz4740_clockevent_resume,
112         .rating = 200,
113 #ifdef CONFIG_MACH_JZ4740
114         .irq = JZ4740_IRQ_TCU0,
115 #endif
116 #if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780)
117         .irq = JZ4780_IRQ_TCU2,
118 #endif
119 };
120 
121 static struct irqaction timer_irqaction = {
122         .handler        = jz4740_clockevent_irq,
123         .flags          = IRQF_PERCPU | IRQF_TIMER,
124         .name           = "jz4740-timerirq",
125         .dev_id         = &jz4740_clockevent,
126 };
127 
128 void __init plat_time_init(void)
129 {
130         int ret;
131         uint32_t clk_rate;
132         uint16_t ctrl;
133         struct clk *ext_clk;
134 
135         of_clk_init(NULL);
136         jz4740_timer_init();
137 
138         ext_clk = clk_get(NULL, "ext");
139         if (IS_ERR(ext_clk))
140                 panic("unable to get ext clock");
141         clk_rate = clk_get_rate(ext_clk) >> 4;
142         clk_put(ext_clk);
143 
144         jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
145 
146         clockevent_set_clock(&jz4740_clockevent, clk_rate);
147         jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
148         jz4740_clockevent.min_delta_ticks = 100;
149         jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
150         jz4740_clockevent.max_delta_ticks = 0xffff;
151         jz4740_clockevent.cpumask = cpumask_of(0);
152 
153         clockevents_register_device(&jz4740_clockevent);
154 
155         ret = clocksource_register_hz(&jz4740_clocksource, clk_rate);
156 
157         if (ret)
158                 printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
159 
160         sched_clock_register(jz4740_read_sched_clock, 16, clk_rate);
161 
162         setup_irq(jz4740_clockevent.irq, &timer_irqaction);
163 
164         ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
165 
166         jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
167         jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
168 
169         jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
170         jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
171 
172         jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
173 
174         jz4740_timer_enable(TIMER_CLOCKEVENT);
175         jz4740_timer_enable(TIMER_CLOCKSOURCE);
176 }
177 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp