All of lore.kernel.org
 help / color / mirror / Atom feed
From: Medad Young <medadyoung@gmail.com>
To: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Benjamin Fair <benjaminfair@google.com>,
	Nancy Yuen <yuenn@google.com>,
	Patrick Venture <venture@google.com>,
	Tali Perry <tali.perry1@gmail.com>,
	Tomer Maimon <tmaimon77@gmail.com>,
	Avi Fishman <avifishman70@gmail.com>,
	Rob Herring <robh+dt@kernel.org>,
	a.zummo@towertech.it, KWLIU@nuvoton.com, YSCHU@nuvoton.com,
	JJLIU0@nuvoton.com, KFTING <KFTING@nuvoton.com>,
	ctcchien@nuvoton.com, OpenBMC Maillist <openbmc@lists.ozlabs.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	devicetree <devicetree@vger.kernel.org>,
	linux-rtc@vger.kernel.org, Mining Lin <mimi05633@gmail.com>
Subject: Re: [PATCH v3 3/3] RTC: nuvoton: Add NCT3018Y real time clock driver
Date: Thu, 7 Jul 2022 13:30:59 +0800	[thread overview]
Message-ID: <CAHpyw9cdmCSZEE4ZbpnehpyvFhpPWA+_E5zXzJerNX9xqYet5Q@mail.gmail.com> (raw)
In-Reply-To: <YrYd+FkiFPz84twJ@mail.local>

Hello Alexandre,

Thanks for your comments.
I add Mining Lin <mimi05633@gmail.com> into this mail thread,
and she is going to follow up this RTC driver.
She will be in charge of maintaining this driver.

