+\f
+\f
+/*
+ * RTC Support
+ */
+struct marvel_rtc_access_info {
+ unsigned long function;
+ unsigned long index;
+ unsigned long data;
+};
+
+static void
+__marvel_access_rtc(void *info)
+{
+ struct marvel_rtc_access_info *rtc_access = info;
+
+ register unsigned long __r0 __asm__("$0");
+ register unsigned long __r16 __asm__("$16") = rtc_access->function;
+ register unsigned long __r17 __asm__("$17") = rtc_access->index;
+ register unsigned long __r18 __asm__("$18") = rtc_access->data;
+
+ __asm__ __volatile__(
+ "call_pal %4 # cserve rtc"
+ : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
+ : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
+ : "$1", "$22", "$23", "$24", "$25");
+
+ rtc_access->data = __r0;
+}
+
+static u8
+__marvel_rtc_io(u8 b, unsigned long addr, int write)
+{
+ static u8 index = 0;
+
+ struct marvel_rtc_access_info rtc_access;
+ u8 ret = 0;
+
+ switch(addr) {
+ case 0x70: /* RTC_PORT(0) */
+ if (write) index = b;
+ ret = index;
+ break;
+
+ case 0x71: /* RTC_PORT(1) */
+ rtc_access.index = index;
+ rtc_access.data = BCD_TO_BIN(b);
+ rtc_access.function = 0x48 + !write; /* GET/PUT_TOY */
+
+#ifdef CONFIG_SMP
+ if (smp_processor_id() != boot_cpuid)
+ smp_call_function_on_cpu(__marvel_access_rtc,
+ &rtc_access, 1, 1,
+ cpumask_of_cpu(boot_cpuid));
+ else
+ __marvel_access_rtc(&rtc_access);
+#else
+ __marvel_access_rtc(&rtc_access);
+#endif
+ ret = BIN_TO_BCD(rtc_access.data);
+ break;
+
+ default:
+ printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
+ break;
+ }
+
+ return ret;
+}
+