Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  DS1287 clockevent driver
0004  *
0005  *  Copyright (C) 2008  Yoichi Yuasa <yuasa@linux-mips.org>
0006  */
0007 #include <linux/clockchips.h>
0008 #include <linux/init.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/mc146818rtc.h>
0011 #include <linux/irq.h>
0012 
0013 #include <asm/time.h>
0014 
0015 int ds1287_timer_state(void)
0016 {
0017     return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
0018 }
0019 
0020 int ds1287_set_base_clock(unsigned int hz)
0021 {
0022     u8 rate;
0023 
0024     switch (hz) {
0025     case 128:
0026         rate = 0x9;
0027         break;
0028     case 256:
0029         rate = 0x8;
0030         break;
0031     case 1024:
0032         rate = 0x6;
0033         break;
0034     default:
0035         return -EINVAL;
0036     }
0037 
0038     CMOS_WRITE(RTC_REF_CLCK_32KHZ | rate, RTC_REG_A);
0039 
0040     return 0;
0041 }
0042 
0043 static int ds1287_set_next_event(unsigned long delta,
0044                  struct clock_event_device *evt)
0045 {
0046     return -EINVAL;
0047 }
0048 
0049 static int ds1287_shutdown(struct clock_event_device *evt)
0050 {
0051     u8 val;
0052 
0053     spin_lock(&rtc_lock);
0054 
0055     val = CMOS_READ(RTC_REG_B);
0056     val &= ~RTC_PIE;
0057     CMOS_WRITE(val, RTC_REG_B);
0058 
0059     spin_unlock(&rtc_lock);
0060     return 0;
0061 }
0062 
0063 static int ds1287_set_periodic(struct clock_event_device *evt)
0064 {
0065     u8 val;
0066 
0067     spin_lock(&rtc_lock);
0068 
0069     val = CMOS_READ(RTC_REG_B);
0070     val |= RTC_PIE;
0071     CMOS_WRITE(val, RTC_REG_B);
0072 
0073     spin_unlock(&rtc_lock);
0074     return 0;
0075 }
0076 
0077 static void ds1287_event_handler(struct clock_event_device *dev)
0078 {
0079 }
0080 
0081 static struct clock_event_device ds1287_clockevent = {
0082     .name           = "ds1287",
0083     .features       = CLOCK_EVT_FEAT_PERIODIC,
0084     .set_next_event     = ds1287_set_next_event,
0085     .set_state_shutdown = ds1287_shutdown,
0086     .set_state_periodic = ds1287_set_periodic,
0087     .tick_resume        = ds1287_shutdown,
0088     .event_handler      = ds1287_event_handler,
0089 };
0090 
0091 static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
0092 {
0093     struct clock_event_device *cd = &ds1287_clockevent;
0094 
0095     /* Ack the RTC interrupt. */
0096     CMOS_READ(RTC_REG_C);
0097 
0098     cd->event_handler(cd);
0099 
0100     return IRQ_HANDLED;
0101 }
0102 
0103 int __init ds1287_clockevent_init(int irq)
0104 {
0105     unsigned long flags = IRQF_PERCPU | IRQF_TIMER;
0106     struct clock_event_device *cd;
0107 
0108     cd = &ds1287_clockevent;
0109     cd->rating = 100;
0110     cd->irq = irq;
0111     clockevent_set_clock(cd, 32768);
0112     cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
0113     cd->max_delta_ticks = 0x7fffffff;
0114     cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
0115     cd->min_delta_ticks = 0x300;
0116     cd->cpumask = cpumask_of(0);
0117 
0118     clockevents_register_device(&ds1287_clockevent);
0119 
0120     return request_irq(irq, ds1287_interrupt, flags, "ds1287", NULL);
0121 }