Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0792a2c8 authored by Finn Thain's avatar Finn Thain Committed by Michael Ellerman
Browse files

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 22db552b
("powerpc/powermac: Fix rtc read/write functions").

Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 053c5a75
Loading
Loading
Loading
Loading
+10 −65
Original line number Diff line number Diff line
@@ -37,35 +37,6 @@
static void (*rom_reset)(void);

#ifdef CONFIG_ADB_CUDA
static time64_t cuda_read_time(void)
{
	struct adb_request req;
	time64_t time;

	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
		return 0;
	while (!req.complete)
		cuda_poll();

	time = (u32)((req.reply[3] << 24) | (req.reply[4] << 16) |
		     (req.reply[5] << 8) | req.reply[6]);

	return time - RTC_OFFSET;
}

static void cuda_write_time(time64_t time)
{
	struct adb_request req;
	u32 data = lower_32_bits(time + RTC_OFFSET);

	if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
			 (data >> 24) & 0xFF, (data >> 16) & 0xFF,
			 (data >> 8) & 0xFF, data & 0xFF) < 0)
		return;
	while (!req.complete)
		cuda_poll();
}

static __u8 cuda_read_pram(int offset)
{
	struct adb_request req;
@@ -91,33 +62,6 @@ static void cuda_write_pram(int offset, __u8 data)
#endif /* CONFIG_ADB_CUDA */

#ifdef CONFIG_ADB_PMU
static time64_t pmu_read_time(void)
{
	struct adb_request req;
	time64_t time;

	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
		return 0;
	pmu_wait_complete(&req);

	time = (u32)((req.reply[0] << 24) | (req.reply[1] << 16) |
		     (req.reply[2] << 8) | req.reply[3]);

	return time - RTC_OFFSET;
}

static void pmu_write_time(time64_t time)
{
	struct adb_request req;
	u32 data = lower_32_bits(time + RTC_OFFSET);

	if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
			(data >> 24) & 0xFF, (data >> 16) & 0xFF,
			(data >> 8) & 0xFF, data & 0xFF) < 0)
		return;
	pmu_wait_complete(&req);
}

static __u8 pmu_read_pram(int offset)
{
	struct adb_request req;
@@ -295,13 +239,17 @@ static time64_t via_read_time(void)
 * is basically any machine with Mac II-style ADB.
 */

static void via_write_time(time64_t time)
static void via_set_rtc_time(struct rtc_time *tm)
{
	union {
		__u8 cdata[4];
		__u32 idata;
	} data;
	__u8 temp;
	time64_t time;

	time = mktime64(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
	                tm->tm_hour, tm->tm_min, tm->tm_sec);

	/* Clear the write protect bit */

@@ -641,12 +589,12 @@ int mac_hwclk(int op, struct rtc_time *t)
#ifdef CONFIG_ADB_CUDA
		case MAC_ADB_EGRET:
		case MAC_ADB_CUDA:
			now = cuda_read_time();
			now = cuda_get_time();
			break;
#endif
#ifdef CONFIG_ADB_PMU
		case MAC_ADB_PB2:
			now = pmu_read_time();
			now = pmu_get_time();
			break;
#endif
		default:
@@ -665,24 +613,21 @@ int mac_hwclk(int op, struct rtc_time *t)
		         __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
		         t->tm_hour, t->tm_min, t->tm_sec);

		now = mktime64(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
			       t->tm_hour, t->tm_min, t->tm_sec);

		switch (macintosh_config->adb_type) {
		case MAC_ADB_IOP:
		case MAC_ADB_II:
		case MAC_ADB_PB1:
			via_write_time(now);
			via_set_rtc_time(t);
			break;
#ifdef CONFIG_ADB_CUDA
		case MAC_ADB_EGRET:
		case MAC_ADB_CUDA:
			cuda_write_time(now);
			cuda_set_rtc_time(t);
			break;
#endif
#ifdef CONFIG_ADB_PMU
		case MAC_ADB_PB2:
			pmu_write_time(now);
			pmu_set_rtc_time(t);
			break;
#endif
		default:
+20 −106
Original line number Diff line number Diff line
@@ -44,13 +44,6 @@
#define DBG(x...)
#endif

/*
 * Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU
 * times wrap in 2040. If we need to handle later times, the read_time functions
 * need to be changed to interpret wrapped times as post-2040.
 */
#define RTC_OFFSET	2082844800

/*
 * Calibrate the decrementer frequency with the VIA timer 1.
 */
@@ -90,98 +83,6 @@ long __init pmac_time_init(void)
	return delta;
}

#ifdef CONFIG_ADB_CUDA
static time64_t cuda_get_time(void)
{
	struct adb_request req;
	time64_t now;

	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
		return 0;
	while (!req.complete)
		cuda_poll();
	if (req.reply_len != 7)
		printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
		       req.reply_len);
	now = (u32)((req.reply[3] << 24) + (req.reply[4] << 16) +
		    (req.reply[5] << 8) + req.reply[6]);
	/* it's either after year 2040, or the RTC has gone backwards */
	WARN_ON(now < RTC_OFFSET);

	return now - RTC_OFFSET;
}

