All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] mips: CMOS RTC refactoring
@ 2025-07-13 10:04 Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 1/4] mips: remove unused function mc146818_set_rtc_mmss Mateusz Jończyk
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Mateusz Jończyk @ 2025-07-13 10:04 UTC (permalink / raw)
  To: Jiaxun Yang, Huacai Chen, Thomas Bogendoerfer
  Cc: Alexandre Belloni, linux-mips, linux-rtc, Mateusz Jończyk

Hello,

A while ago I wrote some patches that refactor a bit the RTC CMOS support on the
MIPS architecture. These were in response to a bug report about locking
problems during suspend / resume:

Link: https://lore.kernel.org/all/CAP-bSRZ0CWyZZsMtx046YV8L28LhY0fson2g4EqcwRAVN1Jk+Q@mail.gmail.com/

Back then, I was trying to convert the rtc_lock to a raw spinlock. This proved
to be unnecessary and harmful, but in the process I removed some dead and
duplicated code that touches the MC146818 (the chip of the CMOS RTC) for
the MIPS architecture.

These patches were tested only in an emulator, as I don't have the hardware.
They are roughly in the order of increasing risk.

Greetings,
Mateusz

Mateusz Jończyk (4):
  mips: remove unused function mc146818_set_rtc_mmss
  mips/mach-rm: remove custom mc146818rtc.h file
  mips: remove redundant macro mc146818_decode_year
  mips/malta,loongson2ef: use generic mc146818_get_time function

 arch/mips/Kconfig                             |   2 +
 .../include/asm/mach-generic/mc146818rtc.h    |   4 -
 arch/mips/include/asm/mach-jazz/mc146818rtc.h |   2 -
 .../mips/include/asm/mach-malta/mc146818rtc.h |   2 -
 arch/mips/include/asm/mach-rm/mc146818rtc.h   |  21 ----
 arch/mips/include/asm/mc146818-time.h         | 105 ++----------------
 6 files changed, 9 insertions(+), 127 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-rm/mc146818rtc.h


base-commit: d7b8f8e20813f0179d8ef519541a3527e7661d3a
-- 
2.25.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] mips: remove unused function mc146818_set_rtc_mmss
  2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
@ 2025-07-13 10:04 ` Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 2/4] mips/mach-rm: remove custom mc146818rtc.h file Mateusz Jończyk
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mateusz Jończyk @ 2025-07-13 10:04 UTC (permalink / raw)
  To: Jiaxun Yang, Huacai Chen, Thomas Bogendoerfer
  Cc: Alexandre Belloni, linux-mips, linux-rtc, Mateusz Jończyk

I have checked carefully: this function is unused, so remove it.

The last caller appears to have been removed in 2007 in
commit 4b550488f894 ("[MIPS] Deforest the function pointer jungle in the time code.")

mc146818-time.h is included only in three files:
- arch/mips/mti-malta/malta-time.c
- arch/mips/loongson64/numa.c
- arch/mips/loongson2ef/common/time.c

Also, remove unused macros USEC_AFTER/USEC_BEFORE.

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
---
 arch/mips/include/asm/mc146818-time.h | 74 ---------------------------
 1 file changed, 74 deletions(-)

diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h
index cbf5cec345f1..07bf30bee792 100644
--- a/arch/mips/include/asm/mc146818-time.h
+++ b/arch/mips/include/asm/mc146818-time.h
@@ -12,80 +12,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/time.h>
 
-/*
- * For check timing call set_rtc_mmss() 500ms; used in timer interrupt.
- */
-#define USEC_AFTER	500000
-#define USEC_BEFORE	500000
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *	sets the minutes. Usually you'll only notice that after reboot!
- */
-static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
-{
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-	int retval = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		cmos_minutes = bcd2bin(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-			real_seconds = bin2bcd(real_seconds);
-			real_minutes = bin2bcd(real_minutes);
-		}
-		CMOS_WRITE(real_seconds, RTC_SECONDS);
-		CMOS_WRITE(real_minutes, RTC_MINUTES);
-	} else {
-		printk_once(KERN_NOTICE
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...			       -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-
-	return retval;
-}
-
 static inline time64_t mc146818_get_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] mips/mach-rm: remove custom mc146818rtc.h file
  2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 1/4] mips: remove unused function mc146818_set_rtc_mmss Mateusz Jończyk
@ 2025-07-13 10:04 ` Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 3/4] mips: remove redundant macro mc146818_decode_year Mateusz Jończyk
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mateusz Jończyk @ 2025-07-13 10:04 UTC (permalink / raw)
  To: Jiaxun Yang, Huacai Chen, Thomas Bogendoerfer
  Cc: Alexandre Belloni, linux-mips, linux-rtc, Mateusz Jończyk

