OpenNuvoton / NUC970_Linux_Kernel

Linux Kernel Source Code for NUC970 Series Microprocessor
Other
68 stars 69 forks source link

dts: confirm: #gpio-cells or gpio-cells #23

Closed qianfan-Zhao closed 6 years ago

qianfan-Zhao commented 6 years ago

I am try register a heart-beat led(on PE.4) by using device tree, but that's may be not easy.

device tree is like this:

/ {
    model = "Nuvoton NUC972 EVB";
    compatible = "nuvoton,nuc972-evb", "nuvoton,nuc972", "nuvoton,nuc970";

    leds {
        compatible = "gpio-leds";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_leds>;

        status-led {
            label = "status";
            gpios = <&gpio 0x44 0>;
            linux,default-trigger = "heartbeat";
        };
    };

    apb {
        pinctrl: pinctrl@b0000000 {
            status = "okay";

            boards {
                pinctrl_leds: leds {
                    nuvoton,pins = <4 4 0 0>; /* PE.4 as GPIO */
                };
            };
        };

after the kernel bootup, prompt that couldn't find gpio-cells. so i add a '#' in nuc970.dtsi

/leds/status-led: could not get #gpio-cells for /apb/gpio@b8003000
/leds/status-led: could not get #gpio-cells for /apb/gpio@b8003000
leds-gpio leds.4: Skipping unavailable LED gpio -22 (status)

now there doesn't have # problem, but register leds-gpio failed:

platform leds.4: Driver leds-gpio requests probe deferral
...
platform leds.4: Driver leds-gpio requests probe deferral
...
platform leds.4: Driver leds-gpio requests probe deferral
...

how to solve this problem?

qianfan-Zhao commented 6 years ago

I had changed i2c-gpio's state to 'okay' in nuc972-evb.dts, next is the log:

# dmesg | grep i2c
i2c_gpio_probe - pdev = i2c_gpio.2
platform i2c_gpio.2: Driver i2c-gpio requests probe deferral
i2c_gpio_probe - pdev = i2c_gpio.2
platform i2c_gpio.2: Driver i2c-gpio requests probe deferral
i2c_gpio_probe - pdev = i2c_gpio.2
platform i2c_gpio.2: Driver i2c-gpio requests probe deferral

the dts about gpio may have bug.

yachen commented 6 years ago

Hi,

Did you enable GPIO in dts/dtsi?

Sincerely,

Yi-An Chen

qianfan-Zhao commented 6 years ago

@yachen yes, the default gpio status in nuc970.dtsi is disabled, i2c-gpio was registed after i change gpio's status to okay.

but please check if we forget a '#' in the front of gpio-cells.

qianfan-Zhao commented 6 years ago

@yachen what's the relationship between gpios and nuvoton,pins ?

such as nuvoton,pins = <4 4 0 0>; / PE.4 as GPIO / the first 4 means PE, the next means pin 4, the first 0 means multi-function

list = of_get_property(np, "nuvoton,pins", &size);
    /* we do not check return since it's safe node passed down */
    size /= sizeof(*list);
    if (!size || size % 4) {
        dev_err(info->dev, "wrong setting!\n");
        return -EINVAL;
    }

    grp->npins = size / 4;
    pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct nuc970_pmx_pin), GFP_KERNEL);
    grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), GFP_KERNEL);
    if (!grp->pins_conf || !grp->pins)
        return -ENOMEM;

    for (i = 0, j = 0; i < size; i += 4, j++) {
        pin->bank = be32_to_cpu(*list++);
        pin->pin = be32_to_cpu(*list++);
        grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin;
        pin->func = be32_to_cpu(*list++);
        pin->conf = be32_to_cpu(*list++);

        nuc970_pin_dbg(info->dev, pin);
        pin++;
    }

i want register PE.4 as leds-gpio, so i add this to dts: gpios = <&gpio 0x44 0>; next is the log:

request gpio 0x44
Please Check GPIOC04's multi-function = 0x5
create_gpio_led: -22

in the fucntion nuc970_gpio_core_to_request try translate 0x44 to PX.X, there only 16 pins one group, but GPIO_OFFSET was defined as 0x20, it will translate 0x44 to PC.2, it's very ridiculous.

so if i want register PE.4, the number in gpios will be 4(menas PE) GPIO_OFFSET + 4(menas pin 4) = 4 32 + 4 = 132, is it right?

static int nuc970_gpio_core_to_request(struct gpio_chip *chip, unsigned offset)
{
    unsigned int group,num1,num,reg,value;
    group = offset / GPIO_OFFSET;
    num1  = num = offset % GPIO_OFFSET;
    reg   = (unsigned int)REG_MFP_GPA_L+(group* 0x08);
    if(num>7)
    {
        num -= 8;
        reg = reg + 0x04 ;
    }

    value = ( __raw_readl((volatile unsigned int *)reg) & (0xf<<(num*4)))>>(num*4);
    if(value != 0)
    {
            printk(KERN_ERR "Please Check GPIO%c%02d's multi-function = 0x%x \n",(char)(65+group),num1,value);
            return -EINVAL;
    }
    return 0;
}
schung1218 commented 6 years ago

@zhaozhongchen 1 nuvoton,pins = <4 4 0 0> ,1st : group, 2nd : pin number, 3rd: multi-function, 4th: dummy( always 0 )

2 GPIO driver will keep 32 numbers for each group of GPIO from port A to port J. So the number for the GPIOA will be 0x000 - 0x01F, GPIOB will be 0x020 - 0x03F, GPIOC will be 0x040 - 0x05F, GPIOD will be 0x060 - 0x07F, GPIOE will be 0x080 - 0x09F, GPIOF will be 0x0A0 - 0x0BF, GPIOG will be 0x0C0 - 0x0DF, GPIOH will be 0x0E0 - 0x0FF, GPIOI will be 0x100 - 0x11F and GPIOJ will be 0x120 - 0x13F, so PE4 number is 0x84(132)