Linux-GPIO Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v2] pinctrl: intel: Allow to request locked pads
@ 2019-08-08 13:21 Andy Shevchenko
  2019-08-09  8:40 ` Mika Westerberg
  2019-08-09 12:58 ` Linus Walleij
  0 siblings, 2 replies; 3+ messages in thread
From: Andy Shevchenko @ 2019-08-08 13:21 UTC (permalink / raw)
  To: Mika Westerberg, linux-gpio, Linus Walleij; +Cc: Andy Shevchenko

Some firmwares would like to protect pads from being modified by OS
and at the same time provide them to OS as a resource. So, the driver
in such circumstances may request pad and may not change its state.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
in v2:
- amended comment in intel_pad_locked() respectively to the change (Mika)
- described enum values (Linus)
- lowered case for locking flavour in debugfs for better looking
 drivers/pinctrl/intel/pinctrl-intel.c | 67 ++++++++++++++++++++-------
 1 file changed, 50 insertions(+), 17 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index c949df07cbdf..b84a5579beee 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -220,47 +220,69 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
 	return !(readl(hostown) & BIT(gpp_offset));
 }
 
-static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
+/*
+ * PAD_UNLOCKED:	pad is fully controlled by the configuration registers
+ * PAD_LOCKED:		pad configuration registers, except TX state, are locked
+ * PAD_LOCKED_TX:	pad configuration TX state is locked
+ * PAD_LOCKED_FULL:	pad configuration registers are locked completely
+ *
+ * Locking is considered as read-only mode for corresponding registers and
+ * their respective fields. That said, TX state bit is locked separately from
+ * the main locking scheme.
+ */
+enum {
+	PAD_UNLOCKED	= 0,
+	PAD_LOCKED	= 1,
+	PAD_LOCKED_TX	= 2,
+	PAD_LOCKED_FULL	= PAD_LOCKED | PAD_LOCKED_TX,
+};
+
+static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
 {
 	struct intel_community *community;
 	const struct intel_padgroup *padgrp;
 	unsigned int offset, gpp_offset;
 	u32 value;
+	int ret = PAD_UNLOCKED;
 
 	community = intel_get_community(pctrl, pin);
 	if (!community)
-		return true;
+		return PAD_LOCKED_FULL;
 	if (!community->padcfglock_offset)
-		return false;
+		return PAD_UNLOCKED;
 
 	padgrp = intel_community_get_padgroup(community, pin);
 	if (!padgrp)
-		return true;
+		return PAD_LOCKED_FULL;
 
 	gpp_offset = padgroup_offset(padgrp, pin);
 
 	/*
 	 * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
 	 * the pad is considered unlocked. Any other case means that it is
-	 * either fully or partially locked and we don't touch it.
+	 * either fully or partially locked.
 	 */
-	offset = community->padcfglock_offset + padgrp->reg_num * 8;
+	offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8;
 	value = readl(community->regs + offset);
 	if (value & BIT(gpp_offset))
-		return true;
+		ret |= PAD_LOCKED;
 
 	offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
 	value = readl(community->regs + offset);
 	if (value & BIT(gpp_offset))
-		return true;
+		ret |= PAD_LOCKED_TX;
 
-	return false;
+	return ret;
+}
+
+static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin)
+{
+	return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED;
 }
 
 static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
 {
-	return intel_pad_owned_by_host(pctrl, pin) &&
-		!intel_pad_locked(pctrl, pin);
+	return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin);
 }
 
 static int intel_get_groups_count(struct pinctrl_dev *pctldev)
@@ -294,7 +316,8 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 	void __iomem *padcfg;
 	u32 cfg0, cfg1, mode;
