Example #1
0
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, &reg);
	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, &reg);
	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;
}
Example #2
0
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;
}
Example #3
0
 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;
}
Example #4
0
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;
    }
}
Example #6
0
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;
}
Example #7
0
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);
}
Example #8
0
/*!
 * 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;
}
Example #9
0
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;
}
Example #10
0
/*!
 * 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;
}
Example #11
0
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, &reg);
    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, &reg);
    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;
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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");

}
Example #17
0
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);
}
Example #18
0
static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
{
	rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
}
Example #19
0
File: rtc.c Project: 0day-ci/xen
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;
}
Example #20
0
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;
}
Example #21
0
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;
}
Example #22
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;
}
Example #23
0
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);
}
Example #24
0
/**
 * 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;
}