static irqreturn_t ricoh583_rtc_irq(int irq, void *data) { struct device *dev = data; struct ricoh583_rtc *rtc = dev_get_drvdata(dev); u8 reg; int err; /* clear alarm-Y status bits.*/ err = ricoh583_read_regs(dev, rtc_ctrl2, 1, ®); if (err) { dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n"); return -EBUSY; } reg &= ~0x8; err = ricoh583_write_regs(dev, rtc_ctrl2, 1, ®); if (err) { dev_err(dev->parent, "unable to program rtc_status reg\n"); return -EBUSY; } rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); return IRQ_HANDLED; }
static irqreturn_t nuc900_rtc_interrupt(int irq, void *_rtc) { struct nuc900_rtc *rtc = _rtc; unsigned long events = 0, rtc_irq; rtc_irq = __raw_readl(rtc->rtc_reg + REG_RTC_RIIR); if (rtc_irq & ALARMINTENB) { rtc_irq &= ~ALARMINTENB; __raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR); events |= RTC_AF | RTC_IRQF; } if (rtc_irq & TICKINTENB) { rtc_irq &= ~TICKINTENB; __raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR); events |= RTC_UF | RTC_IRQF; } rtc_update_irq(rtc->rtcdev, 1, events); return IRQ_HANDLED; }
static irqreturn_t ds1511_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); unsigned long events = 0; spin_lock(&pdata->lock); /* * read and clear interrupt */ if (rtc_read(RTC_CMD1) & DS1511_IRQF) { events = RTC_IRQF; if (rtc_read(RTC_ALARM_SEC) & 0x80) events |= RTC_UF; else events |= RTC_AF; if (likely(pdata->rtc)) rtc_update_irq(pdata->rtc, 1, events); } spin_unlock(&pdata->lock); return events ? IRQ_HANDLED : IRQ_NONE; }
static u32 rtc_handler(void *context) { struct device *dev = context; struct cmos_rtc *cmos = dev_get_drvdata(dev); unsigned char rtc_control = 0; unsigned char rtc_intr; spin_lock_irq(&rtc_lock); if (cmos_rtc.suspend_ctrl) rtc_control = CMOS_READ(RTC_CONTROL); if (rtc_control & RTC_AIE) { cmos_rtc.suspend_ctrl &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_update_irq(cmos->rtc, 1, rtc_intr); } spin_unlock_irq(&rtc_lock); pm_wakeup_event(dev, 0); acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); return ACPI_INTERRUPT_HANDLED; }
/* IRQ Handlers, irq no. is shared with timer2 */ static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id) { struct rtc_device *rdev = id; u32 val; #ifdef RTC_ALARM_DEBUG _dev_info(&(rdev->dev), "sunxi_rtc_alarmirq\n"); #endif /*judge the int is whether ours*/ val = readl(sunxi_rtc_base + SUNXI_ALARM_INT_STATUS_REG)&(RTC_ENABLE_WK_IRQ | RTC_ENABLE_CNT_IRQ); if (val) { /*Clear pending count alarm*/ val = readl(sunxi_rtc_base + SUNXI_ALARM_INT_STATUS_REG);//0x11c val |= (RTC_ENABLE_CNT_IRQ); //0x00000001 writel(val, sunxi_rtc_base + SUNXI_ALARM_INT_STATUS_REG); rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); return IRQ_HANDLED; } else { return IRQ_NONE; } }
static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) { u32 tmp; struct lpc32xx_rtc_priv *lpc32xx_rtc_dat = (struct lpc32xx_rtc_priv *) dev; spin_lock(&lpc32xx_rtc_dat->lock); /* If the alarm isn't disabled, the match will keep occuring, so disable it now */ tmp = __raw_readl(RTC_CTRL(lpc32xx_rtc_dat->rtc_base)); tmp &= ~RTC_MATCH0_EN; __raw_writel(tmp, RTC_CTRL(lpc32xx_rtc_dat->rtc_base)); /* Clear match event */ __raw_writel(RTC_MATCH0_INT_STS, RTC_INTSTAT(lpc32xx_rtc_dat->rtc_base)); /* Alarm event */ rtc_update_irq(lpc32xx_rtc_dat->rtc, 1, RTC_AF); spin_unlock(&lpc32xx_rtc_dat->lock); return IRQ_HANDLED; }
static void ds1374_work(struct work_struct *work) { struct ds1374 *ds1374 = container_of(work, struct ds1374, work); struct i2c_client *client = ds1374->client; int stat, control; mutex_lock(&ds1374->mutex); stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR); if (stat < 0) return; if (stat & DS1374_REG_SR_AF) { stat &= ~DS1374_REG_SR_AF; i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat); control = i2c_smbus_read_byte_data(client, DS1374_REG_CR); if (control < 0) goto out; control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE); i2c_smbus_write_byte_data(client, DS1374_REG_CR, control); /* rtc_update_irq() assumes that it is called * from IRQ-disabled context. */ local_irq_disable(); rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF); local_irq_enable(); } out: if (!ds1374->exiting) enable_irq(client->irq); mutex_unlock(&ds1374->mutex); }
/*! * This function is the RTC interrupt service routine. * * @param irq RTC IRQ number * @param dev_id device ID which is not used * * @return IRQ_HANDLED as defined in the include/linux/interrupt.h file. */ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct rtc_drv_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; u32 lp_status, lp_cr; u32 events = 0; clk_enable(pdata->clk); lp_status = __raw_readl(ioaddr + SRTC_LPSR); lp_cr = __raw_readl(ioaddr + SRTC_LPCR); /* update irq data & counter */ if (lp_status & SRTC_LPSR_ALP) { if (lp_cr & SRTC_LPCR_ALP) events |= (RTC_AF | RTC_IRQF); /* disable further lp alarm interrupts */ lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); } /* Update interrupt enables */ __raw_writel(lp_cr, ioaddr + SRTC_LPCR); /* If no interrupts are enabled, turn off interrupts in kernel */ if (((lp_cr & SRTC_LPCR_ALL_INT_EN) == 0) && (pdata->irq_enable)) { disable_irq(pdata->irq); pdata->irq_enable = false; } /* clear interrupt status */ __raw_writel(lp_status, ioaddr + SRTC_LPSR); clk_disable(pdata->clk); rtc_update_irq(pdata->rtc, 1, events); return IRQ_HANDLED; }
bool_t rtc_periodic_interrupt(void *opaque) { RTCState *s = opaque; bool_t ret; spin_lock(&s->lock); ret = rtc_mode_is(s, no_ack) || !(s->hw.cmos_data[RTC_REG_C] & RTC_IRQF); if ( rtc_mode_is(s, no_ack) || !(s->hw.cmos_data[RTC_REG_C] & RTC_PF) ) { s->hw.cmos_data[RTC_REG_C] |= RTC_PF; rtc_update_irq(s); } else if ( ++(s->pt_dead_ticks) >= 10 ) { /* VM is ignoring its RTC; no point in running the timer */ destroy_periodic_time(&s->pt); s->pt_code = 0; } if ( !(s->hw.cmos_data[RTC_REG_C] & RTC_IRQF) ) ret = 0; spin_unlock(&s->lock); return ret; }
/*! * This function is the RTC interrupt service routine. * * @param irq RTC IRQ number * @param dev_id device ID which is not used * * @return IRQ_HANDLED as defined in the include/linux/interrupt.h file. */ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; u32 status; u32 events = 0; spin_lock(&rtc_lock); status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); /* clear interrupt sources */ writew(status, ioaddr + RTC_RTCISR); /* clear alarm interrupt if it has occurred */ if (status & RTC_ALM_BIT) { status &= ~RTC_ALM_BIT; } /* update irq data & counter */ if (status & RTC_ALM_BIT) { events |= (RTC_AF | RTC_IRQF); } if (status & RTC_1HZ_BIT) { events |= (RTC_UF | RTC_IRQF); } if (status & PIT_ALL_ON) { events |= (RTC_PF | RTC_IRQF); } if ((status & RTC_ALM_BIT) && rtc_valid_tm(&g_rtc_alarm)) { rtc_update_alarm(&pdev->dev, &g_rtc_alarm); } spin_unlock(&rtc_lock); rtc_update_irq(pdata->rtc, 1, events); return IRQ_HANDLED; }
static irqreturn_t tps6591x_rtc_irq(int irq, void *data) { struct device *dev = data; struct tps6591x_rtc *rtc = dev_get_drvdata(dev); u8 reg; int err; /* clear Alarm status bits.*/ err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); if (err) { dev_err(dev->parent, "unable to read RTC_STATUS reg\n"); return -EBUSY; } reg = ALARM_INT_STATUS; err = tps6591x_write_regs(dev, RTC_STATUS, 1, ®); if (err) { dev_err(dev->parent, "unable to program RTC_STATUS reg\n"); return -EBUSY; } rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); return IRQ_HANDLED; }
static irqreturn_t rtc_irq(int irq, void *dev_id) { struct omap_rtc *rtc = dev_id; unsigned long events = 0; u8 irq_data; irq_data = rtc_read(rtc, OMAP_RTC_STATUS_REG); /* alarm irq? */ if (irq_data & OMAP_RTC_STATUS_ALARM) { rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); rtc->type->lock(rtc); events |= RTC_IRQF | RTC_AF; } /* 1/sec periodic/update irq? */ if (irq_data & OMAP_RTC_STATUS_1S_EVENT) events |= RTC_IRQF | RTC_UF; rtc_update_irq(rtc->rtc, 1, events); return IRQ_HANDLED; }
static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id) { struct rtc_at32ap700x *rtc = (struct rtc_at32ap700x *)dev_id; unsigned long isr = rtc_readl(rtc, ISR); unsigned long events = 0; int ret = IRQ_NONE; spin_lock(&rtc->lock); if (isr & RTC_BIT(ISR_TOPI)) { rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) & ~RTC_BIT(CTRL_TOPEN)); rtc_writel(rtc, VAL, rtc->alarm_time); events = RTC_AF | RTC_IRQF; rtc_update_irq(rtc->rtc, 1, events); ret = IRQ_HANDLED; } spin_unlock(&rtc->lock); return ret; }
static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) { unsigned long events = 0; int ret = IRQ_NONE; int res; u8 rd_reg; /* clear the RTC interrupt in TWL4030 power module */ res = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, REG_PWR_ISR1); if (res) goto out; /* Check if interrupt is sourced by RTC */ if (!(rd_reg & PWR_RTC_INT_CLR)) goto out; rd_reg |= PWR_RTC_INT_CLR; res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, rd_reg, REG_PWR_ISR1); if (res) goto out; res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG. * only one (ALARM or RTC) interrupt source may be enabled * at time, we also could check our results * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) events |= RTC_IRQF | RTC_AF; else events |= RTC_IRQF | RTC_UF; res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; /* * Workaround for strange behaviour with T2. Need to write into ISR * register one more time to clear the interrupt. Otherwise, the same * RTC event generates 2 interrupts in a row. * (no errata document available) */ res = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, REG_PWR_ISR1); if (res) goto out; rd_reg |= PWR_RTC_INT_CLR; res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, rd_reg, REG_PWR_ISR1); if (res) goto out; /* Notify RTC core on event */ rtc_update_irq(rtc, 1, events); ret = IRQ_HANDLED; out: return ret; }
static void test_rtc_alarm_handler(struct timer_list *t) { struct rtc_test_data *rtd = from_timer(rtd, t, alarm); rtc_update_irq(rtd->rtc, 1, RTC_AF | RTC_IRQF); }
/* static void rtc_tasklet_handler(unsigned long data) */ static void rtc_handler(void) { bool pwron_alm = false, isLowPowerIrq = false, pwron_alarm = false; struct rtc_time nowtm; struct rtc_time tm; rtc_xinfo("rtc_tasklet_handler start\n"); spin_lock(&rtc_lock); isLowPowerIrq = hal_rtc_is_lp_irq(); if (isLowPowerIrq) { spin_unlock(&rtc_lock); return; } #if RTC_RELPWR_WHEN_XRST /* set AUTO bit because AUTO = 0 when PWREN = 1 and alarm occurs */ hal_rtc_reload_power(); #endif pwron_alarm = hal_rtc_check_pwron_alarm_rg(&nowtm, &tm); nowtm.tm_year += RTC_MIN_YEAR; tm.tm_year += RTC_MIN_YEAR; if (pwron_alarm) { unsigned long now_time, time; now_time = mktime(nowtm.tm_year, nowtm.tm_mon, nowtm.tm_mday, nowtm.tm_hour, nowtm.tm_min, nowtm.tm_sec); time = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); if (now_time >= time - 1 && now_time <= time + 4) { /* power on */ #if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) if (g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT) { time += 1; rtc_time_to_tm(time, &tm); tm.tm_year -= RTC_MIN_YEAR_OFFSET; tm.tm_mon += 1; /* tm.tm_sec += 1; */ hal_rtc_set_alarm_time(&tm); spin_unlock(&rtc_lock); arch_reset(0, "kpoc"); } else { hal_rtc_set_pwron_alarm(); pwron_alm = true; } #else hal_rtc_set_pwron_alarm(); pwron_alm = true; #endif } else if (now_time < time) { /* set power-on alarm */ if (tm.tm_sec == 0) { tm.tm_sec = 59; tm.tm_min -= 1; } else { tm.tm_sec -= 1; } hal_rtc_set_alarm_time(&tm); } } spin_unlock(&rtc_lock); if (rtc != NULL) rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); if (rtc_show_alarm) rtc_xinfo("%s time is up\n", pwron_alm ? "power-on" : "alarm"); }
static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) { rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); writeb(mask, info->base + S3C2410_INTP); }
static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) { rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); }
static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data) { RTCState *s = opaque; struct domain *d = vrtc_domain(s); uint32_t orig; spin_lock(&s->lock); if ( (addr & 1) == 0 ) { data &= 0x7f; s->hw.cmos_index = data; spin_unlock(&s->lock); return (data < RTC_CMOS_SIZE); } if ( s->hw.cmos_index >= RTC_CMOS_SIZE ) { spin_unlock(&s->lock); return 0; } orig = s->hw.cmos_data[s->hw.cmos_index]; switch ( s->hw.cmos_index ) { case RTC_SECONDS_ALARM: case RTC_MINUTES_ALARM: case RTC_HOURS_ALARM: s->hw.cmos_data[s->hw.cmos_index] = data; alarm_timer_update(s); break; case RTC_SECONDS: case RTC_MINUTES: case RTC_HOURS: case RTC_DAY_OF_WEEK: case RTC_DAY_OF_MONTH: case RTC_MONTH: case RTC_YEAR: /* if in set mode, just write the register */ if ( (s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) s->hw.cmos_data[s->hw.cmos_index] = data; else { /* Fetch the current time and update just this field. */ s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); s->hw.cmos_data[s->hw.cmos_index] = data; rtc_set_time(s); } alarm_timer_update(s); break; case RTC_REG_A: /* UIP bit is read only */ s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (orig & RTC_UIP); if ( (data ^ orig) & ~RTC_UIP ) rtc_timer_update(s); break; case RTC_REG_B: if ( data & RTC_SET ) { /* set mode: reset UIP mode */ s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP; /* adjust cmos before stopping */ if (!(orig & RTC_SET)) { s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); } } else { /* if disabling set mode, update the time */ if ( orig & RTC_SET ) rtc_set_time(s); } check_for_pf_ticks(s); s->hw.cmos_data[RTC_REG_B] = data; /* * If the interrupt is already set when the interrupt becomes * enabled, raise an interrupt immediately. */ rtc_update_irq(s); if ( (data ^ orig) & RTC_PIE ) { TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER); destroy_periodic_time(&s->pt); s->period = 0; rtc_timer_update(s); } if ( (data ^ orig) & RTC_SET ) check_update_timer(s); if ( (data ^ orig) & (RTC_24H | RTC_DM_BINARY | RTC_SET) ) alarm_timer_update(s); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; } spin_unlock(&s->lock); return 1; }
static irqreturn_t _abb5zes3_rtc_interrupt(int irq, void *data) { struct i2c_client *client = data; struct device *dev = &client->dev; struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); struct rtc_device *rtc = rtc_data->rtc; u8 regs[ABB5ZES3_CTRL_SEC_LEN]; int ret, handled = IRQ_NONE; ret = regmap_bulk_read(rtc_data->regmap, 0, regs, ABB5ZES3_CTRL_SEC_LEN); if (ret) { dev_err(dev, "%s: unable to read control section (%d)!\n", __func__, ret); return handled; } /* * Check battery low detection flag and disable battery low interrupt * generation if flag is set (interrupt can only be cleared when * battery is replaced). */ if (regs[ABB5ZES3_REG_CTRL3] & ABB5ZES3_REG_CTRL3_BLF) { dev_err(dev, "RTC battery is low; please change it!\n"); _abb5zes3_rtc_battery_low_irq_enable(rtc_data->regmap, false); handled = IRQ_HANDLED; } /* Check alarm flag */ if (regs[ABB5ZES3_REG_CTRL2] & ABB5ZES3_REG_CTRL2_AF) { dev_dbg(dev, "RTC alarm!\n"); rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); /* Acknowledge and disable the alarm */ _abb5zes3_rtc_clear_alarm(dev); _abb5zes3_rtc_update_alarm(dev, 0); handled = IRQ_HANDLED; } /* Check watchdog Timer A flag */ if (regs[ABB5ZES3_REG_CTRL2] & ABB5ZES3_REG_CTRL2_WTAF) { dev_dbg(dev, "RTC timer!\n"); rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); /* * Acknowledge and disable the alarm. Note: WTAF * flag had been cleared when reading CTRL2 */ _abb5zes3_rtc_update_timer(dev, 0); rtc_data->timer_alarm = 0; handled = IRQ_HANDLED; } return handled; }
static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct cmos_rtc *cmos = dev_get_drvdata(dev); unsigned char mon, mday, hrs, min, sec; unsigned char rtc_control, rtc_intr; if (!is_valid_irq(cmos->irq)) return -EIO; /* REVISIT this assumes PC style usage: always BCD */ /* Writing 0xff means "don't care" or "match all". */ mon = t->time.tm_mon; mon = (mon < 12) ? BIN2BCD(mon) : 0xff; mon++; mday = t->time.tm_mday; mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; hrs = t->time.tm_hour; hrs = (hrs < 24) ? BIN2BCD(hrs) : 0xff; min = t->time.tm_min; min = (min < 60) ? BIN2BCD(min) : 0xff; sec = t->time.tm_sec; sec = (sec < 60) ? BIN2BCD(sec) : 0xff; spin_lock_irq(&rtc_lock); /* next rtc irq must not be from previous alarm setting */ rtc_control = CMOS_READ(RTC_CONTROL); rtc_control &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); if (rtc_intr) rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); /* update alarm */ CMOS_WRITE(hrs, RTC_HOURS_ALARM); CMOS_WRITE(min, RTC_MINUTES_ALARM); CMOS_WRITE(sec, RTC_SECONDS_ALARM); /* the system may support an "enhanced" alarm */ if (cmos->day_alrm) { CMOS_WRITE(mday, cmos->day_alrm); if (cmos->mon_alrm) CMOS_WRITE(mon, cmos->mon_alrm); } if (t->enabled) { rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); if (rtc_intr) rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); } spin_unlock_irq(&rtc_lock); return 0; }
static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) { unsigned long events = 0; int ret = IRQ_NONE; int res; u8 rd_reg; #ifdef WORKQUEUE_RTC static struct work_struct task; #endif #ifdef CONFIG_LOCKDEP /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which * we don't want and can't tolerate. Although it might be * friendlier not to borrow this thread context... */ local_irq_enable(); #endif #ifdef WORKQUEUE_RTC printk("twl_rtc_interrupt rtc "); rtc_ins.rtc =(int)rtc ; INIT_WORK(&task, rtc_interrupt_bottom_half); queue_work(omap_rtc_wq, &task); #endif #ifndef WORKQUEUE_RTC res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG. * only one (ALARM or RTC) interrupt source may be enabled * at time, we also could check our results * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) events |= RTC_IRQF | RTC_AF; else events |= RTC_IRQF | RTC_UF; res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; if (twl_class_is_4030()) { /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1 * needs 2 reads to clear the interrupt. One read is done in * do_twl_pwrirq(). Doing the second read, to clear * the bit. * * FIXME the reason PWR_ISR1 needs an extra read is that * RTC_IF retriggered until we cleared REG_ALARM_M above. * But re-reading like this is a bad hack; by doing so we * risk wrongly clearing status for some other IRQ (losing * the interrupt). Be smarter about handling RTC_UF ... */ res = twl_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, TWL4030_INT_PWR_ISR1); if (res) goto out; } /* Notify RTC core on event */ rtc_update_irq(rtc, 1, events); #endif ret = IRQ_HANDLED; out: return ret; }
static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq, void *data) { struct rtc_device *rtc = wm8350->rtc.rtc; rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); }
/** * ds1685_rtc_irq_handler - IRQ handler. * @irq: IRQ number. * @dev_id: platform device pointer. */ static irqreturn_t ds1685_rtc_irq_handler(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct ds1685_priv *rtc = platform_get_drvdata(pdev); u8 ctrlb, ctrlc; unsigned long events = 0; u8 num_irqs = 0; /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */ if (unlikely(!rtc)) return IRQ_HANDLED; /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ spin_lock(&rtc->lock); ctrlb = rtc->read(rtc, RTC_CTRL_B); ctrlc = rtc->read(rtc, RTC_CTRL_C); /* Is the IRQF bit set? */ if (likely(ctrlc & RTC_CTRL_C_IRQF)) { /* * We need to determine if it was one of the standard * events: PF, AF, or UF. If so, we handle them and * update the RTC core. */ if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) { events = RTC_IRQF; /* Check for a periodic interrupt. */ if ((ctrlb & RTC_CTRL_B_PIE) && (ctrlc & RTC_CTRL_C_PF)) { events |= RTC_PF; num_irqs++; } /* Check for an alarm interrupt. */ if ((ctrlb & RTC_CTRL_B_AIE) && (ctrlc & RTC_CTRL_C_AF)) { events |= RTC_AF; num_irqs++; } /* Check for an update interrupt. */ if ((ctrlb & RTC_CTRL_B_UIE) && (ctrlc & RTC_CTRL_C_UF)) { events |= RTC_UF; num_irqs++; } rtc_update_irq(rtc->dev, num_irqs, events); } else { /* * One of the "extended" interrupts was received that * is not recognized by the RTC core. These need to * be handled in task context as they can call other * functions and the time spent in irq context needs * to be minimized. Schedule them into a workqueue * and inform the RTC core that the IRQs were handled. */ spin_unlock(&rtc->lock); schedule_work(&rtc->work); rtc_update_irq(rtc->dev, 0, 0); return IRQ_HANDLED; } } spin_unlock(&rtc->lock); return events ? IRQ_HANDLED : IRQ_NONE; }