diff mbox series

[v2,2/5] rtc: gamecube: Report low battery as invalid data

Message ID 20211027223516.2031-3-linkmauve@linkmauve.fr
State Superseded
Headers show
Series rtc: nintendo: Add a RTC driver for the GameCube, Wii and Wii U | expand

Commit Message

Emmanuel Gil Peyrot Oct. 27, 2021, 10:35 p.m. UTC
I haven’t been able to test this patch as all of my consoles have a
working RTC battery, but according to the documentation it should work
like that.

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
---
 drivers/rtc/rtc-gamecube.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Alexandre Belloni Nov. 30, 2021, 10:45 p.m. UTC | #1
Hello,

On 28/10/2021 00:35:12+0200, Emmanuel Gil Peyrot wrote:
> I haven’t been able to test this patch as all of my consoles have a
> working RTC battery, but according to the documentation it should work
> like that.
> 
> Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
> ---
>  drivers/rtc/rtc-gamecube.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c
> index e8260c82c07d..1932c6fe1301 100644
> --- a/drivers/rtc/rtc-gamecube.c
> +++ b/drivers/rtc/rtc-gamecube.c
> @@ -83,6 +83,10 @@
>  #define RTC_CONTROL0	0x21000c
>  #define RTC_CONTROL1	0x21000d
>  
> +/* RTC flags */
> +#define RTC_CONTROL0_UNSTABLE_POWER	0x00000800
> +#define RTC_CONTROL0_LOW_BATTERY	0x00000200
> +
>  struct priv {
>  	struct regmap *regmap;
>  	void __iomem *iob;
> @@ -182,9 +186,35 @@ static int gamecube_rtc_set_time(struct device *dev, struct rtc_time *t)
>  	return regmap_write(d->regmap, RTC_COUNTER, timestamp - d->rtc_bias);
>  }
>  
> +static int gamecube_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
> +{
> +	struct priv *d = dev_get_drvdata(dev);
> +	int value;
> +	int control0;
> +	int ret;
> +
> +	switch (cmd) {
> +	case RTC_VL_READ:
> +		ret = regmap_read(d->regmap, RTC_CONTROL0, &control0);
> +		if (ret)
> +			return ret;
> +
> +		value = 0;
> +		if (control0 & RTC_CONTROL0_UNSTABLE_POWER)
> +			value |= RTC_VL_DATA_INVALID;
> +		if (control0 & RTC_CONTROL0_LOW_BATTERY)
> +			value |= RTC_VL_DATA_INVALID;

Shouldn't that one be RTC_VL_BACKUP_LOW?

Else, the driver is great, I'm ready to apply it.

> +		return put_user(value, (unsigned int __user *)arg);
> +
> +	default:
> +		return -ENOIOCTLCMD;
> +	}
> +}
> +
>  static const struct rtc_class_ops gamecube_rtc_ops = {
>  	.read_time	= gamecube_rtc_read_time,
>  	.set_time	= gamecube_rtc_set_time,
> +	.ioctl		= gamecube_rtc_ioctl,
>  };
>  
>  static int gamecube_rtc_read_offset_from_sram(struct priv *d)
> -- 
> 2.33.1
>
Emmanuel Gil Peyrot Dec. 15, 2021, 5:52 p.m. UTC | #2
On Tue, Nov 30, 2021 at 11:45:18PM +0100, Alexandre Belloni wrote:
> Hello,

Hi,

