int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, irq_handler_t handler, const char *name, void *dev) { int ret; ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev); if (ret) return ret; ret = mc13xxx_irq_unmask(mc13xxx, irq); if (ret) { mc13xxx->irqhandler[irq] = NULL; mc13xxx->irqdata[irq] = NULL; return ret; } return 0; }
static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; seconds = secs % 86400; days = secs / 86400; mc13xxx_lock(priv->mc13xxx); /* */ ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); if (unlikely(ret)) goto out; if (alarmseconds < 86400) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; } /* */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); if (unlikely(ret)) goto out; /* */ if (alarmseconds < 86400) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, alarmseconds); if (unlikely(ret)) goto out; } ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); if (unlikely(ret)) goto out; ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); out: priv->valid = !ret; mc13xxx_unlock(priv->mc13xxx); return ret; }
static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; days = div_s64_rem(secs, SEC_PER_DAY, &seconds); mc13xxx_lock(priv->mc13xxx); /* * temporarily invalidate alarm to prevent triggering it when the day is * already updated while the time isn't yet. */ ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); if (unlikely(ret)) goto out; if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; } /* * write seconds=0 to prevent a day switch between writing days * and seconds below */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); if (unlikely(ret)) goto out; /* restore alarm */ if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, alarmseconds); if (unlikely(ret)) goto out; } if (!priv->valid) { ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); if (unlikely(ret)) goto out; ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); } out: priv->valid = !ret; mc13xxx_unlock(priv->mc13xxx); return ret; }