Alexandre Belloni <alexandre.belloni@bootlin.com> 於 2022年6月25日 週六 凌晨4:26寫道:
>
> Hello,
>
> Please run ./scripts/checkpatch.pl --strict on your patch, there are a
> bunch of issues.
>
> On 27/05/2022 16:46:47+0800, medadyoung@gmail.com wrote:
> > +static int nct3018y_set_alarm_mode(struct i2c_client *client, bool on)
> > +{
> > +     int err, flags;
> > +
> > +     dev_dbg(&client->dev, "%s:on:%d\n", __func__, on);
> > +
> > +     flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
> > +     if (flags < 0) {
> > +             dev_err(&client->dev,
> > +                     "Failed to read NCT3018Y_REG_CTRL\n");
>
> You should cut down on the number of error messages, they are usually
> not useful as the user doesn't have any specific action after getting
> one of them apart from trying the action once again. Also, this will
> make your code shorter. dev_dbg is fine.
>
> > +/*
> > + * In the routines that deal directly with the nct3018y hardware, we use
> > + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> > + */
> > +static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[10];
> > +     int err;
> > +
>
> You should still return an error if the time is invalid there but without
> an error message.
>
> > +     err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SC, sizeof(buf), buf);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     tm->tm_sec = bcd2bin(buf[0] & 0x7F);
> > +     tm->tm_min = bcd2bin(buf[2] & 0x7F);
> > +     tm->tm_hour = bcd2bin(buf[4] & 0x3F);
> > +     tm->tm_wday = buf[6] & 0x07;
> > +     tm->tm_mday = bcd2bin(buf[7] & 0x3F);
> > +     tm->tm_mon = bcd2bin(buf[8] & 0x1F) - 1;
> > +     tm->tm_year = bcd2bin(buf[9]) + 100;
> > +
> > +     return 0;
> > +}
> > +
> > +static int nct3018y_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[5];
> > +     int err;
> > +
> > +     err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SCA,
> > +                                         sizeof(buf), buf);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to read date\n");
> > +             return -EIO;
> > +     }
> > +
> > +     dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n",
> > +             __func__, buf[0], buf[2], buf[4]);
> > +
> > +     tm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
> > +     tm->time.tm_min = bcd2bin(buf[2] & 0x7F);
> > +     tm->time.tm_hour = bcd2bin(buf[4] & 0x3F);
> > +
> > +     err = nct3018y_get_alarm_mode(client, &tm->enabled, &tm->pending);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n",
> > +             __func__, tm->time.tm_sec, tm->time.tm_min,
> > +             tm->time.tm_hour, tm->enabled, tm->pending);
> > +
> > +     return 0;
> > +}
> > +
> > +static int nct3018y_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[3];
> > +     int err;
> > +
> > +     dev_dbg(dev, "%s, sec=%d, min=%d hour=%d tm->enabled:%d\n",
> > +             __func__, tm->time.tm_sec, tm->time.tm_min, tm->time.tm_hour,
> > +             tm->enabled);
> > +
> > +     buf[0] = bin2bcd(tm->time.tm_sec);
> > +     buf[1] = bin2bcd(tm->time.tm_min);
> > +     buf[2] = bin2bcd(tm->time.tm_hour);
>
> I don't think buf is useful in this function
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SCA, buf[0]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_SCA\n");
> > +             return err;
> > +     }
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MNA, buf[1]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_MNA\n");
> > +             return err;
> > +     }
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HRA, buf[2]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_HRA\n");
> > +             return err;
> > +     }
> > +
> > +     return nct3018y_set_alarm_mode(client, tm->enabled);
> > +}
> > +
>
>
> > +static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y)
> > +{
> > +     struct i2c_client *client = nct3018y->client;
> > +     struct device_node *node = client->dev.of_node;
> > +     struct clk *clk;
> > +     struct clk_init_data init;
> > +     int flags, err;
> > +
> > +     /* disable the clkout output */
> > +     flags = 0;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags);
>
> BTW, this introduces a glitch in the clock output if the clock is
> actually used. Maybe you could just rely on the CCF core to disable this
> clock when there are no users.
>
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write oscillator status register\n");
> > +             return ERR_PTR(err);
> > +     }
> > +
> > +     init.name = "nct3018y-clkout";
> > +     init.ops = &nct3018y_clkout_ops;
> > +     init.flags = 0;
> > +     init.parent_names = NULL;
> > +     init.num_parents = 0;
> > +     nct3018y->clkout_hw.init = &init;
> > +
> > +     /* optional override of the clockname */
> > +     of_property_read_string(node, "clock-output-names", &init.name);
> > +
> > +     /* register the clock */
> > +     clk = devm_clk_register(&client->dev, &nct3018y->clkout_hw);
> > +
> > +     if (!IS_ERR(clk))
> > +             of_clk_add_provider(node, of_clk_src_simple_get, clk);
> > +
> > +     return clk;
> > +}
> > +#endif
> > +
> > +static const struct rtc_class_ops nct3018y_rtc_ops = {
> > +     .read_time      = nct3018y_rtc_read_time,
> > +     .set_time       = nct3018y_rtc_set_time,
> > +     .read_alarm     = nct3018y_rtc_read_alarm,
> > +     .set_alarm      = nct3018y_rtc_set_alarm,
> > +     .alarm_irq_enable = nct3018y_irq_enable,
> > +     .ioctl          = nct3018y_ioctl,
> > +};
> > +
> > +static int nct3018y_probe(struct i2c_client *client,
> > +                       const struct i2c_device_id *id)
> > +{
> > +     struct nct3018y *nct3018y;
> > +     int err, flags;
> > +
> > +     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
>
> Don't you rather need I2C_FUNC_SMBUS_BYTE and I2C_FUNC_SMBUS_BLOCK_DATA?
>
> > +             dev_err(&client->dev, "%s: ENODEV\n", __func__);
> > +             return -ENODEV;
> > +     }
> > +
> > +     nct3018y = devm_kzalloc(&client->dev, sizeof(struct nct3018y),
> > +                             GFP_KERNEL);
> > +     if (!nct3018y)
> > +             return -ENOMEM;
> > +
> > +     i2c_set_clientdata(client, nct3018y);
> > +     nct3018y->client = client;
> > +     device_set_wakeup_capable(&client->dev, 1);
> > +
> > +     flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
> > +     if (flags < 0) {
> > +             dev_err(&client->dev, "%s: read error\n", __func__);
> > +             return flags;
> > +     } else if (flags & NCT3018Y_BIT_TWO)
> > +             dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
> > +
> > +
> > +     flags = NCT3018Y_BIT_TWO;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
> > +             return err;
> > +     }
> > +
> > +     flags = 0;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "%s: write error\n", __func__);
> > +             return err;
> > +     }
> > +
> > +
> > +     nct3018y->rtc = devm_rtc_allocate_device(&client->dev);
> > +     if (IS_ERR(nct3018y->rtc))
> > +             return PTR_ERR(nct3018y->rtc);
> > +
> > +     nct3018y->rtc->ops = &nct3018y_rtc_ops;
> > +     nct3018y->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
> > +     nct3018y->rtc->range_max = RTC_TIMESTAMP_END_2099;
> > +
> > +     if (client->irq > 0) {
> > +             err = devm_request_threaded_irq(&client->dev, client->irq,
> > +                             NULL, nct3018y_irq,
> > +                             IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
> > +                             "nct3018y", client);
> > +             if (err) {
> > +                     dev_err(&client->dev, "unable to request IRQ %d\n", client->irq);
> > +                     return err;
> > +             }
> > +     }
>
> You need to clear RTC_FEATURE_UPDATE_INTERRUPT and RTC_FEATURE_ALARM
> from nct3018y->rtc->features when client->irq <= 0
>
> > +
> > +     return devm_rtc_register_device(nct3018y->rtc);
> > +
>
> > +#ifdef CONFIG_COMMON_CLK
> > +     /* register clk in common clk framework */
> > +     nct3018y_clkout_register_clk(nct3018y);
> > +#endif
> > +
>
> This code is not reachable anymore
>
> > +     return 0;
> > +}
> > +
> > +static const struct i2c_device_id nct3018y_id[] = {
> > +     { "nct3018y", 0 },
> > +     { }
> > +};
> > +MODULE_DEVICE_TABLE(i2c, nct3018y_id);
> > +
> > +
> > +static const struct of_device_id nct3018y_of_match[] = {
> > +     { .compatible = "nuvoton,nct3018y" },
> > +     {}
> > +};
> > +MODULE_DEVICE_TABLE(of, nct3018y_of_match);
> > +
> > +static struct i2c_driver nct3018y_driver = {
> > +     .driver         = {
> > +             .name   = "rtc-nct3018y",
> > +             .of_match_table = of_match_ptr(nct3018y_of_match),
> > +     },
> > +     .probe          = nct3018y_probe,
> > +     .id_table       = nct3018y_id,
> > +};
> > +
> > +module_i2c_driver(nct3018y_driver);
> > +
> > +MODULE_AUTHOR("Medad CChien <ctcchien@nuvoton.com>");
> > +MODULE_DESCRIPTION("Nuvoton NCT3018Y RTC driver");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.17.1
> >
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

