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

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

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