aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sh.c
diff options
context:
space:
mode:
authorAlessandro Zummo <a.zummo@towertech.it>2009-08-20 00:25:11 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-20 00:25:11 -0400
commit5c9740a8b797c9141a39e8115f5652d7bb28a67d (patch)
tree33b8abf39e7b7bae684436b47c564ec2aab92093 /drivers/rtc/rtc-sh.c
parent2bfc3305f6b3e08645f7d6b9514211d955b02698 (diff)
rtc: rtc-sh fixes
- simplifies irq set freq - ioctl() was duplicating functionalities of rtc-dev core - corrected initialization sequence - use platform_driver_probe Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: Angelo Castello <angelo.castello@st.com> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Cc: Jamie Lenehan <lenehan@twibble.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/rtc/rtc-sh.c')
-rw-r--r--drivers/rtc/rtc-sh.c93
1 files changed, 32 insertions, 61 deletions
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index d7310adb7152..39a2fcd98c2d 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -29,7 +29,7 @@
29#include <asm/rtc.h> 29#include <asm/rtc.h>
30 30
31#define DRV_NAME "sh-rtc" 31#define DRV_NAME "sh-rtc"
32#define DRV_VERSION "0.2.2" 32#define DRV_VERSION "0.2.3"
33 33
34#define RTC_REG(r) ((r) * rtc_reg_size) 34#define RTC_REG(r) ((r) * rtc_reg_size)
35 35
@@ -215,7 +215,7 @@ static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
215 return IRQ_RETVAL(ret); 215 return IRQ_RETVAL(ret);
216} 216}
217 217
218static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) 218static int sh_rtc_irq_set_state(struct device *dev, int enable)
219{ 219{
220 struct sh_rtc *rtc = dev_get_drvdata(dev); 220 struct sh_rtc *rtc = dev_get_drvdata(dev);
221 unsigned int tmp; 221 unsigned int tmp;
@@ -225,17 +225,22 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
225 tmp = readb(rtc->regbase + RCR2); 225 tmp = readb(rtc->regbase + RCR2);
226 226
227 if (enable) { 227 if (enable) {
228 rtc->periodic_freq |= PF_KOU;
228 tmp &= ~RCR2_PEF; /* Clear PES bit */ 229 tmp &= ~RCR2_PEF; /* Clear PES bit */
229 tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */ 230 tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */
230 } else 231 } else {
232 rtc->periodic_freq &= ~PF_KOU;
231 tmp &= ~(RCR2_PESMASK | RCR2_PEF); 233 tmp &= ~(RCR2_PESMASK | RCR2_PEF);
234 }
232 235
233 writeb(tmp, rtc->regbase + RCR2); 236 writeb(tmp, rtc->regbase + RCR2);
234 237
235 spin_unlock_irq(&rtc->lock); 238 spin_unlock_irq(&rtc->lock);
239
240 return 0;
236} 241}
237 242
238static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq) 243static int sh_rtc_irq_set_freq(struct device *dev, int freq)
239{ 244{
240 struct sh_rtc *rtc = dev_get_drvdata(dev); 245 struct sh_rtc *rtc = dev_get_drvdata(dev);
241 int tmp, ret = 0; 246 int tmp, ret = 0;
@@ -346,10 +351,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
346 unsigned int ret = 0; 351 unsigned int ret = 0;
347 352
348 switch (cmd) { 353 switch (cmd) {
349 case RTC_PIE_OFF:
350 case RTC_PIE_ON:
351 sh_rtc_setpie(dev, cmd == RTC_PIE_ON);
352 break;
353 case RTC_AIE_OFF: 354 case RTC_AIE_OFF:
354 case RTC_AIE_ON: 355 case RTC_AIE_ON:
355 sh_rtc_setaie(dev, cmd == RTC_AIE_ON); 356 sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
@@ -362,13 +363,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
362 rtc->periodic_freq |= PF_OXS; 363 rtc->periodic_freq |= PF_OXS;
363 sh_rtc_setcie(dev, 1); 364 sh_rtc_setcie(dev, 1);
364 break; 365 break;
365 case RTC_IRQP_READ:
366 ret = put_user(rtc->rtc_dev->irq_freq,
367 (unsigned long __user *)arg);
368 break;
369 case RTC_IRQP_SET:
370 ret = sh_rtc_setfreq(dev, arg);
371 break;
372 default: 366 default:
373 ret = -ENOIOCTLCMD; 367 ret = -ENOIOCTLCMD;
374 } 368 }
@@ -602,28 +596,6 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
602 return 0; 596 return 0;
603} 597}
604 598
605static int sh_rtc_irq_set_state(struct device *dev, int enabled)
606{
607 struct platform_device *pdev = to_platform_device(dev);
608 struct sh_rtc *rtc = platform_get_drvdata(pdev);
609
610 if (enabled) {
611 rtc->periodic_freq |= PF_KOU;
612 return sh_rtc_ioctl(dev, RTC_PIE_ON, 0);
613 } else {
614 rtc->periodic_freq &= ~PF_KOU;
615 return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0);
616 }
617}
618
619static int sh_rtc_irq_set_freq(struct device *dev, int freq)
620{
621 if (!is_power_of_2(freq))
622 return -EINVAL;
623
624 return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
625}
626
627static struct rtc_class_ops sh_rtc_ops = { 599static struct rtc_class_ops sh_rtc_ops = {
628 .ioctl = sh_rtc_ioctl, 600 .ioctl = sh_rtc_ioctl,
629 .read_time = sh_rtc_read_time, 601 .read_time = sh_rtc_read_time,
@@ -635,7 +607,7 @@ static struct rtc_class_ops sh_rtc_ops = {
635 .proc = sh_rtc_proc, 607 .proc = sh_rtc_proc,
636}; 608};
637 609
638static int __devinit sh_rtc_probe(struct platform_device *pdev) 610static int __init sh_rtc_probe(struct platform_device *pdev)
639{ 611{
640 struct sh_rtc *rtc; 612 struct sh_rtc *rtc;
641 struct resource *res; 613 struct resource *res;
@@ -702,13 +674,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
702 674
703 clk_enable(rtc->clk); 675 clk_enable(rtc->clk);
704 676
705 rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
706 &sh_rtc_ops, THIS_MODULE);
707 if (IS_ERR(rtc->rtc_dev)) {
708 ret = PTR_ERR(rtc->rtc_dev);
709 goto err_unmap;
710 }
711
712 rtc->capabilities = RTC_DEF_CAPABILITIES; 677 rtc->capabilities = RTC_DEF_CAPABILITIES;
713 if (pdev->dev.platform_data) { 678 if (pdev->dev.platform_data) {
714 struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data; 679 struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data;
@@ -720,10 +685,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
720 rtc->capabilities |= pinfo->capabilities; 685 rtc->capabilities |= pinfo->capabilities;
721 } 686 }
722 687
723 rtc->rtc_dev->max_user_freq = 256;
724
725 platform_set_drvdata(pdev, rtc);
726
727 if (rtc->carry_irq <= 0) { 688 if (rtc->carry_irq <= 0) {
728 /* register shared periodic/carry/alarm irq */ 689 /* register shared periodic/carry/alarm irq */
729 ret = request_irq(rtc->periodic_irq, sh_rtc_shared, 690 ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
@@ -767,13 +728,26 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
767 } 728 }
768 } 729 }
769 730
731 platform_set_drvdata(pdev, rtc);
732
770 /* everything disabled by default */ 733 /* everything disabled by default */
771 rtc->periodic_freq = 0; 734 sh_rtc_irq_set_freq(&pdev->dev, 0);
772 rtc->rtc_dev->irq_freq = 0; 735 sh_rtc_irq_set_state(&pdev->dev, 0);
773 sh_rtc_setpie(&pdev->dev, 0);
774 sh_rtc_setaie(&pdev->dev, 0); 736 sh_rtc_setaie(&pdev->dev, 0);
775 sh_rtc_setcie(&pdev->dev, 0); 737 sh_rtc_setcie(&pdev->dev, 0);
776 738
739 rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
740 &sh_rtc_ops, THIS_MODULE);
741 if (IS_ERR(rtc->rtc_dev)) {
742 ret = PTR_ERR(rtc->rtc_dev);
743 free_irq(rtc->periodic_irq, rtc);
744 free_irq(rtc->carry_irq, rtc);
745 free_irq(rtc->alarm_irq, rtc);
746 goto err_unmap;
747 }
748
749 rtc->rtc_dev->max_user_freq = 256;
750
777 /* reset rtc to epoch 0 if time is invalid */ 751 /* reset rtc to epoch 0 if time is invalid */
778 if (rtc_read_time(rtc->rtc_dev, &r) < 0) { 752 if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
779 rtc_time_to_tm(0, &r); 753 rtc_time_to_tm(0, &r);
@@ -795,14 +769,13 @@ err_badres:
795 return ret; 769 return ret;
796} 770}
797 771
798static int __devexit sh_rtc_remove(struct platform_device *pdev) 772static int __exit sh_rtc_remove(struct platform_device *pdev)
799{ 773{
800 struct sh_rtc *rtc = platform_get_drvdata(pdev); 774 struct sh_rtc *rtc = platform_get_drvdata(pdev);
801 775
802 if (likely(rtc->rtc_dev)) 776 rtc_device_unregister(rtc->rtc_dev);
803 rtc_device_unregister(rtc->rtc_dev); 777 sh_rtc_irq_set_state(&pdev->dev, 0);
804 778
805 sh_rtc_setpie(&pdev->dev, 0);
806 sh_rtc_setaie(&pdev->dev, 0); 779 sh_rtc_setaie(&pdev->dev, 0);
807 sh_rtc_setcie(&pdev->dev, 0); 780 sh_rtc_setcie(&pdev->dev, 0);
808 781
@@ -813,9 +786,8 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
813 free_irq(rtc->alarm_irq, rtc); 786 free_irq(rtc->alarm_irq, rtc);
814 } 787 }
815 788
816 release_resource(rtc->res);
817
818 iounmap(rtc->regbase); 789 iounmap(rtc->regbase);
790 release_resource(rtc->res);
819 791
820 clk_disable(rtc->clk); 792 clk_disable(rtc->clk);
821 clk_put(rtc->clk); 793 clk_put(rtc->clk);
@@ -867,13 +839,12 @@ static struct platform_driver sh_rtc_platform_driver = {
867 .owner = THIS_MODULE, 839 .owner = THIS_MODULE,
868 .pm = &sh_rtc_dev_pm_ops, 840 .pm = &sh_rtc_dev_pm_ops,
869 }, 841 },
870 .probe = sh_rtc_probe, 842 .remove = __exit_p(sh_rtc_remove),
871 .remove = __devexit_p(sh_rtc_remove),
872}; 843};
873 844
874static int __init sh_rtc_init(void) 845static int __init sh_rtc_init(void)
875{ 846{
876 return platform_driver_register(&sh_rtc_platform_driver); 847 return platform_driver_probe(&sh_rtc_platform_driver, sh_rtc_probe);
877} 848}
878 849
879static void __exit sh_rtc_exit(void) 850static void __exit sh_rtc_exit(void)