B.R.
Medad

WARNING: multiple messages have this Message-ID (diff)
From: Medad Young <medadyoung@gmail.com>
To: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: linux-rtc@vger.kernel.org, a.zummo@towertech.it,
	YSCHU@nuvoton.com, Tomer Maimon <tmaimon77@gmail.com>,
	KWLIU@nuvoton.com, Avi Fishman <avifishman70@gmail.com>,
	Patrick Venture <venture@google.com>,
	OpenBMC Maillist <openbmc@lists.ozlabs.org>,
	KFTING <KFTING@nuvoton.com>,
	JJLIU0@nuvoton.com, ctcchien@nuvoton.com,
	Tali Perry <tali.perry1@gmail.com>,
	devicetree <devicetree@vger.kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	Mining Lin <mimi05633@gmail.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Benjamin Fair <benjaminfair@google.com>
Subject: Re: [PATCH v3 3/3] RTC: nuvoton: Add NCT3018Y real time clock driver
Date: Thu, 7 Jul 2022 13:30:59 +0800	[thread overview]
Message-ID: <CAHpyw9cdmCSZEE4ZbpnehpyvFhpPWA+_E5zXzJerNX9xqYet5Q@mail.gmail.com> (raw)
In-Reply-To: <YrYd+FkiFPz84twJ@mail.local>