The mc146818_decode_year macro is used only in mc146818_get_cmos_time,
which in turn is called only in
	arch/mips/loongson2ef/common/time.c
and
	arch/mips/mti-malta/malta-time.c

So no SNI or mach-rm content. SNI did not use mc146818_get_cmos_time
apparently since
commit 06cf5583fd9a ("[MIPS] SNI RM updates")
in 2007.

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
---
 arch/mips/include/asm/mach-rm/mc146818rtc.h | 21 ---------------------
 1 file changed, 21 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-rm/mc146818rtc.h

diff --git a/arch/mips/include/asm/mach-rm/mc146818rtc.h b/arch/mips/include/asm/mach-rm/mc146818rtc.h
deleted file mode 100644
index a074f4f84f75..000000000000
--- a/arch/mips/include/asm/mach-rm/mc146818rtc.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 by Ralf Baechle
- *
- * RTC routines for PC style attached Dallas chip with ARC epoch.
- */
-#ifndef __ASM_MACH_RM_MC146818RTC_H
-#define __ASM_MACH_RM_MC146818RTC_H
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
-#else
-#define mc146818_decode_year(year) ((year) + 1980)
-#endif
-
-#include <asm/mach-generic/mc146818rtc.h>
-
-#endif /* __ASM_MACH_RM_MC146818RTC_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] mips: remove redundant macro mc146818_decode_year
  2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 1/4] mips: remove unused function mc146818_set_rtc_mmss Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 2/4] mips/mach-rm: remove custom mc146818rtc.h file Mateusz Jończyk
@ 2025-07-13 10:04 ` Mateusz Jończyk
  2025-07-13 10:04 ` [PATCH 4/4] mips/malta,loongson2ef: use generic mc146818_get_time function Mateusz Jończyk
  2025-07-16 18:07 ` [PATCH 0/4] mips: CMOS RTC refactoring Thomas Bogendoerfer
  4 siblings, 0 replies; 6+ messages in thread
From: Mateusz Jończyk @ 2025-07-13 10:04 UTC (permalink / raw)
  To: Jiaxun Yang, Huacai Chen, Thomas Bogendoerfer
  Cc: Alexandre Belloni, linux-mips, linux-rtc, Mateusz Jończyk

The mc146818_decode_year macro is used only in mc146818_get_cmos_time(),
which in turn is called only in
	arch/mips/loongson2ef/common/time.c
and
	arch/mips/mti-malta/malta-time.c
so on mach-jazz it is unused and can be removed. On other platforms it
is defined in the same way, so it can be safely folded into
mc146818_get_cmos_time().

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
---
 arch/mips/include/asm/mach-generic/mc146818rtc.h | 4 ----
 arch/mips/include/asm/mach-jazz/mc146818rtc.h    | 2 --
 arch/mips/include/asm/mach-malta/mc146818rtc.h   | 2 --
 arch/mips/include/asm/mc146818-time.h            | 5 ++++-
 4 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/mips/include/asm/mach-generic/mc146818rtc.h b/arch/mips/include/asm/mach-generic/mc146818rtc.h
index 9c72e540ff56..249279b0494d 100644
--- a/arch/mips/include/asm/mach-generic/mc146818rtc.h
+++ b/arch/mips/include/asm/mach-generic/mc146818rtc.h
@@ -29,8 +29,4 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
 
 #define RTC_ALWAYS_BCD	0
 
-#ifndef mc146818_decode_year
-#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
-#endif
-
 #endif /* __ASM_MACH_GENERIC_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-jazz/mc146818rtc.h b/arch/mips/include/asm/mach-jazz/mc146818rtc.h
index 987f727afe25..639bff8ebca3 100644
--- a/arch/mips/include/asm/mach-jazz/mc146818rtc.h
+++ b/arch/mips/include/asm/mach-jazz/mc146818rtc.h
@@ -33,6 +33,4 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
 
 #define RTC_ALWAYS_BCD	0
 
-#define mc146818_decode_year(year) ((year) + 1980)
-
 #endif /* __ASM_MACH_JAZZ_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-malta/mc146818rtc.h b/arch/mips/include/asm/mach-malta/mc146818rtc.h
index e8cc7fdf7415..7da2c0ea55da 100644
--- a/arch/mips/include/asm/mach-malta/mc146818rtc.h
+++ b/arch/mips/include/asm/mach-malta/mc146818rtc.h
@@ -31,6 +31,4 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
 
 #define RTC_ALWAYS_BCD	0
 
-#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
-
 #endif /* __ASM_MACH_MALTA_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h
index 07bf30bee792..4e07914e94e6 100644
--- a/arch/mips/include/asm/mc146818-time.h
+++ b/arch/mips/include/asm/mc146818-time.h
@@ -37,7 +37,10 @@ static inline time64_t mc146818_get_cmos_time(void)
 		year = bcd2bin(year);
 	}
 	spin_unlock_irqrestore(&rtc_lock, flags);
-	year = mc146818_decode_year(year);
+	if (year < 70)
+		year += 2000;
+	else
+		year += 1900;
 
 	return mktime64(year, mon, day, hour, min, sec);
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] mips/malta,loongson2ef: use generic mc146818_get_time function
  2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
                   ` (2 preceding siblings ...)
  2025-07-13 10:04 ` [PATCH 3/4] mips: remove redundant macro mc146818_decode_year Mateusz Jończyk
@ 2025-07-13 10:04 ` Mateusz Jończyk
  2025-07-16 18:07 ` [PATCH 0/4] mips: CMOS RTC refactoring Thomas Bogendoerfer
  4 siblings, 0 replies; 6+ messages in thread
From: Mateusz Jończyk @ 2025-07-13 10:04 UTC (permalink / raw)
  To: Jiaxun Yang, Huacai Chen, Thomas Bogendoerfer
  Cc: Alexandre Belloni, linux-mips, linux-rtc, Mateusz Jończyk

mc146818_get_cmos_time() is now mostly equivalent to mc146818_get_time()
from drivers/rtc/rtc-mc146818-lib.c, with the latter using a more
advanced algorithm (which checks the UIP bit in the CMOS). The Malta
and Loongson2ef platforms, the only users of mc146818_get_cmos_time()
have RTC devices that should be MC146818 compatible.

So, rewrite mc146818_get_cmos_time() in a way that uses
mc146818_get_time() and add CONFIG_RTC_MC146818_LIB as a dependency of
CONFIG_MIPS_MALTA and CONFIG_CPU_LOONGSON2EF.

The should be safe as:

- malta_defconfig already uses a standard RTC CMOS driver
  (CONFIG_RTC_DRV_CMOS=y). The Malta board has an Intel 82371EB (PIIX4E)
  south bridge with the CMOS RTC, so should work correctly with the
  modification,

- Loongson2e and 2f apparently use the VIA686B south bridge and the AMD
  CS5536 south bridge respectively (at least according to Kconfig). I
  have checked datasheets of both and these appear to be MC146818
  software compatible.

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>

--

Tested only in an emulator for Malta.
---
 arch/mips/Kconfig                     |  2 ++
 arch/mips/include/asm/mc146818-time.h | 34 ++++++---------------------
 2 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 1e48184ecf1e..4df5589b3d35 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -563,6 +563,7 @@ config MIPS_MALTA
 	select MIPS_L1_CACHE_SHIFT_6
 	select MIPS_MSC
 	select PCI_GT64XXX_PCI0
+	select RTC_MC146818_LIB
 	select SMP_UP if SMP
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_MIPS32_R1
@@ -1837,6 +1838,7 @@ config CPU_LOONGSON2EF
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
 	select CPU_SUPPORTS_HUGEPAGES
+	select RTC_MC146818_LIB
 
 config CPU_LOONGSON32
 	bool
diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h
index 4e07914e94e6..ac52a30b4161 100644
--- a/arch/mips/include/asm/mc146818-time.h
+++ b/arch/mips/include/asm/mc146818-time.h
@@ -8,41 +8,21 @@
 #ifndef __ASM_MC146818_TIME_H
 #define __ASM_MC146818_TIME_H
 
-#include <linux/bcd.h>
 #include <linux/mc146818rtc.h>
 #include <linux/time.h>
 
+#ifdef CONFIG_RTC_MC146818_LIB
 static inline time64_t mc146818_get_cmos_time(void)
 {
-	unsigned int year, mon, day, hour, min, sec;
-	unsigned long flags;
+	struct rtc_time tm;
 
-	spin_lock_irqsave(&rtc_lock, flags);
-
-	do {
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-	} while (sec != CMOS_READ(RTC_SECONDS));
-
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		sec = bcd2bin(sec);
-		min = bcd2bin(min);
-		hour = bcd2bin(hour);
-		day = bcd2bin(day);
-		mon = bcd2bin(mon);
-		year = bcd2bin(year);
+	if (mc146818_get_time(&tm, 1000)) {
+		pr_err("Unable to read current time from RTC\n");
+		return 0;
 	}
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	if (year < 70)
-		year += 2000;
-	else
-		year += 1900;
 
-	return mktime64(year, mon, day, hour, min, sec);
+	return rtc_tm_to_time64(&tm);
 }
+#endif /* CONFIG_RTC_MC146818_LIB */
 
 #endif /* __ASM_MC146818_TIME_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] mips: CMOS RTC refactoring
  2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
                   ` (3 preceding siblings ...)
  2025-07-13 10:04 ` [PATCH 4/4] mips/malta,loongson2ef: use generic mc146818_get_time function Mateusz Jończyk
@ 2025-07-16 18:07 ` Thomas Bogendoerfer
  4 siblings, 0 replies; 6+ messages in thread
From: Thomas Bogendoerfer @ 2025-07-16 18:07 UTC (permalink / raw)
  To: Mateusz Jończyk
  Cc: Jiaxun Yang, Huacai Chen, Alexandre Belloni, linux-mips,
	linux-rtc

On Sun, Jul 13, 2025 at 12:04:30PM +0200, Mateusz Jończyk wrote:
> Hello,
> 
> A while ago I wrote some patches that refactor a bit the RTC CMOS support on the
> MIPS architecture. These were in response to a bug report about locking
> problems during suspend / resume:
> 
> Link: https://lore.kernel.org/all/CAP-bSRZ0CWyZZsMtx046YV8L28LhY0fson2g4EqcwRAVN1Jk+Q@mail.gmail.com/
> 
> Back then, I was trying to convert the rtc_lock to a raw spinlock. This proved
> to be unnecessary and harmful, but in the process I removed some dead and
> duplicated code that touches the MC146818 (the chip of the CMOS RTC) for
> the MIPS architecture.
> 
> These patches were tested only in an emulator, as I don't have the hardware.
> They are roughly in the order of increasing risk.
> 
> Greetings,
> Mateusz
> 
> Mateusz Jończyk (4):
>   mips: remove unused function mc146818_set_rtc_mmss
>   mips/mach-rm: remove custom mc146818rtc.h file
>   mips: remove redundant macro mc146818_decode_year
>   mips/malta,loongson2ef: use generic mc146818_get_time function
> 
>  arch/mips/Kconfig                             |   2 +
>  .../include/asm/mach-generic/mc146818rtc.h    |   4 -
>  arch/mips/include/asm/mach-jazz/mc146818rtc.h |   2 -
>  .../mips/include/asm/mach-malta/mc146818rtc.h |   2 -
>  arch/mips/include/asm/mach-rm/mc146818rtc.h   |  21 ----
>  arch/mips/include/asm/mc146818-time.h         | 105 ++----------------
>  6 files changed, 9 insertions(+), 127 deletions(-)
>  delete mode 100644 arch/mips/include/asm/mach-rm/mc146818rtc.h
> 
> 
> base-commit: d7b8f8e20813f0179d8ef519541a3527e7661d3a
> -- 
> 2.25.1

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-07-16 18:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-13 10:04 [PATCH 0/4] mips: CMOS RTC refactoring Mateusz Jończyk
2025-07-13 10:04 ` [PATCH 1/4] mips: remove unused function mc146818_set_rtc_mmss Mateusz Jończyk
2025-07-13 10:04 ` [PATCH 2/4] mips/mach-rm: remove custom mc146818rtc.h file Mateusz Jończyk
2025-07-13 10:04 ` [PATCH 3/4] mips: remove redundant macro mc146818_decode_year Mateusz Jończyk
2025-07-13 10:04 ` [PATCH 4/4] mips/malta,loongson2ef: use generic mc146818_get_time function Mateusz Jończyk
2025-07-16 18:07 ` [PATCH 0/4] mips: CMOS RTC refactoring Thomas Bogendoerfer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.