#define cuda_get_rtc_time(tm)	rtc_time64_to_tm(cuda_get_time(), (tm))

static int cuda_set_rtc_time(struct rtc_time *tm)
{
	u32 nowtime;
	struct adb_request req;

	nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
	if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
			 nowtime >> 24, nowtime >> 16, nowtime >> 8,
			 nowtime) < 0)
		return -ENXIO;
	while (!req.complete)
		cuda_poll();
	if ((req.reply_len != 3) && (req.reply_len != 7))
		printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
		       req.reply_len);
	return 0;
}

#else
#define cuda_get_time()		0
#define cuda_get_rtc_time(tm)
#define cuda_set_rtc_time(tm)	0
#endif

#ifdef CONFIG_ADB_PMU
static time64_t pmu_get_time(void)
{
	struct adb_request req;
	time64_t now;

	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
		return 0;
	pmu_wait_complete(&req);
	if (req.reply_len != 4)
		printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
		       req.reply_len);
	now = (u32)((req.reply[0] << 24) + (req.reply[1] << 16)	+
		    (req.reply[2] << 8) + req.reply[3]);

	/* it's either after year 2040, or the RTC has gone backwards */
	WARN_ON(now < RTC_OFFSET);

	return now - RTC_OFFSET;
}

#define pmu_get_rtc_time(tm)	rtc_time64_to_tm(pmu_get_time(), (tm))

static int pmu_set_rtc_time(struct rtc_time *tm)
{
	u32 nowtime;
	struct adb_request req;

	nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
	if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
			nowtime >> 16, nowtime >> 8, nowtime) < 0)
		return -ENXIO;
	pmu_wait_complete(&req);
	if (req.reply_len != 0)
		printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
		       req.reply_len);
	return 0;
}

#else
#define pmu_get_time()		0
#define pmu_get_rtc_time(tm)
#define pmu_set_rtc_time(tm)	0
#endif

#ifdef CONFIG_PMAC_SMU
static time64_t smu_get_time(void)
{
@@ -191,11 +92,6 @@ static time64_t smu_get_time(void)
		return 0;
	return rtc_tm_to_time64(&tm);
}

#else
#define smu_get_time()			0
#define smu_get_rtc_time(tm, spin)
#define smu_set_rtc_time(tm, spin)	0
#endif

/* Can't be __init, it's called when suspending and resuming */
@@ -203,12 +99,18 @@ time64_t pmac_get_boot_time(void)
{
	/* Get the time from the RTC, used only at boot time */
	switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
	case SYS_CTRLER_CUDA:
		return cuda_get_time();
#endif
#ifdef CONFIG_ADB_PMU
	case SYS_CTRLER_PMU:
		return pmu_get_time();
#endif
#ifdef CONFIG_PMAC_SMU
	case SYS_CTRLER_SMU:
		return smu_get_time();
#endif
	default:
		return 0;
	}
