[PATCH v1] Cubieboard2:Fix Cubieboard2 freeze, when LED boot enabled
Javad Rahimi
javad321javad at gmail.com
Fri Dec 10 04:00:17 CET 2021
On Thu, Dec 9, 2021 at 7:18 PM Andre Przywara <andre.przywara at arm.com> wrote:
Hi Andre,
>
> On Thu, 9 Dec 2021 18:50:06 +0330
> Javad Rahimi <javad321javad at gmail.com> wrote:
>
> Hi Javad,
>
> thanks for the patch!
>
> > When enabling the LED support for Cubieboard2 (SUN7I)
> > the uboot freezes in status_led_init() function.
> > It uses a static global variable, while the .BSS is defined in DRAM area
> > while that function is called before DRAM
>
> So I'd say that the commit message and the subject is misleading, it's not
> a real fix, because nothing was really broken before. That fact that sunxi
> puts the BSS into DRAM, even when this is not available at the very
> beginning, is more a nasty workaround than a feature.
>
> So can you please reword the commit message, to focus on what this patch
> actually does, and mention that this allow to get rid of a global
> variable. And then just briefly mention that it helps sunxi to enable LEDs
> early, as a motivation.
>
> Some things below ....
>
Sure, I will change the patch title and will present what exactly this patch
is doing and why it should be done.
> > Signed-off-by: Javad Rahimi <javad321javad at gmail.com>
> > ---
> >
> > drivers/misc/status_led.c | 28 +++++++++++++++++++---------
> > 1 file changed, 19 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c
> > index a6e9c03a02..7d30355423 100644
> > --- a/drivers/misc/status_led.c
> > +++ b/drivers/misc/status_led.c
> > @@ -23,6 +23,7 @@ typedef struct {
> > int state;
> > int period;
> > int cnt;
> > + int initialized:1;
>
> This bitfield doesn't really help here, since the compiler will pad it
> with 31 more bits. So just make it a "bool", and let the compiler figure
> out what's best here.
> Or can you check whether you can fold this bit into the "state" variable?
> By introducing something like an "uninitialised" state? Or is there is
> another way to detect initialisation (period != 0)?
>
Exactly, I will try to fold it into the "state" variable. Because only
one bit of this
variable is used. Other bit fields are free to be used.
> > } led_dev_t;
> >
> > led_dev_t led_dev[] = {
> > @@ -30,12 +31,14 @@ led_dev_t led_dev[] = {
> > CONFIG_LED_STATUS_STATE,
> > LED_STATUS_PERIOD,
> > 0,
> > + 0,
> > },
> > #if defined(CONFIG_LED_STATUS1)
> > { CONFIG_LED_STATUS_BIT1,
> > CONFIG_LED_STATUS_STATE1,
> > LED_STATUS_PERIOD1,
> > 0,
> > + 0,
> > },
> > #endif
> > #if defined(CONFIG_LED_STATUS2)
> > @@ -43,6 +46,7 @@ led_dev_t led_dev[] = {
> > CONFIG_LED_STATUS_STATE2,
> > LED_STATUS_PERIOD2,
> > 0,
> > + 0,
> > },
> > #endif
> > #if defined(CONFIG_LED_STATUS3)
> > @@ -50,6 +54,7 @@ led_dev_t led_dev[] = {
> > CONFIG_LED_STATUS_STATE3,
> > LED_STATUS_PERIOD3,
> > 0,
> > + 0,
> > },
> > #endif
> > #if defined(CONFIG_LED_STATUS4)
> > @@ -57,6 +62,7 @@ led_dev_t led_dev[] = {
> > CONFIG_LED_STATUS_STATE4,
> > LED_STATUS_PERIOD4,
> > 0,
> > + 0,
> > },
> > #endif
> > #if defined(CONFIG_LED_STATUS5)
> > @@ -64,22 +70,26 @@ led_dev_t led_dev[] = {
> > CONFIG_LED_STATUS_STATE5,
> > LED_STATUS_PERIOD5,
> > 0,
> > + 0,
> > },
> > #endif
> > };
> >
> > #define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
> >
> > -static int status_led_init_done = 0;
> >
> > void status_led_init(void)
> > {
> > led_dev_t *ld;
> > int i;
> >
> > - for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
> > + for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
> > __led_init (ld->mask, ld->state);
> > - status_led_init_done = 1;
> > + ld->initialized = 1;
> > + }
> > +
> > + return 0;
> > +
> > }
> >
> > void status_led_tick(ulong timestamp)
> > @@ -87,11 +97,11 @@ void status_led_tick(ulong timestamp)
> > led_dev_t *ld;
> > int i;
> >
> > - if (!status_led_init_done)
> > - status_led_init();
> > -
> > for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
> >
> > + if (!ld->initialized)
> > + continue;
>
> But this is not what the current code does, is it? At the moment a call to
> status_led_tick() would initialise all LEDs, now you just skip over (all
> of) them?
>
Right, I missed calling "status_led_init" before for loop.
Because I thought "status_led_init" is called before
any LED I/O manipulation.
If these functions are called without calling "status_led_init"
the initialization should be done, However, I think it may be a
bad practice to call any I/O handling function without doing
some initialization.
> > +
> > if (ld->state != CONFIG_LED_STATUS_BLINKING)
> > continue;
> >
> > @@ -110,11 +120,11 @@ void status_led_set(int led, int state)
> > if (led < 0 || led >= MAX_LED_DEV)
> > return;
> >
> > - if (!status_led_init_done)
> > - status_led_init();
> > -
> > ld = &led_dev[led];
> >
> > + if (!ld->initialized)
> > + return;
>
> Same here, I think?
Same as above :)
>
> Cheers,
> Andre
>
> > ld->state = state;
> > if (state == CONFIG_LED_STATUS_BLINKING) {
> > ld->cnt = 0; /* always start with full period */
>
More information about the U-Boot
mailing list