aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/time.c37
-rw-r--r--drivers/sbus/char/rtc.c103
-rw-r--r--include/asm-sparc64/mostek.h6
3 files changed, 123 insertions, 23 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 6a717d4d2bc5..c60785c046be 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -48,7 +48,7 @@
48 48
49DEFINE_SPINLOCK(mostek_lock); 49DEFINE_SPINLOCK(mostek_lock);
50DEFINE_SPINLOCK(rtc_lock); 50DEFINE_SPINLOCK(rtc_lock);
51unsigned long mstk48t02_regs = 0UL; 51void * __iomem mstk48t02_regs = 0UL;
52#ifdef CONFIG_PCI 52#ifdef CONFIG_PCI
53unsigned long ds1287_regs = 0UL; 53unsigned long ds1287_regs = 0UL;
54#endif 54#endif
@@ -59,8 +59,8 @@ u64 jiffies_64 = INITIAL_JIFFIES;
59 59
60EXPORT_SYMBOL(jiffies_64); 60EXPORT_SYMBOL(jiffies_64);
61 61
62static unsigned long mstk48t08_regs = 0UL; 62static void * __iomem mstk48t08_regs;
63static unsigned long mstk48t59_regs = 0UL; 63static void * __iomem mstk48t59_regs;
64 64
65static int set_rtc_mmss(unsigned long); 65static int set_rtc_mmss(unsigned long);
66 66
@@ -520,7 +520,7 @@ void timer_tick_interrupt(struct pt_regs *regs)
520/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ 520/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
521static void __init kick_start_clock(void) 521static void __init kick_start_clock(void)
522{ 522{
523 unsigned long regs = mstk48t02_regs; 523 void * __iomem regs = mstk48t02_regs;
524 u8 sec, tmp; 524 u8 sec, tmp;
525 int i, count; 525 int i, count;
526 526
@@ -604,7 +604,7 @@ static void __init kick_start_clock(void)
604/* Return nonzero if the clock chip battery is low. */ 604/* Return nonzero if the clock chip battery is low. */
605static int __init has_low_battery(void) 605static int __init has_low_battery(void)
606{ 606{
607 unsigned long regs = mstk48t02_regs; 607 void * __iomem regs = mstk48t02_regs;
608 u8 data1, data2; 608 u8 data1, data2;
609 609
610 spin_lock_irq(&mostek_lock); 610 spin_lock_irq(&mostek_lock);
@@ -623,7 +623,7 @@ static int __init has_low_battery(void)
623static void __init set_system_time(void) 623static void __init set_system_time(void)
624{ 624{
625 unsigned int year, mon, day, hour, min, sec; 625 unsigned int year, mon, day, hour, min, sec;
626 unsigned long mregs = mstk48t02_regs; 626 void * __iomem mregs = mstk48t02_regs;
627#ifdef CONFIG_PCI 627#ifdef CONFIG_PCI
628 unsigned long dregs = ds1287_regs; 628 unsigned long dregs = ds1287_regs;
629#else 629#else
@@ -843,7 +843,8 @@ void __init clock_probe(void)
843 !strcmp(model, "m5823")) { 843 !strcmp(model, "m5823")) {
844 ds1287_regs = edev->resource[0].start; 844 ds1287_regs = edev->resource[0].start;
845 } else { 845 } else {
846 mstk48t59_regs = edev->resource[0].start; 846 mstk48t59_regs = (void * __iomem)
847 edev->resource[0].start;
847 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; 848 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
848 } 849 }
849 break; 850 break;
@@ -865,7 +866,8 @@ try_isa_clock:
865 !strcmp(model, "m5823")) { 866 !strcmp(model, "m5823")) {
866 ds1287_regs = isadev->resource.start; 867 ds1287_regs = isadev->resource.start;
867 } else { 868 } else {
868 mstk48t59_regs = isadev->resource.start; 869 mstk48t59_regs = (void * __iomem)
870 isadev->resource.start;
869 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; 871 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
870 } 872 }
871 break; 873 break;
@@ -893,21 +895,24 @@ try_isa_clock:
893 } 895 }
894 896
895 if(model[5] == '0' && model[6] == '2') { 897 if(model[5] == '0' && model[6] == '2') {
896 mstk48t02_regs = (((u64)clk_reg[0].phys_addr) | 898 mstk48t02_regs = (void * __iomem)
897 (((u64)clk_reg[0].which_io)<<32UL)); 899 (((u64)clk_reg[0].phys_addr) |
900 (((u64)clk_reg[0].which_io)<<32UL));
898 } else if(model[5] == '0' && model[6] == '8') { 901 } else if(model[5] == '0' && model[6] == '8') {
899 mstk48t08_regs = (((u64)clk_reg[0].phys_addr) | 902 mstk48t08_regs = (void * __iomem)
900 (((u64)clk_reg[0].which_io)<<32UL)); 903 (((u64)clk_reg[0].phys_addr) |
904 (((u64)clk_reg[0].which_io)<<32UL));
901 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02; 905 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
902 } else { 906 } else {
903 mstk48t59_regs = (((u64)clk_reg[0].phys_addr) | 907 mstk48t59_regs = (void * __iomem)
904 (((u64)clk_reg[0].which_io)<<32UL)); 908 (((u64)clk_reg[0].phys_addr) |
909 (((u64)clk_reg[0].which_io)<<32UL));
905 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; 910 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
906 } 911 }
907 break; 912 break;
908 } 913 }
909 914
910 if (mstk48t02_regs != 0UL) { 915 if (mstk48t02_regs != NULL) {
911 /* Report a low battery voltage condition. */ 916 /* Report a low battery voltage condition. */
912 if (has_low_battery()) 917 if (has_low_battery())
913 prom_printf("NVRAM: Low battery voltage!\n"); 918 prom_printf("NVRAM: Low battery voltage!\n");
@@ -1087,7 +1092,7 @@ unsigned long long sched_clock(void)
1087static int set_rtc_mmss(unsigned long nowtime) 1092static int set_rtc_mmss(unsigned long nowtime)
1088{ 1093{
1089 int real_seconds, real_minutes, chip_minutes; 1094 int real_seconds, real_minutes, chip_minutes;
1090 unsigned long mregs = mstk48t02_regs; 1095 void * __iomem mregs = mstk48t02_regs;
1091#ifdef CONFIG_PCI 1096#ifdef CONFIG_PCI
1092 unsigned long dregs = ds1287_regs; 1097 unsigned long dregs = ds1287_regs;
1093#else 1098#else
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index bf3273eb1c8b..49d1cd99d5ac 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -28,6 +28,42 @@
28 28
29static int rtc_busy = 0; 29static int rtc_busy = 0;
30 30
31/* This is the structure layout used by drivers/char/rtc.c, we
32 * support that driver's ioctls so that things are less messy in
33 * userspace.
34 */
35struct rtc_time_generic {
36 int tm_sec;
37 int tm_min;
38 int tm_hour;
39 int tm_mday;
40 int tm_mon;
41 int tm_year;
42 int tm_wday;
43 int tm_yday;
44 int tm_isdst;
45};
46#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
47#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
48#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
49#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
50#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
51#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
52#define RTC_WIE_ON _IO('p', 0x0f) /* Watchdog int. enable on */
53#define RTC_WIE_OFF _IO('p', 0x10) /* ... off */
54#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time_generic) /* Read RTC time */
55#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time_generic) /* Set RTC time */
56#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
57#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
58#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
59#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
60#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
61#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
62#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
63#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
64#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
65#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
66
31/* Retrieve the current date and time from the real time clock. */ 67/* Retrieve the current date and time from the real time clock. */
32static void get_rtc_time(struct rtc_time *t) 68static void get_rtc_time(struct rtc_time *t)
33{ 69{
@@ -82,29 +118,87 @@ void set_rtc_time(struct rtc_time *t)
82 spin_unlock_irq(&mostek_lock); 118 spin_unlock_irq(&mostek_lock);
83} 119}
84 120
121static int put_rtc_time_generic(void __user *argp, struct rtc_time *tm)
122{
123 struct rtc_time_generic __user *utm = argp;
124
125 if (__put_user(tm->sec, &utm->tm_sec) ||
126 __put_user(tm->min, &utm->tm_min) ||
127 __put_user(tm->hour, &utm->tm_hour) ||
128 __put_user(tm->dom, &utm->tm_mday) ||
129 __put_user(tm->month, &utm->tm_mon) ||
130 __put_user(tm->year, &utm->tm_year) ||
131 __put_user(tm->dow, &utm->tm_wday) ||
132 __put_user(0, &utm->tm_yday) ||
133 __put_user(0, &utm->tm_isdst))
134 return -EFAULT;
135
136 return 0;
137}
138
139static int get_rtc_time_generic(struct rtc_time *tm, void __user *argp)
140{
141 struct rtc_time_generic __user *utm = argp;
142
143 if (__get_user(tm->sec, &utm->tm_sec) ||
144 __get_user(tm->min, &utm->tm_min) ||
145 __get_user(tm->hour, &utm->tm_hour) ||
146 __get_user(tm->dom, &utm->tm_mday) ||
147 __get_user(tm->month, &utm->tm_mon) ||
148 __get_user(tm->year, &utm->tm_year) ||
149 __get_user(tm->dow, &utm->tm_wday))
150 return -EFAULT;
151
152 return 0;
153}
154
85static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 155static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
86 unsigned long arg) 156 unsigned long arg)
87{ 157{
88 struct rtc_time rtc_tm; 158 struct rtc_time rtc_tm;
89 void __user *argp = (void __user *)arg; 159 void __user *argp = (void __user *)arg;
90 160
91 switch (cmd) 161 switch (cmd) {
92 { 162 /* No interrupt support, return an error
163 * compatible with drivers/char/rtc.c
164 */
165 case RTC_AIE_OFF:
166 case RTC_AIE_ON:
167 case RTC_PIE_OFF:
168 case RTC_PIE_ON:
169 case RTC_UIE_OFF:
170 case RTC_UIE_ON:
171 case RTC_IRQP_READ:
172 case RTC_IRQP_SET:
173 case RTC_EPOCH_SET:
174 case RTC_EPOCH_READ:
175 return -EINVAL;
176
93 case RTCGET: 177 case RTCGET:
178 case RTC_RD_TIME:
94 memset(&rtc_tm, 0, sizeof(struct rtc_time)); 179 memset(&rtc_tm, 0, sizeof(struct rtc_time));
95 get_rtc_time(&rtc_tm); 180 get_rtc_time(&rtc_tm);
96 181
97 if (copy_to_user(argp, &rtc_tm, sizeof(struct rtc_time))) 182 if (cmd == RTCGET) {
183 if (copy_to_user(argp, &rtc_tm,
184 sizeof(struct rtc_time)))
185 return -EFAULT;
186 } else if (put_rtc_time_generic(argp, &rtc_tm))
98 return -EFAULT; 187 return -EFAULT;
99 188
100 return 0; 189 return 0;
101 190
102 191
103 case RTCSET: 192 case RTCSET:
193 case RTC_SET_TIME:
104 if (!capable(CAP_SYS_TIME)) 194 if (!capable(CAP_SYS_TIME))
105 return -EPERM; 195 return -EPERM;
106 196
107 if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time))) 197 if (cmd == RTCSET) {
198 if (copy_from_user(&rtc_tm, argp,
199 sizeof(struct rtc_time)))
200 return -EFAULT;
201 } else if (get_rtc_time_generic(&rtc_tm, argp))
108 return -EFAULT; 202 return -EFAULT;
109 203
110 set_rtc_time(&rtc_tm); 204 set_rtc_time(&rtc_tm);
@@ -164,6 +258,7 @@ static int __init rtc_sun_init(void)
164 printk(KERN_ERR "rtc: unable to get misc minor for Mostek\n"); 258 printk(KERN_ERR "rtc: unable to get misc minor for Mostek\n");
165 return error; 259 return error;
166 } 260 }
261 printk("rtc_sun_init: Registered Mostek RTC driver.\n");
167 262
168 return 0; 263 return 0;
169} 264}
diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h
index ccf2f5f82d7f..1f9b1356a48e 100644
--- a/include/asm-sparc64/mostek.h
+++ b/include/asm-sparc64/mostek.h
@@ -38,7 +38,7 @@
38 * 38 *
39 * We now deal with physical addresses for I/O to the chip. -DaveM 39 * We now deal with physical addresses for I/O to the chip. -DaveM
40 */ 40 */
41static __inline__ u8 mostek_read(unsigned long addr) 41static __inline__ u8 mostek_read(void * __iomem addr)
42{ 42{
43 u8 ret; 43 u8 ret;
44 44
@@ -48,7 +48,7 @@ static __inline__ u8 mostek_read(unsigned long addr)
48 return ret; 48 return ret;
49} 49}
50 50
51static __inline__ void mostek_write(unsigned long addr, u8 val) 51static __inline__ void mostek_write(void * __iomem addr, u8 val)
52{ 52{
53 __asm__ __volatile__("stba %0, [%1] %2" 53 __asm__ __volatile__("stba %0, [%1] %2"
54 : /* no outputs */ 54 : /* no outputs */
@@ -67,7 +67,7 @@ static __inline__ void mostek_write(unsigned long addr, u8 val)
67#define MOSTEK_YEAR 0x07ffUL 67#define MOSTEK_YEAR 0x07ffUL
68 68
69extern spinlock_t mostek_lock; 69extern spinlock_t mostek_lock;
70extern unsigned long mstk48t02_regs; 70extern void *__iomem mstk48t02_regs;
71 71
72/* Control register values. */ 72/* Control register values. */
73#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */ 73#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */