Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * arch/sh/boards/dreamcast/rtc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Dreamcast AICA RTC routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7)  * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8)  * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)    seconds) to get the standard Unix Epoch when getting the time, and add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)    20 years when setting the time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)    registers.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AICA_RTC_SECS_H		0xa0710000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AICA_RTC_SECS_L		0xa0710004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)  * aica_rtc_gettimeofday - Get the time from the AICA RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)  * @dev: the RTC device (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)  * @tm: pointer to resulting RTC time structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)  * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int aica_rtc_gettimeofday(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 	unsigned long val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	time64_t t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 		val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 		val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 	} while (val1 != val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	/* normalize to 1970..2106 time range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	t = (u32)(val1 - TWENTY_YEARS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	rtc_time64_to_tm(t, tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)  * aica_rtc_settimeofday - Set the AICA RTC to the current time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)  * @dev: the RTC device (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)  * @tm: pointer to new RTC time structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)  * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int aica_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 	unsigned long val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	time64_t secs = rtc_tm_to_time64(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	u32 adj = secs + TWENTY_YEARS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 		__raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 		__raw_writel((adj & 0xffff), AICA_RTC_SECS_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 		val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 		val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	} while (val1 != val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const struct rtc_class_ops rtc_generic_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 	.read_time = aica_rtc_gettimeofday,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 	.set_time = aica_rtc_settimeofday,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static int __init aica_time_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 	pdev = platform_device_register_data(NULL, "rtc-generic", -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 					     &rtc_generic_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 					     sizeof(rtc_generic_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 	return PTR_ERR_OR_ZERO(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) arch_initcall(aica_time_init);