diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index a86c083cdf7f19e6556c9267cc4912a2f3b28118..fea4ea75b79d20d08cac71369968a5d95c4a104b 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -21,6 +21,7 @@ struct pci_dev;
 struct pci_ops;
 struct pci_controller;
 struct _alpha_agp_info;
+struct rtc_time;
 
 struct alpha_machine_vector
 {
@@ -94,6 +95,9 @@ struct alpha_machine_vector
 
 	struct _alpha_agp_info *(*agp_info)(void);
 
+	unsigned int (*rtc_get_time)(struct rtc_time *);
+	int (*rtc_set_time)(struct rtc_time *);
+
 	const char *vector_name;
 
 	/* NUMA information */
diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h
index 4e854b1333ebbd6595b6ae2cfe9d7af68c9f9a9b..1f7fba671ae68a25f204cf819e3e04bde362810e 100644
--- a/arch/alpha/include/asm/rtc.h
+++ b/arch/alpha/include/asm/rtc.h
@@ -1,9 +1,15 @@
 #ifndef _ALPHA_RTC_H
 #define _ALPHA_RTC_H
 
-/*
- * Alpha uses the default access methods for the RTC.
- */
+#if defined(CONFIG_ALPHA_GENERIC)
+# define get_rtc_time		alpha_mv.rtc_get_time
+# define set_rtc_time		alpha_mv.rtc_set_time
+#else
+# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP)
+#  define get_rtc_time		marvel_get_rtc_time
+#  define set_rtc_time		marvel_set_rtc_time
+# endif
+#endif
 
 #include <asm-generic/rtc.h>
 
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 9cd8dca742a733f8791b850872f96d68e72497a7..e302daecbe56cbe5ac5a9cca91046da88fad51da 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -658,16 +658,8 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
 		rtc_access.data = bcd2bin(b);
 		rtc_access.function = 0x48 + !write;	/* GET/PUT_TOY */
 
-#ifdef CONFIG_SMP
-		if (smp_processor_id() != boot_cpuid)
-			smp_call_function_single(boot_cpuid,
-						 __marvel_access_rtc,
-						 &rtc_access, 1);
-		else
-			__marvel_access_rtc(&rtc_access);
-#else
 		__marvel_access_rtc(&rtc_access);
-#endif
+
 		ret = bin2bcd(rtc_access.data);
 		break;
 
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index 466c9dff818192de44302c5feacd495c6a542c74..512685f78097a0ed5406e1e2226641cc007545c8 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -40,7 +40,10 @@
 #define CAT1(x,y)  x##y
 #define CAT(x,y)   CAT1(x,y)
 
-#define DO_DEFAULT_RTC .rtc_port = 0x70
+#define DO_DEFAULT_RTC \
+	.rtc_port = 0x70, \
+	.rtc_get_time = common_get_rtc_time, \
+	.rtc_set_time = common_set_rtc_time
 
 #define DO_EV4_MMU							\
 	.max_asn =			EV4_MAX_ASN,			\
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 708d5ca87782ad011019250399787e6e1c4258e5..fe14c6747cd651d56e07d10d6094f5671eb532c6 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -145,6 +145,8 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *);
 extern irqreturn_t timer_interrupt(int irq, void *dev);
 extern void common_init_rtc(void);
 extern unsigned long est_cycle_freq;
+extern unsigned int common_get_rtc_time(struct rtc_time *time);
+extern int common_set_rtc_time(struct rtc_time *time);
 
 /* smc37c93x.c */
 extern void SMC93x_Init(void);
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 2c3de97de46ca54416b7f52f6fc50bbac7684f6b..e2516f9a8967e45aa8c4df23f3de48cae1cdd67e 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -261,6 +261,8 @@ struct alpha_machine_vector jensen_mv __initmv = {
 	.machine_check		= jensen_machine_check,
 	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.rtc_port		= 0x170,
+	.rtc_get_time		= common_get_rtc_time,
+	.rtc_set_time		= common_set_rtc_time,
 
 	.nr_irqs		= 16,
 	.device_interrupt	= jensen_device_interrupt,
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 828449cd263687c18bc278358a8e8e2c8c8a01be..c5a1a2438c678191eeb6bb1c39b518cdf1c4adc9 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -23,6 +23,7 @@
 #include <asm/hwrpb.h>
 #include <asm/tlbflush.h>
 #include <asm/vga.h>
+#include <asm/rtc.h>
 
 #include "proto.h"
 #include "err_impl.h"
@@ -426,6 +427,57 @@ marvel_init_rtc(void)
 	init_rtc_irq();
 }
 
