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)  * RTC related functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/mc146818rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/vsyscall.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/x86_init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <asm/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/intel-mid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * This is a special lock that is owned by the CPU and holds the index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * register we are working with.  It is required for NMI access to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) volatile unsigned long cmos_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) EXPORT_SYMBOL(cmos_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #endif /* CONFIG_X86_32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* For two digit years assume time is always after that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define CMOS_YEARS_OFFS 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) DEFINE_SPINLOCK(rtc_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) EXPORT_SYMBOL(rtc_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * In order to set the CMOS clock precisely, set_rtc_mmss has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * called 500 ms after the second nowtime has started, because when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * nowtime is written into the registers of the CMOS clock, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * jump to the next second precisely 500 ms later. Check the Motorola
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * MC146818A or Dallas DS12887 data sheet for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) int mach_set_rtc_mmss(const struct timespec64 *now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	unsigned long long nowtime = now->tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct rtc_time tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	rtc_time64_to_tm(nowtime, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (!rtc_valid_tm(&tm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		retval = mc146818_set_time(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			printk(KERN_ERR "%s: RTC write failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			       __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		       "%s: Invalid RTC value: write of %llx to RTC failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			__func__, nowtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) void mach_get_cmos_time(struct timespec64 *now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	unsigned int status, year, mon, day, hour, min, sec, century = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * If pm_trace abused the RTC as storage, set the timespec to 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * which tells the caller that this RTC value is unusable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (!pm_trace_rtc_valid()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		now->tv_sec = now->tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	spin_lock_irqsave(&rtc_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * If UIP is clear, then we have >= 244 microseconds before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * RTC registers will be updated.  Spec sheet says that this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * is the reliable way to read RTC - registers. If UIP is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * then the register access might be invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	sec = CMOS_READ(RTC_SECONDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	min = CMOS_READ(RTC_MINUTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	hour = CMOS_READ(RTC_HOURS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	day = CMOS_READ(RTC_DAY_OF_MONTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	mon = CMOS_READ(RTC_MONTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	year = CMOS_READ(RTC_YEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	    acpi_gbl_FADT.century)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		century = CMOS_READ(acpi_gbl_FADT.century);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	status = CMOS_READ(RTC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	spin_unlock_irqrestore(&rtc_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		sec = bcd2bin(sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		min = bcd2bin(min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		hour = bcd2bin(hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		day = bcd2bin(day);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		mon = bcd2bin(mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		year = bcd2bin(year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (century) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		century = bcd2bin(century);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		year += century * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		year += CMOS_YEARS_OFFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	now->tv_sec = mktime64(year, mon, day, hour, min, sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	now->tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Routines for accessing the CMOS RAM/RTC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned char rtc_cmos_read(unsigned char addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	lock_cmos_prefix(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	outb(addr, RTC_PORT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	val = inb(RTC_PORT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	lock_cmos_suffix(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) EXPORT_SYMBOL(rtc_cmos_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void rtc_cmos_write(unsigned char val, unsigned char addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	lock_cmos_prefix(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	outb(addr, RTC_PORT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	outb(val, RTC_PORT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	lock_cmos_suffix(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) EXPORT_SYMBOL(rtc_cmos_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int update_persistent_clock64(struct timespec64 now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return x86_platform.set_wallclock(&now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* not static: needed by APM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) void read_persistent_clock64(struct timespec64 *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	x86_platform.get_wallclock(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct resource rtc_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		.start	= RTC_PORT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		.end	= RTC_PORT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		.flags	= IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		.start	= RTC_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		.end	= RTC_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		.flags	= IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static struct platform_device rtc_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.name		= "rtc_cmos",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	.id		= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	.resource	= rtc_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	.num_resources	= ARRAY_SIZE(rtc_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static __init int add_rtc_cmos(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	static const char * const ids[] __initconst =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	    { "PNP0b00", "PNP0b01", "PNP0b02", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	struct pnp_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct pnp_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	pnp_for_each_dev(dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		for (id = dev->id; id; id = id->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			for (i = 0; i < ARRAY_SIZE(ids); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				if (compare_pnp_id(id, ids[i]) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (!x86_platform.legacy.rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	platform_device_register(&rtc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	dev_info(&rtc_device.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		 "registered platform RTC device (no PNP device found)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) device_initcall(add_rtc_cmos);