diff options
-rw-r--r-- | arch/x86/include/asm/smpboot_hooks.h | 8 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 39 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-stmp3xxx.c | 153 | ||||
-rw-r--r-- | drivers/rtc/rtc-vt8500.c | 6 |
5 files changed, 127 insertions, 85 deletions
diff --git a/arch/x86/include/asm/smpboot_hooks.h b/arch/x86/include/asm/smpboot_hooks.h index 725b7783199..49adfd7bb4a 100644 --- a/arch/x86/include/asm/smpboot_hooks.h +++ b/arch/x86/include/asm/smpboot_hooks.h | |||
@@ -10,7 +10,11 @@ static inline void smpboot_clear_io_apic_irqs(void) | |||
10 | 10 | ||
11 | static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) | 11 | static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) |
12 | { | 12 | { |
13 | unsigned long flags; | ||
14 | |||
15 | spin_lock_irqsave(&rtc_lock, flags); | ||
13 | CMOS_WRITE(0xa, 0xf); | 16 | CMOS_WRITE(0xa, 0xf); |
17 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
14 | local_flush_tlb(); | 18 | local_flush_tlb(); |
15 | pr_debug("1.\n"); | 19 | pr_debug("1.\n"); |
16 | *((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) = | 20 | *((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) = |
@@ -23,6 +27,8 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) | |||
23 | 27 | ||
24 | static inline void smpboot_restore_warm_reset_vector(void) | 28 | static inline void smpboot_restore_warm_reset_vector(void) |
25 | { | 29 | { |
30 | unsigned long flags; | ||
31 | |||
26 | /* | 32 | /* |
27 | * Install writable page 0 entry to set BIOS data area. | 33 | * Install writable page 0 entry to set BIOS data area. |
28 | */ | 34 | */ |
@@ -32,7 +38,9 @@ static inline void smpboot_restore_warm_reset_vector(void) | |||
32 | * Paranoid: Set warm reset code and vector here back | 38 | * Paranoid: Set warm reset code and vector here back |
33 | * to default values. | 39 | * to default values. |
34 | */ | 40 | */ |
41 | spin_lock_irqsave(&rtc_lock, flags); | ||
35 | CMOS_WRITE(0, 0xf); | 42 | CMOS_WRITE(0, 0xf); |
43 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
36 | 44 | ||
37 | *((volatile u32 *)phys_to_virt(apic->trampoline_phys_low)) = 0; | 45 | *((volatile u32 *)phys_to_virt(apic->trampoline_phys_low)) = 0; |
38 | } | 46 | } |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 899e393d8e7..cfc588ce115 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -79,26 +79,50 @@ early_param("add_efi_memmap", setup_add_efi_memmap); | |||
79 | 79 | ||
80 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | 80 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
81 | { | 81 | { |
82 | return efi_call_virt2(get_time, tm, tc); | 82 | unsigned long flags; |
83 | efi_status_t status; | ||
84 | |||
85 | spin_lock_irqsave(&rtc_lock, flags); | ||
86 | status = efi_call_virt2(get_time, tm, tc); | ||
87 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
88 | return status; | ||
83 | } | 89 | } |
84 | 90 | ||
85 | static efi_status_t virt_efi_set_time(efi_time_t *tm) | 91 | static efi_status_t virt_efi_set_time(efi_time_t *tm) |
86 | { | 92 | { |
87 | return efi_call_virt1(set_time, tm); | 93 | unsigned long flags; |
94 | efi_status_t status; | ||
95 | |||
96 | spin_lock_irqsave(&rtc_lock, flags); | ||
97 | status = efi_call_virt1(set_time, tm); | ||
98 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
99 | return status; | ||
88 | } | 100 | } |
89 | 101 | ||
90 | static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, | 102 | static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, |
91 | efi_bool_t *pending, | 103 | efi_bool_t *pending, |
92 | efi_time_t *tm) | 104 | efi_time_t *tm) |
93 | { | 105 | { |
94 | return efi_call_virt3(get_wakeup_time, | 106 | unsigned long flags; |
95 | enabled, pending, tm); | 107 | efi_status_t status; |
108 | |||
109 | spin_lock_irqsave(&rtc_lock, flags); | ||
110 | status = efi_call_virt3(get_wakeup_time, | ||
111 | enabled, pending, tm); | ||
112 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
113 | return status; | ||
96 | } | 114 | } |
97 | 115 | ||
98 | static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) | 116 | static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) |
99 | { | 117 | { |
100 | return efi_call_virt2(set_wakeup_time, | 118 | unsigned long flags; |
101 | enabled, tm); | 119 | efi_status_t status; |
120 | |||
121 | spin_lock_irqsave(&rtc_lock, flags); | ||
122 | status = efi_call_virt2(set_wakeup_time, | ||
123 | enabled, tm); | ||
124 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
125 | return status; | ||
102 | } | 126 | } |
103 | 127 | ||
104 | static efi_status_t virt_efi_get_variable(efi_char16_t *name, | 128 | static efi_status_t virt_efi_get_variable(efi_char16_t *name, |
@@ -164,11 +188,14 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
164 | static efi_status_t __init phys_efi_get_time(efi_time_t *tm, | 188 | static efi_status_t __init phys_efi_get_time(efi_time_t *tm, |
165 | efi_time_cap_t *tc) | 189 | efi_time_cap_t *tc) |
166 | { | 190 | { |
191 | unsigned long flags; | ||
167 | efi_status_t status; | 192 | efi_status_t status; |
168 | 193 | ||
194 | spin_lock_irqsave(&rtc_lock, flags); | ||
169 | efi_call_phys_prelog(); | 195 | efi_call_phys_prelog(); |
170 | status = efi_call_phys2(efi_phys.get_time, tm, tc); | 196 | status = efi_call_phys2(efi_phys.get_time, tm, tc); |
171 | efi_call_phys_epilog(); | 197 | efi_call_phys_epilog(); |
198 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
172 | return status; | 199 | return status; |
173 | } | 200 | } |
174 | 201 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index ce2aabf5c55..dcb61e23b98 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -981,11 +981,11 @@ config RTC_DRV_COH901331 | |||
981 | 981 | ||
982 | 982 | ||
983 | config RTC_DRV_STMP | 983 | config RTC_DRV_STMP |
984 | tristate "Freescale STMP3xxx RTC" | 984 | tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC" |
985 | depends on ARCH_STMP3XXX | 985 | depends on ARCH_MXS |
986 | help | 986 | help |
987 | If you say yes here you will get support for the onboard | 987 | If you say yes here you will get support for the onboard |
988 | STMP3xxx RTC. | 988 | STMP3xxx/i.MX23/i.MX28 RTC. |
989 | 989 | ||
990 | This driver can also be built as a module. If so, the module | 990 | This driver can also be built as a module. If so, the module |
991 | will be called rtc-stmp3xxx. | 991 | will be called rtc-stmp3xxx. |
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 572e9534b59..7315068daa5 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * | 6 | * |
7 | * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. | 7 | * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. |
8 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. | 8 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. |
9 | * Copyright 2011 Wolfram Sang, Pengutronix e.K. | ||
9 | */ | 10 | */ |
10 | 11 | ||
11 | /* | 12 | /* |
@@ -18,21 +19,41 @@ | |||
18 | */ | 19 | */ |
19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/io.h> | ||
21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
24 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
26 | 28 | ||
27 | #include <mach/platform.h> | 29 | #include <mach/common.h> |
28 | #include <mach/stmp3xxx.h> | 30 | |
29 | #include <mach/regs-rtc.h> | 31 | #define STMP3XXX_RTC_CTRL 0x0 |
32 | #define STMP3XXX_RTC_CTRL_SET 0x4 | ||
33 | #define STMP3XXX_RTC_CTRL_CLR 0x8 | ||
34 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 | ||
35 | #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 | ||
36 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 | ||
37 | |||
38 | #define STMP3XXX_RTC_STAT 0x10 | ||
39 | #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 | ||
40 | #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 | ||
41 | |||
42 | #define STMP3XXX_RTC_SECONDS 0x30 | ||
43 | |||
44 | #define STMP3XXX_RTC_ALARM 0x40 | ||
45 | |||
46 | #define STMP3XXX_RTC_PERSISTENT0 0x60 | ||
47 | #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 | ||
48 | #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 | ||
49 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 | ||
50 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 | ||
51 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 | ||
30 | 52 | ||
31 | struct stmp3xxx_rtc_data { | 53 | struct stmp3xxx_rtc_data { |
32 | struct rtc_device *rtc; | 54 | struct rtc_device *rtc; |
33 | unsigned irq_count; | ||
34 | void __iomem *io; | 55 | void __iomem *io; |
35 | int irq_alarm, irq_1msec; | 56 | int irq_alarm; |
36 | }; | 57 | }; |
37 | 58 | ||
38 | static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) | 59 | static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) |
@@ -42,8 +63,8 @@ static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) | |||
42 | * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, | 63 | * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, |
43 | * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS | 64 | * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS |
44 | */ | 65 | */ |
45 | while (__raw_readl(rtc_data->io + HW_RTC_STAT) & | 66 | while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & |
46 | BF(0x80, RTC_STAT_STALE_REGS)) | 67 | (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) |
47 | cpu_relax(); | 68 | cpu_relax(); |
48 | } | 69 | } |
49 | 70 | ||
@@ -53,7 +74,7 @@ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
53 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 74 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
54 | 75 | ||
55 | stmp3xxx_wait_time(rtc_data); | 76 | stmp3xxx_wait_time(rtc_data); |
56 | rtc_time_to_tm(__raw_readl(rtc_data->io + HW_RTC_SECONDS), rtc_tm); | 77 | rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); |
57 | return 0; | 78 | return 0; |
58 | } | 79 | } |
59 | 80 | ||
@@ -61,7 +82,7 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) | |||
61 | { | 82 | { |
62 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 83 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
63 | 84 | ||
64 | __raw_writel(t, rtc_data->io + HW_RTC_SECONDS); | 85 | writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); |
65 | stmp3xxx_wait_time(rtc_data); | 86 | stmp3xxx_wait_time(rtc_data); |
66 | return 0; | 87 | return 0; |
67 | } | 88 | } |
@@ -70,47 +91,34 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) | |||
70 | static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) | 91 | static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) |
71 | { | 92 | { |
72 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); | 93 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); |
73 | u32 status; | 94 | u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL); |
74 | u32 events = 0; | ||
75 | |||
76 | status = __raw_readl(rtc_data->io + HW_RTC_CTRL) & | ||
77 | (BM_RTC_CTRL_ALARM_IRQ | BM_RTC_CTRL_ONEMSEC_IRQ); | ||
78 | 95 | ||
79 | if (status & BM_RTC_CTRL_ALARM_IRQ) { | 96 | if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) { |
80 | stmp3xxx_clearl(BM_RTC_CTRL_ALARM_IRQ, | 97 | writel(STMP3XXX_RTC_CTRL_ALARM_IRQ, |
81 | rtc_data->io + HW_RTC_CTRL); | 98 | rtc_data->io + STMP3XXX_RTC_CTRL_CLR); |
82 | events |= RTC_AF | RTC_IRQF; | 99 | rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF); |
100 | return IRQ_HANDLED; | ||
83 | } | 101 | } |
84 | 102 | ||
85 | if (status & BM_RTC_CTRL_ONEMSEC_IRQ) { | 103 | return IRQ_NONE; |
86 | stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ, | ||
87 | rtc_data->io + HW_RTC_CTRL); | ||
88 | if (++rtc_data->irq_count % 1000 == 0) { | ||
89 | events |= RTC_UF | RTC_IRQF; | ||
90 | rtc_data->irq_count = 0; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | if (events) | ||
95 | rtc_update_irq(rtc_data->rtc, 1, events); | ||
96 | |||
97 | return IRQ_HANDLED; | ||
98 | } | 104 | } |
99 | 105 | ||
100 | static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) | 106 | static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) |
101 | { | 107 | { |
102 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 108 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
103 | void __iomem *p = rtc_data->io + HW_RTC_PERSISTENT0, | ||
104 | *ctl = rtc_data->io + HW_RTC_CTRL; | ||
105 | 109 | ||
106 | if (enabled) { | 110 | if (enabled) { |
107 | stmp3xxx_setl(BM_RTC_PERSISTENT0_ALARM_EN | | 111 | writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | |
108 | BM_RTC_PERSISTENT0_ALARM_WAKE_EN, p); | 112 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, |
109 | stmp3xxx_setl(BM_RTC_CTRL_ALARM_IRQ_EN, ctl); | 113 | rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); |
114 | writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, | ||
115 | rtc_data->io + STMP3XXX_RTC_CTRL_SET); | ||
110 | } else { | 116 | } else { |
111 | stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | | 117 | writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | |
112 | BM_RTC_PERSISTENT0_ALARM_WAKE_EN, p); | 118 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, |
113 | stmp3xxx_clearl(BM_RTC_CTRL_ALARM_IRQ_EN, ctl); | 119 | rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); |
120 | writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, | ||
121 | rtc_data->io + STMP3XXX_RTC_CTRL_CLR); | ||
114 | } | 122 | } |
115 | return 0; | 123 | return 0; |
116 | } | 124 | } |
@@ -119,7 +127,7 @@ static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
119 | { | 127 | { |
120 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 128 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
121 | 129 | ||
122 | rtc_time_to_tm(__raw_readl(rtc_data->io + HW_RTC_ALARM), &alm->time); | 130 | rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); |
123 | return 0; | 131 | return 0; |
124 | } | 132 | } |
125 | 133 | ||
@@ -129,7 +137,10 @@ static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
129 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 137 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
130 | 138 | ||
131 | rtc_tm_to_time(&alm->time, &t); | 139 | rtc_tm_to_time(&alm->time, &t); |
132 | __raw_writel(t, rtc_data->io + HW_RTC_ALARM); | 140 | writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); |
141 | |||
142 | stmp3xxx_alarm_irq_enable(dev, alm->enabled); | ||
143 | |||
133 | return 0; | 144 | return 0; |
134 | } | 145 | } |
135 | 146 | ||
@@ -149,11 +160,11 @@ static int stmp3xxx_rtc_remove(struct platform_device *pdev) | |||
149 | if (!rtc_data) | 160 | if (!rtc_data) |
150 | return 0; | 161 | return 0; |
151 | 162 | ||
152 | stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN | BM_RTC_CTRL_ALARM_IRQ_EN, | 163 | writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, |
153 | rtc_data->io + HW_RTC_CTRL); | 164 | rtc_data->io + STMP3XXX_RTC_CTRL_CLR); |
154 | free_irq(rtc_data->irq_alarm, &pdev->dev); | 165 | free_irq(rtc_data->irq_alarm, &pdev->dev); |
155 | free_irq(rtc_data->irq_1msec, &pdev->dev); | ||
156 | rtc_device_unregister(rtc_data->rtc); | 166 | rtc_device_unregister(rtc_data->rtc); |
167 | platform_set_drvdata(pdev, NULL); | ||
157 | iounmap(rtc_data->io); | 168 | iounmap(rtc_data->io); |
158 | kfree(rtc_data); | 169 | kfree(rtc_data); |
159 | 170 | ||
@@ -185,20 +196,26 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) | |||
185 | } | 196 | } |
186 | 197 | ||
187 | rtc_data->irq_alarm = platform_get_irq(pdev, 0); | 198 | rtc_data->irq_alarm = platform_get_irq(pdev, 0); |
188 | rtc_data->irq_1msec = platform_get_irq(pdev, 1); | ||
189 | 199 | ||
190 | if (!(__raw_readl(HW_RTC_STAT + rtc_data->io) & | 200 | if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & |
191 | BM_RTC_STAT_RTC_PRESENT)) { | 201 | STMP3XXX_RTC_STAT_RTC_PRESENT)) { |
192 | dev_err(&pdev->dev, "no device onboard\n"); | 202 | dev_err(&pdev->dev, "no device onboard\n"); |
193 | err = -ENODEV; | 203 | err = -ENODEV; |
194 | goto out_remap; | 204 | goto out_remap; |
195 | } | 205 | } |
196 | 206 | ||
197 | stmp3xxx_reset_block(rtc_data->io, true); | 207 | platform_set_drvdata(pdev, rtc_data); |
198 | stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | | 208 | |
199 | BM_RTC_PERSISTENT0_ALARM_WAKE_EN | | 209 | mxs_reset_block(rtc_data->io); |
200 | BM_RTC_PERSISTENT0_ALARM_WAKE, | 210 | writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | |
201 | rtc_data->io + HW_RTC_PERSISTENT0); | 211 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | |
212 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, | ||
213 | rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); | ||
214 | |||
215 | writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | | ||
216 | STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, | ||
217 | rtc_data->io + STMP3XXX_RTC_CTRL_CLR); | ||
218 | |||
202 | rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, | 219 | rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, |
203 | &stmp3xxx_rtc_ops, THIS_MODULE); | 220 | &stmp3xxx_rtc_ops, THIS_MODULE); |
204 | if (IS_ERR(rtc_data->rtc)) { | 221 | if (IS_ERR(rtc_data->rtc)) { |
@@ -206,33 +223,20 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) | |||
206 | goto out_remap; | 223 | goto out_remap; |
207 | } | 224 | } |
208 | 225 | ||
209 | rtc_data->irq_count = 0; | 226 | err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, 0, |
210 | err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, | 227 | "RTC alarm", &pdev->dev); |
211 | IRQF_DISABLED, "RTC alarm", &pdev->dev); | ||
212 | if (err) { | 228 | if (err) { |
213 | dev_err(&pdev->dev, "Cannot claim IRQ%d\n", | 229 | dev_err(&pdev->dev, "Cannot claim IRQ%d\n", |
214 | rtc_data->irq_alarm); | 230 | rtc_data->irq_alarm); |
215 | goto out_irq_alarm; | 231 | goto out_irq_alarm; |
216 | } | 232 | } |
217 | err = request_irq(rtc_data->irq_1msec, stmp3xxx_rtc_interrupt, | ||
218 | IRQF_DISABLED, "RTC tick", &pdev->dev); | ||
219 | if (err) { | ||
220 | dev_err(&pdev->dev, "Cannot claim IRQ%d\n", | ||
221 | rtc_data->irq_1msec); | ||
222 | goto out_irq1; | ||
223 | } | ||
224 | |||
225 | platform_set_drvdata(pdev, rtc_data); | ||
226 | 233 | ||
227 | return 0; | 234 | return 0; |
228 | 235 | ||
229 | out_irq1: | ||
230 | free_irq(rtc_data->irq_alarm, &pdev->dev); | ||
231 | out_irq_alarm: | 236 | out_irq_alarm: |
232 | stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN | BM_RTC_CTRL_ALARM_IRQ_EN, | ||
233 | rtc_data->io + HW_RTC_CTRL); | ||
234 | rtc_device_unregister(rtc_data->rtc); | 237 | rtc_device_unregister(rtc_data->rtc); |
235 | out_remap: | 238 | out_remap: |
239 | platform_set_drvdata(pdev, NULL); | ||
236 | iounmap(rtc_data->io); | 240 | iounmap(rtc_data->io); |
237 | out_free: | 241 | out_free: |
238 | kfree(rtc_data); | 242 | kfree(rtc_data); |
@@ -249,11 +253,11 @@ static int stmp3xxx_rtc_resume(struct platform_device *dev) | |||
249 | { | 253 | { |
250 | struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); | 254 | struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); |
251 | 255 | ||
252 | stmp3xxx_reset_block(rtc_data->io, true); | 256 | mxs_reset_block(rtc_data->io); |
253 | stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | | 257 | writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | |
254 | BM_RTC_PERSISTENT0_ALARM_WAKE_EN | | 258 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | |
255 | BM_RTC_PERSISTENT0_ALARM_WAKE, | 259 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, |
256 | rtc_data->io + HW_RTC_PERSISTENT0); | 260 | rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); |
257 | return 0; | 261 | return 0; |
258 | } | 262 | } |
259 | #else | 263 | #else |
@@ -286,5 +290,6 @@ module_init(stmp3xxx_rtc_init); | |||
286 | module_exit(stmp3xxx_rtc_exit); | 290 | module_exit(stmp3xxx_rtc_exit); |
287 | 291 | ||
288 | MODULE_DESCRIPTION("STMP3xxx RTC Driver"); | 292 | MODULE_DESCRIPTION("STMP3xxx RTC Driver"); |
289 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com>"); | 293 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " |
294 | "Wolfram Sang <w.sang@pengutronix.de>"); | ||
290 | MODULE_LICENSE("GPL"); | 295 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index efd6066b5cd..f93f412423c 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -74,6 +74,8 @@ | |||
74 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ | 74 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ |
75 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ | 75 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ |
76 | 76 | ||
77 | #define VT8500_RTC_IS_ALARM (1 << 0) /* Alarm interrupt status */ | ||
78 | |||
77 | struct vt8500_rtc { | 79 | struct vt8500_rtc { |
78 | void __iomem *regbase; | 80 | void __iomem *regbase; |
79 | struct resource *res; | 81 | struct resource *res; |
@@ -96,7 +98,7 @@ static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id) | |||
96 | 98 | ||
97 | spin_unlock(&vt8500_rtc->lock); | 99 | spin_unlock(&vt8500_rtc->lock); |
98 | 100 | ||
99 | if (isr & 1) | 101 | if (isr & VT8500_RTC_IS_ALARM) |
100 | events |= RTC_AF | RTC_IRQF; | 102 | events |= RTC_AF | RTC_IRQF; |
101 | 103 | ||
102 | rtc_update_irq(vt8500_rtc->rtc, 1, events); | 104 | rtc_update_irq(vt8500_rtc->rtc, 1, events); |
@@ -161,8 +163,8 @@ static int vt8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
161 | alrm->time.tm_sec = bcd2bin((alarm & TIME_SEC_MASK)); | 163 | alrm->time.tm_sec = bcd2bin((alarm & TIME_SEC_MASK)); |
162 | 164 | ||
163 | alrm->enabled = (alarm & ALARM_ENABLE_MASK) ? 1 : 0; | 165 | alrm->enabled = (alarm & ALARM_ENABLE_MASK) ? 1 : 0; |
166 | alrm->pending = (isr & VT8500_RTC_IS_ALARM) ? 1 : 0; | ||
164 | 167 | ||
165 | alrm->pending = (isr & 1) ? 1 : 0; | ||
166 | return rtc_valid_tm(&alrm->time); | 168 | return rtc_valid_tm(&alrm->time); |
167 | } | 169 | } |
168 | 170 | ||