Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: rzn1: reduce register access

This RTC has special 32bit registers which return multiple of the same
8bit registers at once. Use these to minimize register access. Also, do
the to/from BCD conversions right away, so 'tm' always contains values
as described in time.h.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20241122101448.4374-3-wsa+renesas@sang-engineering.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Wolfram Sang and committed by
Alexandre Belloni
3ed345c9 692f983b

+33 -42
+33 -42
drivers/rtc/rtc-rzn1.c
··· 35 35 #define RZN1_RTC_CTL2_WUST BIT(5) 36 36 #define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST) 37 37 38 - #define RZN1_RTC_SEC 0x14 39 - #define RZN1_RTC_MIN 0x18 40 - #define RZN1_RTC_HOUR 0x1c 41 - #define RZN1_RTC_WEEK 0x20 42 - #define RZN1_RTC_DAY 0x24 43 - #define RZN1_RTC_MONTH 0x28 44 - #define RZN1_RTC_YEAR 0x2c 38 + #define RZN1_RTC_TIME 0x30 39 + #define RZN1_RTC_TIME_MIN_SHIFT 8 40 + #define RZN1_RTC_TIME_HOUR_SHIFT 16 41 + #define RZN1_RTC_CAL 0x34 42 + #define RZN1_RTC_CAL_DAY_SHIFT 8 43 + #define RZN1_RTC_CAL_MON_SHIFT 16 44 + #define RZN1_RTC_CAL_YEAR_SHIFT 24 45 45 46 46 #define RZN1_RTC_SUBU 0x38 47 47 #define RZN1_RTC_SUBU_DEV BIT(7) ··· 52 52 #define RZN1_RTC_ALW 0x48 53 53 54 54 #define RZN1_RTC_SECC 0x4c 55 - #define RZN1_RTC_MINC 0x50 56 - #define RZN1_RTC_HOURC 0x54 57 - #define RZN1_RTC_WEEKC 0x58 58 - #define RZN1_RTC_DAYC 0x5c 59 - #define RZN1_RTC_MONTHC 0x60 60 - #define RZN1_RTC_YEARC 0x64 55 + #define RZN1_RTC_TIMEC 0x68 56 + #define RZN1_RTC_CALC 0x6c 61 57 62 58 struct rzn1_rtc { 63 59 struct rtc_device *rtcdev; ··· 62 66 63 67 static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm) 64 68 { 65 - tm->tm_sec = readl(rtc->base + RZN1_RTC_SECC); 66 - tm->tm_min = readl(rtc->base + RZN1_RTC_MINC); 67 - tm->tm_hour = readl(rtc->base + RZN1_RTC_HOURC); 68 - tm->tm_wday = readl(rtc->base + RZN1_RTC_WEEKC); 69 - tm->tm_mday = readl(rtc->base + RZN1_RTC_DAYC); 70 - tm->tm_mon = readl(rtc->base + RZN1_RTC_MONTHC); 71 - tm->tm_year = readl(rtc->base + RZN1_RTC_YEARC); 69 + u32 val; 70 + 71 + val = readl(rtc->base + RZN1_RTC_TIMEC); 72 + tm->tm_sec = bcd2bin(val); 73 + tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT); 74 + tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT); 75 + 76 + val = readl(rtc->base + RZN1_RTC_CALC); 77 + tm->tm_wday = val & 0x0f; 78 + tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT); 79 + tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1; 80 + tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100; 72 81 } 73 82 74 83 static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm) ··· 91 90 92 91 rzn1_rtc_get_time_snapshot(rtc, tm); 93 92 secs = readl(rtc->base + RZN1_RTC_SECC); 94 - if (tm->tm_sec != secs) 93 + if (tm->tm_sec != bcd2bin(secs)) 95 94 rzn1_rtc_get_time_snapshot(rtc, tm); 96 - 97 - tm->tm_sec = bcd2bin(tm->tm_sec); 98 - tm->tm_min = bcd2bin(tm->tm_min); 99 - tm->tm_hour = bcd2bin(tm->tm_hour); 100 - tm->tm_mday = bcd2bin(tm->tm_mday); 101 - tm->tm_mon = bcd2bin(tm->tm_mon) - 1; 102 - tm->tm_year = bcd2bin(tm->tm_year) + 100; 103 95 104 96 return 0; 105 97 } ··· 102 108 struct rzn1_rtc *rtc = dev_get_drvdata(dev); 103 109 u32 val; 104 110 int ret; 105 - 106 - tm->tm_sec = bin2bcd(tm->tm_sec); 107 - tm->tm_min = bin2bcd(tm->tm_min); 108 - tm->tm_hour = bin2bcd(tm->tm_hour); 109 - tm->tm_mday = bin2bcd(tm->tm_mday); 110 - tm->tm_mon = bin2bcd(tm->tm_mon + 1); 111 - tm->tm_year = bin2bcd(tm->tm_year - 100); 112 111 113 112 val = readl(rtc->base + RZN1_RTC_CTL2); 114 113 if (!(val & RZN1_RTC_CTL2_STOPPED)) { ··· 116 129 return ret; 117 130 } 118 131 119 - writel(tm->tm_sec, rtc->base + RZN1_RTC_SEC); 120 - writel(tm->tm_min, rtc->base + RZN1_RTC_MIN); 121 - writel(tm->tm_hour, rtc->base + RZN1_RTC_HOUR); 122 - writel(tm->tm_wday, rtc->base + RZN1_RTC_WEEK); 123 - writel(tm->tm_mday, rtc->base + RZN1_RTC_DAY); 124 - writel(tm->tm_mon, rtc->base + RZN1_RTC_MONTH); 125 - writel(tm->tm_year, rtc->base + RZN1_RTC_YEAR); 132 + val = bin2bcd(tm->tm_sec); 133 + val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT; 134 + val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT; 135 + writel(val, rtc->base + RZN1_RTC_TIME); 136 + 137 + val = tm->tm_wday; 138 + val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT; 139 + val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT; 140 + val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT; 141 + writel(val, rtc->base + RZN1_RTC_CAL); 142 + 126 143 writel(0, rtc->base + RZN1_RTC_CTL2); 127 144 128 145 return 0;