Hello, On 22/05/2023 16:46:38+0200, Marek Behún wrote: > Hello RTC guys, > > this is a request for suggestions / question about how to implement a > RTC driver so that it will be accepted into upstream Linux. > > Let me start with the description of the problem. > > The MCU on the Turris Omnia router can disable / enable power > regulators basically for the whole board, giving capability for > platform specific poweroff and for powering the system on at a > specified time. > > I want to add support for this to the MCU firmware and write a driver > for Linux. Since I know only of one utility by which users can request > the system to power on at a specified time - the rtcwake utility - I > want to write this as a RTC driver. > > Because the MCU is not a true RTC in the sense that it does not have > battery to count time when not under power, I am wondering how exactly > to design this. One problem is that the RTC driver must implement the > read function, but the MCU does not know the real time unless it is > told beforehand. > > Note that the board also has a true RTC with battery, handled by the > rtc-armada38x driver. We can make sure that this true RTC is used for > hctosys. > > Proposal 1: > - the MCU will implement only one command, poweroff, with optional > argument wakeup_timeout, the number of seconds after which to power > the board up again > - the corresponding driver will register a system off handler and a RTC > device > - the RTC will implement methods as: > .read_time will use ktime_get(), so it will return monotonic clock > .set_alarm will store the requested wakeup time in an internal > structure > .alarm_irq_enable will just update the internal structure > .read_alarm will return information from the stored structure > - the system off handler will send the poweroff command and it will > take the requested wakeup time from the internal structure and > subtract current time (ktime_get()) to get the wakeup_timeout > argument for the MCU poweroff command > > - advantages: > - MCU needs only to implement one command > - disadvantages: > - the new RTC device will not behave at all like a rtc device > regarding timekeeping, since .read_time returns system's monotonic > clock. This may confuse users who do not know about the fact that > this rtc device is only meant for rtcwake. We can print this info > into dmesg, but... > - removing the driver and loading it back loses information about set > wakeup time > > Proposal 2: > - the MCU will implement: > - command for getting and setting clock that the MCU will count > The clock will be considered invalid unless it was set at least > once. > - command for getting and setting wakeup alarm > - command for power off > - the corresponding driver will again register a system off handler and > a RTC device > - the system off handler will just send the poweroff command > - the RTC device can now behave like a true RTC device, but without a > battery, the RTC_VL_BACKUP_EMPTY bit will be set. > The userspace can set time from the true RTC, so that rtcwake may be > used > > Overall proposal 1 is easier to implement, but the resulting /dev/rtc > device will not be a true RTC, which may confuse users. Proposal 2 > gives more complexity to MCU firmware. > > Personally I prefer proposal one. > > Do you guys have suggestions? Which kind of driver would you be willing > to accept? > You probably need to look at rtc-meson-vrtc.c, rtc-fsl-ftm-alarm.c and rtc-brcmstb-waketimer.c which implement something similar. Honestly, I would go for an in-between proposal where you would store the requested alarm time (or more likely countdown) on set_alarm/alarm_irq_enable so you would get .read_alarm working. However, my main concern is that this is yet another custom protocol. We can't possibly have a driver for everyone implementing a timer in their FPGA/CPLD/cortexM. How will you communicate with the MCU, can't you use an already existing driver? Regards, -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com