aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-nuc900.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-nuc900.c')
-rw-r--r--drivers/rtc/rtc-nuc900.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index a351bd5d8176..62de66af0a68 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -85,25 +85,24 @@ static irqreturn_t nuc900_rtc_interrupt(int irq, void *_rtc)
85 85
86static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc) 86static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc)
87{ 87{
88 unsigned int i; 88 unsigned int timeout = 0x1000;
89 __raw_writel(INIRRESET, nuc900_rtc->rtc_reg + REG_RTC_INIR); 89 __raw_writel(INIRRESET, nuc900_rtc->rtc_reg + REG_RTC_INIR);
90 90
91 mdelay(10); 91 mdelay(10);
92 92
93 __raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER); 93 __raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER);
94 94
95 for (i = 0; i < 1000; i++) { 95 while (!(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB)
96 if (__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB) 96 && timeout--)
97 return 0; 97 mdelay(1);
98 }
99 98
100 if ((__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB) == 0x0) 99 if (!timeout)
101 return ERR_PTR(-ENODEV); 100 return ERR_PTR(-EPERM);
102 101
103 return ERR_PTR(-EPERM); 102 return 0;
104} 103}
105 104
106static void nuc900_rtc_bcd2bin(unsigned int timereg, 105static int nuc900_rtc_bcd2bin(unsigned int timereg,
107 unsigned int calreg, struct rtc_time *tm) 106 unsigned int calreg, struct rtc_time *tm)
108{ 107{
109 tm->tm_mday = bcd2bin(calreg >> 0); 108 tm->tm_mday = bcd2bin(calreg >> 0);
@@ -114,15 +113,21 @@ static void nuc900_rtc_bcd2bin(unsigned int timereg,
114 tm->tm_min = bcd2bin(timereg >> 8); 113 tm->tm_min = bcd2bin(timereg >> 8);
115 tm->tm_hour = bcd2bin(timereg >> 16); 114 tm->tm_hour = bcd2bin(timereg >> 16);
116 115
117 rtc_valid_tm(tm); 116 return rtc_valid_tm(tm);
118} 117}
119 118
120static void nuc900_rtc_bin2bcd(struct rtc_time *settm, 119static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm,
121 struct nuc900_bcd_time *gettm) 120 struct nuc900_bcd_time *gettm)
122{ 121{
123 gettm->bcd_mday = bin2bcd(settm->tm_mday) << 0; 122 gettm->bcd_mday = bin2bcd(settm->tm_mday) << 0;
124 gettm->bcd_mon = bin2bcd(settm->tm_mon) << 8; 123 gettm->bcd_mon = bin2bcd(settm->tm_mon) << 8;
125 gettm->bcd_year = bin2bcd(settm->tm_year - 100) << 16; 124
125 if (settm->tm_year < 100) {
126 dev_warn(dev, "The year will be between 1970-1999, right?\n");
127 gettm->bcd_year = bin2bcd(settm->tm_year) << 16;
128 } else {
129 gettm->bcd_year = bin2bcd(settm->tm_year - 100) << 16;
130 }
126 131
127 gettm->bcd_sec = bin2bcd(settm->tm_sec) << 0; 132 gettm->bcd_sec = bin2bcd(settm->tm_sec) << 0;
128 gettm->bcd_min = bin2bcd(settm->tm_min) << 8; 133 gettm->bcd_min = bin2bcd(settm->tm_min) << 8;
@@ -165,9 +170,7 @@ static int nuc900_rtc_read_time(struct device *dev, struct rtc_time *tm)
165 timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR); 170 timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR);
166 clrval = __raw_readl(rtc->rtc_reg + REG_RTC_CLR); 171 clrval = __raw_readl(rtc->rtc_reg + REG_RTC_CLR);
167 172
168 nuc900_rtc_bcd2bin(timeval, clrval, tm); 173 return nuc900_rtc_bcd2bin(timeval, clrval, tm);
169
170 return 0;
171} 174}
172 175
173static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm) 176static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -177,7 +180,7 @@ static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm)
177 unsigned long val; 180 unsigned long val;
178 int *err; 181 int *err;
179 182
180 nuc900_rtc_bin2bcd(tm, &gettm); 183 nuc900_rtc_bin2bcd(dev, tm, &gettm);
181 184
182 err = check_rtc_access_enable(rtc); 185 err = check_rtc_access_enable(rtc);
183 if (IS_ERR(err)) 186 if (IS_ERR(err))
@@ -200,9 +203,7 @@ static int nuc900_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
200 timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR); 203 timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR);
201 carval = __raw_readl(rtc->rtc_reg + REG_RTC_CAR); 204 carval = __raw_readl(rtc->rtc_reg + REG_RTC_CAR);
202 205
203 nuc900_rtc_bcd2bin(timeval, carval, &alrm->time); 206 return nuc900_rtc_bcd2bin(timeval, carval, &alrm->time);
204
205 return 0;
206} 207}
207 208
208static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 209static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -212,7 +213,7 @@ static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
212 unsigned long val; 213 unsigned long val;
213 int *err; 214 int *err;
214 215
215 nuc900_rtc_bin2bcd(&alrm->time, &tm); 216 nuc900_rtc_bin2bcd(dev, &alrm->time, &tm);
216 217
217 err = check_rtc_access_enable(rtc); 218 err = check_rtc_access_enable(rtc);
218 if (IS_ERR(err)) 219 if (IS_ERR(err))
@@ -268,29 +269,30 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
268 goto fail2; 269 goto fail2;
269 } 270 }
270 271
271 nuc900_rtc->irq_num = platform_get_irq(pdev, 0); 272 platform_set_drvdata(pdev, nuc900_rtc);
272 if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
273 IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) {
274 dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
275 err = -EBUSY;
276 goto fail3;
277 }
278 273
279 nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, 274 nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev,
280 &nuc900_rtc_ops, THIS_MODULE); 275 &nuc900_rtc_ops, THIS_MODULE);
281 if (IS_ERR(nuc900_rtc->rtcdev)) { 276 if (IS_ERR(nuc900_rtc->rtcdev)) {
282 dev_err(&pdev->dev, "rtc device register faild\n"); 277 dev_err(&pdev->dev, "rtc device register faild\n");
283 err = PTR_ERR(nuc900_rtc->rtcdev); 278 err = PTR_ERR(nuc900_rtc->rtcdev);
284 goto fail4; 279 goto fail3;
285 } 280 }
286 281
287 platform_set_drvdata(pdev, nuc900_rtc);
288 __raw_writel(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_TSSR) | MODE24, 282 __raw_writel(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_TSSR) | MODE24,
289 nuc900_rtc->rtc_reg + REG_RTC_TSSR); 283 nuc900_rtc->rtc_reg + REG_RTC_TSSR);
290 284
285 nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
286 if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
287 IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) {
288 dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
289 err = -EBUSY;
290 goto fail4;
291 }
292
291 return 0; 293 return 0;
292 294
293fail4: free_irq(nuc900_rtc->irq_num, nuc900_rtc); 295fail4: rtc_device_unregister(nuc900_rtc->rtcdev);
294fail3: iounmap(nuc900_rtc->rtc_reg); 296fail3: iounmap(nuc900_rtc->rtc_reg);
295fail2: release_mem_region(res->start, resource_size(res)); 297fail2: release_mem_region(res->start, resource_size(res));
296fail1: kfree(nuc900_rtc); 298fail1: kfree(nuc900_rtc);
@@ -302,8 +304,8 @@ static int __devexit nuc900_rtc_remove(struct platform_device *pdev)
302 struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev); 304 struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev);
303 struct resource *res; 305 struct resource *res;
304 306
305 rtc_device_unregister(nuc900_rtc->rtcdev);
306 free_irq(nuc900_rtc->irq_num, nuc900_rtc); 307 free_irq(nuc900_rtc->irq_num, nuc900_rtc);
308 rtc_device_unregister(nuc900_rtc->rtcdev);
307 iounmap(nuc900_rtc->rtc_reg); 309 iounmap(nuc900_rtc->rtc_reg);
308 310
309 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 311 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);