@@ -218,15 +120,21 @@ void pmac_get_rtc_time(struct rtc_time *tm)
{
	/* Get the time from the RTC, used only at boot time */
	switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
	case SYS_CTRLER_CUDA:
		cuda_get_rtc_time(tm);
		rtc_time64_to_tm(cuda_get_time(), tm);
		break;
#endif
#ifdef CONFIG_ADB_PMU
	case SYS_CTRLER_PMU:
		pmu_get_rtc_time(tm);
		rtc_time64_to_tm(pmu_get_time(), tm);
		break;
#endif
#ifdef CONFIG_PMAC_SMU
	case SYS_CTRLER_SMU:
		smu_get_rtc_time(tm, 1);
		break;
#endif
	default:
		;
	}
@@ -235,12 +143,18 @@ void pmac_get_rtc_time(struct rtc_time *tm)
int pmac_set_rtc_time(struct rtc_time *tm)
{
	switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
	case SYS_CTRLER_CUDA:
		return cuda_set_rtc_time(tm);
#endif
#ifdef CONFIG_ADB_PMU
	case SYS_CTRLER_PMU:
		return pmu_set_rtc_time(tm);
#endif
#ifdef CONFIG_PMAC_SMU
	case SYS_CTRLER_SMU:
		return smu_set_rtc_time(tm, 1);
#endif
	default:
		return -ENODEV;
	}
+35 −0
Original line number Diff line number Diff line
@@ -766,3 +766,38 @@ cuda_input(unsigned char *buf, int nb)
	               buf, nb, false);
    }
}

/* Offset between Unix time (1970-based) and Mac time (1904-based) */
#define RTC_OFFSET	2082844800

time64_t cuda_get_time(void)
{
	struct adb_request req;
	u32 now;

	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
		return 0;
	while (!req.complete)
		cuda_poll();
	if (req.reply_len != 7)
		pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
	now = (req.reply[3] << 24) + (req.reply[4] << 16) +
	      (req.reply[5] << 8) + req.reply[6];
	return (time64_t)now - RTC_OFFSET;
}

int cuda_set_rtc_time(struct rtc_time *tm)
{
	u32 now;
	struct adb_request req;

	now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
	if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
	                 now >> 24, now >> 16, now >> 8, now) < 0)
		return -ENXIO;
	while (!req.complete)
		cuda_poll();
	if ((req.reply_len != 3) && (req.reply_len != 7))
		pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
	return 0;
}
+33 −0
Original line number Diff line number Diff line
@@ -1737,6 +1737,39 @@ pmu_enable_irled(int on)
	pmu_wait_complete(&req);
}

/* Offset between Unix time (1970-based) and Mac time (1904-based) */
#define RTC_OFFSET	2082844800

time64_t pmu_get_time(void)
{
	struct adb_request req;
	u32 now;

	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
		return 0;
	pmu_wait_complete(&req);
	if (req.reply_len != 4)
		pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
	now = (req.reply[0] << 24) + (req.reply[1] << 16) +
	      (req.reply[2] << 8) + req.reply[3];
	return (time64_t)now - RTC_OFFSET;
}

int pmu_set_rtc_time(struct rtc_time *tm)
{
	u32 now;
	struct adb_request req;

	now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
	if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
	                now >> 24, now >> 16, now >> 8, now) < 0)
		return -ENXIO;
	pmu_wait_complete(&req);
	if (req.reply_len != 0)
		pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
	return 0;
}

void
pmu_restart(void)
{
+4 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#ifndef _LINUX_CUDA_H
#define _LINUX_CUDA_H

#include <linux/rtc.h>
#include <uapi/linux/cuda.h>


@@ -16,4 +17,7 @@ extern int cuda_request(struct adb_request *req,
			void (*done)(struct adb_request *), int nbytes, ...);
extern void cuda_poll(void);

extern time64_t cuda_get_time(void);
extern int cuda_set_rtc_time(struct rtc_time *tm);

#endif /* _LINUX_CUDA_H */
Loading