X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Frtc%2Finterface.c;h=ef40df0f169d2a1039ddca745f586dd122731afa;hb=7776a94c311504f26e73060920dfb3ccf02786b7;hp=56e490709b87582fff3aaae2f17c43c7f9980a35;hpb=79072f38909e3d9883317238887460c39ddcc4cb;p=linux-2.6-omap-h63xx.git diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 56e490709b8..ef40df0f169 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -145,6 +145,13 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) } EXPORT_SYMBOL_GPL(rtc_set_alarm); +/** + * rtc_update_irq - report RTC periodic, alarm, and/or update irqs + * @class_dev: the rtc's class device + * @num: how many irqs are being reported (usually one) + * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF + * Context: in_interrupt(), irqs blocked + */ void rtc_update_irq(struct class_device *class_dev, unsigned long num, unsigned long events) { @@ -172,7 +179,7 @@ struct class_device *rtc_class_open(char *name) down(&rtc_class->sem); list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { - class_dev = class_dev_tmp; + class_dev = class_device_get(class_dev_tmp); break; } } @@ -190,6 +197,7 @@ EXPORT_SYMBOL_GPL(rtc_class_open); void rtc_class_close(struct class_device *class_dev) { module_put(to_rtc_device(class_dev)->owner); + class_device_put(class_dev); } EXPORT_SYMBOL_GPL(rtc_class_close); @@ -201,12 +209,12 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) if (task == NULL || task->func == NULL) return -EINVAL; - spin_lock(&rtc->irq_task_lock); + spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task == NULL) { rtc->irq_task = task; retval = 0; } - spin_unlock(&rtc->irq_task_lock); + spin_unlock_irq(&rtc->irq_task_lock); return retval; } @@ -216,10 +224,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) { struct rtc_device *rtc = to_rtc_device(class_dev); - spin_lock(&rtc->irq_task_lock); + spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task == task) rtc->irq_task = NULL; - spin_unlock(&rtc->irq_task_lock); + spin_unlock_irq(&rtc->irq_task_lock); } EXPORT_SYMBOL_GPL(rtc_irq_unregister); @@ -229,6 +237,9 @@ int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int unsigned long flags; struct rtc_device *rtc = to_rtc_device(class_dev); + if (rtc->ops->irq_set_state == NULL) + return -ENXIO; + spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != task) err = -ENXIO; @@ -243,25 +254,12 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_state); int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) { - int err = 0, tmp = 0; + int err = 0; unsigned long flags; struct rtc_device *rtc = to_rtc_device(class_dev); - /* allowed range is 2-8192 */ - if (freq < 2 || freq > 8192) - return -EINVAL; -/* - FIXME: this does not belong here, will move where appropriate - at a later stage. It cannot hurt right now, trust me :) - if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) - return -EACCES; -*/ - /* check if freq is a power of 2 */ - while (freq > (1 << tmp)) - tmp++; - - if (freq != (1 << tmp)) - return -EINVAL; + if (rtc->ops->irq_set_freq == NULL) + return -ENXIO; spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != task) @@ -275,3 +273,4 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int } return err; } +EXPORT_SYMBOL_GPL(rtc_irq_set_freq);