user2474374
user2474374

Reputation: 1

Error: initializer element is not constant - linux driver

I am really not able to solve this issue.

error: initializer element is not constant

error: (near initialization for tca6507_leds1.leds.num_leds)

I think the problem is related to struct led_info *leds inside led_platform_data. Is this somehow not a const since it is a pointer? I am particularly baffled since led_platform_data and led_info are part of the linux kernel. tca6507_platform_data is also a part of a driver that is included in the kernel source.

Here is my initialization:

static struct led_info tca6507_led_infos[] = {
    {
            .name                   = "left_blue",
            .default_trigger        = "heartbeat",
    },
};

static struct led_platform_data tca6507_leds2 = {
    .leds           = tca6507_led_infos,
};

struct tca6507_platform_data tca6507_leds1 = {
    .leds           = tca6507_leds1
};

All the structs are defined in header files that I did not write.

struct led_info {
    const char      *name;
    const char      *default_trigger;
    int             flags;
};

struct led_platform_data {
    int             num_leds;
    struct          led_info *leds;
};

struct tca6507_platform_data {
    struct led_platform_data leds;
#ifdef CONFIG_GPIOLIB
    int gpio_base;
    void (*setup)(unsigned gpio_base, unsigned ngpio);
#endif
};

Upvotes: 0

Views: 902

Answers (1)

torek
torek

Reputation: 488163

The problem is right in the middle of this three line bit:

struct tca6507_platform_data tca6507_leds1 = {
    .leds           = tca6507_leds1
};

What is the (compile time) value of tca6507_leds1? Note that it is a structure, not an array.

Compare that with the (valid):

static struct led_platform_data tca6507_leds2 = {
    .leds           = tca6507_led_infos,
};

What is the (compile time) value of tca6507_led_infos? (Note that it is an array, and the "value" of an array is the address of its first element.) And most importantly (perhaps I should not have buried the lede :-) ), compare with the (also valid):

static struct led_info tca6507_led_infos[] = {
    {
            .name                   = "left_blue",
            .default_trigger        = "heartbeat",
    },
};

Note that instead of using the value of a variable, the initializer here is a brace-enclosed list of items. This (like the failing case) is an instance of struct led_info, which must contain one actual struct led_platform_data instance (not a pointer to one-or-more, as is used in struct led_platform_data).


(The above is meant as an exercise. The answer is, the value of a structure is the value of the structure—but that is not a compile-time constant. Moreover, you are trying to use the value of the structure that you have not yet finished initializing in the first place. You need X to set X but you have to find X first, which you do by finding X, and there's no end to the recursion.)

Upvotes: 1

Related Questions