+struct marvel_rtc_time {
+	struct rtc_time *time;
+	int retval;
+};
+
+#ifdef CONFIG_SMP
+static void
+smp_get_rtc_time(void *data)
+{
+	struct marvel_rtc_time *mrt = data;
+	mrt->retval = __get_rtc_time(mrt->time);
+}
+
+static void
+smp_set_rtc_time(void *data)
+{
+	struct marvel_rtc_time *mrt = data;
+	mrt->retval = __set_rtc_time(mrt->time);
+}
+#endif
+
+static unsigned int
+marvel_get_rtc_time(struct rtc_time *time)
+{
+#ifdef CONFIG_SMP
+	struct marvel_rtc_time mrt;
+
+	if (smp_processor_id() != boot_cpuid) {
+		mrt.time = time;
+		smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1);
+		return mrt.retval;
+	}
+#endif
+	return __get_rtc_time(time);
+}
+
+static int
+marvel_set_rtc_time(struct rtc_time *time)
+{
+#ifdef CONFIG_SMP
+	struct marvel_rtc_time mrt;
+
+	if (smp_processor_id() != boot_cpuid) {
+		mrt.time = time;
+		smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1);
+		return mrt.retval;
+	}
+#endif
+	return __set_rtc_time(time);
+}
+
 static void
 marvel_smp_callin(void)
 {
@@ -466,7 +518,9 @@ marvel_smp_callin(void)
 struct alpha_machine_vector marvel_ev7_mv __initmv = {
 	.vector_name		= "MARVEL/EV7",
 	DO_EV7_MMU,
-	DO_DEFAULT_RTC,
+	.rtc_port		= 0x70,
+	.rtc_get_time		= marvel_get_rtc_time,
+	.rtc_set_time		= marvel_set_rtc_time,
 	DO_MARVEL_IO,
 	.machine_check		= marvel_machine_check,
 	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index e6a231435cbac57f90ffe77907af51cf4b5ccc4f..b04e2cbf23a445cb441839a415f204e49665830e 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/hwrpb.h>
 #include <asm/8253pit.h>
+#include <asm/rtc.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/time.h>
@@ -180,6 +181,15 @@ common_init_rtc(void)
 	init_rtc_irq();
 }
 
+unsigned int common_get_rtc_time(struct rtc_time *time)
+{
+	return __get_rtc_time(time);
+}
+
+int common_set_rtc_time(struct rtc_time *time)
+{
+	return __set_rtc_time(time);
+}
 
 /* Validate a computed cycle counter result against the known bounds for
    the given processor core.  There's too much brokenness in the way of
diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
index 89061c1a67d473f42c039780e0dcfa1506bec640..763e3b060f432542e07a6730a837185853418148 100644
--- a/include/asm-generic/rtc.h
+++ b/include/asm-generic/rtc.h
@@ -42,7 +42,7 @@ static inline unsigned char rtc_is_updating(void)
 	return uip;
 }
 
-static inline unsigned int get_rtc_time(struct rtc_time *time)
+static inline unsigned int __get_rtc_time(struct rtc_time *time)
 {
 	unsigned char ctrl;
 	unsigned long flags;
@@ -108,8 +108,12 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
 	return RTC_24H;
 }
 
+#ifndef get_rtc_time
+#define get_rtc_time	__get_rtc_time
+#endif
+
 /* Set the current date and time in the real time clock. */
-static inline int set_rtc_time(struct rtc_time *time)
+static inline int __set_rtc_time(struct rtc_time *time)
 {
 	unsigned long flags;
 	unsigned char mon, day, hrs, min, sec;
@@ -190,11 +194,15 @@ static inline int set_rtc_time(struct rtc_time *time)
 	return 0;
 }
 
+#ifndef set_rtc_time
+#define set_rtc_time	__set_rtc_time
+#endif
+
 static inline unsigned int get_rtc_ss(void)
 {
 	struct rtc_time h;
 
-	get_rtc_time(&h);
+	__get_rtc_time(&h);
 	return h.tm_sec;
 }