public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Christian Marangi <ansuelsmth@gmail.com>
To: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>,
	Joe Hershberger <joe.hershberger@ni.com>,
	Ramon Fried <rfried.dev@gmail.com>,
	Michal Simek <michal.simek@amd.com>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	AKASHI Takahiro <akashi.tkhro@gmail.com>,
	Sean Anderson <seanga2@gmail.com>,
	Ashok Reddy Soma <ashok.reddy.soma@amd.com>,
	Eddie James <eajames@linux.ibm.com>,
	Mattijs Korpershoek <mkorpershoek@baylibre.com>,
	Yang Xiwen <forbidden405@outlook.com>,
	Caleb Connolly <caleb.connolly@linaro.org>,
	Dario Binacchi <dario.binacchi@amarulasolutions.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Arseniy Krasnov <avkrasnov@salutedevices.com>,
	Heiko Schocher <hs@denx.de>,
	Alexey Romanov <avromanov@salutedevices.com>,
	Martin Kurbanov <mmkurbanov@salutedevices.com>,
	Michael Trimarchi <michael@amarulasolutions.com>,
	Rasmus Villemoes <rasmus.villemoes@prevas.dk>,
	Artur Rojek <artur@conclusive.pl>,
	Leo Yu-Chi Liang <ycliang@andestech.com>,
	Vasileios Amoiridis <vassilisamir@gmail.com>,
	Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>,
	Michael Polyntsov <michael.polyntsov@iopsys.eu>,
	Doug Zobel <douglas.zobel@climate.com>,
	Marek Vasut <marex@denx.de>,
	u-boot@lists.denx.de, John Crispin <john@phrozen.org>
Subject: Re: [PATCH v4 03/11] led: implement LED boot API
Date: Sun, 29 Sep 2024 14:48:04 +0200	[thread overview]
Message-ID: <66f94c89.5d0a0220.286c21.6077@mx.google.com> (raw)
In-Reply-To: <CAFLszThtgGo9aszNyB45rBbWB1FPsiao1CKeiAARZnGqDhc2jA@mail.gmail.com>

On Thu, Sep 26, 2024 at 11:33:18PM +0200, Simon Glass wrote:
> Hi Christian,
> 
> On Sat, 21 Sept 2024 at 00:51, Christian Marangi <ansuelsmth@gmail.com> wrote:
> >
> > Implement LED boot API to signal correct boot of the system.
> >
> > led_boot_on/off/blink() are introduced to turn ON, OFF and BLINK the
> > designated boot LED.
> >
> > New Kconfig is introduced, CONFIG_LED_BOOT to enable the feature.
> > This makes use of the /options/u-boot property "boot-led" to the
> > define the boot LED.
> > It's also introduced a new /options/u-boot property "boot-led-period"
> > to define the default period when the LED is set to blink mode.
> >
> > If "boot-led-period" is not defined, the value of 250 (ms) is
> > used by default.
> >
> > If CONFIG_LED_BLINK or CONFIG_LED_SW_BLINK is not enabled,
> > led_boot_blink call will fallback to simple LED ON.
> >
> > To cache the data we repurpose the now unused led_uc_priv for storage of
> > global LED uclass info.
> 
> Some things to tweak below
> 

Hi, thanks for the review. I asked some clarification, thanks for any
comments.

> >
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >  drivers/led/Kconfig      |   7 +++
> >  drivers/led/led-uclass.c | 100 +++++++++++++++++++++++++++++++++++++++
> >  include/led.h            |  56 +++++++++++++++++++++-
> >  3 files changed, 161 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> > index bee74b25751..6149cfa02b8 100644
> > --- a/drivers/led/Kconfig
> > +++ b/drivers/led/Kconfig
> > @@ -9,6 +9,13 @@ config LED
> >           can provide access to board-specific LEDs. Use of the device tree
> >           for configuration is encouraged.
> >
> > +config LED_BOOT
> > +       bool "Enable LED boot support"
> > +       help
> > +         Enable LED boot support.
> > +
> > +         LED boot is a specific LED assigned to signal boot operation status.
> 
> Here you should link to the /options binding in
> doc/device-tree-bindings/options, perhaps
>

