Linux6.16では全般的に大きな変更はないですが、SHプロセッサに限っては大幅な改変がRTCドライバにありました。
これまでのRTCドライバは、アラーム、桁上げ、周期割り込みの3つの割り込みを扱っていましたが、今回の改変でアラーム割り込みのみに限定され、それに伴う大幅改変であり、ついでにそれと関係ない部分も大幅改変がなされました。
それらの大幅改変は基本的には問題ないようですが、どうやら実機での確認をしていないようなので、そのままでは正常に動作しません。
そのため、大幅改変されたソースコードのうち、問題のある部分をバグ修正しないといけません。
大きな問題は、桁上げ割り込みを廃止したにもかかわらず、時刻読み出しをする sh_rtc_read_time関数では、桁上げ割り込みを前提とした下記のソースコードとなっています。
static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct sh_rtc *rtc = dev_get_drvdata(dev);
unsigned int sec128, sec2, yr, yr100, cf_bit;
if (!(readb(rtc->regbase + RCR2) & RCR2_RTCEN))
return -EINVAL;
do {
unsigned int tmp;
spin_lock_irq(&rtc->lock);
tmp = readb(rtc->regbase + RCR1);
tmp &= ~RCR1_CF; /* Clear CF-bit */
tmp |= RCR1_CIE;
writeb(tmp, rtc->regbase + RCR1);
sec128 = readb(rtc->regbase + R64CNT);
tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT));
tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT));
tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT));
tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT));
tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT));
tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1;
if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
yr = readw(rtc->regbase + RYRCNT);
yr100 = bcd2bin(yr >> 8);
yr &= 0xff;
} else {
yr = readb(rtc->regbase + RYRCNT);
yr100 = bcd2bin((yr == 0x99) ? 0x19 : 0x20);
}
tm->tm_year = (yr100 * 100 + bcd2bin(yr)) - 1900;
sec2 = readb(rtc->regbase + R64CNT);
cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;
spin_unlock_irq(&rtc->lock);
} while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
#if RTC_BIT_INVERTED != 0
if ((sec128 & RTC_BIT_INVERTED))
tm->tm_sec--;
#endif
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
__func__, tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
return 0;
}
SHのハードウェアマニュアルでは下記のようなフローが記載されています。

桁上げ割り込みを廃止した場合、(a)の手順で処理をしないといけないですが、実際の改変では、(b)となったままですので、(a)の手順で処理するようにしなければなりません。
また、ドライバ初期化部分では、アラーム割り込み番号がplatform_get_irq関数で取得できたら、そのまま割り込み番号をセットすればいいですが、下記コードではそうなっていません。
static int __init sh_rtc_probe(struct platform_device *pdev)
{
------- 中略 --------
ret = platform_get_irq(pdev, 0);
if (unlikely(ret <= 0)) {
dev_err(&pdev->dev, "No IRQ resource\n");
return -ENOENT;
}
if (!pdev->dev.of_node)
rtc->alarm_irq = platform_get_irq(pdev, 2);
else
rtc->alarm_irq = ret;
これを下記のように修正します。
static int __init sh_rtc_probe(struct platform_device *pdev)
{
------- 中略 --------
ret = platform_get_irq(pdev, 0);
if (unlikely(ret <= 0)) {
dev_err(&pdev->dev, "No IRQ resource\n");
return -ENOENT;
}
rtc->alarm_irq = ret;