REGRESSION: [PATCH v5 3/3] gpiolib: Show correct direction from the beginning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2018-10-05 at 08:53 +0200, Ricardo Ribalda Delgado wrote:
> Current code assumes that the direction is input if direction_input
> function is set.
> This might not be the case on GPIOs with programmable direction.

Unfortunately, this breaks at least Apalis T30 and Apalis TK1. Enabling
earlycon reveals the following:

[    0.721165] Unable to handle kernel NULL pointer dereference at
virtual addre
ss 000001f8
[    0.729570] pgd = (ptrval)
[    0.732417] [000001f8] *pgd=00000000
[    0.736137] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[    0.741643] Modules linked in:
[    0.744819] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.0-rc7-
next-2018101
2 #6
[    0.752579] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[    0.759092] PC is at gpiod_hog+0x2c/0x150
[    0.763255] LR is at of_gpiochip_add+0x34c/0x510
[    0.768040] pc : [<c044c9a4>]    lr : [<c044e840>]    psr: 60000013
[    0.774534] sp : f68c9cd0  ip : 00000000  fp : f68c9d18
[    0.779946] r10: c0ccb3c8  r9 : 00000000  r8 : 00000000
[    0.785359] r7 : 00000007  r6 : c20019c4  r5 : f6a7b970  r4 :
f6a78a24
[    0.792121] r3 : 00000000  r2 : 00000000  r1 : c20019c4  r0 :
f6a7b970
[    0.798884] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA
ARM  Segment none
[    0.806273] Control: 10c5387d  Table: 8000404a  DAC: 00000051
[    0.812227] Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
[    0.818451] Stack: (0xf68c9cd0 to 0xf68ca000)
...
[    1.043490] [<c044c9a4>] (gpiod_hog) from [<c044e840>]
(of_gpiochip_add+0x34c/0x510)
[    1.051531] [<c044e840>] (of_gpiochip_add) from [<c044d1cc>]
(gpiochip_add_data_with_key+0x668/0x958)
[    1.061091] [<c044d1cc>] (gpiochip_add_data_with_key) from
[<c044d504>] (devm_gpiochip_add_data+0x48/0x84)
[    1.071109] [<c044d504>] (devm_gpiochip_add_data) from [<c045166c>]
(tegra_gpio_probe+0x2d4/0x420)
[    1.080413] [<c045166c>] (tegra_gpio_probe) from [<c0574040>]
(platform_drv_probe+0x48/0x98)
[    1.089171] [<c0574040>] (platform_drv_probe) from [<c0572164>]
(really_probe+0x1e0/0x2cc)
[    1.097746] [<c0572164>] (really_probe) from [<c05723b4>]
(driver_probe_device+0x60/0x16c)
[    1.106317] [<c05723b4>] (driver_probe_device) from [<c057259c>]
(__driver_attach+0xdc/0xe0)
[    1.115071] [<c057259c>] (__driver_attach) from [<c05704a8>]
(bus_for_each_dev+0x74/0xb4)
[    1.123554] [<c05704a8>] (bus_for_each_dev) from [<c0571644>]
(bus_add_driver+0x1c0/0x204)
[    1.132122] [<c0571644>] (bus_add_driver) from [<c05731b8>]
(driver_register+0x74/0x108)
[    1.140521] [<c05731b8>] (driver_register) from [<c0102ebc>]
(do_one_initcall+0x54/0x284)
[    1.149015] [<c0102ebc>] (do_one_initcall) from [<c0e01134>]
(kernel_init_freeable+0x2d0/0x364)
[    1.158043] [<c0e01134>] (kernel_init_freeable) from [<c0a24c78>]
(kernel_init+0x8/0x110)
[    1.166527] [<c0a24c78>] (kernel_init) from [<c01010e8>]
(ret_from_fork+0x14/0x2c)
[    1.174375] Exception stack(0xf68c9fb0 to 0xf68c9ff8)
...

Just reverting this one patch made it boot again. I will investigate
further...

> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@xxxxxxxxx>
> ---
>  drivers/gpio/gpiolib.c | 27 +++++++++++++--------------
>  1 file changed, 13 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 907019b67a58..e016b22658ff 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1349,20 +1349,6 @@ int gpiochip_add_data_with_key(struct
> gpio_chip *chip, void *data,
>  
>  	spin_unlock_irqrestore(&gpio_lock, flags);
>  
> -	for (i = 0; i < chip->ngpio; i++) {
> -		struct gpio_desc *desc = &gdev->descs[i];
> -
> -		desc->gdev = gdev;
> -
> -		/* REVISIT: most hardware initializes GPIOs as
> inputs (often
> -		 * with pullups enabled) so power usage is
> minimized. Linux
> -		 * code should set the gpio direction first thing;
> but until
> -		 * it does, and in case chip->get_direction is not
> set, we may
> -		 * expose the wrong direction in sysfs.
> -		 */
> -		desc->flags = !chip->direction_input ? (1 <<
> FLAG_IS_OUT) : 0;
> -	}
> -
>  #ifdef CONFIG_PINCTRL
>  	INIT_LIST_HEAD(&gdev->pin_ranges);
>  #endif
> @@ -1391,6 +1377,19 @@ int gpiochip_add_data_with_key(struct
> gpio_chip *chip, void *data,
>  	if (status)
>  		goto err_remove_chip;
>  
> +	for (i = 0; i < chip->ngpio; i++) {
> +		struct gpio_desc *desc = &gdev->descs[i];
> +
> +		desc->gdev = gdev;
> +
> +		if (chip->get_direction &&
> gpiochip_line_is_valid(chip, i))
> +			desc->flags = !chip->get_direction(chip, i)
> ?
> +					(1 << FLAG_IS_OUT) : 0;
> +		else
> +			desc->flags = !chip->direction_input ?
> +					(1 << FLAG_IS_OUT) : 0;
> +	}
> +
>  	acpi_gpiochip_add(chip);
>  
>  	machine_gpiochip_add(chip);




[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux