All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Hans de Goede <hdegoede@redhat.com>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Sudip Mukherjee <sudipm.mukherjee@gmail.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.4 02/54] pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH)
Date: Thu, 10 Dec 2020 15:26:39 +0100	[thread overview]
Message-ID: <20201210142602.166196368@linuxfoundation.org> (raw)
In-Reply-To: <20201210142602.037095225@linuxfoundation.org>

From: Hans de Goede <hdegoede@redhat.com>

commit 156abe2961601d60a8c2a60c6dc8dd6ce7adcdaf upstream

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 e2b74419e5cc ("pinctrl: baytrail: Replace WARN with dev_info_once
when setting direct-irq pin to output")

Cc: stable@vger.kernel.org
Fixes: 86e3ef812fe3 ("pinctrl: baytrail: Update gpio chip operations")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[sudip: use byt_gpio and vg->pdev->dev for dev_info()]
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/pinctrl/intel/pinctrl-baytrail.c | 67 +++++++++++++++++++-----
 1 file changed, 53 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 326e85f0f3ab5..5a1174a8e2bac 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -811,6 +811,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
 	pm_runtime_put(&vg->pdev->dev);
 }
 
+static void byt_gpio_direct_irq_check(struct byt_gpio *vg,
+				      unsigned int offset)
+{
+	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+
+	/*
+	 * Before making any direction modifications, do a check if gpio is set
+	 * for direct IRQ. On Bay Trail, setting GPIO to output does not make
+	 * sense, so let's at least inform the caller before they shoot
+	 * themselves in the foot.
+	 */
+	if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
+		dev_info_once(&vg->pdev->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
+}
+
 static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
 				  struct pinctrl_gpio_range *range,
 				  unsigned int offset,
@@ -818,7 +833,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
 {
 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
-	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
 	unsigned long flags;
 	u32 value;
 
@@ -828,14 +842,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
 	value &= ~BYT_DIR_MASK;
 	if (input)
 		value |= BYT_OUTPUT_EN;
-	else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
-		/*
-		 * Before making any direction modifications, do a check if gpio
-		 * is set for direct IRQ.  On baytrail, setting GPIO to output
-		 * does not make sense, so let's at least inform the caller before
-		 * they shoot themselves in the foot.
-		 */
-		dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
+	else
+		byt_gpio_direct_irq_check(vg, offset);
 
 	writel(value, val_reg);
 
@@ -1176,19 +1184,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
 
 static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
 {
-	return pinctrl_gpio_direction_input(chip->base + offset);
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 reg;
+
+	raw_spin_lock_irqsave(&byt_lock, flags);
+
+	reg = readl(val_reg);
+	reg &= ~BYT_DIR_MASK;
+	reg |= BYT_OUTPUT_EN;
+	writel(reg, val_reg);
+
+	raw_spin_unlock_irqrestore(&byt_lock, flags);
+	return 0;
 }
 
+/*
+ * Note despite the temptation this MUST NOT be converted into a call to
+ * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
+ * MUST be done as a single BYT_VAL_REG register write.
+ * See the commit message of the commit adding this comment for details.
+ */
 static int byt_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned int offset, int value)
 {
-	int ret = pinctrl_gpio_direction_output(chip->base + offset);
+	struct byt_gpio *vg = gpiochip_get_data(chip);
+	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 reg;
 
-	if (ret)
-		return ret;
+	raw_spin_lock_irqsave(&byt_lock, flags);
 
-	byt_gpio_set(chip, offset, value);
+	byt_gpio_direct_irq_check(vg, offset);
 
+	reg = readl(val_reg);
+	reg &= ~BYT_DIR_MASK;
+	if (value)
+		reg |= BYT_LEVEL;
+	else
+		reg &= ~BYT_LEVEL;
+
+	writel(reg, val_reg);
+
+	raw_spin_unlock_irqrestore(&byt_lock, flags);
 	return 0;
 }
 
-- 
2.27.0




  parent reply	other threads:[~2020-12-10 15:41 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-10 14:26 [PATCH 5.4 00/54] 5.4.83-rc1 review Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 01/54] pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output Greg Kroah-Hartman
2020-12-10 14:26 ` Greg Kroah-Hartman [this message]
2020-12-10 14:26 ` [PATCH 5.4 03/54] Partially revert bpf: Zero-fill re-used per-cpu map element Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 04/54] usb: gadget: f_fs: Use local copy of descriptors for userspace copy Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 05/54] USB: serial: kl5kusb105: fix memleak on open Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 06/54] USB: serial: ch341: add new Product ID for CH341A Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 07/54] USB: serial: ch341: sort device-id entries Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 08/54] USB: serial: option: add Fibocom NL668 variants Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 09/54] USB: serial: option: add support for Thales Cinterion EXS82 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 10/54] USB: serial: option: fix Quectel BG96 matching Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 11/54] tty: Fix ->pgrp locking in tiocspgrp() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 12/54] tty: Fix ->session locking Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 13/54] ALSA: hda/realtek: Fix bass speaker DAC assignment on Asus Zephyrus G14 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 14/54] ALSA: hda/realtek: Add mute LED quirk to yet another HP x360 model Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 15/54] ALSA: hda/realtek: Enable headset of ASUS UX482EG & B9400CEA with ALC294 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 16/54] ALSA: hda/realtek - Add new codec supported for ALC897 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 17/54] ALSA: hda/generic: Add option to enforce preferred_dacs pairs Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 18/54] ftrace: Fix updating FTRACE_FL_TRAMP Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 19/54] cifs: allow syscalls to be restarted in __smb_send_rqst() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 20/54] cifs: fix potential use-after-free in cifs_echo_request() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 21/54] s390/pci: fix CPU address in MSI for directed IRQ Greg Kroah-Hartman
2020-12-10 16:34   ` Niklas Schnelle
2020-12-10 16:46     ` Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 5.4 22/54] i2c: imx: Dont generate STOP condition if arbitration has been lost Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 23/54] thunderbolt: Fix use-after-free in remove_unplugged_switch() Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 24/54] drm/i915/gt: Program mocs:63 for cache eviction on gen9 Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 25/54] scsi: mpt3sas: Fix ioctl timeout Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 26/54] dm writecache: fix the maximum number of arguments Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 27/54] powerpc/64s/powernv: Fix memory corruption when saving SLB entries on MCE Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 28/54] genirq/irqdomain: Add an irq_create_mapping_affinity() function Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 29/54] powerpc/pseries: Pass MSI affinity to irq_create_mapping() Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 30/54] dm: fix bug with RCU locking in dm_blk_report_zones Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 31/54] dm: remove invalid sparse __acquires and __releases annotations Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 32/54] x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 33/54] coredump: fix core_pattern parse error Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 34/54] mm: list_lru: set shrinker map bit when child nr_items is not zero Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 35/54] mm/swapfile: do not sleep with a spin lock held Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 36/54] speakup: Reject setting the speakup line discipline outside of speakup Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 37/54] i2c: imx: Fix reset of I2SR_IAL flag Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 38/54] i2c: imx: Check for I2SR_IAL after every byte Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 39/54] spi: bcm2835: Release the DMA channel if probe fails after dma_init Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 40/54] iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 41/54] tracing: Fix userstacktrace option for instances Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 42/54] lib/syscall: fix syscall registers retrieval on 32-bit platforms Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 43/54] can: af_can: can_rx_unregister(): remove WARN() statement from list operation sanity check Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 44/54] gfs2: check for empty rgrp tree in gfs2_ri_update Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 45/54] netfilter: ipset: prevent uninit-value in hash_ip6_add Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 46/54] tipc: fix a deadlock when flushing scheduled work Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 47/54] ASoC: wm_adsp: fix error return code in wm_adsp_load() Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 48/54] rtw88: debug: Fix uninitialized memory in debugfs code Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 49/54] i2c: qup: Fix error return code in qup_i2c_bam_schedule_desc() Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 50/54] dm writecache: remove BUG() and fail gracefully instead Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 51/54] Input: i8042 - fix error return code in i8042_setup_aux() Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 52/54] netfilter: nf_tables: avoid false-postive lockdep splat Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 53/54] netfilter: nftables_offload: set address type in control dissector Greg Kroah-Hartman
2020-12-10 14:27 ` [PATCH 5.4 54/54] x86/insn-eval: Use new for_each_insn_prefix() macro to loop over prefixes bytes Greg Kroah-Hartman
2020-12-10 21:04 ` [PATCH 5.4 00/54] 5.4.83-rc1 review Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201210142602.166196368@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=hdegoede@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=sudipm.mukherjee@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.