Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: max730x: bring gpiochip_add_data after port config

gpiochip_add_data being called before might cause premature calls of
the gpiochip operations before the port_config values are initialized,
which would possibily write zeros to port configuration registers,
an operation not allowed. For example, if there are gpio-hog nodes
in a device-tree, the sequence of function calls are performed

gpiochip_add_data
of_gpiochip_add
of_gpiochip_scan_gpios
of_gpiochip_add_hog
gpiod_hog
gpiochip_request_own_desc
gpiod_configure_flags
gpiod_direction_output/gpiod_direction_input

which would call later the gpiochip operation direction_output or
direction_input prior the port_config[] initialization.

Moreover, gpiochip_get_data is replaced by the container_of macro
inside the gpiochip operations, which would allow the calling of
max7301_direction_input prior to gpiochip_add_data

Signed-off-by: Rodrigo Alencar <455.rodrigo.alencar@gmail.com>
[Bartosz: tweaked the commit message]
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>

authored by

Rodrigo Alencar and committed by
Bartosz Golaszewski
47a3734b 3831c051

+5 -7
+5 -7
drivers/gpio/gpio-max730x.c
··· 47 47 48 48 static int max7301_direction_input(struct gpio_chip *chip, unsigned offset) 49 49 { 50 - struct max7301 *ts = gpiochip_get_data(chip); 50 + struct max7301 *ts = container_of(chip, struct max7301, chip); 51 51 u8 *config; 52 52 u8 offset_bits, pin_config; 53 53 int ret; ··· 89 89 static int max7301_direction_output(struct gpio_chip *chip, unsigned offset, 90 90 int value) 91 91 { 92 - struct max7301 *ts = gpiochip_get_data(chip); 92 + struct max7301 *ts = container_of(chip, struct max7301, chip); 93 93 u8 *config; 94 94 u8 offset_bits; 95 95 int ret; ··· 189 189 ts->chip.parent = dev; 190 190 ts->chip.owner = THIS_MODULE; 191 191 192 - ret = gpiochip_add_data(&ts->chip, ts); 193 - if (ret) 194 - goto exit_destroy; 195 - 196 192 /* 197 193 * initialize pullups according to platform data and cache the 198 194 * register values for later use. ··· 210 214 } 211 215 } 212 216 213 - return ret; 217 + ret = gpiochip_add_data(&ts->chip, ts); 218 + if (!ret) 219 + return ret; 214 220 215 221 exit_destroy: 216 222 mutex_destroy(&ts->lock);