-	bool locked, acpi;
+	int locked;
+	bool acpi;
 
 	if (!intel_pad_owned_by_host(pctrl, pin)) {
 		seq_puts(s, "not available");
@@ -322,11 +345,16 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 
 	if (locked || acpi) {
 		seq_puts(s, " [");
-		if (locked) {
+		if (locked)
 			seq_puts(s, "LOCKED");
-			if (acpi)
-				seq_puts(s, ", ");
-		}
+		if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX)
+			seq_puts(s, " tx");
+		else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL)
+			seq_puts(s, " full");
+
+		if (locked && acpi)
+			seq_puts(s, ", ");
+
 		if (acpi)
 			seq_puts(s, "ACPI");
 		seq_puts(s, "]");
@@ -448,11 +476,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 	raw_spin_lock_irqsave(&pctrl->lock, flags);
 
-	if (!intel_pad_usable(pctrl, pin)) {
+	if (!intel_pad_owned_by_host(pctrl, pin)) {
 		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 		return -EBUSY;
 	}
 
+	if (!intel_pad_is_unlocked(pctrl, pin)) {
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		return 0;
+	}
+
 	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
 	intel_gpio_set_gpio_mode(padcfg0);
 	/* Disable TX buffer and enable RX (this will be input) */
-- 
2.20.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] pinctrl: intel: Allow to request locked pads
  2019-08-08 13:21 [PATCH v2] pinctrl: intel: Allow to request locked pads Andy Shevchenko
@ 2019-08-09  8:40 ` Mika Westerberg
  2019-08-09 12:58 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Mika Westerberg @ 2019-08-09  8:40 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-gpio, Linus Walleij

On Thu, Aug 08, 2019 at 04:21:28PM +0300, Andy Shevchenko wrote:
> Some firmwares would like to protect pads from being modified by OS
> and at the same time provide them to OS as a resource. So, the driver
> in such circumstances may request pad and may not change its state.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> in v2:
> - amended comment in intel_pad_locked() respectively to the change (Mika)
> - described enum values (Linus)
> - lowered case for locking flavour in debugfs for better looking
>  drivers/pinctrl/intel/pinctrl-intel.c | 67 ++++++++++++++++++++-------
>  1 file changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
> index c949df07cbdf..b84a5579beee 100644
> --- a/drivers/pinctrl/intel/pinctrl-intel.c
> +++ b/drivers/pinctrl/intel/pinctrl-intel.c
> @@ -220,47 +220,69 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
>  	return !(readl(hostown) & BIT(gpp_offset));
>  }
>  
> -static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
> +/*

This should be /**

> + * PAD_UNLOCKED:	pad is fully controlled by the configuration registers

These should have @ prefix, I think.

Otherwise looks good.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] pinctrl: intel: Allow to request locked pads
  2019-08-08 13:21 [PATCH v2] pinctrl: intel: Allow to request locked pads Andy Shevchenko
  2019-08-09  8:40 ` Mika Westerberg
@ 2019-08-09 12:58 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2019-08-09 12:58 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: Mika Westerberg, open list:GPIO SUBSYSTEM

On Thu, Aug 8, 2019 at 3:21 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> Some firmwares would like to protect pads from being modified by OS
> and at the same time provide them to OS as a resource. So, the driver
> in such circumstances may request pad and may not change its state.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> in v2:
> - amended comment in intel_pad_locked() respectively to the change (Mika)
> - described enum values (Linus)
> - lowered case for locking flavour in debugfs for better looking
>  drivers/pinctrl/intel/pinctrl-intel.c | 67 ++++++++++++++++++++-------
>  1 file changed, 50 insertions(+), 17 deletions(-)

Mika pointed out some typos or so, apart from that:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-08 13:21 [PATCH v2] pinctrl: intel: Allow to request locked pads Andy Shevchenko
2019-08-09  8:40 ` Mika Westerberg
2019-08-09 12:58 ` Linus Walleij

Linux-GPIO Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-gpio/0 linux-gpio/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-gpio linux-gpio/ https://lore.kernel.org/linux-gpio \
		linux-gpio@vger.kernel.org linux-gpio@archiver.kernel.org
	public-inbox-index linux-gpio


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-gpio


AGPL code for this site: git clone https://public-inbox.org/ public-inbox