summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-09-11 20:18:44 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-10-08 07:53:10 -0400
commit0792a2c8e0bbda3605b8d42c6b9635be7b19982a (patch)
treeba1ddd80dac3a672746caa2447a217cec910cbee
parent053c5a753e951c5dd1729af2cf4d8107f2e6e09b (diff)
macintosh: Use common code to access RTC
Now that the 68k Mac port has adopted the via-pmu driver, the same RTC code can be shared between m68k and powerpc. Replace duplicated code in arch/powerpc and arch/m68k with common RTC accessors for Cuda and PMU. Drop the problematic WARN_ON which was introduced in commit 22db552b50fa ("powerpc/powermac: Fix rtc read/write functions"). Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Arnd Bergmann <arnd@arndb.de> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/m68k/mac/misc.c75
-rw-r--r--arch/powerpc/platforms/powermac/time.c126
-rw-r--r--drivers/macintosh/via-cuda.c35
-rw-r--r--drivers/macintosh/via-pmu.c33
-rw-r--r--include/linux/cuda.h4
-rw-r--r--include/linux/pmu.h4
6 files changed, 106 insertions, 171 deletions
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 1b083c500b9a..ebb3b6d169ea 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -37,35 +37,6 @@
37static void (*rom_reset)(void); 37static void (*rom_reset)(void);
38 38
39#ifdef CONFIG_ADB_CUDA 39#ifdef CONFIG_ADB_CUDA
40static time64_t cuda_read_time(void)
41{
42 struct adb_request req;
43 time64_t time;
44
45 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
46 return 0;
47 while (!req.complete)
48 cuda_poll();
49
50 time = (u32)((req.reply[3] << 24) | (req.reply[4] << 16) |
51 (req.reply[5] << 8) | req.reply[6]);
52
53 return time - RTC_OFFSET;
54}
55
56static void cuda_write_time(time64_t time)
57{
58 struct adb_request req;
59 u32 data = lower_32_bits(time + RTC_OFFSET);
60
61 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
62 (data >> 24) & 0xFF, (data >> 16) & 0xFF,
63 (data >> 8) & 0xFF, data & 0xFF) < 0)
64 return;
65 while (!req.complete)
66 cuda_poll();
67}
68
69static __u8 cuda_read_pram(int offset) 40static __u8 cuda_read_pram(int offset)
70{ 41{
71 struct adb_request req; 42 struct adb_request req;
@@ -91,33 +62,6 @@ static void cuda_write_pram(int offset, __u8 data)
91#endif /* CONFIG_ADB_CUDA */ 62#endif /* CONFIG_ADB_CUDA */
92 63
93#ifdef CONFIG_ADB_PMU 64#ifdef CONFIG_ADB_PMU
94static time64_t pmu_read_time(void)
95{
96 struct adb_request req;
97 time64_t time;
98
99 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
100 return 0;
101 pmu_wait_complete(&req);
102
103 time = (u32)((req.reply[0] << 24) | (req.reply[1] << 16) |
104 (req.reply[2] << 8) | req.reply[3]);
105
106 return time - RTC_OFFSET;
107}
108
109static void pmu_write_time(time64_t time)
110{
111 struct adb_request req;
112 u32 data = lower_32_bits(time + RTC_OFFSET);
113
114 if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
115 (data >> 24) & 0xFF, (data >> 16) & 0xFF,
116 (data >> 8) & 0xFF, data & 0xFF) < 0)
117 return;
118 pmu_wait_complete(&req);
119}
120
121static __u8 pmu_read_pram(int offset) 65static __u8 pmu_read_pram(int offset)
122{ 66{
123 struct adb_request req; 67 struct adb_request req;
@@ -295,13 +239,17 @@ static time64_t via_read_time(void)
295 * is basically any machine with Mac II-style ADB. 239 * is basically any machine with Mac II-style ADB.
296 */ 240 */
297 241
298static void via_write_time(time64_t time) 242static void via_set_rtc_time(struct rtc_time *tm)
299{ 243{
300 union { 244 union {
301 __u8 cdata[4]; 245 __u8 cdata[4];
302 __u32 idata; 246 __u32 idata;
303 } data; 247 } data;
304 __u8 temp; 248 __u8 temp;
249 time64_t time;
250
251 time = mktime64(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
252 tm->tm_hour, tm->tm_min, tm->tm_sec);
305 253
306 /* Clear the write protect bit */ 254 /* Clear the write protect bit */
307 255
@@ -641,12 +589,12 @@ int mac_hwclk(int op, struct rtc_time *t)
641#ifdef CONFIG_ADB_CUDA 589#ifdef CONFIG_ADB_CUDA
642 case MAC_ADB_EGRET: 590 case MAC_ADB_EGRET:
643 case MAC_ADB_CUDA: 591 case MAC_ADB_CUDA:
644 now = cuda_read_time(); 592 now = cuda_get_time();
645 break; 593 break;
646#endif 594#endif
647#ifdef CONFIG_ADB_PMU 595#ifdef CONFIG_ADB_PMU
648 case MAC_ADB_PB2: 596 case MAC_ADB_PB2:
649 now = pmu_read_time(); 597 now = pmu_get_time();
650 break; 598 break;
651#endif 599#endif
652 default: 600 default:
@@ -665,24 +613,21 @@ int mac_hwclk(int op, struct rtc_time *t)
665 __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, 613 __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
666 t->tm_hour, t->tm_min, t->tm_sec); 614 t->tm_hour, t->tm_min, t->tm_sec);
667 615
668 now = mktime64(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
669 t->tm_hour, t->tm_min, t->tm_sec);
670
671 switch (macintosh_config->adb_type) { 616 switch (macintosh_config->adb_type) {
672 case MAC_ADB_IOP: 617 case MAC_ADB_IOP:
673 case MAC_ADB_II: 618 case MAC_ADB_II:
674 case MAC_ADB_PB1: 619 case MAC_ADB_PB1:
675 via_write_time(now); 620 via_set_rtc_time(t);
676 break; 621 break;
677#ifdef CONFIG_ADB_CUDA 622#ifdef CONFIG_ADB_CUDA
678 case MAC_ADB_EGRET: 623 case MAC_ADB_EGRET:
679 case MAC_ADB_CUDA: 624 case MAC_ADB_CUDA:
680 cuda_write_time(now); 625 cuda_set_rtc_time(t);
681 break; 626 break;
682#endif 627#endif
683#ifdef CONFIG_ADB_PMU 628#ifdef CONFIG_ADB_PMU
684 case MAC_ADB_PB2: 629 case MAC_ADB_PB2:
685 pmu_write_time(now); 630 pmu_set_rtc_time(t);
686 break; 631 break;
687#endif 632#endif
688 default: 633 default:
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index f92c1918fb56..f157e3d071f2 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -45,13 +45,6 @@
45#endif 45#endif
46 46
47/* 47/*
48 * Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU
49 * times wrap in 2040. If we need to handle later times, the read_time functions
50 * need to be changed to interpret wrapped times as post-2040.
51 */
52#define RTC_OFFSET 2082844800
53
54/*
55 * Calibrate the decrementer frequency with the VIA timer 1. 48 * Calibrate the decrementer frequency with the VIA timer 1.
56 */ 49 */
57#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ 50#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
@@ -90,98 +83,6 @@ long __init pmac_time_init(void)
90 return delta; 83 return delta;
91} 84}
92 85
93#ifdef CONFIG_ADB_CUDA
94static time64_t cuda_get_time(void)
95{
96 struct adb_request req;
97 time64_t now;
98
99 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
100 return 0;
101 while (!req.complete)
102 cuda_poll();
103 if (req.reply_len != 7)
104 printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
105 req.reply_len);
106 now = (u32)((req.reply[3] << 24) + (req.reply[4] << 16) +
107 (req.reply[5] << 8) + req.reply[6]);
108 /* it's either after year 2040, or the RTC has gone backwards */
109 WARN_ON(now < RTC_OFFSET);
110
111 return now - RTC_OFFSET;
112}
113
114#define cuda_get_rtc_time(tm) rtc_time64_to_tm(cuda_get_time(), (tm))
115
116static int cuda_set_rtc_time(struct rtc_time *tm)
117{
118 u32 nowtime;
119 struct adb_request req;
120
121 nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
122 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
123 nowtime >> 24, nowtime >> 16, nowtime >> 8,
124 nowtime) < 0)
125 return -ENXIO;
126 while (!req.complete)
127 cuda_poll();
128 if ((req.reply_len != 3) && (req.reply_len != 7))
129 printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
130 req.reply_len);
131 return 0;
132}
133
134#else
135#define cuda_get_time() 0
136#define cuda_get_rtc_time(tm)
137#define cuda_set_rtc_time(tm) 0
138#endif
139
140#ifdef CONFIG_ADB_PMU
141static time64_t pmu_get_time(void)
142{
143 struct adb_request req;
144 time64_t now;
145
146 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
147 return 0;
148 pmu_wait_complete(&req);
149 if (req.reply_len != 4)
150 printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
151 req.reply_len);
152 now = (u32)((req.reply[0] << 24) + (req.reply[1] << 16) +
153 (req.reply[2] << 8) + req.reply[3]);
154
155 /* it's either after year 2040, or the RTC has gone backwards */
156 WARN_ON(now < RTC_OFFSET);
157
158 return now - RTC_OFFSET;
159}
160
161#define pmu_get_rtc_time(tm) rtc_time64_to_tm(pmu_get_time(), (tm))
162
163static int pmu_set_rtc_time(struct rtc_time *tm)
164{
165 u32 nowtime;
166 struct adb_request req;
167
168 nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
169 if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
170 nowtime >> 16, nowtime >> 8, nowtime) < 0)
171 return -ENXIO;
172 pmu_wait_complete(&req);
173 if (req.reply_len != 0)
174 printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
175 req.reply_len);
176 return 0;
177}
178
179#else
180#define pmu_get_time() 0
181#define pmu_get_rtc_time(tm)
182#define pmu_set_rtc_time(tm) 0
183#endif
184
185#ifdef CONFIG_PMAC_SMU 86#ifdef CONFIG_PMAC_SMU
186static time64_t smu_get_time(void) 87static time64_t smu_get_time(void)
187{ 88{
@@ -191,11 +92,6 @@ static time64_t smu_get_time(void)
191 return 0; 92 return 0;
192 return rtc_tm_to_time64(&tm); 93 return rtc_tm_to_time64(&tm);
193} 94}
194
195#else
196#define smu_get_time() 0
197#define smu_get_rtc_time(tm, spin)
198#define smu_set_rtc_time(tm, spin) 0
199#endif 95#endif
200 96
201/* Can't be __init, it's called when suspending and resuming */ 97/* Can't be __init, it's called when suspending and resuming */
@@ -203,12 +99,18 @@ time64_t pmac_get_boot_time(void)
203{ 99{
204 /* Get the time from the RTC, used only at boot time */ 100 /* Get the time from the RTC, used only at boot time */
205 switch (sys_ctrler) { 101 switch (sys_ctrler) {
102#ifdef CONFIG_ADB_CUDA
206 case SYS_CTRLER_CUDA: 103 case SYS_CTRLER_CUDA:
207 return cuda_get_time(); 104 return cuda_get_time();
105#endif
106#ifdef CONFIG_ADB_PMU
208 case SYS_CTRLER_PMU: 107 case SYS_CTRLER_PMU:
209 return pmu_get_time(); 108 return pmu_get_time();
109#endif
110#ifdef CONFIG_PMAC_SMU
210 case SYS_CTRLER_SMU: 111 case SYS_CTRLER_SMU:
211 return smu_get_time(); 112 return smu_get_time();
113#endif
212 default: 114 default:
213 return 0; 115 return 0;
214 } 116 }
@@ -218,15 +120,21 @@ void pmac_get_rtc_time(struct rtc_time *tm)
218{ 120{
219 /* Get the time from the RTC, used only at boot time */ 121 /* Get the time from the RTC, used only at boot time */
220 switch (sys_ctrler) { 122 switch (sys_ctrler) {
123#ifdef CONFIG_ADB_CUDA
221 case SYS_CTRLER_CUDA: 124 case SYS_CTRLER_CUDA:
222 cuda_get_rtc_time(tm); 125 rtc_time64_to_tm(cuda_get_time(), tm);
223 break; 126 break;
127#endif
128#ifdef CONFIG_ADB_PMU
224 case SYS_CTRLER_PMU: 129 case SYS_CTRLER_PMU:
225 pmu_get_rtc_time(tm); 130 rtc_time64_to_tm(pmu_get_time(), tm);
226 break; 131 break;
132#endif
133#ifdef CONFIG_PMAC_SMU
227 case SYS_CTRLER_SMU: 134 case SYS_CTRLER_SMU:
228 smu_get_rtc_time(tm, 1); 135 smu_get_rtc_time(tm, 1);
229 break; 136 break;
137#endif
230 default: 138 default:
231 ; 139 ;
232 } 140 }
@@ -235,12 +143,18 @@ void pmac_get_rtc_time(struct rtc_time *tm)
235int pmac_set_rtc_time(struct rtc_time *tm) 143int pmac_set_rtc_time(struct rtc_time *tm)
236{ 144{
237 switch (sys_ctrler) { 145 switch (sys_ctrler) {
146#ifdef CONFIG_ADB_CUDA
238 case SYS_CTRLER_CUDA: 147 case SYS_CTRLER_CUDA:
239 return cuda_set_rtc_time(tm); 148 return cuda_set_rtc_time(tm);
149#endif
150#ifdef CONFIG_ADB_PMU
240 case SYS_CTRLER_PMU: 151 case SYS_CTRLER_PMU:
241 return pmu_set_rtc_time(tm); 152 return pmu_set_rtc_time(tm);
153#endif
154#ifdef CONFIG_PMAC_SMU
242 case SYS_CTRLER_SMU: 155 case SYS_CTRLER_SMU:
243 return smu_set_rtc_time(tm, 1); 156 return smu_set_rtc_time(tm, 1);
157#endif
244 default: 158 default:
245 return -ENODEV; 159 return -ENODEV;
246 } 160 }
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 98dd702eb867..bbec6ac0a966 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -766,3 +766,38 @@ cuda_input(unsigned char *buf, int nb)
766 buf, nb, false); 766 buf, nb, false);
767 } 767 }
768} 768}
769
770/* Offset between Unix time (1970-based) and Mac time (1904-based) */
771#define RTC_OFFSET 2082844800
772
773time64_t cuda_get_time(void)
774{
775 struct adb_request req;
776 u32 now;
777
778 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
779 return 0;
780 while (!req.complete)
781 cuda_poll();
782 if (req.reply_len != 7)
783 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
784 now = (req.reply[3] << 24) + (req.reply[4] << 16) +
785 (req.reply[5] << 8) + req.reply[6];
786 return (time64_t)now - RTC_OFFSET;
787}
788
789int cuda_set_rtc_time(struct rtc_time *tm)
790{
791 u32 now;
792 struct adb_request req;
793
794 now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
795 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
796 now >> 24, now >> 16, now >> 8, now) < 0)
797 return -ENXIO;
798 while (!req.complete)
799 cuda_poll();
800 if ((req.reply_len != 3) && (req.reply_len != 7))
801 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
802 return 0;
803}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index d72c450aebe5..60f57e2abf21 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1737,6 +1737,39 @@ pmu_enable_irled(int on)
1737 pmu_wait_complete(&req); 1737 pmu_wait_complete(&req);
1738} 1738}
1739 1739
1740/* Offset between Unix time (1970-based) and Mac time (1904-based) */
1741#define RTC_OFFSET 2082844800
1742
1743time64_t pmu_get_time(void)
1744{
1745 struct adb_request req;
1746 u32 now;
1747
1748 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
1749 return 0;
1750 pmu_wait_complete(&req);
1751 if (req.reply_len != 4)
1752 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
1753 now = (req.reply[0] << 24) + (req.reply[1] << 16) +
1754 (req.reply[2] << 8) + req.reply[3];
1755 return (time64_t)now - RTC_OFFSET;
1756}
1757
1758int pmu_set_rtc_time(struct rtc_time *tm)
1759{
1760 u32 now;
1761 struct adb_request req;
1762
1763 now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
1764 if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
1765 now >> 24, now >> 16, now >> 8, now) < 0)
1766 return -ENXIO;
1767 pmu_wait_complete(&req);
1768 if (req.reply_len != 0)
1769 pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
1770 return 0;
1771}
1772
1740void 1773void
1741pmu_restart(void) 1774pmu_restart(void)
1742{ 1775{
diff --git a/include/linux/cuda.h b/include/linux/cuda.h
index 056867f09a01..45bfe9d61271 100644
--- a/include/linux/cuda.h
+++ b/include/linux/cuda.h
@@ -8,6 +8,7 @@
8#ifndef _LINUX_CUDA_H 8#ifndef _LINUX_CUDA_H
9#define _LINUX_CUDA_H 9#define _LINUX_CUDA_H
10 10
11#include <linux/rtc.h>
11#include <uapi/linux/cuda.h> 12#include <uapi/linux/cuda.h>
12 13
13 14
@@ -16,4 +17,7 @@ extern int cuda_request(struct adb_request *req,
16 void (*done)(struct adb_request *), int nbytes, ...); 17 void (*done)(struct adb_request *), int nbytes, ...);
17extern void cuda_poll(void); 18extern void cuda_poll(void);
18 19
20extern time64_t cuda_get_time(void);
21extern int cuda_set_rtc_time(struct rtc_time *tm);
22
19#endif /* _LINUX_CUDA_H */ 23#endif /* _LINUX_CUDA_H */
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index 9ac8fc60ad49..52453a24a24f 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -9,6 +9,7 @@
9#ifndef _LINUX_PMU_H 9#ifndef _LINUX_PMU_H
10#define _LINUX_PMU_H 10#define _LINUX_PMU_H
11 11
12#include <linux/rtc.h>
12#include <uapi/linux/pmu.h> 13#include <uapi/linux/pmu.h>
13 14
14 15
@@ -36,6 +37,9 @@ static inline void pmu_resume(void)
36 37
37extern void pmu_enable_irled(int on); 38extern void pmu_enable_irled(int on);
38 39
40extern time64_t pmu_get_time(void);
41extern int pmu_set_rtc_time(struct rtc_time *tm);
42
39extern void pmu_restart(void); 43extern void pmu_restart(void);
40extern void pmu_shutdown(void); 44extern void pmu_shutdown(void);
41extern void pmu_unlock(void); 45extern void pmu_unlock(void);