mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge branches 'aaci', 'mmci-dma', 'pl' and 'pl011' into drivers
This commit is contained in:
commit
9c9585e0e9
1461 changed files with 19547 additions and 10879 deletions
|
|
@ -143,6 +143,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
|
|||
rtc->id = id;
|
||||
rtc->ops = ops;
|
||||
rtc->owner = owner;
|
||||
rtc->irq_freq = 1;
|
||||
rtc->max_user_freq = 64;
|
||||
rtc->dev.parent = dev;
|
||||
rtc->dev.class = rtc_class;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
#include <linux/log2.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
|
||||
static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
|
||||
|
||||
static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -120,12 +123,18 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|||
err = mutex_lock_interruptible(&rtc->ops_lock);
|
||||
if (err)
|
||||
return err;
|
||||
alarm->enabled = rtc->aie_timer.enabled;
|
||||
if (alarm->enabled)
|
||||
if (rtc->ops == NULL)
|
||||
err = -ENODEV;
|
||||
else if (!rtc->ops->read_alarm)
|
||||
err = -EINVAL;
|
||||
else {
|
||||
memset(alarm, 0, sizeof(struct rtc_wkalrm));
|
||||
alarm->enabled = rtc->aie_timer.enabled;
|
||||
alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires);
|
||||
}
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_read_alarm);
|
||||
|
||||
|
|
@ -175,16 +184,14 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|||
return err;
|
||||
if (rtc->aie_timer.enabled) {
|
||||
rtc_timer_remove(rtc, &rtc->aie_timer);
|
||||
rtc->aie_timer.enabled = 0;
|
||||
}
|
||||
rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
|
||||
rtc->aie_timer.period = ktime_set(0, 0);
|
||||
if (alarm->enabled) {
|
||||
rtc->aie_timer.enabled = 1;
|
||||
rtc_timer_enqueue(rtc, &rtc->aie_timer);
|
||||
err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
|
||||
}
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_set_alarm);
|
||||
|
||||
|
|
@ -195,16 +202,15 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
|
|||
return err;
|
||||
|
||||
if (rtc->aie_timer.enabled != enabled) {
|
||||
if (enabled) {
|
||||
rtc->aie_timer.enabled = 1;
|
||||
rtc_timer_enqueue(rtc, &rtc->aie_timer);
|
||||
} else {
|
||||
if (enabled)
|
||||
err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
|
||||
else
|
||||
rtc_timer_remove(rtc, &rtc->aie_timer);
|
||||
rtc->aie_timer.enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rtc->ops)
|
||||
if (err)
|
||||
/* nothing */;
|
||||
else if (!rtc->ops)
|
||||
err = -ENODEV;
|
||||
else if (!rtc->ops->alarm_irq_enable)
|
||||
err = -EINVAL;
|
||||
|
|
@ -222,6 +228,12 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
|
||||
if (enabled == 0 && rtc->uie_irq_active) {
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return rtc_dev_update_irq_enable_emul(rtc, 0);
|
||||
}
|
||||
#endif
|
||||
/* make sure we're changing state */
|
||||
if (rtc->uie_rtctimer.enabled == enabled)
|
||||
goto out;
|
||||
|
|
@ -235,15 +247,22 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
|
|||
now = rtc_tm_to_ktime(tm);
|
||||
rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
|
||||
rtc->uie_rtctimer.period = ktime_set(1, 0);
|
||||
rtc->uie_rtctimer.enabled = 1;
|
||||
rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
|
||||
} else {
|
||||
err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
|
||||
} else
|
||||
rtc_timer_remove(rtc, &rtc->uie_rtctimer);
|
||||
rtc->uie_rtctimer.enabled = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
|
||||
/*
|
||||
* Enable emulation if the driver did not provide
|
||||
* the update_irq_enable function pointer or if returned
|
||||
* -EINVAL to signal that it has been configured without
|
||||
* interrupts or that are not available at the moment.
|
||||
*/
|
||||
if (err == -EINVAL)
|
||||
err = rtc_dev_update_irq_enable_emul(rtc, enabled);
|
||||
#endif
|
||||
return err;
|
||||
|
||||
}
|
||||
|
|
@ -259,7 +278,7 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
|
|||
*
|
||||
* Triggers the registered irq_task function callback.
|
||||
*/
|
||||
static void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
|
||||
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -460,6 +479,9 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
|
|||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (freq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&rtc->irq_task_lock, flags);
|
||||
if (rtc->irq_task != NULL && task == NULL)
|
||||
err = -EBUSY;
|
||||
|
|
@ -488,10 +510,13 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
|
|||
* Enqueues a timer onto the rtc devices timerqueue and sets
|
||||
* the next alarm event appropriately.
|
||||
*
|
||||
* Sets the enabled bit on the added timer.
|
||||
*
|
||||
* Must hold ops_lock for proper serialization of timerqueue
|
||||
*/
|
||||
void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
{
|
||||
timer->enabled = 1;
|
||||
timerqueue_add(&rtc->timerqueue, &timer->node);
|
||||
if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
|
||||
struct rtc_wkalrm alarm;
|
||||
|
|
@ -501,7 +526,13 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
|||
err = __rtc_set_alarm(rtc, &alarm);
|
||||
if (err == -ETIME)
|
||||
schedule_work(&rtc->irqwork);
|
||||
else if (err) {
|
||||
timerqueue_del(&rtc->timerqueue, &timer->node);
|
||||
timer->enabled = 0;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -512,13 +543,15 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
|||
* Removes a timer onto the rtc devices timerqueue and sets
|
||||
* the next alarm event appropriately.
|
||||
*
|
||||
* Clears the enabled bit on the removed timer.
|
||||
*
|
||||
* Must hold ops_lock for proper serialization of timerqueue
|
||||
*/
|
||||
void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
{
|
||||
struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
|
||||
timerqueue_del(&rtc->timerqueue, &timer->node);
|
||||
|
||||
timer->enabled = 0;
|
||||
if (next == &timer->node) {
|
||||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
|
|
@ -626,8 +659,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
|
|||
timer->node.expires = expires;
|
||||
timer->period = period;
|
||||
|
||||
timer->enabled = 1;
|
||||
rtc_timer_enqueue(rtc, timer);
|
||||
ret = rtc_timer_enqueue(rtc, timer);
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return ret;
|
||||
|
|
@ -645,7 +677,6 @@ int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
|
|||
mutex_lock(&rtc->ops_lock);
|
||||
if (timer->enabled)
|
||||
rtc_timer_remove(rtc, timer);
|
||||
timer->enabled = 0;
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,36 +134,29 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int at32_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irq(&rtc->lock);
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_ON:
|
||||
if(enabled) {
|
||||
if (rtc_readl(rtc, VAL) > rtc->alarm_time) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
|
||||
| RTC_BIT(CTRL_TOPEN));
|
||||
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
|
||||
rtc_writel(rtc, IER, RTC_BIT(IER_TOPI));
|
||||
break;
|
||||
case RTC_AIE_OFF:
|
||||
} else {
|
||||
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
|
||||
& ~RTC_BIT(CTRL_TOPEN));
|
||||
rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
|
||||
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_irq(&rtc->lock);
|
||||
|
||||
return ret;
|
||||
|
|
@ -195,11 +188,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
static struct rtc_class_ops at32_rtc_ops = {
|
||||
.ioctl = at32_rtc_ioctl,
|
||||
.read_time = at32_rtc_readtime,
|
||||
.set_time = at32_rtc_settime,
|
||||
.read_alarm = at32_rtc_readalarm,
|
||||
.set_alarm = at32_rtc_setalarm,
|
||||
.alarm_irq_enable = at32_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __init at32_rtc_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -195,13 +195,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
|
||||
/* important: scrub old status before enabling IRQs */
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF: /* alarm off */
|
||||
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
|
||||
break;
|
||||
case RTC_AIE_ON: /* alarm on */
|
||||
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
|
||||
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
|
||||
break;
|
||||
case RTC_UIE_OFF: /* update off */
|
||||
at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
|
||||
break;
|
||||
|
|
@ -217,6 +210,18 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
pr_debug("%s(): cmd=%08x\n", __func__, enabled);
|
||||
|
||||
if (enabled) {
|
||||
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
|
||||
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
|
||||
} else
|
||||
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Provide additional RTC information in /proc/driver/rtc
|
||||
*/
|
||||
|
|
@ -270,6 +275,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
|
|||
.read_alarm = at91_rtc_readalarm,
|
||||
.set_alarm = at91_rtc_setalarm,
|
||||
.proc = at91_rtc_proc,
|
||||
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -229,12 +229,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr);
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF: /* alarm off */
|
||||
rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
|
||||
break;
|
||||
case RTC_AIE_ON: /* alarm on */
|
||||
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
|
||||
break;
|
||||
case RTC_UIE_OFF: /* update off */
|
||||
rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
|
||||
break;
|
||||
|
|
@ -249,6 +243,19 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct sam9_rtc *rtc = dev_get_drvdata(dev);
|
||||
u32 mr = rtt_readl(rtc, MR);
|
||||
|
||||
dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr);
|
||||
if (enabled)
|
||||
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
|
||||
else
|
||||
rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide additional RTC information in /proc/driver/rtc
|
||||
*/
|
||||
|
|
@ -302,6 +309,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
|
|||
.read_alarm = at91_rtc_readalarm,
|
||||
.set_alarm = at91_rtc_setalarm,
|
||||
.proc = at91_rtc_proc,
|
||||
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -259,15 +259,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
|
|||
bfin_rtc_int_clear(~RTC_ISTAT_SEC);
|
||||
break;
|
||||
|
||||
case RTC_AIE_ON:
|
||||
dev_dbg_stamp(dev);
|
||||
bfin_rtc_int_set_alarm(rtc);
|
||||
break;
|
||||
case RTC_AIE_OFF:
|
||||
dev_dbg_stamp(dev);
|
||||
bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_dbg_stamp(dev);
|
||||
ret = -ENOIOCTLCMD;
|
||||
|
|
@ -276,6 +267,17 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct bfin_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg_stamp(dev);
|
||||
if (enabled)
|
||||
bfin_rtc_int_set_alarm(rtc);
|
||||
else
|
||||
bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
|
||||
}
|
||||
|
||||
static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct bfin_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
|
@ -362,6 +364,7 @@ static struct rtc_class_ops bfin_rtc_ops = {
|
|||
.read_alarm = bfin_rtc_read_alarm,
|
||||
.set_alarm = bfin_rtc_set_alarm,
|
||||
.proc = bfin_rtc_proc,
|
||||
.alarm_irq_enable = bfin_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit bfin_rtc_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,105 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
|
||||
/*
|
||||
* Routine to poll RTC seconds field for change as often as possible,
|
||||
* after first RTC_UIE use timer to reduce polling
|
||||
*/
|
||||
static void rtc_uie_task(struct work_struct *work)
|
||||
{
|
||||
struct rtc_device *rtc =
|
||||
container_of(work, struct rtc_device, uie_task);
|
||||
struct rtc_time tm;
|
||||
int num = 0;
|
||||
int err;
|
||||
|
||||
err = rtc_read_time(rtc, &tm);
|
||||
|
||||
spin_lock_irq(&rtc->irq_lock);
|
||||
if (rtc->stop_uie_polling || err) {
|
||||
rtc->uie_task_active = 0;
|
||||
} else if (rtc->oldsecs != tm.tm_sec) {
|
||||
num = (tm.tm_sec + 60 - rtc->oldsecs) % 60;
|
||||
rtc->oldsecs = tm.tm_sec;
|
||||
rtc->uie_timer.expires = jiffies + HZ - (HZ/10);
|
||||
rtc->uie_timer_active = 1;
|
||||
rtc->uie_task_active = 0;
|
||||
add_timer(&rtc->uie_timer);
|
||||
} else if (schedule_work(&rtc->uie_task) == 0) {
|
||||
rtc->uie_task_active = 0;
|
||||
}
|
||||
spin_unlock_irq(&rtc->irq_lock);
|
||||
if (num)
|
||||
rtc_handle_legacy_irq(rtc, num, RTC_UF);
|
||||
}
|
||||
static void rtc_uie_timer(unsigned long data)
|
||||
{
|
||||
struct rtc_device *rtc = (struct rtc_device *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rtc->irq_lock, flags);
|
||||
rtc->uie_timer_active = 0;
|
||||
rtc->uie_task_active = 1;
|
||||
if ((schedule_work(&rtc->uie_task) == 0))
|
||||
rtc->uie_task_active = 0;
|
||||
spin_unlock_irqrestore(&rtc->irq_lock, flags);
|
||||
}
|
||||
|
||||
static int clear_uie(struct rtc_device *rtc)
|
||||
{
|
||||
spin_lock_irq(&rtc->irq_lock);
|
||||
if (rtc->uie_irq_active) {
|
||||
rtc->stop_uie_polling = 1;
|
||||
if (rtc->uie_timer_active) {
|
||||
spin_unlock_irq(&rtc->irq_lock);
|
||||
del_timer_sync(&rtc->uie_timer);
|
||||
spin_lock_irq(&rtc->irq_lock);
|
||||
rtc->uie_timer_active = 0;
|
||||
}
|
||||
if (rtc->uie_task_active) {
|
||||
spin_unlock_irq(&rtc->irq_lock);
|
||||
flush_scheduled_work();
|
||||
spin_lock_irq(&rtc->irq_lock);
|
||||
}
|
||||
rtc->uie_irq_active = 0;
|
||||
}
|
||||
spin_unlock_irq(&rtc->irq_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_uie(struct rtc_device *rtc)
|
||||
{
|
||||
struct rtc_time tm;
|
||||
int err;
|
||||
|
||||
err = rtc_read_time(rtc, &tm);
|
||||
if (err)
|
||||
return err;
|
||||
spin_lock_irq(&rtc->irq_lock);
|
||||
if (!rtc->uie_irq_active) {
|
||||
rtc->uie_irq_active = 1;
|
||||
rtc->stop_uie_polling = 0;
|
||||
rtc->oldsecs = tm.tm_sec;
|
||||
rtc->uie_task_active = 1;
|
||||
if (schedule_work(&rtc->uie_task) == 0)
|
||||
rtc->uie_task_active = 0;
|
||||
}
|
||||
rtc->irq_data = 0;
|
||||
spin_unlock_irq(&rtc->irq_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled)
|
||||
{
|
||||
if (enabled)
|
||||
return set_uie(rtc);
|
||||
else
|
||||
return clear_uie(rtc);
|
||||
}
|
||||
EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul);
|
||||
|
||||
#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */
|
||||
|
||||
static ssize_t
|
||||
rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
|
|
@ -154,19 +253,7 @@ static long rtc_dev_ioctl(struct file *file,
|
|||
if (err)
|
||||
goto done;
|
||||
|
||||
/* try the driver's ioctl interface */
|
||||
if (ops->ioctl) {
|
||||
err = ops->ioctl(rtc->dev.parent, cmd, arg);
|
||||
if (err != -ENOIOCTLCMD) {
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the driver does not provide the ioctl interface
|
||||
* or if that particular ioctl was not implemented
|
||||
* (-ENOIOCTLCMD), we will try to emulate here.
|
||||
*
|
||||
/*
|
||||
* Drivers *SHOULD NOT* provide ioctl implementations
|
||||
* for these requests. Instead, provide methods to
|
||||
* support the following code, so that the RTC's main
|
||||
|
|
@ -329,7 +416,12 @@ static long rtc_dev_ioctl(struct file *file,
|
|||
return err;
|
||||
|
||||
default:
|
||||
err = -ENOTTY;
|
||||
/* Finally try the driver's ioctl interface */
|
||||
if (ops->ioctl) {
|
||||
err = ops->ioctl(rtc->dev.parent, cmd, arg);
|
||||
if (err == -ENOIOCTLCMD)
|
||||
err = -ENOTTY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -394,6 +486,11 @@ void rtc_dev_prepare(struct rtc_device *rtc)
|
|||
|
||||
rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
|
||||
INIT_WORK(&rtc->uie_task, rtc_uie_task);
|
||||
setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
|
||||
#endif
|
||||
|
||||
cdev_init(&rtc->char_dev, &rtc_dev_fops);
|
||||
rtc->char_dev.owner = rtc->owner;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)
|
|||
__raw_writel(data, &priv->rtcregs[reg]);
|
||||
}
|
||||
|
||||
|
||||
static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct ds1286_priv *priv = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
unsigned char val;
|
||||
|
||||
/* Allow or mask alarm interrupts */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
val = ds1286_rtc_read(priv, RTC_CMD);
|
||||
if (enabled)
|
||||
val &= ~RTC_TDM;
|
||||
else
|
||||
val |= RTC_TDM;
|
||||
ds1286_rtc_write(priv, val, RTC_CMD);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV
|
||||
|
||||
static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
|
|
@ -49,22 +69,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
unsigned char val;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
/* Mask alarm int. enab. bit */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
val = ds1286_rtc_read(priv, RTC_CMD);
|
||||
val |= RTC_TDM;
|
||||
ds1286_rtc_write(priv, val, RTC_CMD);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case RTC_AIE_ON:
|
||||
/* Allow alarm interrupts. */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
val = ds1286_rtc_read(priv, RTC_CMD);
|
||||
val &= ~RTC_TDM;
|
||||
ds1286_rtc_write(priv, val, RTC_CMD);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case RTC_WIE_OFF:
|
||||
/* Mask watchdog int. enab. bit */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
|
@ -316,12 +320,13 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
|||
}
|
||||
|
||||
static const struct rtc_class_ops ds1286_ops = {
|
||||
.ioctl = ds1286_ioctl,
|
||||
.proc = ds1286_proc,
|
||||
.ioctl = ds1286_ioctl,
|
||||
.proc = ds1286_proc,
|
||||
.read_time = ds1286_read_time,
|
||||
.set_time = ds1286_set_time,
|
||||
.read_alarm = ds1286_read_alarm,
|
||||
.set_alarm = ds1286_set_alarm,
|
||||
.alarm_irq_enable = ds1286_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit ds1286_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -139,49 +139,32 @@ static u8 hour2bcd(bool hr12, int hour)
|
|||
* Interface to RTC framework
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV
|
||||
|
||||
/*
|
||||
* Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
|
||||
*/
|
||||
static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
|
||||
static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct ds1305 *ds1305 = dev_get_drvdata(dev);
|
||||
u8 buf[2];
|
||||
int status = -ENOIOCTLCMD;
|
||||
long err = -EINVAL;
|
||||
|
||||
buf[0] = DS1305_WRITE | DS1305_CONTROL;
|
||||
buf[1] = ds1305->ctrl[0];
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
status = 0;
|
||||
if (!(buf[1] & DS1305_AEI0))
|
||||
goto done;
|
||||
buf[1] &= ~DS1305_AEI0;
|
||||
break;
|
||||
|
||||
case RTC_AIE_ON:
|
||||
status = 0;
|
||||
if (enabled) {
|
||||
if (ds1305->ctrl[0] & DS1305_AEI0)
|
||||
goto done;
|
||||
buf[1] |= DS1305_AEI0;
|
||||
break;
|
||||
} else {
|
||||
if (!(buf[1] & DS1305_AEI0))
|
||||
goto done;
|
||||
buf[1] &= ~DS1305_AEI0;
|
||||
}
|
||||
if (status == 0) {
|
||||
status = spi_write_then_read(ds1305->spi, buf, sizeof buf,
|
||||
NULL, 0);
|
||||
if (status >= 0)
|
||||
ds1305->ctrl[0] = buf[1];
|
||||
}
|
||||
|
||||
err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0);
|
||||
if (err >= 0)
|
||||
ds1305->ctrl[0] = buf[1];
|
||||
done:
|
||||
return status;
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define ds1305_ioctl NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get/set of date and time is pretty normal.
|
||||
|
|
@ -460,12 +443,12 @@ done:
|
|||
#endif
|
||||
|
||||
static const struct rtc_class_ops ds1305_ops = {
|
||||
.ioctl = ds1305_ioctl,
|
||||
.read_time = ds1305_get_time,
|
||||
.set_time = ds1305_set_time,
|
||||
.read_alarm = ds1305_get_alarm,
|
||||
.set_alarm = ds1305_set_alarm,
|
||||
.proc = ds1305_proc,
|
||||
.alarm_irq_enable = ds1305_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static void ds1305_work(struct work_struct *work)
|
||||
|
|
|
|||
|
|
@ -495,50 +495,27 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct ds1307 *ds1307 = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -ENOTTY;
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -ENOTTY;
|
||||
|
||||
ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (enabled)
|
||||
ret |= DS1337_BIT_A1IE;
|
||||
else
|
||||
ret &= ~DS1337_BIT_A1IE;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client,
|
||||
DS1337_REG_CONTROL, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
||||
case RTC_AIE_ON:
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -ENOTTY;
|
||||
|
||||
ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret |= DS1337_BIT_A1IE;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client,
|
||||
DS1337_REG_CONTROL, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -548,7 +525,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
|
|||
.set_time = ds1307_set_time,
|
||||
.read_alarm = ds1337_read_alarm,
|
||||
.set_alarm = ds1337_set_alarm,
|
||||
.ioctl = ds1307_ioctl,
|
||||
.alarm_irq_enable = ds1307_alarm_irq_enable,
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -307,42 +307,25 @@ unlock:
|
|||
mutex_unlock(&ds1374->mutex);
|
||||
}
|
||||
|
||||
static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct ds1374 *ds1374 = i2c_get_clientdata(client);
|
||||
int ret = -ENOIOCTLCMD;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ds1374->mutex);
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret &= ~DS1374_REG_CR_WACE;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
break;
|
||||
|
||||
case RTC_AIE_ON:
|
||||
ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (enabled) {
|
||||
ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
|
||||
ret &= ~DS1374_REG_CR_WDALM;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
break;
|
||||
} else {
|
||||
ret &= ~DS1374_REG_CR_WACE;
|
||||
}
|
||||
ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
|
||||
|
||||
out:
|
||||
mutex_unlock(&ds1374->mutex);
|
||||
|
|
@ -354,7 +337,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
|
|||
.set_time = ds1374_set_time,
|
||||
.read_alarm = ds1374_read_alarm,
|
||||
.set_alarm = ds1374_set_alarm,
|
||||
.ioctl = ds1374_ioctl,
|
||||
.alarm_irq_enable = ds1374_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int ds1374_probe(struct i2c_client *client,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C
|
||||
*
|
||||
* Copyright (C) 2009-2010 Freescale Semiconductor.
|
||||
* Copyright (C) 2009-2011 Freescale Semiconductor.
|
||||
* Author: Jack Lan <jack.lan@freescale.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
|
@ -141,9 +141,11 @@ static int ds3232_read_time(struct device *dev, struct rtc_time *time)
|
|||
time->tm_hour = bcd2bin(hour);
|
||||
}
|
||||
|
||||
time->tm_wday = bcd2bin(week);
|
||||
/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
|
||||
time->tm_wday = bcd2bin(week) - 1;
|
||||
time->tm_mday = bcd2bin(day);
|
||||
time->tm_mon = bcd2bin(month & 0x7F);
|
||||
/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
|
||||
time->tm_mon = bcd2bin(month & 0x7F) - 1;
|
||||
if (century)
|
||||
add_century = 100;
|
||||
|
||||
|
|
@ -162,9 +164,11 @@ static int ds3232_set_time(struct device *dev, struct rtc_time *time)
|
|||
buf[0] = bin2bcd(time->tm_sec);
|
||||
buf[1] = bin2bcd(time->tm_min);
|
||||
buf[2] = bin2bcd(time->tm_hour);
|
||||
buf[3] = bin2bcd(time->tm_wday); /* Day of the week */
|
||||
/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
|
||||
buf[3] = bin2bcd(time->tm_wday + 1);
|
||||
buf[4] = bin2bcd(time->tm_mday); /* Date */
|
||||
buf[5] = bin2bcd(time->tm_mon);
|
||||
/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
|
||||
buf[5] = bin2bcd(time->tm_mon + 1);
|
||||
if (time->tm_year >= 100) {
|
||||
buf[5] |= 0x80;
|
||||
buf[6] = bin2bcd(time->tm_year - 100);
|
||||
|
|
|
|||
|
|
@ -213,41 +213,27 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
return m41t80_set_datetime(to_i2c_client(dev), tm);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
|
||||
static int
|
||||
m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int rc;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
rc &= ~M41T80_ALMON_AFE;
|
||||
break;
|
||||
case RTC_AIE_ON:
|
||||
|
||||
if (enabled)
|
||||
rc |= M41T80_ALMON_AFE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
rc &= ~M41T80_ALMON_AFE;
|
||||
|
||||
if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return -EIO;
|
||||
}
|
||||
#else
|
||||
#define m41t80_rtc_ioctl NULL
|
||||
#endif
|
||||
|
||||
static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
||||
{
|
||||
|
|
@ -374,7 +360,7 @@ static struct rtc_class_ops m41t80_rtc_ops = {
|
|||
.read_alarm = m41t80_rtc_read_alarm,
|
||||
.set_alarm = m41t80_rtc_set_alarm,
|
||||
.proc = m41t80_rtc_proc,
|
||||
.ioctl = m41t80_rtc_ioctl,
|
||||
.alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
|
||||
|
|
|
|||
|
|
@ -263,30 +263,21 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
/*
|
||||
* Handle commands from user-space
|
||||
*/
|
||||
static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct m48t59_plat_data *pdata = pdev->dev.platform_data;
|
||||
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&m48t59->lock, flags);
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF: /* alarm interrupt off */
|
||||
M48T59_WRITE(0x00, M48T59_INTR);
|
||||
break;
|
||||
case RTC_AIE_ON: /* alarm interrupt on */
|
||||
if (enabled)
|
||||
M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
else
|
||||
M48T59_WRITE(0x00, M48T59_INTR);
|
||||
spin_unlock_irqrestore(&m48t59->lock, flags);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
|
||||
|
|
@ -330,12 +321,12 @@ static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
static const struct rtc_class_ops m48t59_rtc_ops = {
|
||||
.ioctl = m48t59_rtc_ioctl,
|
||||
.read_time = m48t59_rtc_read_time,
|
||||
.set_time = m48t59_rtc_set_time,
|
||||
.read_alarm = m48t59_rtc_readalarm,
|
||||
.set_alarm = m48t59_rtc_setalarm,
|
||||
.proc = m48t59_rtc_proc,
|
||||
.alarm_irq_enable = m48t59_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static const struct rtc_class_ops m48t02_rtc_ops = {
|
||||
|
|
|
|||
|
|
@ -255,42 +255,21 @@ static int mrst_irq_set_state(struct device *dev, int enabled)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
|
||||
|
||||
/* Currently, the vRTC doesn't support UIE ON/OFF */
|
||||
static int
|
||||
mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct mrst_rtc *mrst = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
if (!mrst->irq)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
/* PIE ON/OFF is handled by mrst_irq_set_state() */
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF: /* alarm off */
|
||||
mrst_irq_disable(mrst, RTC_AIE);
|
||||
break;
|
||||
case RTC_AIE_ON: /* alarm on */
|
||||
if (enabled)
|
||||
mrst_irq_enable(mrst, RTC_AIE);
|
||||
break;
|
||||
}
|
||||
else
|
||||
mrst_irq_disable(mrst, RTC_AIE);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define mrst_rtc_ioctl NULL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
|
||||
|
||||
|
|
@ -317,13 +296,13 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq)
|
|||
#endif
|
||||
|
||||
static const struct rtc_class_ops mrst_rtc_ops = {
|
||||
.ioctl = mrst_rtc_ioctl,
|
||||
.read_time = mrst_read_time,
|
||||
.set_time = mrst_set_time,
|
||||
.read_alarm = mrst_read_alarm,
|
||||
.set_alarm = mrst_set_alarm,
|
||||
.proc = mrst_procfs,
|
||||
.irq_set_state = mrst_irq_set_state,
|
||||
.alarm_irq_enable = mrst_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static struct mrst_rtc mrst_rtc;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static inline unsigned int msm6242_read(struct msm6242_priv *priv,
|
|||
static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
|
||||
unsigned int reg)
|
||||
{
|
||||
return __raw_writel(val, &priv->regs[reg]);
|
||||
__raw_writel(val, &priv->regs[reg]);
|
||||
}
|
||||
|
||||
static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
|
||||
|
|
|
|||
|
|
@ -169,25 +169,19 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mv_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
||||
void __iomem *ioaddr = pdata->ioaddr;
|
||||
|
||||
if (pdata->irq < 0)
|
||||
return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
|
||||
break;
|
||||
case RTC_AIE_ON:
|
||||
return -EINVAL; /* fall back into rtc-dev's emulation */
|
||||
|
||||
if (enabled)
|
||||
writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
else
|
||||
writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +210,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = {
|
|||
.set_time = mv_rtc_set_time,
|
||||
.read_alarm = mv_rtc_read_alarm,
|
||||
.set_alarm = mv_rtc_set_alarm,
|
||||
.ioctl = mv_rtc_ioctl,
|
||||
.alarm_irq_enable = mv_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit mv_rtc_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -143,8 +143,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
u8 reg;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
case RTC_UIE_OFF:
|
||||
case RTC_UIE_ON:
|
||||
break;
|
||||
|
|
@ -156,13 +154,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
rtc_wait_not_busy();
|
||||
reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
switch (cmd) {
|
||||
/* AIE = Alarm Interrupt Enable */
|
||||
case RTC_AIE_OFF:
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
break;
|
||||
case RTC_AIE_ON:
|
||||
reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
break;
|
||||
/* UIE = Update Interrupt Enable (1/second) */
|
||||
case RTC_UIE_OFF:
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER;
|
||||
|
|
@ -182,6 +173,24 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
#define omap_rtc_ioctl NULL
|
||||
#endif
|
||||
|
||||
static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
local_irq_disable();
|
||||
rtc_wait_not_busy();
|
||||
reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
if (enabled)
|
||||
reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
else
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
rtc_wait_not_busy();
|
||||
rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this hardware doesn't support "don't care" alarm fields */
|
||||
static int tm2bcd(struct rtc_time *tm)
|
||||
{
|
||||
|
|
@ -309,6 +318,7 @@ static struct rtc_class_ops omap_rtc_ops = {
|
|||
.set_time = omap_rtc_set_time,
|
||||
.read_alarm = omap_rtc_read_alarm,
|
||||
.set_alarm = omap_rtc_set_alarm,
|
||||
.alarm_irq_enable = omap_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int omap_rtc_alarm;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static const struct rtc_class_ops pl030_ops = {
|
|||
.set_alarm = pl030_set_alarm,
|
||||
};
|
||||
|
||||
static int pl030_probe(struct amba_device *dev, struct amba_id *id)
|
||||
static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
{
|
||||
struct pl030_rtc *rtc;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ static int pl031_remove(struct amba_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pl031_probe(struct amba_device *adev, struct amba_id *id)
|
||||
static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
{
|
||||
int ret;
|
||||
struct pl031_local *ldata;
|
||||
|
|
|
|||
|
|
@ -81,12 +81,16 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
|
|||
|
||||
static int rtc_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
struct rtc_device *rtc = PDE(inode)->data;
|
||||
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, rtc_proc_show, rtc);
|
||||
ret = single_open(file, rtc_proc_show, rtc);
|
||||
if (ret)
|
||||
module_put(THIS_MODULE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtc_proc_release(struct inode *inode, struct file *file)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
|
|||
static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
|
||||
unsigned int reg)
|
||||
{
|
||||
return __raw_writel(val, &priv->regs[reg]);
|
||||
__raw_writel(val, &priv->regs[reg]);
|
||||
}
|
||||
|
||||
static void rp5c01_lock(struct rp5c01_priv *priv)
|
||||
|
|
|
|||
|
|
@ -299,14 +299,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
if (rs5c->type == rtc_rs5c372a
|
||||
&& (buf & RS5C372A_CTRL1_SL1))
|
||||
return -ENOIOCTLCMD;
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
/* these irq management calls only make sense for chips
|
||||
* which are wired up to an IRQ.
|
||||
*/
|
||||
if (!rs5c->has_irq)
|
||||
return -ENOIOCTLCMD;
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
|
@ -317,12 +309,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
|
||||
addr = RS5C_ADDR(RS5C_REG_CTRL1);
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF: /* alarm off */
|
||||
buf &= ~RS5C_CTRL1_AALE;
|
||||
break;
|
||||
case RTC_AIE_ON: /* alarm on */
|
||||
buf |= RS5C_CTRL1_AALE;
|
||||
break;
|
||||
case RTC_UIE_OFF: /* update off */
|
||||
buf &= ~RS5C_CTRL1_CT_MASK;
|
||||
break;
|
||||
|
|
@ -347,6 +333,39 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
#endif
|
||||
|
||||
|
||||
static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct rs5c372 *rs5c = i2c_get_clientdata(client);
|
||||
unsigned char buf;
|
||||
int status, addr;
|
||||
|
||||
buf = rs5c->regs[RS5C_REG_CTRL1];
|
||||
|
||||
if (!rs5c->has_irq)
|
||||
return -EINVAL;
|
||||
|
||||
status = rs5c_get_regs(rs5c);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
addr = RS5C_ADDR(RS5C_REG_CTRL1);
|
||||
if (enabled)
|
||||
buf |= RS5C_CTRL1_AALE;
|
||||
else
|
||||
buf &= ~RS5C_CTRL1_AALE;
|
||||
|
||||
if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
|
||||
printk(KERN_WARNING "%s: can't update alarm\n",
|
||||
rs5c->rtc->name);
|
||||
status = -EIO;
|
||||
} else
|
||||
rs5c->regs[RS5C_REG_CTRL1] = buf;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI,
|
||||
* which only exposes a polled programming interface; and since
|
||||
* these calls map directly to those EFI requests; we don't demand
|
||||
|
|
@ -466,6 +485,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = {
|
|||
.set_time = rs5c372_rtc_set_time,
|
||||
.read_alarm = rs5c_read_alarm,
|
||||
.set_alarm = rs5c_set_alarm,
|
||||
.alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
|
||||
|
|
|
|||
|
|
@ -77,18 +77,20 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
|
|||
}
|
||||
|
||||
/* Update control registers */
|
||||
static void s3c_rtc_setaie(int to)
|
||||
static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
pr_debug("%s: aie=%d\n", __func__, to);
|
||||
pr_debug("%s: aie=%d\n", __func__, enabled);
|
||||
|
||||
tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
|
||||
|
||||
if (to)
|
||||
if (enabled)
|
||||
tmp |= S3C2410_RTCALM_ALMEN;
|
||||
|
||||
writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c_rtc_setpie(struct device *dev, int enabled)
|
||||
|
|
@ -308,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
|
||||
writeb(alrm_en, base + S3C2410_RTCALM);
|
||||
|
||||
s3c_rtc_setaie(alrm->enabled);
|
||||
s3c_rtc_setaie(dev, alrm->enabled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -440,7 +442,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
|
|||
rtc_device_unregister(rtc);
|
||||
|
||||
s3c_rtc_setpie(&dev->dev, 0);
|
||||
s3c_rtc_setaie(0);
|
||||
s3c_rtc_setaie(&dev->dev, 0);
|
||||
|
||||
clk_disable(rtc_clk);
|
||||
clk_put(rtc_clk);
|
||||
|
|
|
|||
|
|
@ -314,16 +314,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
spin_lock_irq(&sa1100_rtc_lock);
|
||||
RTSR &= ~RTSR_ALE;
|
||||
spin_unlock_irq(&sa1100_rtc_lock);
|
||||
return 0;
|
||||
case RTC_AIE_ON:
|
||||
spin_lock_irq(&sa1100_rtc_lock);
|
||||
RTSR |= RTSR_ALE;
|
||||
spin_unlock_irq(&sa1100_rtc_lock);
|
||||
return 0;
|
||||
case RTC_UIE_OFF:
|
||||
spin_lock_irq(&sa1100_rtc_lock);
|
||||
RTSR &= ~RTSR_HZE;
|
||||
|
|
@ -338,6 +328,17 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
spin_lock_irq(&sa1100_rtc_lock);
|
||||
if (enabled)
|
||||
RTSR |= RTSR_ALE;
|
||||
else
|
||||
RTSR &= ~RTSR_ALE;
|
||||
spin_unlock_irq(&sa1100_rtc_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
rtc_time_to_tm(RCNR, tm);
|
||||
|
|
@ -410,6 +411,7 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
|
|||
.proc = sa1100_rtc_proc,
|
||||
.irq_set_freq = sa1100_irq_set_freq,
|
||||
.irq_set_state = sa1100_irq_set_state,
|
||||
.alarm_irq_enable = sa1100_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int sa1100_rtc_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -350,10 +350,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
unsigned int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_AIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
|
||||
break;
|
||||
case RTC_UIE_OFF:
|
||||
rtc->periodic_freq &= ~PF_OXS;
|
||||
sh_rtc_setcie(dev, 0);
|
||||
|
|
@ -369,6 +365,12 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
sh_rtc_setaie(dev, enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
|
@ -604,6 +606,7 @@ static struct rtc_class_ops sh_rtc_ops = {
|
|||
.irq_set_state = sh_rtc_irq_set_state,
|
||||
.irq_set_freq = sh_rtc_irq_set_freq,
|
||||
.proc = sh_rtc_proc,
|
||||
.alarm_irq_enable = sh_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __init sh_rtc_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -50,24 +50,9 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
|
||||
{
|
||||
/* We do support interrupts, they're generated
|
||||
* using the sysfs interface.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case RTC_PIE_ON:
|
||||
case RTC_PIE_OFF:
|
||||
case RTC_UIE_ON:
|
||||
case RTC_UIE_OFF:
|
||||
case RTC_AIE_ON:
|
||||
case RTC_AIE_OFF:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops test_rtc_ops = {
|
||||
|
|
@ -76,7 +61,7 @@ static const struct rtc_class_ops test_rtc_ops = {
|
|||
.read_alarm = test_rtc_read_alarm,
|
||||
.set_alarm = test_rtc_set_alarm,
|
||||
.set_mmss = test_rtc_set_mmss,
|
||||
.ioctl = test_rtc_ioctl,
|
||||
.alarm_irq_enable = test_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static ssize_t test_irq_show(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -240,26 +240,6 @@ static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
|
|||
static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case RTC_AIE_ON:
|
||||
spin_lock_irq(&rtc_lock);
|
||||
|
||||
if (!alarm_enabled) {
|
||||
enable_irq(aie_irq);
|
||||
alarm_enabled = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
break;
|
||||
case RTC_AIE_OFF:
|
||||
spin_lock_irq(&rtc_lock);
|
||||
|
||||
if (alarm_enabled) {
|
||||
disable_irq(aie_irq);
|
||||
alarm_enabled = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
break;
|
||||
case RTC_EPOCH_READ:
|
||||
return put_user(epoch, (unsigned long __user *)arg);
|
||||
case RTC_EPOCH_SET:
|
||||
|
|
@ -275,6 +255,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
spin_lock_irq(&rtc_lock);
|
||||
if (enabled) {
|
||||
if (!alarm_enabled) {
|
||||
enable_irq(aie_irq);
|
||||
alarm_enabled = 1;
|
||||
}
|
||||
} else {
|
||||
if (alarm_enabled) {
|
||||
disable_irq(aie_irq);
|
||||
alarm_enabled = 0;
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct platform_device *pdev = (struct platform_device *)dev_id;
|
||||
|
|
|
|||
Loading…
Reference in a new issue