> 
> On 28/10/2021 00:35:12+0200, Emmanuel Gil Peyrot wrote:
> > I haven’t been able to test this patch as all of my consoles have a
> > working RTC battery, but according to the documentation it should work
> > like that.
> > 
> > Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
> > ---
> >  drivers/rtc/rtc-gamecube.c | 30 ++++++++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> > 
> > diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c
> > index e8260c82c07d..1932c6fe1301 100644
> > --- a/drivers/rtc/rtc-gamecube.c
> > +++ b/drivers/rtc/rtc-gamecube.c
> > @@ -83,6 +83,10 @@
> >  #define RTC_CONTROL0	0x21000c
> >  #define RTC_CONTROL1	0x21000d
> >  
> > +/* RTC flags */
> > +#define RTC_CONTROL0_UNSTABLE_POWER	0x00000800
> > +#define RTC_CONTROL0_LOW_BATTERY	0x00000200
> > +
> >  struct priv {
> >  	struct regmap *regmap;
> >  	void __iomem *iob;
> > @@ -182,9 +186,35 @@ static int gamecube_rtc_set_time(struct device *dev, struct rtc_time *t)
> >  	return regmap_write(d->regmap, RTC_COUNTER, timestamp - d->rtc_bias);
> >  }
> >  
> > +static int gamecube_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
> > +{
> > +	struct priv *d = dev_get_drvdata(dev);
> > +	int value;
> > +	int control0;
> > +	int ret;
> > +
> > +	switch (cmd) {
> > +	case RTC_VL_READ:
> > +		ret = regmap_read(d->regmap, RTC_CONTROL0, &control0);
> > +		if (ret)
> > +			return ret;
> > +
> > +		value = 0;
> > +		if (control0 & RTC_CONTROL0_UNSTABLE_POWER)
> > +			value |= RTC_VL_DATA_INVALID;
> > +		if (control0 & RTC_CONTROL0_LOW_BATTERY)
> > +			value |= RTC_VL_DATA_INVALID;
> 
> Shouldn't that one be RTC_VL_BACKUP_LOW?

Oops indeed, that seems like a better report, I’ll send a v3 with this
change only.

> 
> Else, the driver is great, I'm ready to apply it.

Perfect!

> 
> > +		return put_user(value, (unsigned int __user *)arg);
> > +
> > +	default:
> > +		return -ENOIOCTLCMD;
> > +	}
> > +}
> > +
> >  static const struct rtc_class_ops gamecube_rtc_ops = {
> >  	.read_time	= gamecube_rtc_read_time,
> >  	.set_time	= gamecube_rtc_set_time,
> > +	.ioctl		= gamecube_rtc_ioctl,
> >  };
> >  
> >  static int gamecube_rtc_read_offset_from_sram(struct priv *d)
> > -- 
> > 2.33.1
> > 
> 
> -- 
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
diff mbox series

Patch

diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c
index e8260c82c07d..1932c6fe1301 100644
--- a/drivers/rtc/rtc-gamecube.c
+++ b/drivers/rtc/rtc-gamecube.c
@@ -83,6 +83,10 @@ 
 #define RTC_CONTROL0	0x21000c
 #define RTC_CONTROL1	0x21000d
 
+/* RTC flags */
+#define RTC_CONTROL0_UNSTABLE_POWER	0x00000800
+#define RTC_CONTROL0_LOW_BATTERY	0x00000200
+
 struct priv {
 	struct regmap *regmap;
 	void __iomem *iob;
@@ -182,9 +186,35 @@  static int gamecube_rtc_set_time(struct device *dev, struct rtc_time *t)
 	return regmap_write(d->regmap, RTC_COUNTER, timestamp - d->rtc_bias);
 }
 
+static int gamecube_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	struct priv *d = dev_get_drvdata(dev);
+	int value;
+	int control0;
+	int ret;
+
+	switch (cmd) {
+	case RTC_VL_READ:
+		ret = regmap_read(d->regmap, RTC_CONTROL0, &control0);
+		if (ret)
+			return ret;
+
+		value = 0;
+		if (control0 & RTC_CONTROL0_UNSTABLE_POWER)
+			value |= RTC_VL_DATA_INVALID;
+		if (control0 & RTC_CONTROL0_LOW_BATTERY)
+			value |= RTC_VL_DATA_INVALID;
+		return put_user(value, (unsigned int __user *)arg);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 static const struct rtc_class_ops gamecube_rtc_ops = {
 	.read_time	= gamecube_rtc_read_time,
 	.set_time	= gamecube_rtc_set_time,
+	.ioctl		= gamecube_rtc_ioctl,
 };
 
 static int gamecube_rtc_read_offset_from_sram(struct priv *d)