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

TOMOYO Linux Cross Reference
Linux/arch/unicore32/kernel/time.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/arch/unicore32/kernel/time.c
  3  *
  4  * Code specific to PKUnity SoC and UniCore ISA
  5  *
  6  *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
  7  *      Copyright (C) 2001-2010 Guan Xuetao
  8  *
  9  * This program is free software; you can redistribute it and/or modify
 10  * it under the terms of the GNU General Public License version 2 as
 11  * published by the Free Software Foundation.
 12  */
 13 #include <linux/init.h>
 14 #include <linux/errno.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/irq.h>
 17 #include <linux/timex.h>
 18 #include <linux/clockchips.h>
 19 
 20 #include <mach/hardware.h>
 21 
 22 #define MIN_OSCR_DELTA 2
 23 
 24 static irqreturn_t puv3_ost0_interrupt(int irq, void *dev_id)
 25 {
 26         struct clock_event_device *c = dev_id;
 27 
 28         /* Disarm the compare/match, signal the event. */
 29         writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
 30         writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
 31         c->event_handler(c);
 32 
 33         return IRQ_HANDLED;
 34 }
 35 
 36 static int
 37 puv3_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
 38 {
 39         unsigned long next, oscr;
 40 
 41         writel(readl(OST_OIER) | OST_OIER_E0, OST_OIER);
 42         next = readl(OST_OSCR) + delta;
 43         writel(next, OST_OSMR0);
 44         oscr = readl(OST_OSCR);
 45 
 46         return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
 47 }
 48 
 49 static int puv3_osmr0_shutdown(struct clock_event_device *evt)
 50 {
 51         writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
 52         writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
 53         return 0;
 54 }
 55 
 56 static struct clock_event_device ckevt_puv3_osmr0 = {
 57         .name                   = "osmr0",
 58         .features               = CLOCK_EVT_FEAT_ONESHOT,
 59         .rating                 = 200,
 60         .set_next_event         = puv3_osmr0_set_next_event,
 61         .set_state_shutdown     = puv3_osmr0_shutdown,
 62         .set_state_oneshot      = puv3_osmr0_shutdown,
 63 };
 64 
 65 static u64 puv3_read_oscr(struct clocksource *cs)
 66 {
 67         return readl(OST_OSCR);
 68 }
 69 
 70 static struct clocksource cksrc_puv3_oscr = {
 71         .name           = "oscr",
 72         .rating         = 200,
 73         .read           = puv3_read_oscr,
 74         .mask           = CLOCKSOURCE_MASK(32),
 75         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 76 };
 77 
 78 static struct irqaction puv3_timer_irq = {
 79         .name           = "ost0",
 80         .flags          = IRQF_TIMER | IRQF_IRQPOLL,
 81         .handler        = puv3_ost0_interrupt,
 82         .dev_id         = &ckevt_puv3_osmr0,
 83 };
 84 
 85 void __init time_init(void)
 86 {
 87         writel(0, OST_OIER);            /* disable any timer interrupts */
 88         writel(0, OST_OSSR);            /* clear status on all timers */
 89 
 90         clockevents_calc_mult_shift(&ckevt_puv3_osmr0, CLOCK_TICK_RATE, 5);
 91 
 92         ckevt_puv3_osmr0.max_delta_ns =
 93                 clockevent_delta2ns(0x7fffffff, &ckevt_puv3_osmr0);
 94         ckevt_puv3_osmr0.max_delta_ticks = 0x7fffffff;
 95         ckevt_puv3_osmr0.min_delta_ns =
 96                 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_puv3_osmr0) + 1;
 97         ckevt_puv3_osmr0.min_delta_ticks = MIN_OSCR_DELTA * 2;
 98         ckevt_puv3_osmr0.cpumask = cpumask_of(0);
 99 
100         setup_irq(IRQ_TIMER0, &puv3_timer_irq);
101 
102         clocksource_register_hz(&cksrc_puv3_oscr, CLOCK_TICK_RATE);
103         clockevents_register_device(&ckevt_puv3_osmr0);
104 }
105 
106 #ifdef CONFIG_PM
107 unsigned long osmr[4], oier;
108 
109 void puv3_timer_suspend(void)
110 {
111         osmr[0] = readl(OST_OSMR0);
112         osmr[1] = readl(OST_OSMR1);
113         osmr[2] = readl(OST_OSMR2);
114         osmr[3] = readl(OST_OSMR3);
115         oier = readl(OST_OIER);
116 }
117 
118 void puv3_timer_resume(void)
119 {
120         writel(0, OST_OSSR);
121         writel(osmr[0], OST_OSMR0);
122         writel(osmr[1], OST_OSMR1);
123         writel(osmr[2], OST_OSMR2);
124         writel(osmr[3], OST_OSMR3);
125         writel(oier, OST_OIER);
126 
127         /*
128          * OSMR0 is the system timer: make sure OSCR is sufficiently behind
129          */
130         writel(readl(OST_OSMR0) - LATCH, OST_OSCR);
131 }
132 #else
133 void puv3_timer_suspend(void) { };
134 void puv3_timer_resume(void) { };
135 #endif
136 
137 

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