Hello Alexandre,

Thanks for your comments.
I add Mining Lin <mimi05633@gmail.com> into this mail thread,
and she is going to follow up this RTC driver.
She will be in charge of maintaining this driver.

Alexandre Belloni <alexandre.belloni@bootlin.com> 於 2022年6月25日 週六 凌晨4:26寫道:
>
> Hello,
>
> Please run ./scripts/checkpatch.pl --strict on your patch, there are a
> bunch of issues.
>
> On 27/05/2022 16:46:47+0800, medadyoung@gmail.com wrote:
> > +static int nct3018y_set_alarm_mode(struct i2c_client *client, bool on)
> > +{
> > +     int err, flags;
> > +
> > +     dev_dbg(&client->dev, "%s:on:%d\n", __func__, on);
> > +
> > +     flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
> > +     if (flags < 0) {
> > +             dev_err(&client->dev,
> > +                     "Failed to read NCT3018Y_REG_CTRL\n");
>
> You should cut down on the number of error messages, they are usually
> not useful as the user doesn't have any specific action after getting
> one of them apart from trying the action once again. Also, this will
> make your code shorter. dev_dbg is fine.
>
> > +/*
> > + * In the routines that deal directly with the nct3018y hardware, we use
> > + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> > + */
> > +static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[10];
> > +     int err;
> > +
>
> You should still return an error if the time is invalid there but without
> an error message.
>
> > +     err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SC, sizeof(buf), buf);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     tm->tm_sec = bcd2bin(buf[0] & 0x7F);
> > +     tm->tm_min = bcd2bin(buf[2] & 0x7F);
> > +     tm->tm_hour = bcd2bin(buf[4] & 0x3F);
> > +     tm->tm_wday = buf[6] & 0x07;
> > +     tm->tm_mday = bcd2bin(buf[7] & 0x3F);
> > +     tm->tm_mon = bcd2bin(buf[8] & 0x1F) - 1;
> > +     tm->tm_year = bcd2bin(buf[9]) + 100;
> > +
> > +     return 0;
> > +}
> > +
> > +static int nct3018y_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[5];
> > +     int err;
> > +
> > +     err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SCA,
> > +                                         sizeof(buf), buf);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to read date\n");
> > +             return -EIO;
> > +     }
> > +
> > +     dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n",
> > +             __func__, buf[0], buf[2], buf[4]);
> > +
> > +     tm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
> > +     tm->time.tm_min = bcd2bin(buf[2] & 0x7F);
> > +     tm->time.tm_hour = bcd2bin(buf[4] & 0x3F);
> > +
> > +     err = nct3018y_get_alarm_mode(client, &tm->enabled, &tm->pending);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n",
> > +             __func__, tm->time.tm_sec, tm->time.tm_min,
> > +             tm->time.tm_hour, tm->enabled, tm->pending);
> > +
> > +     return 0;
> > +}
> > +
> > +static int nct3018y_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
> > +{
> > +     struct i2c_client *client = to_i2c_client(dev);
> > +     unsigned char buf[3];
> > +     int err;
> > +
> > +     dev_dbg(dev, "%s, sec=%d, min=%d hour=%d tm->enabled:%d\n",
> > +             __func__, tm->time.tm_sec, tm->time.tm_min, tm->time.tm_hour,
> > +             tm->enabled);
> > +
> > +     buf[0] = bin2bcd(tm->time.tm_sec);
> > +     buf[1] = bin2bcd(tm->time.tm_min);
> > +     buf[2] = bin2bcd(tm->time.tm_hour);
>
> I don't think buf is useful in this function
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SCA, buf[0]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_SCA\n");
> > +             return err;
> > +     }
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MNA, buf[1]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_MNA\n");
> > +             return err;
> > +     }
> > +
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HRA, buf[2]);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_HRA\n");
> > +             return err;
> > +     }
> > +
> > +     return nct3018y_set_alarm_mode(client, tm->enabled);
> > +}
> > +
>
>
> > +static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y)
> > +{
> > +     struct i2c_client *client = nct3018y->client;
> > +     struct device_node *node = client->dev.of_node;
> > +     struct clk *clk;
> > +     struct clk_init_data init;
> > +     int flags, err;
> > +
> > +     /* disable the clkout output */
> > +     flags = 0;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags);
>
> BTW, this introduces a glitch in the clock output if the clock is
> actually used. Maybe you could just rely on the CCF core to disable this
> clock when there are no users.
>
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write oscillator status register\n");
> > +             return ERR_PTR(err);
> > +     }
> > +
> > +     init.name = "nct3018y-clkout";
> > +     init.ops = &nct3018y_clkout_ops;
> > +     init.flags = 0;
> > +     init.parent_names = NULL;
> > +     init.num_parents = 0;
> > +     nct3018y->clkout_hw.init = &init;
> > +
> > +     /* optional override of the clockname */
> > +     of_property_read_string(node, "clock-output-names", &init.name);
> > +
> > +     /* register the clock */
> > +     clk = devm_clk_register(&client->dev, &nct3018y->clkout_hw);
> > +
> > +     if (!IS_ERR(clk))
> > +             of_clk_add_provider(node, of_clk_src_simple_get, clk);
> > +
> > +     return clk;
> > +}
> > +#endif
> > +
> > +static const struct rtc_class_ops nct3018y_rtc_ops = {
> > +     .read_time      = nct3018y_rtc_read_time,
> > +     .set_time       = nct3018y_rtc_set_time,
> > +     .read_alarm     = nct3018y_rtc_read_alarm,
> > +     .set_alarm      = nct3018y_rtc_set_alarm,
> > +     .alarm_irq_enable = nct3018y_irq_enable,
> > +     .ioctl          = nct3018y_ioctl,
> > +};
> > +
> > +static int nct3018y_probe(struct i2c_client *client,
> > +                       const struct i2c_device_id *id)
> > +{
> > +     struct nct3018y *nct3018y;
> > +     int err, flags;
> > +
> > +     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
>
> Don't you rather need I2C_FUNC_SMBUS_BYTE and I2C_FUNC_SMBUS_BLOCK_DATA?
>
> > +             dev_err(&client->dev, "%s: ENODEV\n", __func__);
> > +             return -ENODEV;
> > +     }
> > +
> > +     nct3018y = devm_kzalloc(&client->dev, sizeof(struct nct3018y),
> > +                             GFP_KERNEL);
> > +     if (!nct3018y)
> > +             return -ENOMEM;
> > +
> > +     i2c_set_clientdata(client, nct3018y);
> > +     nct3018y->client = client;
> > +     device_set_wakeup_capable(&client->dev, 1);
> > +
> > +     flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
> > +     if (flags < 0) {
> > +             dev_err(&client->dev, "%s: read error\n", __func__);
> > +             return flags;
> > +     } else if (flags & NCT3018Y_BIT_TWO)
> > +             dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
> > +
> > +
> > +     flags = NCT3018Y_BIT_TWO;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
> > +             return err;
> > +     }
> > +
> > +     flags = 0;
> > +     err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags);
> > +     if (err < 0) {
> > +             dev_err(&client->dev, "%s: write error\n", __func__);
> > +             return err;
> > +     }
> > +
> > +
> > +     nct3018y->rtc = devm_rtc_allocate_device(&client->dev);
> > +     if (IS_ERR(nct3018y->rtc))
> > +             return PTR_ERR(nct3018y->rtc);
> > +
> > +     nct3018y->rtc->ops = &nct3018y_rtc_ops;
> > +     nct3018y->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
> > +     nct3018y->rtc->range_max = RTC_TIMESTAMP_END_2099;
> > +
> > +     if (client->irq > 0) {
> > +             err = devm_request_threaded_irq(&client->dev, client->irq,
> > +                             NULL, nct3018y_irq,
> > +                             IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
> > +                             "nct3018y", client);
> > +             if (err) {
> > +                     dev_err(&client->dev, "unable to request IRQ %d\n", client->irq);
> > +                     return err;
> > +             }
> > +     }
>
> You need to clear RTC_FEATURE_UPDATE_INTERRUPT and RTC_FEATURE_ALARM
> from nct3018y->rtc->features when client->irq <= 0
>
> > +
> > +     return devm_rtc_register_device(nct3018y->rtc);
> > +
>
> > +#ifdef CONFIG_COMMON_CLK
> > +     /* register clk in common clk framework */
> > +     nct3018y_clkout_register_clk(nct3018y);
> > +#endif
> > +
>
> This code is not reachable anymore
>
> > +     return 0;
> > +}
> > +
> > +static const struct i2c_device_id nct3018y_id[] = {
> > +     { "nct3018y", 0 },
> > +     { }
> > +};
> > +MODULE_DEVICE_TABLE(i2c, nct3018y_id);
> > +
> > +
> > +static const struct of_device_id nct3018y_of_match[] = {
> > +     { .compatible = "nuvoton,nct3018y" },
> > +     {}
> > +};
> > +MODULE_DEVICE_TABLE(of, nct3018y_of_match);
> > +
> > +static struct i2c_driver nct3018y_driver = {
> > +     .driver         = {
> > +             .name   = "rtc-nct3018y",
> > +             .of_match_table = of_match_ptr(nct3018y_of_match),
> > +     },
> > +     .probe          = nct3018y_probe,
> > +     .id_table       = nct3018y_id,
> > +};
> > +
> > +module_i2c_driver(nct3018y_driver);
> > +
> > +MODULE_AUTHOR("Medad CChien <ctcchien@nuvoton.com>");
> > +MODULE_DESCRIPTION("Nuvoton NCT3018Y RTC driver");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.17.1
> >
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