Ok.

> > +
> >  config LED_BCM6328
> >         bool "LED Support for BCM6328"
> >         depends on LED && ARCH_BMIPS
> > diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
> > index 199d68bc25a..c5b560982b0 100644
> > --- a/drivers/led/led-uclass.c
> > +++ b/drivers/led/led-uclass.c
> > @@ -94,17 +94,101 @@ int led_set_period(struct udevice *dev, int period_ms)
> >         return -ENOSYS;
> >  }
> >
> > +#ifdef CONFIG_LED_BOOT
> > +int led_boot_on(void)
> > +{
> > +       struct uclass *uc = uclass_find(UCLASS_LED);
> > +       struct led_uc_priv *priv;
> > +       struct udevice *dev;
> > +
> > +       if (!uc)
> > +               return -ENOENT;
> > +
> 
> The normal way is:
> 
> ret = uclass_first_device_ret(UCLASS_LED, &dev);
> if (ret)
>    return ret;
> 
> > +       priv = uclass_get_priv(uc);
> > +       if (!priv->boot_led_dev ||
> > +           uclass_get_device_tail(priv->boot_led_dev, 0, &dev)) {
> 
> That is an internal function...I suppose it should really have an
> underscore and be in uclass-internal.h
> 
> But if you are looking for boot_led_label, don't you need to search
> through the LEDs to find it? Or use led_get_by_label() ?
> 

Idea here and up is to cache the dev on bind to prevent
useless/additional loop on search in each UCLASS LED the boot LED.

uclass_get_device_tail is needed to actually trigger probe of the LED if
it hasn't been done prev.

The uclass_get_priv is followed by the rkmtd_get_cur_dev()
implementation, for the sake of getting the UCLASS alone it seems too
much to have all the additional operation to get the first device.

Also considering uclass_get_device_tail is also used by get_by_label I
assume it's ok to also use it here.

Should I ignore caching the dev and just search for the boot LED from
label everytime out of simplicity?

> > +               printf("Failed to get boot LED %s\n",
> > +                      priv->boot_led_label);
> > +               return -EINVAL;
> > +       }
> > +
> > +       return led_set_state(dev, LEDST_ON);
> > +}
> > +
> > +int led_boot_off(void)
> > +{
> > +       struct uclass *uc = uclass_find(UCLASS_LED);
> > +       struct led_uc_priv *priv;
> > +       struct udevice *dev;
> > +
> > +       if (!uc)
> > +               return -ENOENT;
> > +
> 
> Same here.
> 
> > +       priv = uclass_get_priv(uc);
> > +       if (!priv->boot_led_dev ||
> > +           uclass_get_device_tail(priv->boot_led_dev, 0, &dev)) {
> > +               printf("Failed to get boot LED %s\n",
> > +                      priv->boot_led_label);
> > +               return -EINVAL;
> > +       }
> > +
> > +       return led_set_state(dev, LEDST_OFF);
> > +}
> > +
> > +#if defined(CONFIG_LED_BLINK) || defined(CONFIG_LED_SW_BLINK)
> > +int led_boot_blink(void)
> > +{
> > +       struct uclass *uc = uclass_find(UCLASS_LED);
> > +       struct led_uc_priv *priv;
> > +       struct udevice *dev;
> > +       int ret;
> > +
> > +       if (!uc)
> > +               return -ENOENT;
> > +
> > +       priv = uclass_get_priv(uc);
> > +       if (!priv->boot_led_dev ||
> > +           uclass_get_device_tail(priv->boot_led_dev, 0, &dev)) {
> > +               printf("Failed to get boot LED %s\n",
> > +                      priv->boot_led_label);
> > +               return -EINVAL;
> > +       }
> 
> This looks like the same code again. I think it should be in a
> function so the code is not repeated.
> 
> > +
> > +       ret = led_set_period(dev, priv->boot_led_period);
> > +       if (ret) {
> > +               if (ret != -ENOSYS)
> > +                       return ret;
> > +
> > +               /* fallback to ON with no set_period and no SW_BLINK */
> > +               return led_set_state(dev, LEDST_ON);
> > +       }
> > +
> > +       return led_set_state(dev, LEDST_BLINK);
> > +}
> > +#endif
> > +#endif
> > +
> >  static int led_post_bind(struct udevice *dev)
> >  {
> >         struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
> >         const char *default_state;
> >
> > +#ifdef CONFIG_LED_BOOT
> > +       struct led_uc_priv *priv = uclass_get_priv(dev->uclass);
> > +#endif
> > +
> >         if (!uc_plat->label)
> >                 uc_plat->label = dev_read_string(dev, "label");
> >
> >         if (!uc_plat->label && !dev_read_string(dev, "compatible"))
> >                 uc_plat->label = ofnode_get_name(dev_ofnode(dev));
> >
> > +#ifdef CONFIG_LED_BOOT
> > +       /* check if we are binding boot LED and assign it */
> > +       if (!strcmp(priv->boot_led_label, uc_plat->label))
> > +               priv->boot_led_dev = dev;
> > +#endif
> > +
> >         uc_plat->default_state = LEDST_COUNT;
> >
> >         default_state = dev_read_string(dev, "default-state");
> > @@ -158,10 +242,26 @@ static int led_post_probe(struct udevice *dev)
> >         return ret;
> >  }
> >
> > +#ifdef CONFIG_LED_BOOT
> > +static int led_init(struct uclass *uc)
> > +{
> > +       struct led_uc_priv *priv = uclass_get_priv(uc);
> > +
> > +       priv->boot_led_label = ofnode_options_read_str("boot-led");
> > +       priv->boot_led_period = ofnode_options_read_int("boot-led-period", 250);
> > +
> > +       return 0;
> > +}
> > +#endif
> > +
> >  UCLASS_DRIVER(led) = {
> >         .id             = UCLASS_LED,
> >         .name           = "led",
> >         .per_device_plat_auto   = sizeof(struct led_uc_plat),
> >         .post_bind      = led_post_bind,
> >         .post_probe     = led_post_probe,
> > +#ifdef CONFIG_LED_BOOT
> > +       .init           = led_init,
> > +       .priv_auto      = sizeof(struct led_uc_priv),
> > +#endif
> 
> I don't love all these #ifdefs but I suppose it is OK here. Ideally we
> would have static inline accessors for the fields, in the header file,
> e.g. like asm-generic/global_data.h
> 

Didn't know of the global_data but then I read the comments and it seems
we should not really pollute it with too much stuff. Also considering
most of the LED are driven with gpio the possibility of having this that
early on boot might be closer to 0.

> >  };
> > diff --git a/include/led.h b/include/led.h
> > index 99f93c5ef86..ca495217777 100644
> > --- a/include/led.h
> > +++ b/include/led.h
> > @@ -9,6 +9,7 @@
> >
> >  #include <stdbool.h>
> >  #include <cyclic.h>
> > +#include <dm/ofnode.h>
> >
> >  struct udevice;
> >
> > @@ -52,10 +53,16 @@ struct led_uc_plat {
> >  /**
> >   * struct led_uc_priv - Private data the uclass stores about each device
> >   *
> > - * @period_ms: Flash period in milliseconds
> > + * @boot_led_label:    Boot LED label
> > + * @boot_led_dev:      Boot LED dev
> > + * @boot_led_period:   Boot LED blink period
> >   */
> >  struct led_uc_priv {
> > -       int period_ms;
> > +#ifdef CONFIG_LED_BOOT
> > +       const char *boot_led_label;
> > +       struct udevice *boot_led_dev;
> > +       int boot_led_period;
> > +#endif
> >  };
> >
> >  struct led_ops {
> > @@ -141,4 +148,49 @@ int led_sw_set_period(struct udevice *dev, int period_ms);
> >  bool led_sw_is_blinking(struct udevice *dev);
> >  bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state);
> >
> > +#ifdef CONFIG_LED_BOOT
> > +
> > +/**
> > + * led_boot_on() - turn ON the designated LED for booting
> > + *
> > + * Return: 0 if OK, -ve on error
> > + */
> > +int led_boot_on(void);
> > +
> > +/**
> > + * led_boot_off() - turn OFF the designated LED for booting
> > + *
> > + * Return: 0 if OK, -ve on error
> > + */
> > +int led_boot_off(void);
> > +
> > +#if defined(CONFIG_LED_BLINK) || defined(CONFIG_LED_SW_BLINK)
> > +/**
> > + * led_boot_blink() - turn ON the designated LED for booting
> > + *
> > + * Return: 0 if OK, -ve on error
> > + */
> > +int led_boot_blink(void);
> > +
> > +#else
> > +/* If LED BLINK is not supported/enabled, fallback to LED ON */
> > +#define led_boot_blink led_boot_on
> > +#endif
> > +#else
> > +static inline int led_boot_on(void)
> > +{
> > +       return -ENOSYS;
> > +}
> > +
> > +static inline int led_boot_off(void)
> > +{
> > +       return -ENOSYS;
> > +}
> > +
> > +static inline int led_boot_blink(void)
> > +{
> > +       return -ENOSYS;
> > +}
> > +#endif
> > +
> >  #endif
> > --
> > 2.45.2
> >
> 
> Regards,
> Simon

-- 
	Ansuel

  reply	other threads:[~2024-09-29 12:48 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-20 22:49 [PATCH v4 00/11] led: introduce LED boot and activity function Christian Marangi
2024-09-20 22:49 ` [PATCH v4 01/11] led: toggle LED on initial SW blink Christian Marangi
2024-09-21 11:14   ` Michael Nazzareno Trimarchi
2024-09-22 16:15     ` Christian Marangi
2024-09-20 22:49 ` [PATCH v4 02/11] dm: core: implement ofnode_options helpers Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:49 ` [PATCH v4 03/11] led: implement LED boot API Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-29 12:48     ` Christian Marangi [this message]
2024-09-20 22:49 ` [PATCH v4 04/11] common: board_r: rework BOOT LED handling Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:49 ` [PATCH v4 05/11] led: implement LED activity API Christian Marangi
2024-09-20 22:49 ` [PATCH v4 06/11] tftp: implement support for LED activity Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:50 ` [PATCH v4 07/11] mtd: " Christian Marangi
2024-09-21 10:13   ` Miquel Raynal
2024-09-21 10:22     ` Christian Marangi
2024-09-20 22:50 ` [PATCH v4 08/11] ubi: " Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:50 ` [PATCH v4 09/11] doc: introduce led.rst documentation Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:50 ` [PATCH v4 10/11] test: dm: Add tests for LED boot and activity Christian Marangi
2024-09-26 21:33   ` Simon Glass
2024-09-20 22:50 ` [PATCH v4 11/11] test: dm: Expand ofnode options test with new helper Christian Marangi
2024-09-26 21:33   ` Simon Glass

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=66f94c89.5d0a0220.286c21.6077@mx.google.com \
    --to=ansuelsmth@gmail.com \
    --cc=akashi.tkhro@gmail.com \
    --cc=artur@conclusive.pl \
    --cc=ashok.reddy.soma@amd.com \
    --cc=avkrasnov@salutedevices.com \
    --cc=avromanov@salutedevices.com \
    --cc=caleb.connolly@linaro.org \
    --cc=dario.binacchi@amarulasolutions.com \
    --cc=douglas.zobel@climate.com \
    --cc=eajames@linux.ibm.com \
    --cc=forbidden405@outlook.com \
    --cc=hs@denx.de \
    --cc=ilias.apalodimas@linaro.org \
    --cc=joe.hershberger@ni.com \
    --cc=john@phrozen.org \
    --cc=marex@denx.de \
    --cc=michael.polyntsov@iopsys.eu \
    --cc=michael@amarulasolutions.com \
    --cc=michal.simek@amd.com \
    --cc=mikhail.kshevetskiy@iopsys.eu \
    --cc=miquel.raynal@bootlin.com \
    --cc=mkorpershoek@baylibre.com \
    --cc=mmkurbanov@salutedevices.com \
    --cc=rasmus.villemoes@prevas.dk \
    --cc=rfried.dev@gmail.com \
    --cc=seanga2@gmail.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=vassilisamir@gmail.com \
    --cc=xypron.glpk@gmx.de \
    --cc=ycliang@andestech.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox