• Hans de Goede's avatar
    pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH) · 45c11a92
    Hans de Goede authored
    The pins on the Bay Trail SoC have separate input-buffer and output-buffer
    enable bits and a read of the level bit of the value register will always
    return the value from the input-buffer.
    
    The BIOS of a device may configure a pin in output-only mode, only enabling
    the output buffer, and write 1 to the level bit to drive the pin high.
    This 1 written to the level bit will be stored inside the data-latch of the
    output buffer.
    
    But a subsequent read of the value register will return 0 for the level bit
    because the input-buffer is disabled. This causes a read-modify-write as
    done by byt_gpio_set_direction() to write 0 to the level bit, driving the
    pin low!
    
    Before this commit byt_gpio_direction_output() relied on
    pinctrl_gpio_direction_output() to set the direction, followed by a call
    to byt_gpio_set() to apply the selected value. This causes the pin to
    go low between the pinctrl_gpio_direction_output() and byt_gpio_set()
    calls.
    
    Change byt_gpio_direction_output() to directly make the register
    modifications itself instead. Replacing the 2 subsequent writes to the
    value register with a single write.
    
    Note that the pinctrl code does not keep track internally of the direction,
    so not going through pinctrl_gpio_direction_output() is not an issue.
    
    This issue was noticed on a Trekstor SurfTab Twin 10.1. When the panel is
    already on at boot (no external monitor connected), then the i915 driver
    does a gpiod_get(..., GPIOD_OUT_HIGH) for the panel-enable GPIO. The
    temporarily going low of that GPIO was causing the panel to reset itself
    after which it would not show an image until it was turned off and back on
    again (until a full modeset was done on it). This commit fixes this.
    
    This commit also updates the byt_gpio_direction_input() to use direct
    register accesses instead of going through pinctrl_gpio_direction_input(),
    to keep it consistent with byt_gpio_direction_output().
    
    Note for backporting, this commit depends on:
    commit e2b74419 ("pinctrl: baytrail: Replace WARN with dev_info_once
    when setting direct-irq pin to output")
    
    Cc: stable@vger.kernel.org
    Fixes: 86e3ef81 ("pinctrl: baytrail: Update gpio chip operations")
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    45c11a92
pinctrl-baytrail.c 48.3 KB