Thread (17 messages) 17 messages, 3 authors, 2019-08-23

Re: [PATCH v2 2/4] rtc: Add support for the MediaTek MT2712 RTC

From: Ran Bi <hidden>
Date: 2019-08-22 12:34:27
Also in: linux-arm-kernel, linux-mediatek, linux-rtc, lkml

Hi,
quoted
+
+#define MTK_RTC_DEV		KBUILD_MODNAME
You probably shouldn't do that and have a static string for the driver
name. I probably doesn't matter much though because DT is used to probe
the driver.
Will change it at next patch.
quoted
+/* we map HW YEAR 0 to 2000 because 2000 is the leap year */
+#define MT2712_MIN_YEAR		2000
+#define MT2712_BASE_YEAR	1900
+#define MT2712_MIN_YEAR_OFFSET	(MT2712_MIN_YEAR - MT2712_BASE_YEAR)
+#define MT2712_MAX_YEAR_OFFSET	(MT2712_MIN_YEAR_OFFSET + 127)
+
All those defines are unecessary, see below.
Will change it at next patch.
quoted
+struct mt2712_rtc {
+	struct device		*dev;
Looking at the code closely, it seems this is only used for debug and
error messages. Maybe you could use rtc_dev->dev instead.
Will change it at next patch.
quoted
+	mutex_lock(&rtc->rtc_dev->ops_lock);
+
+	irqsta = mt2712_readl(rtc, MT2712_IRQ_STA);
Do you have to lock that read? Is the register cleared on read?
Yes, this register is read clear register.
quoted
+	do {
+		__mt2712_rtc_read_time(rtc, tm, &sec);
+	} while (sec < tm->tm_sec);	/* SEC has carried */
Shouldn't that be while (tm->tm_sec < sec)?
In __mt2712_rtc_read_time function, we read tm->tm_sec before read sec.
Sometimes we can meet situation like "tm->tm_sec == 59" and "sec == 0".
It means that TC_SEC has carried and we need to reload the tm struct. I
suppose it was correct that using "while (sec < tm->tm_sec)"
quoted
+
+	/* HW register use 7 bits to store year data, minus
+	 * MT2712_MIN_YEAR_OFFSET brfore write year data to register, and plus
+	 * MT2712_MIN_YEAR_OFFSET back after read year from register
+	 */
+	tm->tm_year += MT2712_MIN_YEAR_OFFSET;
Simply add 100 in __mt2712_rtc_read_time
Will change it at next patch.
quoted
+
+	/* HW register start mon from one, but tm_mon start from zero. */
+	tm->tm_mon--;
+
You can also do that in __mt2712_rtc_read_time.
Will change it at next patch.
quoted
+	if (rtc_valid_tm(tm)) {
This check is unnecessary, the validity is always checked by the core.
Will remove this at next patch.
quoted
+	if (tm->tm_year > MT2712_MAX_YEAR_OFFSET) {
+		dev_dbg(rtc->dev, "Set year %d out of range. (%d - %d)\n",
+			1900 + tm->tm_year, 1900 + MT2712_MIN_YEAR_OFFSET,
+			1900 + MT2712_MAX_YEAR_OFFSET);
+		return -EINVAL;
+	}
This check is unnecessary, see below.
Will change it at next patch.
quoted
+
+	tm->tm_year -= MT2712_MIN_YEAR_OFFSET;
+	tm->tm_mon++;
You should probably avoid modifying tm, move the substraction and
addition in the mt2712_writel calls.
Will change it at next patch.

quoted
+	if (tm->tm_year > MT2712_MAX_YEAR_OFFSET) {
+		dev_dbg(rtc->dev, "Set year %d out of range. (%d - %d)\n",
+			1900 + tm->tm_year, 1900 + MT2712_MIN_YEAR_OFFSET,
+			1900 + MT2712_MAX_YEAR_OFFSET);
+		return -EINVAL;
+	}
+
Unnecessary check.
Will change it at next patch.
quoted
+	p1 = mt2712_readl(rtc, MT2712_POWERKEY1);
+	p2 = mt2712_readl(rtc, MT2712_POWERKEY2);
+	if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY)
+		dev_dbg(rtc->dev, "powerkey not set (lost power)\n");
+
This info is valuable, you should check that when reading the time and
return -EINVAL if power was lost.
Will change it at next patch.
quoted
+	/* RTC need POWERKEY1/2 match, then goto normal work mode */
+	mt2712_writel(rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY);
+	mt2712_writel(rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY);
This should be written when setting the time after power was lost.
I suppose we can move this into mt2712_rtc_read_time function's "if
(p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY)" condition
which will be added at next patch. We need additional flag to mark this
condition or another if condition in mt2712_rtc_set_time fucntion if we
put these code in mt2712_rtc_set_time function.
quoted
+static const struct rtc_class_ops mt2712_rtc_ops = {
+	.read_time	= mt2712_rtc_read_time,
+	.set_time	= mt2712_rtc_set_time,
+	.read_alarm	= mt2712_rtc_read_alarm,
+	.set_alarm	= mt2712_rtc_set_alarm,
For proper operations, you should also provide the .alarm_irq_enable
callback.
Will change it at next patch.
quoted
+	rtc->rtc_dev->ops = &mt2712_rtc_ops;
If you set the range properly here using rtc_dev->range_min and
rtc_dev->range_max, then the core will be able to do range checking and
will also take care of the year offset/windowing calculations instead of
having to hardcode that in the driver.
Will change it at next patch.

Best Regards,
Ran
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help