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

TOMOYO Linux Cross Reference
Linux/arch/arm/plat-iop/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  * arch/arm/plat-iop/time.c
  3  *
  4  * Timer code for IOP32x and IOP33x based systems
  5  *
  6  * Author: Deepak Saxena <dsaxena@mvista.com>
  7  *
  8  * Copyright 2002-2003 MontaVista Software Inc.
  9  *
 10  * This program is free software; you can redistribute it and/or modify it
 11  * under the terms of the GNU General Public License as published by the
 12  * Free Software Foundation; either version 2 of the License, or (at your
 13  * option) any later version.
 14  */
 15 
 16 #include <linux/kernel.h>
 17 #include <linux/interrupt.h>
 18 #include <linux/time.h>
 19 #include <linux/init.h>
 20 #include <linux/timex.h>
 21 #include <linux/io.h>
 22 #include <linux/clocksource.h>
 23 #include <linux/clockchips.h>
 24 #include <linux/export.h>
 25 #include <linux/sched_clock.h>
 26 #include <mach/hardware.h>
 27 #include <asm/irq.h>
 28 #include <asm/uaccess.h>
 29 #include <asm/mach/irq.h>
 30 #include <asm/mach/time.h>
 31 #include <mach/time.h>
 32 
 33 /*
 34  * Minimum clocksource/clockevent timer range in seconds
 35  */
 36 #define IOP_MIN_RANGE 4
 37 
 38 /*
 39  * IOP clocksource (free-running timer 1).
 40  */
 41 static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
 42 {
 43         return 0xffffffffu - read_tcr1();
 44 }
 45 
 46 static struct clocksource iop_clocksource = {
 47         .name           = "iop_timer1",
 48         .rating         = 300,
 49         .read           = iop_clocksource_read,
 50         .mask           = CLOCKSOURCE_MASK(32),
 51         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 52 };
 53 
 54 /*
 55  * IOP sched_clock() implementation via its clocksource.
 56  */
 57 static u64 notrace iop_read_sched_clock(void)
 58 {
 59         return 0xffffffffu - read_tcr1();
 60 }
 61 
 62 /*
 63  * IOP clockevents (interrupting timer 0).
 64  */
 65 static int iop_set_next_event(unsigned long delta,
 66                               struct clock_event_device *unused)
 67 {
 68         u32 tmr = IOP_TMR_PRIVILEGED | IOP_TMR_RATIO_1_1;
 69 
 70         BUG_ON(delta == 0);
 71         write_tmr0(tmr & ~(IOP_TMR_EN | IOP_TMR_RELOAD));
 72         write_tcr0(delta);
 73         write_tmr0((tmr & ~IOP_TMR_RELOAD) | IOP_TMR_EN);
 74 
 75         return 0;
 76 }
 77 
 78 static unsigned long ticks_per_jiffy;
 79 
 80 static void iop_set_mode(enum clock_event_mode mode,
 81                          struct clock_event_device *unused)
 82 {
 83         u32 tmr = read_tmr0();
 84 
 85         switch (mode) {
 86         case CLOCK_EVT_MODE_PERIODIC:
 87                 write_tmr0(tmr & ~IOP_TMR_EN);
 88                 write_tcr0(ticks_per_jiffy - 1);
 89                 write_trr0(ticks_per_jiffy - 1);
 90                 tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
 91                 break;
 92         case CLOCK_EVT_MODE_ONESHOT:
 93                 /* ->set_next_event sets period and enables timer */
 94                 tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
 95                 break;
 96         case CLOCK_EVT_MODE_RESUME:
 97                 tmr |= IOP_TMR_EN;
 98                 break;
 99         case CLOCK_EVT_MODE_SHUTDOWN:
100         case CLOCK_EVT_MODE_UNUSED:
101         default:
102                 tmr &= ~IOP_TMR_EN;
103                 break;
104         }
105 
106         write_tmr0(tmr);
107 }
108 
109 static struct clock_event_device iop_clockevent = {
110         .name           = "iop_timer0",
111         .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
112         .rating         = 300,
113         .set_next_event = iop_set_next_event,
114         .set_mode       = iop_set_mode,
115 };
116 
117 static irqreturn_t
118 iop_timer_interrupt(int irq, void *dev_id)
119 {
120         struct clock_event_device *evt = dev_id;
121 
122         write_tisr(1);
123         evt->event_handler(evt);
124         return IRQ_HANDLED;
125 }
126 
127 static struct irqaction iop_timer_irq = {
128         .name           = "IOP Timer Tick",
129         .handler        = iop_timer_interrupt,
130         .flags          = IRQF_TIMER | IRQF_IRQPOLL,
131         .dev_id         = &iop_clockevent,
132 };
133 
134 static unsigned long iop_tick_rate;
135 unsigned long get_iop_tick_rate(void)
136 {
137         return iop_tick_rate;
138 }
139 EXPORT_SYMBOL(get_iop_tick_rate);
140 
141 void __init iop_init_time(unsigned long tick_rate)
142 {
143         u32 timer_ctl;
144 
145         sched_clock_register(iop_read_sched_clock, 32, tick_rate);
146 
147         ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
148         iop_tick_rate = tick_rate;
149 
150         timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
151                         IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
152 
153         /*
154          * Set up interrupting clockevent timer 0.
155          */
156         write_tmr0(timer_ctl & ~IOP_TMR_EN);
157         write_tisr(1);
158         setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
159         iop_clockevent.cpumask = cpumask_of(0);
160         clockevents_config_and_register(&iop_clockevent, tick_rate,
161                                         0xf, 0xfffffffe);
162 
163         /*
164          * Set up free-running clocksource timer 1.
165          */
166         write_trr1(0xffffffff);
167         write_tcr1(0xffffffff);
168         write_tmr1(timer_ctl);
169         clocksource_register_hz(&iop_clocksource, tick_rate);
170 }
171 

~ [ 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