B.R.
Medad

  reply	other threads:[~2022-07-07  5:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-27  8:46 [PATCH v3 0/3] RTC: nuvoton: Add nuvoton real time clock driver medadyoung
2022-05-27  8:46 ` medadyoung
2022-05-27  8:46 ` [PATCH v3 1/3] dt-bindings: rtc: nuvoton: add NCT3018Y Real Time Clock medadyoung
2022-05-27  8:46   ` medadyoung
2022-06-01 18:51   ` Rob Herring
2022-06-01 18:51     ` Rob Herring
2022-05-27  8:46 ` [PATCH v3 2/3] ARM: dts: nuvoton: Add nuvoton RTC3018Y node medadyoung
2022-05-27  8:46   ` medadyoung
2022-05-27  8:46 ` [PATCH v3 3/3] RTC: nuvoton: Add NCT3018Y real time clock driver medadyoung
2022-05-27  8:46   ` medadyoung
2022-06-24 20:26   ` Alexandre Belloni
2022-06-24 20:26     ` Alexandre Belloni
2022-07-07  5:30     ` Medad Young [this message]
2022-07-07  5:30       ` Medad Young
2022-07-07  7:17       ` Mining Lin
2022-07-07  7:52         ` Alexandre Belloni
2022-07-07  7:52           ` Alexandre Belloni
2022-07-07  9:36           ` Mining Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAHpyw9cdmCSZEE4ZbpnehpyvFhpPWA+_E5zXzJerNX9xqYet5Q@mail.gmail.com \
    --to=medadyoung@gmail.com \
    --cc=JJLIU0@nuvoton.com \
    --cc=KFTING@nuvoton.com \
    --cc=KWLIU@nuvoton.com \
    --cc=YSCHU@nuvoton.com \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=avifishman70@gmail.com \
    --cc=benjaminfair@google.com \
    --cc=ctcchien@nuvoton.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=mimi05633@gmail.com \
    --cc=openbmc@lists.ozlabs.org \
    --cc=robh+dt@kernel.org \
    --cc=tali.perry1@gmail.com \
    --cc=tmaimon77@gmail.com \
    --cc=venture@google.com \
    --cc=yuenn@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.