diff options
Diffstat (limited to 'drivers/rtc/rtc-vt8500.c')
-rw-r--r-- | drivers/rtc/rtc-vt8500.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 14e2d8cfcc83..a000bc0a8bff 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -70,7 +70,7 @@ | |||
70 | | ALARM_SEC_BIT) | 70 | | ALARM_SEC_BIT) |
71 | 71 | ||
72 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ | 72 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ |
73 | #define VT8500_RTC_CR_24H (1 << 1) /* 24h time format */ | 73 | #define VT8500_RTC_CR_12H (1 << 1) /* 12h time format */ |
74 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ | 74 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ |
75 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ | 75 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ |
76 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ | 76 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ |
@@ -119,7 +119,7 @@ static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
119 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); | 119 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); |
120 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); | 120 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); |
121 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); | 121 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); |
122 | tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S); | 122 | tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S) - 1; |
123 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) | 123 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) |
124 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); | 124 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); |
125 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; | 125 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; |
@@ -137,9 +137,10 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | } | 138 | } |
139 | 139 | ||
140 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | 140 | writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S) |
141 | | (bin2bcd(tm->tm_mon) << DATE_MONTH_S) | 141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) |
142 | | (bin2bcd(tm->tm_mday)), | 142 | | (bin2bcd(tm->tm_mday)) |
143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), | ||
143 | vt8500_rtc->regbase + VT8500_RTC_DS); | 144 | vt8500_rtc->regbase + VT8500_RTC_DS); |
144 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) | 145 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) |
145 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) | 146 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) |
@@ -205,7 +206,7 @@ static const struct rtc_class_ops vt8500_rtc_ops = { | |||
205 | .alarm_irq_enable = vt8500_alarm_irq_enable, | 206 | .alarm_irq_enable = vt8500_alarm_irq_enable, |
206 | }; | 207 | }; |
207 | 208 | ||
208 | static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | 209 | static int vt8500_rtc_probe(struct platform_device *pdev) |
209 | { | 210 | { |
210 | struct vt8500_rtc *vt8500_rtc; | 211 | struct vt8500_rtc *vt8500_rtc; |
211 | int ret; | 212 | int ret; |
@@ -230,24 +231,25 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
230 | return -ENXIO; | 231 | return -ENXIO; |
231 | } | 232 | } |
232 | 233 | ||
233 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | 234 | vt8500_rtc->res = devm_request_mem_region(&pdev->dev, |
234 | resource_size(vt8500_rtc->res), | 235 | vt8500_rtc->res->start, |
235 | "vt8500-rtc"); | 236 | resource_size(vt8500_rtc->res), |
237 | "vt8500-rtc"); | ||
236 | if (vt8500_rtc->res == NULL) { | 238 | if (vt8500_rtc->res == NULL) { |
237 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 239 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
238 | return -EBUSY; | 240 | return -EBUSY; |
239 | } | 241 | } |
240 | 242 | ||
241 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | 243 | vt8500_rtc->regbase = devm_ioremap(&pdev->dev, vt8500_rtc->res->start, |
242 | resource_size(vt8500_rtc->res)); | 244 | resource_size(vt8500_rtc->res)); |
243 | if (!vt8500_rtc->regbase) { | 245 | if (!vt8500_rtc->regbase) { |
244 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); | 246 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); |
245 | ret = -EBUSY; | 247 | ret = -EBUSY; |
246 | goto err_release; | 248 | goto err_return; |
247 | } | 249 | } |
248 | 250 | ||
249 | /* Enable RTC and set it to 24-hour mode */ | 251 | /* Enable RTC and set it to 24-hour mode */ |
250 | writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, | 252 | writel(VT8500_RTC_CR_ENABLE, |
251 | vt8500_rtc->regbase + VT8500_RTC_CR); | 253 | vt8500_rtc->regbase + VT8500_RTC_CR); |
252 | 254 | ||
253 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, | 255 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, |
@@ -256,11 +258,11 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
256 | ret = PTR_ERR(vt8500_rtc->rtc); | 258 | ret = PTR_ERR(vt8500_rtc->rtc); |
257 | dev_err(&pdev->dev, | 259 | dev_err(&pdev->dev, |
258 | "Failed to register RTC device -> %d\n", ret); | 260 | "Failed to register RTC device -> %d\n", ret); |
259 | goto err_unmap; | 261 | goto err_return; |
260 | } | 262 | } |
261 | 263 | ||
262 | ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, | 264 | ret = devm_request_irq(&pdev->dev, vt8500_rtc->irq_alarm, |
263 | "rtc alarm", vt8500_rtc); | 265 | vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc); |
264 | if (ret < 0) { | 266 | if (ret < 0) { |
265 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | 267 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", |
266 | vt8500_rtc->irq_alarm, ret); | 268 | vt8500_rtc->irq_alarm, ret); |
@@ -271,27 +273,18 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
271 | 273 | ||
272 | err_unreg: | 274 | err_unreg: |
273 | rtc_device_unregister(vt8500_rtc->rtc); | 275 | rtc_device_unregister(vt8500_rtc->rtc); |
274 | err_unmap: | 276 | err_return: |
275 | iounmap(vt8500_rtc->regbase); | ||
276 | err_release: | ||
277 | release_mem_region(vt8500_rtc->res->start, | ||
278 | resource_size(vt8500_rtc->res)); | ||
279 | return ret; | 277 | return ret; |
280 | } | 278 | } |
281 | 279 | ||
282 | static int __devexit vt8500_rtc_remove(struct platform_device *pdev) | 280 | static int vt8500_rtc_remove(struct platform_device *pdev) |
283 | { | 281 | { |
284 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | 282 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); |
285 | 283 | ||
286 | free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); | ||
287 | |||
288 | rtc_device_unregister(vt8500_rtc->rtc); | 284 | rtc_device_unregister(vt8500_rtc->rtc); |
289 | 285 | ||
290 | /* Disable alarm matching */ | 286 | /* Disable alarm matching */ |
291 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); | 287 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); |
292 | iounmap(vt8500_rtc->regbase); | ||
293 | release_mem_region(vt8500_rtc->res->start, | ||
294 | resource_size(vt8500_rtc->res)); | ||
295 | 288 | ||
296 | platform_set_drvdata(pdev, NULL); | 289 | platform_set_drvdata(pdev, NULL); |
297 | 290 | ||
@@ -305,7 +298,7 @@ static const struct of_device_id wmt_dt_ids[] = { | |||
305 | 298 | ||
306 | static struct platform_driver vt8500_rtc_driver = { | 299 | static struct platform_driver vt8500_rtc_driver = { |
307 | .probe = vt8500_rtc_probe, | 300 | .probe = vt8500_rtc_probe, |
308 | .remove = __devexit_p(vt8500_rtc_remove), | 301 | .remove = vt8500_rtc_remove, |
309 | .driver = { | 302 | .driver = { |
310 | .name = "vt8500-rtc", | 303 | .name = "vt8500-rtc", |
311 | .owner = THIS_MODULE, | 304 | .owner = THIS_MODULE, |