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

pinctrl: pinctrl-single: Fix pcs_request_gpio() when bits_per_mux != 0

This fixes pcs_request_gpio() in the pinctrl-single driver when
bits_per_mux != 0. It appears this was overlooked when the multiple
pins per register feature was added.

Fixes: 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules")
Signed-off-by: David Lechner <david@lechnology.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

David Lechner and committed by
Linus Walleij
45dcb54f 864670d5

+19 -3
+19 -3
drivers/pinctrl/pinctrl-single.c
··· 391 391 || pin < frange->offset) 392 392 continue; 393 393 mux_bytes = pcs->width / BITS_PER_BYTE; 394 - data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; 395 - data |= frange->gpiofunc; 396 - pcs->write(data, pcs->base + pin * mux_bytes); 394 + 395 + if (pcs->bits_per_mux) { 396 + int byte_num, offset, pin_shift; 397 + 398 + byte_num = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; 399 + offset = (byte_num / mux_bytes) * mux_bytes; 400 + pin_shift = pin % (pcs->width / pcs->bits_per_pin) * 401 + pcs->bits_per_pin; 402 + 403 + data = pcs->read(pcs->base + offset); 404 + data &= ~(pcs->fmask << pin_shift); 405 + data |= frange->gpiofunc << pin_shift; 406 + pcs->write(data, pcs->base + offset); 407 + } else { 408 + data = pcs->read(pcs->base + pin * mux_bytes); 409 + data &= ~pcs->fmask; 410 + data |= frange->gpiofunc; 411 + pcs->write(data, pcs->base + pin * mux_bytes); 412 + } 397 413 break; 398 414 } 399 415 return 0;