diff options
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/rtc/rtc-sa1100.c | 295 |
2 files changed, 114 insertions, 183 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e19a4031f45e..3a125b835546 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -774,7 +774,7 @@ config RTC_DRV_EP93XX | |||
| 774 | 774 | ||
| 775 | config RTC_DRV_SA1100 | 775 | config RTC_DRV_SA1100 |
| 776 | tristate "SA11x0/PXA2xx" | 776 | tristate "SA11x0/PXA2xx" |
| 777 | depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP | 777 | depends on ARCH_SA1100 || ARCH_PXA |
| 778 | help | 778 | help |
| 779 | If you say Y here you will get access to the real time clock | 779 | If you say Y here you will get access to the real time clock |
| 780 | built into your SA11x0 or PXA2xx CPU. | 780 | built into your SA11x0 or PXA2xx CPU. |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 4595d3e645a7..cb9a585312cc 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
| @@ -27,42 +27,34 @@ | |||
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 30 | #include <linux/string.h> | ||
| 30 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
| 31 | #include <linux/slab.h> | 32 | #include <linux/bitops.h> |
| 32 | #include <linux/clk.h> | ||
| 33 | #include <linux/io.h> | ||
| 34 | 33 | ||
| 35 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
| 36 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
| 37 | 36 | ||
| 37 | #ifdef CONFIG_ARCH_PXA | ||
| 38 | #include <mach/regs-rtc.h> | ||
| 39 | #endif | ||
| 40 | |||
| 38 | #define RTC_DEF_DIVIDER (32768 - 1) | 41 | #define RTC_DEF_DIVIDER (32768 - 1) |
| 39 | #define RTC_DEF_TRIM 0 | 42 | #define RTC_DEF_TRIM 0 |
| 40 | #define RTC_FREQ 1024 | 43 | |
| 41 | 44 | static const unsigned long RTC_FREQ = 1024; | |
| 42 | #define RCNR 0x00 /* RTC Count Register */ | 45 | static struct rtc_time rtc_alarm; |
| 43 | #define RTAR 0x04 /* RTC Alarm Register */ | 46 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
| 44 | #define RTSR 0x08 /* RTC Status Register */ | 47 | |
| 45 | #define RTTR 0x0c /* RTC Timer Trim Register */ | 48 | static inline int rtc_periodic_alarm(struct rtc_time *tm) |
| 46 | 49 | { | |
| 47 | #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ | 50 | return (tm->tm_year == -1) || |
| 48 | #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ | 51 | ((unsigned)tm->tm_mon >= 12) || |
| 49 | #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ | 52 | ((unsigned)(tm->tm_mday - 1) >= 31) || |
| 50 | #define RTSR_AL (1 << 0) /* RTC alarm detected */ | 53 | ((unsigned)tm->tm_hour > 23) || |
| 51 | 54 | ((unsigned)tm->tm_min > 59) || | |
| 52 | #define rtc_readl(sa1100_rtc, reg) \ | 55 | ((unsigned)tm->tm_sec > 59); |
| 53 | readl_relaxed((sa1100_rtc)->base + (reg)) | 56 | } |
| 54 | #define rtc_writel(sa1100_rtc, reg, value) \ | 57 | |
| 55 | writel_relaxed((value), (sa1100_rtc)->base + (reg)) | ||
| 56 | |||
| 57 | struct sa1100_rtc { | ||
| 58 | struct resource *ress; | ||
| 59 | void __iomem *base; | ||
| 60 | struct clk *clk; | ||
| 61 | int irq_1Hz; | ||
| 62 | int irq_Alrm; | ||
| 63 | struct rtc_device *rtc; | ||
| 64 | spinlock_t lock; /* Protects this structure */ | ||
| 65 | }; | ||
| 66 | /* | 58 | /* |
| 67 | * Calculate the next alarm time given the requested alarm time mask | 59 | * Calculate the next alarm time given the requested alarm time mask |
| 68 | * and the current time. | 60 | * and the current time. |
| @@ -90,26 +82,46 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | |||
| 90 | } | 82 | } |
| 91 | } | 83 | } |
| 92 | 84 | ||
| 85 | static int rtc_update_alarm(struct rtc_time *alrm) | ||
| 86 | { | ||
| 87 | struct rtc_time alarm_tm, now_tm; | ||
| 88 | unsigned long now, time; | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | do { | ||
| 92 | now = RCNR; | ||
| 93 | rtc_time_to_tm(now, &now_tm); | ||
| 94 | rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); | ||
| 95 | ret = rtc_tm_to_time(&alarm_tm, &time); | ||
| 96 | if (ret != 0) | ||
| 97 | break; | ||
| 98 | |||
| 99 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | ||
| 100 | RTAR = time; | ||
| 101 | } while (now != RCNR); | ||
| 102 | |||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 93 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | 106 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) |
| 94 | { | 107 | { |
| 95 | struct platform_device *pdev = to_platform_device(dev_id); | 108 | struct platform_device *pdev = to_platform_device(dev_id); |
| 96 | struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); | 109 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 97 | unsigned int rtsr; | 110 | unsigned int rtsr; |
| 98 | unsigned long events = 0; | 111 | unsigned long events = 0; |
| 99 | 112 | ||
| 100 | spin_lock(&sa1100_rtc->lock); | 113 | spin_lock(&sa1100_rtc_lock); |
| 101 | 114 | ||
| 115 | rtsr = RTSR; | ||
| 102 | /* clear interrupt sources */ | 116 | /* clear interrupt sources */ |
| 103 | rtsr = rtc_readl(sa1100_rtc, RTSR); | 117 | RTSR = 0; |
| 104 | rtc_writel(sa1100_rtc, RTSR, 0); | ||
| 105 | |||
| 106 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 118 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
| 107 | * See also the comments in sa1100_rtc_probe(). */ | 119 | * See also the comments in sa1100_rtc_probe(). */ |
| 108 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { | 120 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { |
| 109 | /* This is the original code, before there was the if test | 121 | /* This is the original code, before there was the if test |
| 110 | * above. This code does not clear interrupts that were not | 122 | * above. This code does not clear interrupts that were not |
| 111 | * enabled. */ | 123 | * enabled. */ |
| 112 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ) & (rtsr >> 2)); | 124 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); |
| 113 | } else { | 125 | } else { |
| 114 | /* For some reason, it is possible to enter this routine | 126 | /* For some reason, it is possible to enter this routine |
| 115 | * without interruptions enabled, it has been tested with | 127 | * without interruptions enabled, it has been tested with |
| @@ -118,13 +130,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
| 118 | * This situation leads to an infinite "loop" of interrupt | 130 | * This situation leads to an infinite "loop" of interrupt |
| 119 | * routine calling and as a result the processor seems to | 131 | * routine calling and as a result the processor seems to |
| 120 | * lock on its first call to open(). */ | 132 | * lock on its first call to open(). */ |
| 121 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); | 133 | RTSR = RTSR_AL | RTSR_HZ; |
| 122 | } | 134 | } |
| 123 | 135 | ||
| 124 | /* clear alarm interrupt if it has occurred */ | 136 | /* clear alarm interrupt if it has occurred */ |
| 125 | if (rtsr & RTSR_AL) | 137 | if (rtsr & RTSR_AL) |
| 126 | rtsr &= ~RTSR_ALE; | 138 | rtsr &= ~RTSR_ALE; |
| 127 | rtc_writel(sa1100_rtc, RTSR, rtsr & (RTSR_ALE | RTSR_HZE)); | 139 | RTSR = rtsr & (RTSR_ALE | RTSR_HZE); |
| 128 | 140 | ||
| 129 | /* update irq data & counter */ | 141 | /* update irq data & counter */ |
| 130 | if (rtsr & RTSR_AL) | 142 | if (rtsr & RTSR_AL) |
| @@ -132,100 +144,89 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
| 132 | if (rtsr & RTSR_HZ) | 144 | if (rtsr & RTSR_HZ) |
| 133 | events |= RTC_UF | RTC_IRQF; | 145 | events |= RTC_UF | RTC_IRQF; |
| 134 | 146 | ||
| 135 | rtc_update_irq(sa1100_rtc->rtc, 1, events); | 147 | rtc_update_irq(rtc, 1, events); |
| 136 | 148 | ||
| 137 | spin_unlock(&sa1100_rtc->lock); | 149 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) |
| 150 | rtc_update_alarm(&rtc_alarm); | ||
| 151 | |||
| 152 | spin_unlock(&sa1100_rtc_lock); | ||
| 138 | 153 | ||
| 139 | return IRQ_HANDLED; | 154 | return IRQ_HANDLED; |
| 140 | } | 155 | } |
| 141 | 156 | ||
| 142 | static int sa1100_rtc_open(struct device *dev) | 157 | static int sa1100_rtc_open(struct device *dev) |
| 143 | { | 158 | { |
| 144 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
| 145 | int ret; | 159 | int ret; |
| 160 | struct platform_device *plat_dev = to_platform_device(dev); | ||
| 161 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | ||
| 146 | 162 | ||
| 147 | ret = request_irq(sa1100_rtc->irq_1Hz, sa1100_rtc_interrupt, | 163 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
| 148 | IRQF_DISABLED, "rtc 1Hz", dev); | 164 | "rtc 1Hz", dev); |
| 149 | if (ret) { | 165 | if (ret) { |
| 150 | dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_1Hz); | 166 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
| 151 | goto fail_ui; | 167 | goto fail_ui; |
| 152 | } | 168 | } |
| 153 | ret = request_irq(sa1100_rtc->irq_Alrm, sa1100_rtc_interrupt, | 169 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
| 154 | IRQF_DISABLED, "rtc Alrm", dev); | 170 | "rtc Alrm", dev); |
| 155 | if (ret) { | 171 | if (ret) { |
| 156 | dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_Alrm); | 172 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
| 157 | goto fail_ai; | 173 | goto fail_ai; |
| 158 | } | 174 | } |
| 159 | sa1100_rtc->rtc->max_user_freq = RTC_FREQ; | 175 | rtc->max_user_freq = RTC_FREQ; |
| 160 | rtc_irq_set_freq(sa1100_rtc->rtc, NULL, RTC_FREQ); | 176 | rtc_irq_set_freq(rtc, NULL, RTC_FREQ); |
| 161 | 177 | ||
| 162 | return 0; | 178 | return 0; |
| 163 | 179 | ||
| 164 | fail_ai: | 180 | fail_ai: |
| 165 | free_irq(sa1100_rtc->irq_1Hz, dev); | 181 | free_irq(IRQ_RTC1Hz, dev); |
| 166 | fail_ui: | 182 | fail_ui: |
| 167 | return ret; | 183 | return ret; |
| 168 | } | 184 | } |
| 169 | 185 | ||
| 170 | static void sa1100_rtc_release(struct device *dev) | 186 | static void sa1100_rtc_release(struct device *dev) |
| 171 | { | 187 | { |
| 172 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 188 | spin_lock_irq(&sa1100_rtc_lock); |
| 173 | 189 | RTSR = 0; | |
| 174 | spin_lock_irq(&sa1100_rtc->lock); | 190 | spin_unlock_irq(&sa1100_rtc_lock); |
| 175 | rtc_writel(sa1100_rtc, RTSR, 0); | ||
| 176 | spin_unlock_irq(&sa1100_rtc->lock); | ||
| 177 | 191 | ||
| 178 | free_irq(sa1100_rtc->irq_Alrm, dev); | 192 | free_irq(IRQ_RTCAlrm, dev); |
| 179 | free_irq(sa1100_rtc->irq_1Hz, dev); | 193 | free_irq(IRQ_RTC1Hz, dev); |
| 180 | } | 194 | } |
| 181 | 195 | ||
| 182 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 196 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
| 183 | { | 197 | { |
| 184 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 198 | spin_lock_irq(&sa1100_rtc_lock); |
| 185 | unsigned int rtsr; | ||
| 186 | |||
| 187 | spin_lock_irq(&sa1100_rtc->lock); | ||
| 188 | |||
| 189 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
| 190 | if (enabled) | 199 | if (enabled) |
| 191 | rtsr |= RTSR_ALE; | 200 | RTSR |= RTSR_ALE; |
| 192 | else | 201 | else |
| 193 | rtsr &= ~RTSR_ALE; | 202 | RTSR &= ~RTSR_ALE; |
| 194 | rtc_writel(sa1100_rtc, RTSR, rtsr); | 203 | spin_unlock_irq(&sa1100_rtc_lock); |
| 195 | |||
| 196 | spin_unlock_irq(&sa1100_rtc->lock); | ||
| 197 | return 0; | 204 | return 0; |
| 198 | } | 205 | } |
| 199 | 206 | ||
| 200 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 207 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 201 | { | 208 | { |
| 202 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 209 | rtc_time_to_tm(RCNR, tm); |
| 203 | |||
| 204 | rtc_time_to_tm(rtc_readl(sa1100_rtc, RCNR), tm); | ||
| 205 | return 0; | 210 | return 0; |
| 206 | } | 211 | } |
| 207 | 212 | ||
| 208 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) | 213 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| 209 | { | 214 | { |
| 210 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
| 211 | unsigned long time; | 215 | unsigned long time; |
| 212 | int ret; | 216 | int ret; |
| 213 | 217 | ||
| 214 | ret = rtc_tm_to_time(tm, &time); | 218 | ret = rtc_tm_to_time(tm, &time); |
| 215 | if (ret == 0) | 219 | if (ret == 0) |
| 216 | rtc_writel(sa1100_rtc, RCNR, time); | 220 | RCNR = time; |
| 217 | return ret; | 221 | return ret; |
| 218 | } | 222 | } |
| 219 | 223 | ||
| 220 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 224 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| 221 | { | 225 | { |
| 222 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 226 | u32 rtsr; |
| 223 | unsigned long time; | ||
| 224 | unsigned int rtsr; | ||
| 225 | 227 | ||
| 226 | time = rtc_readl(sa1100_rtc, RCNR); | 228 | memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); |
| 227 | rtc_time_to_tm(time, &alrm->time); | 229 | rtsr = RTSR; |
| 228 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
| 229 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; | 230 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; |
| 230 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; | 231 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; |
| 231 | return 0; | 232 | return 0; |
| @@ -233,39 +234,26 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 233 | 234 | ||
| 234 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 235 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| 235 | { | 236 | { |
| 236 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 237 | int ret; |
| 237 | struct rtc_time now_tm, alarm_tm; | ||
| 238 | unsigned long time, alarm; | ||
| 239 | unsigned int rtsr; | ||
| 240 | |||
| 241 | spin_lock_irq(&sa1100_rtc->lock); | ||
| 242 | |||
| 243 | time = rtc_readl(sa1100_rtc, RCNR); | ||
| 244 | rtc_time_to_tm(time, &now_tm); | ||
| 245 | rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); | ||
| 246 | rtc_tm_to_time(&alarm_tm, &alarm); | ||
| 247 | rtc_writel(sa1100_rtc, RTAR, alarm); | ||
| 248 | |||
| 249 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
| 250 | if (alrm->enabled) | ||
| 251 | rtsr |= RTSR_ALE; | ||
| 252 | else | ||
| 253 | rtsr &= ~RTSR_ALE; | ||
| 254 | rtc_writel(sa1100_rtc, RTSR, rtsr); | ||
| 255 | 238 | ||
| 256 | spin_unlock_irq(&sa1100_rtc->lock); | 239 | spin_lock_irq(&sa1100_rtc_lock); |
| 240 | ret = rtc_update_alarm(&alrm->time); | ||
| 241 | if (ret == 0) { | ||
| 242 | if (alrm->enabled) | ||
| 243 | RTSR |= RTSR_ALE; | ||
| 244 | else | ||
| 245 | RTSR &= ~RTSR_ALE; | ||
| 246 | } | ||
| 247 | spin_unlock_irq(&sa1100_rtc_lock); | ||
| 257 | 248 | ||
| 258 | return 0; | 249 | return ret; |
| 259 | } | 250 | } |
| 260 | 251 | ||
| 261 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) | 252 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
| 262 | { | 253 | { |
| 263 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | 254 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); |
| 255 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); | ||
| 264 | 256 | ||
| 265 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", | ||
| 266 | rtc_readl(sa1100_rtc, RTTR)); | ||
| 267 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", | ||
| 268 | rtc_readl(sa1100_rtc, RTSR)); | ||
| 269 | return 0; | 257 | return 0; |
| 270 | } | 258 | } |
| 271 | 259 | ||
| @@ -282,51 +270,7 @@ static const struct rtc_class_ops sa1100_rtc_ops = { | |||
| 282 | 270 | ||
| 283 | static int sa1100_rtc_probe(struct platform_device *pdev) | 271 | static int sa1100_rtc_probe(struct platform_device *pdev) |
| 284 | { | 272 | { |
| 285 | struct sa1100_rtc *sa1100_rtc; | 273 | struct rtc_device *rtc; |
| 286 | unsigned int rttr; | ||
| 287 | int ret; | ||
| 288 | |||
| 289 | sa1100_rtc = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); | ||
| 290 | if (!sa1100_rtc) | ||
| 291 | return -ENOMEM; | ||
| 292 | |||
| 293 | spin_lock_init(&sa1100_rtc->lock); | ||
| 294 | platform_set_drvdata(pdev, sa1100_rtc); | ||
| 295 | |||
| 296 | ret = -ENXIO; | ||
| 297 | sa1100_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 298 | if (!sa1100_rtc->ress) { | ||
| 299 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); | ||
| 300 | goto err_ress; | ||
| 301 | } | ||
| 302 | |||
| 303 | sa1100_rtc->irq_1Hz = platform_get_irq(pdev, 0); | ||
| 304 | if (sa1100_rtc->irq_1Hz < 0) { | ||
| 305 | dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); | ||
| 306 | goto err_ress; | ||
| 307 | } | ||
| 308 | sa1100_rtc->irq_Alrm = platform_get_irq(pdev, 1); | ||
| 309 | if (sa1100_rtc->irq_Alrm < 0) { | ||
| 310 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); | ||
| 311 | goto err_ress; | ||
| 312 | } | ||
| 313 | |||
| 314 | ret = -ENOMEM; | ||
| 315 | sa1100_rtc->base = ioremap(sa1100_rtc->ress->start, | ||
| 316 | resource_size(sa1100_rtc->ress)); | ||
| 317 | if (!sa1100_rtc->base) { | ||
| 318 | dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); | ||
| 319 | goto err_map; | ||
| 320 | } | ||
| 321 | |||
| 322 | sa1100_rtc->clk = clk_get(&pdev->dev, NULL); | ||
| 323 | if (IS_ERR(sa1100_rtc->clk)) { | ||
| 324 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | ||
| 325 | ret = PTR_ERR(sa1100_rtc->clk); | ||
| 326 | goto err_clk; | ||
| 327 | } | ||
| 328 | clk_prepare(sa1100_rtc->clk); | ||
| 329 | clk_enable(sa1100_rtc->clk); | ||
| 330 | 274 | ||
| 331 | /* | 275 | /* |
| 332 | * According to the manual we should be able to let RTTR be zero | 276 | * According to the manual we should be able to let RTTR be zero |
| @@ -335,24 +279,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
| 335 | * If the clock divider is uninitialized then reset it to the | 279 | * If the clock divider is uninitialized then reset it to the |
| 336 | * default value to get the 1Hz clock. | 280 | * default value to get the 1Hz clock. |
| 337 | */ | 281 | */ |
| 338 | if (rtc_readl(sa1100_rtc, RTTR) == 0) { | 282 | if (RTTR == 0) { |
| 339 | rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 283 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
| 340 | rtc_writel(sa1100_rtc, RTTR, rttr); | 284 | dev_warn(&pdev->dev, "warning: " |
| 341 | dev_warn(&pdev->dev, "warning: initializing default clock" | 285 | "initializing default clock divider/trim value\n"); |
| 342 | " divider/trim value\n"); | ||
| 343 | /* The current RTC value probably doesn't make sense either */ | 286 | /* The current RTC value probably doesn't make sense either */ |
| 344 | rtc_writel(sa1100_rtc, RCNR, 0); | 287 | RCNR = 0; |
| 345 | } | 288 | } |
| 346 | 289 | ||
| 347 | device_init_wakeup(&pdev->dev, 1); | 290 | device_init_wakeup(&pdev->dev, 1); |
| 348 | 291 | ||
| 349 | sa1100_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 292 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
| 350 | &sa1100_rtc_ops, THIS_MODULE); | 293 | THIS_MODULE); |
| 351 | if (IS_ERR(sa1100_rtc->rtc)) { | 294 | |
| 352 | dev_err(&pdev->dev, "Failed to register RTC device -> %d\n", | 295 | if (IS_ERR(rtc)) |
| 353 | ret); | 296 | return PTR_ERR(rtc); |
| 354 | goto err_rtc_reg; | 297 | |
| 355 | } | 298 | platform_set_drvdata(pdev, rtc); |
| 299 | |||
| 356 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 300 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
| 357 | * See also the comments in sa1100_rtc_interrupt(). | 301 | * See also the comments in sa1100_rtc_interrupt(). |
| 358 | * | 302 | * |
| @@ -375,46 +319,33 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
| 375 | * | 319 | * |
| 376 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to | 320 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to |
| 377 | * the corresponding bits in RTSR. */ | 321 | * the corresponding bits in RTSR. */ |
| 378 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); | 322 | RTSR = RTSR_AL | RTSR_HZ; |
| 379 | 323 | ||
| 380 | return 0; | 324 | return 0; |
| 381 | |||
| 382 | err_rtc_reg: | ||
| 383 | err_clk: | ||
| 384 | iounmap(sa1100_rtc->base); | ||
| 385 | err_ress: | ||
| 386 | err_map: | ||
| 387 | kfree(sa1100_rtc); | ||
| 388 | return ret; | ||
| 389 | } | 325 | } |
| 390 | 326 | ||
| 391 | static int sa1100_rtc_remove(struct platform_device *pdev) | 327 | static int sa1100_rtc_remove(struct platform_device *pdev) |
| 392 | { | 328 | { |
| 393 | struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); | 329 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 330 | |||
| 331 | if (rtc) | ||
| 332 | rtc_device_unregister(rtc); | ||
| 394 | 333 | ||
| 395 | rtc_device_unregister(sa1100_rtc->rtc); | ||
| 396 | clk_disable(sa1100_rtc->clk); | ||
| 397 | clk_unprepare(sa1100_rtc->clk); | ||
| 398 | iounmap(sa1100_rtc->base); | ||
| 399 | return 0; | 334 | return 0; |
| 400 | } | 335 | } |
| 401 | 336 | ||
| 402 | #ifdef CONFIG_PM | 337 | #ifdef CONFIG_PM |
| 403 | static int sa1100_rtc_suspend(struct device *dev) | 338 | static int sa1100_rtc_suspend(struct device *dev) |
| 404 | { | 339 | { |
| 405 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
| 406 | |||
| 407 | if (device_may_wakeup(dev)) | 340 | if (device_may_wakeup(dev)) |
| 408 | enable_irq_wake(sa1100_rtc->irq_Alrm); | 341 | enable_irq_wake(IRQ_RTCAlrm); |
| 409 | return 0; | 342 | return 0; |
| 410 | } | 343 | } |
| 411 | 344 | ||
| 412 | static int sa1100_rtc_resume(struct device *dev) | 345 | static int sa1100_rtc_resume(struct device *dev) |
| 413 | { | 346 | { |
| 414 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
| 415 | |||
| 416 | if (device_may_wakeup(dev)) | 347 | if (device_may_wakeup(dev)) |
| 417 | disable_irq_wake(sa1100_rtc->irq_Alrm); | 348 | disable_irq_wake(IRQ_RTCAlrm); |
| 418 | return 0; | 349 | return 0; |
| 419 | } | 350 | } |
| 420 | 351 | ||
