All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella
@ 2019-12-09 13:09 Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 01/24] pinctrl: lynxpoint: Move GPIO driver to pin controller folder Andy Shevchenko
                   ` (25 more replies)
  0 siblings, 26 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Intel Lynxpoint GPIO is actually half way to the Chassis specification
that has been established starting from Intel Skylake. It has some pin control
properties we may utilize. To achieve this, move the driver under pin control
umbrella and do a bunch of clean ups.

The series has been tested on Broadwell Ultrabook where Lynxpoint GPIO
is exposed to the OS.

It has a dependency to patches in my review branch [1]. That dependency patch
is supposed to be submitted soon as a part of Baytrail clean up. In the
mentioned branch the patches are represented in the correct order.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git/log/?h=review-andy

Changes v2:
- fixed ordering in Kconfig and Makefile (Mika)
- finished conversion to pin control

Andy Shevchenko (24):
  pinctrl: lynxpoint: Move GPIO driver to pin controller folder
  pinctrl: lynxpoint: Use raw_spinlock for locking
  pinctrl: lynxpoint: Correct amount of pins
  pinctrl: lynxpoint: Drop useless assignment
  pinctrl: lynxpoint: Use %pR to print IO resource
  pinctrl: lynxpoint: Use standard pattern for memory allocation
  pinctrl: lynxpoint: Assume 2 bits for mode selector
  pinctrl: lynxpoint: Relax GPIO request rules
  pinctrl: lynxpoint: Keep pointer to struct device instead of its
    container
  pinctrl: lynxpoint: Switch to memory mapped IO accessors
  pinctrl: lynxpoint: Convert unsigned to unsigned int
  pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use
  pinctrl: lynxpoint: Move ->remove closer to ->probe()
  pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines
  pinctrl: lynxpoint: Move ownership check to IRQ chip
  pinctrl: lynxpoint: Implement ->irq_ack() callback
  pinctrl: lynxpoint: Implement intel_gpio_get_direction callback
  pinctrl: lynxpoint: Add pin control data structures
  pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
  pinctrl: lynxpoint: Add pin control operations
  pinctrl: lynxpoint: Implement ->pin_dbg_show()
  pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback
  pinctrl: lynxpoint: Switch to pin control API
  pinctrl: lynxpoint: Update summary in the driver

 MAINTAINERS                               |   1 -
 drivers/gpio/Kconfig                      |   8 -
 drivers/gpio/Makefile                     |   1 -
 drivers/gpio/gpio-lynxpoint.c             | 471 -----------
 drivers/pinctrl/intel/Kconfig             |  13 +
 drivers/pinctrl/intel/Makefile            |   1 +
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 975 ++++++++++++++++++++++
 7 files changed, 989 insertions(+), 481 deletions(-)
 delete mode 100644 drivers/gpio/gpio-lynxpoint.c
 create mode 100644 drivers/pinctrl/intel/pinctrl-lynxpoint.c

-- 
2.24.0


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

* [PATCH v2 01/24] pinctrl: lynxpoint: Move GPIO driver to pin controller folder
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 02/24] pinctrl: lynxpoint: Use raw_spinlock for locking Andy Shevchenko
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Move Lynxpoint GPIO driver under Intel pin control umbrella
for further transformation to a real pin control driver.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 MAINTAINERS                                            |  1 -
 drivers/gpio/Kconfig                                   |  8 --------
 drivers/gpio/Makefile                                  |  1 -
 drivers/pinctrl/intel/Kconfig                          | 10 ++++++++++
 drivers/pinctrl/intel/Makefile                         |  1 +
 .../intel/pinctrl-lynxpoint.c}                         |  0
 6 files changed, 11 insertions(+), 10 deletions(-)
 rename drivers/{gpio/gpio-lynxpoint.c => pinctrl/intel/pinctrl-lynxpoint.c} (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index bd5847e802de..6ea3cba0a9b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8344,7 +8344,6 @@ S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
 F:	drivers/gpio/gpio-ich.c
 F:	drivers/gpio/gpio-intel-mid.c
-F:	drivers/gpio/gpio-lynxpoint.c
 F:	drivers/gpio/gpio-merrifield.c
 F:	drivers/gpio/gpio-ml-ioh.c
 F:	drivers/gpio/gpio-pch.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8adffd42f8cb..6923142fd874 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -335,14 +335,6 @@ config GPIO_LPC32XX
 	  Select this option to enable GPIO driver for
 	  NXP LPC32XX devices.
 
-config GPIO_LYNXPOINT
-	tristate "Intel Lynxpoint GPIO support"
-	depends on ACPI && X86
-	select GPIOLIB_IRQCHIP
-	help
-	  driver for GPIO functionality on Intel Lynxpoint PCH chipset
-	  Requires ACPI device enumeration code to set up a platform device.
-
 config GPIO_MB86S7X
 	tristate "GPIO support for Fujitsu MB86S7x Platforms"
 	help
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 34eb8b2b12dd..55b2b645391e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -76,7 +76,6 @@ obj-$(CONFIG_GPIO_LP873X)		+= gpio-lp873x.o
 obj-$(CONFIG_GPIO_LP87565)		+= gpio-lp87565.o
 obj-$(CONFIG_GPIO_LPC18XX)		+= gpio-lpc18xx.o
 obj-$(CONFIG_GPIO_LPC32XX)		+= gpio-lpc32xx.o
-obj-$(CONFIG_GPIO_LYNXPOINT)		+= gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MADERA)		+= gpio-madera.o
 obj-$(CONFIG_GPIO_MAX3191X)		+= gpio-max3191x.o
 obj-$(CONFIG_GPIO_MAX7300)		+= gpio-max7300.o
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index 6091947a8f51..c2e6bc9e3e04 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -31,6 +31,16 @@ config PINCTRL_CHERRYVIEW
 	  Cherryview/Braswell pinctrl driver provides an interface that
 	  allows configuring of SoC pins and using them as GPIOs.
 
+config PINCTRL_LYNXPOINT
+	tristate "Intel Lynxpoint pinctrl and GPIO driver"
+	depends on ACPI
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	help
+	  Lynxpoint is the PCH of Intel Haswell. This pinctrl driver
+	  provides an interface that allows configuring of PCH pins and
+	  using them as GPIOs.
+
 config PINCTRL_MERRIFIELD
 	tristate "Intel Merrifield pinctrl driver"
 	depends on X86_INTEL_MID
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
index 7e620b471ef6..f60f99cfa7aa 100644
--- a/drivers/pinctrl/intel/Makefile
+++ b/drivers/pinctrl/intel/Makefile
@@ -3,6 +3,7 @@
 
 obj-$(CONFIG_PINCTRL_BAYTRAIL)		+= pinctrl-baytrail.o
 obj-$(CONFIG_PINCTRL_CHERRYVIEW)	+= pinctrl-cherryview.o
+obj-$(CONFIG_PINCTRL_LYNXPOINT)		+= pinctrl-lynxpoint.o
 obj-$(CONFIG_PINCTRL_MERRIFIELD)	+= pinctrl-merrifield.o
 obj-$(CONFIG_PINCTRL_INTEL)		+= pinctrl-intel.o
 obj-$(CONFIG_PINCTRL_BROXTON)		+= pinctrl-broxton.o
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
similarity index 100%
rename from drivers/gpio/gpio-lynxpoint.c
rename to drivers/pinctrl/intel/pinctrl-lynxpoint.c
-- 
2.24.0


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

* [PATCH v2 02/24] pinctrl: lynxpoint: Use raw_spinlock for locking
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 01/24] pinctrl: lynxpoint: Move GPIO driver to pin controller folder Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 03/24] pinctrl: lynxpoint: Correct amount of pins Andy Shevchenko
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

The Intel Lynxpoint pinctrl driver implements irqchip callbacks which are
called with desc->lock raw_spinlock held. In mainline this is fine because
spinlock resolves to raw_spinlock. However, running the same code in -rt
we will get a BUG() asserted.

This is because in -rt spinlocks are preemptible so taking the driver
private spinlock in irqchip callbacks causes might_sleep() to trigger.

In order to keep -rt happy but at the same time make sure that register
accesses get serialized, convert the driver to use raw_spinlock instead.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 28 +++++++++++------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 490ce7bae25e..c30fd86846a7 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -47,7 +47,7 @@
 struct lp_gpio {
 	struct gpio_chip	chip;
 	struct platform_device	*pdev;
-	spinlock_t		lock;
+	raw_spinlock_t		lock;
 	unsigned long		reg_base;
 };
 
@@ -144,7 +144,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 	if (hwirq >= lg->chip.ngpio)
 		return -EINVAL;
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 	value = inl(reg);
 
 	/* set both TRIG_SEL and INV bits to 0 for rising edge */
@@ -170,7 +170,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 	else if (type & IRQ_TYPE_LEVEL_MASK)
 		irq_set_handler_locked(d, handle_level_irq);
 
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 
 	return 0;
 }
@@ -187,14 +187,14 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 
 	if (value)
 		outl(inl(reg) | OUT_LVL_BIT, reg);
 	else
 		outl(inl(reg) & ~OUT_LVL_BIT, reg);
 
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
 static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -203,9 +203,9 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 	outl(inl(reg) | DIR_BIT, reg);
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 
 	return 0;
 }
@@ -219,9 +219,9 @@ static int lp_gpio_direction_output(struct gpio_chip *chip,
 
 	lp_gpio_set(chip, offset, value);
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 	outl(inl(reg) & ~DIR_BIT, reg);
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 
 	return 0;
 }
@@ -272,9 +272,9 @@ static void lp_irq_enable(struct irq_data *d)
 	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 	outl(inl(reg) | BIT(hwirq % 32), reg);
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
 static void lp_irq_disable(struct irq_data *d)
@@ -285,9 +285,9 @@ static void lp_irq_disable(struct irq_data *d)
 	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
 
-	spin_lock_irqsave(&lg->lock, flags);
+	raw_spin_lock_irqsave(&lg->lock, flags);
 	outl(inl(reg) & ~BIT(hwirq % 32), reg);
-	spin_unlock_irqrestore(&lg->lock, flags);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
 static struct irq_chip lp_irqchip = {
@@ -351,7 +351,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	spin_lock_init(&lg->lock);
+	raw_spin_lock_init(&lg->lock);
 
 	gc = &lg->chip;
 	gc->label = dev_name(dev);
-- 
2.24.0


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

* [PATCH v2 03/24] pinctrl: lynxpoint: Correct amount of pins
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 01/24] pinctrl: lynxpoint: Move GPIO driver to pin controller folder Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 02/24] pinctrl: lynxpoint: Use raw_spinlock for locking Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 04/24] pinctrl: lynxpoint: Drop useless assignment Andy Shevchenko
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

When we count from 0 it's possible to get into off-by-one error.
That's what had happened to this driver. So, correct amount of pins
and related typos in the code.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index c30fd86846a7..162fc38c929d 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -18,9 +18,9 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
-/* LynxPoint chipset has support for 94 gpio pins */
+/* LynxPoint chipset has support for 95 GPIO pins */
 
-#define LP_NUM_GPIO	94
+#define LP_NUM_GPIO	95
 
 /* Bitmapped register offsets */
 #define LP_ACPI_OWNED	0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */
@@ -54,11 +54,11 @@ struct lp_gpio {
 /*
  * Lynxpoint gpios are controlled through both bitmapped registers and
  * per gpio specific registers. The bitmapped registers are in chunks of
- * 3 x 32bit registers to cover all 94 gpios
+ * 3 x 32bit registers to cover all 95 GPIOs
  *
  * per gpio specific registers consist of two 32bit registers per gpio
- * (LP_CONFIG1 and LP_CONFIG2), with 94 gpios there's a total of
- * 188 config registers.
+ * (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of
+ * 190 config registers.
  *
  * A simplified view of the register layout look like this:
  *
@@ -67,7 +67,7 @@ struct lp_gpio {
  * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94
  * ...
  * LP_INT_ENABLE[31:0] ...
- * LP_INT_ENABLE[63:31] ...
+ * LP_INT_ENABLE[63:32] ...
  * LP_INT_ENABLE[94:64] ...
  * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers)
  * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0
-- 
2.24.0


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

* [PATCH v2 04/24] pinctrl: lynxpoint: Drop useless assignment
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (2 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 03/24] pinctrl: lynxpoint: Correct amount of pins Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 05/24] pinctrl: lynxpoint: Use %pR to print IO resource Andy Shevchenko
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

There is no need to assign ret variable in ->probe().
Drop useless assignment.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 162fc38c929d..6f074323e00e 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -325,7 +325,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	struct resource *io_rc, *irq_rc;
 	struct device *dev = &pdev->dev;
 	unsigned long reg_len;
-	int ret = -ENODEV;
+	int ret;
 
 	lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
 	if (!lg)
-- 
2.24.0


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

* [PATCH v2 05/24] pinctrl: lynxpoint: Use %pR to print IO resource
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (3 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 04/24] pinctrl: lynxpoint: Drop useless assignment Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 06/24] pinctrl: lynxpoint: Use standard pattern for memory allocation Andy Shevchenko
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Replace explicit casting by pointer to struct resource with
specifier replacement to %pR to print the IO resource.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 6f074323e00e..36978a7c2a85 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -346,8 +346,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	reg_len = resource_size(io_rc);
 
 	if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) {
-		dev_err(dev, "failed requesting IO region 0x%x\n",
-			(unsigned int)lg->reg_base);
+		dev_err(dev, "failed requesting IO region %pR\n", &io_rc);
 		return -EBUSY;
 	}
 
-- 
2.24.0


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

* [PATCH v2 06/24] pinctrl: lynxpoint: Use standard pattern for memory allocation
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (4 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 05/24] pinctrl: lynxpoint: Use %pR to print IO resource Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 07/24] pinctrl: lynxpoint: Assume 2 bits for mode selector Andy Shevchenko
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

The pattern
	foo = kmalloc(sizeof(*foo), GFP_KERNEL);
has an advantage when foo type is changed. Since we are planning a such,
better to be prepared by using standard pattern for memory allocation.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 36978a7c2a85..17a7843c8dc9 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -327,7 +327,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	unsigned long reg_len;
 	int ret;
 
-	lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
+	lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL);
 	if (!lg)
 		return -ENOMEM;
 
-- 
2.24.0


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

* [PATCH v2 07/24] pinctrl: lynxpoint: Assume 2 bits for mode selector
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (5 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 06/24] pinctrl: lynxpoint: Use standard pattern for memory allocation Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 08/24] pinctrl: lynxpoint: Relax GPIO request rules Andy Shevchenko
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

New generations can use 2 bits for mode selector.
Update the code to support it.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 17a7843c8dc9..4b2e3f298641 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -38,7 +38,9 @@
 #define TRIG_SEL_BIT	BIT(4) /* 0: Edge, 1: Level */
 #define INT_INV_BIT	BIT(3) /* Invert interrupt triggering */
 #define DIR_BIT		BIT(2) /* 0: Output, 1: Input */
-#define USE_SEL_BIT	BIT(0) /* 0: Native, 1: GPIO */
+#define USE_SEL_MASK	GENMASK(1, 0)	/* 0: Native, 1: GPIO, ... */
+#define USE_SEL_NATIVE	(0 << 0)
+#define USE_SEL_GPIO	(1 << 0)
 
 /* LP_CONFIG2 reg bits */
 #define GPINDIS_BIT	BIT(2) /* disable input sensing */
@@ -111,7 +113,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 		return -EBUSY;
 	}
 	/* Fail if pin is in alternate function mode (not GPIO mode) */
-	if (!(inl(reg) & USE_SEL_BIT))
+	if ((inl(reg) & USE_SEL_MASK) != USE_SEL_GPIO)
 		return -ENODEV;
 
 	/* enable input sensing */
-- 
2.24.0


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

* [PATCH v2 08/24] pinctrl: lynxpoint: Relax GPIO request rules
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (6 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 07/24] pinctrl: lynxpoint: Assume 2 bits for mode selector Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 09/24] pinctrl: lynxpoint: Keep pointer to struct device instead of its container Andy Shevchenko
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

A pin in native mode still can be requested as GPIO, though we assume
that firmware has configured it properly, which sometimes is not the case.

Here we allow turning the pin as GPIO to avoid potential issues,
but issue warning that something might be wrong.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 4b2e3f298641..3ac95f9d6a7f 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -104,6 +104,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
 	unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
+	u32 value;
 
 	pm_runtime_get(&lg->pdev->dev); /* should we put if failed */
 
@@ -112,9 +113,16 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 		dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset);
 		return -EBUSY;
 	}
-	/* Fail if pin is in alternate function mode (not GPIO mode) */
-	if ((inl(reg) & USE_SEL_MASK) != USE_SEL_GPIO)
-		return -ENODEV;
+
+	/*
+	 * Reconfigure pin to GPIO mode if needed and issue a warning,
+	 * since we expect firmware to configure it properly.
+	 */
+	value = inl(reg);
+	if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
+		outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
+		dev_warn(&lg->pdev->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset);
+	}
 
 	/* enable input sensing */
 	outl(inl(conf2) & ~GPINDIS_BIT, conf2);
-- 
2.24.0


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

* [PATCH v2 09/24] pinctrl: lynxpoint: Keep pointer to struct device instead of its container
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (7 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 08/24] pinctrl: lynxpoint: Relax GPIO request rules Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 10/24] pinctrl: lynxpoint: Switch to memory mapped IO accessors Andy Shevchenko
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

There is no need to keep pointer to struct platform_device, which is container
of struct device, because the latter is what have been used everywhere outside
of ->probe() path. In any case we may derive pointer to the container when
needed.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 3ac95f9d6a7f..1d5f5053fe14 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -48,7 +48,7 @@
 
 struct lp_gpio {
 	struct gpio_chip	chip;
-	struct platform_device	*pdev;
+	struct device		*dev;
 	raw_spinlock_t		lock;
 	unsigned long		reg_base;
 };
@@ -106,11 +106,11 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 	unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
 	u32 value;
 
-	pm_runtime_get(&lg->pdev->dev); /* should we put if failed */
+	pm_runtime_get(lg->dev); /* should we put if failed */
 
 	/* Fail if BIOS reserved pin for ACPI use */
 	if (!(inl(acpi_use) & BIT(offset % 32))) {
-		dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset);
+		dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset);
 		return -EBUSY;
 	}
 
@@ -121,7 +121,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 	value = inl(reg);
 	if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
 		outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
-		dev_warn(&lg->pdev->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset);
+		dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset);
 	}
 
 	/* enable input sensing */
@@ -139,7 +139,7 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
 	/* disable input sensing */
 	outl(inl(conf2) | GPINDIS_BIT, conf2);
 
-	pm_runtime_put(&lg->pdev->dev);
+	pm_runtime_put(lg->dev);
 }
 
 static int lp_irq_type(struct irq_data *d, unsigned type)
@@ -341,7 +341,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	if (!lg)
 		return -ENOMEM;
 
-	lg->pdev = pdev;
+	lg->dev = dev;
 	platform_set_drvdata(pdev, lg);
 
 	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -385,7 +385,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 		girq->init_hw = lp_gpio_irq_init_hw;
 		girq->parent_handler = lp_gpio_irq_handler;
 		girq->num_parents = 1;
-		girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+		girq->parents = devm_kcalloc(dev, girq->num_parents,
 					     sizeof(*girq->parents),
 					     GFP_KERNEL);
 		if (!girq->parents)
-- 
2.24.0


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

* [PATCH v2 10/24] pinctrl: lynxpoint: Switch to memory mapped IO accessors
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (8 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 09/24] pinctrl: lynxpoint: Keep pointer to struct device instead of its container Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 11/24] pinctrl: lynxpoint: Convert unsigned to unsigned int Andy Shevchenko
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Convert driver to use memory mapped IO accessors.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 88 +++++++++++------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 1d5f5053fe14..4ed2d4daea19 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -50,7 +50,7 @@ struct lp_gpio {
 	struct gpio_chip	chip;
 	struct device		*dev;
 	raw_spinlock_t		lock;
-	unsigned long		reg_base;
+	void __iomem		*regs;
 };
 
 /*
@@ -82,7 +82,7 @@ struct lp_gpio {
  * LP94_CONFIG2 (gpio 94) ...
  */
 
-static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
+static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
 				 int reg)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
@@ -95,21 +95,21 @@ static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
 		/* bitmapped registers */
 		reg_offset = (offset / 32) * 4;
 
-	return lg->reg_base + reg + reg_offset;
+	return lg->regs + reg + reg_offset;
 }
 
 static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
-	unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
-	unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
+	void __iomem *acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
 	u32 value;
 
 	pm_runtime_get(lg->dev); /* should we put if failed */
 
 	/* Fail if BIOS reserved pin for ACPI use */
-	if (!(inl(acpi_use) & BIT(offset % 32))) {
+	if (!(ioread32(acpi_use) & BIT(offset % 32))) {
 		dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset);
 		return -EBUSY;
 	}
@@ -118,14 +118,14 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 	 * Reconfigure pin to GPIO mode if needed and issue a warning,
 	 * since we expect firmware to configure it properly.
 	 */
-	value = inl(reg);
+	value = ioread32(reg);
 	if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
-		outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
+		iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
 		dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset);
 	}
 
 	/* enable input sensing */
-	outl(inl(conf2) & ~GPINDIS_BIT, conf2);
+	iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2);
 
 
 	return 0;
@@ -134,10 +134,10 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
+	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
 
 	/* disable input sensing */
-	outl(inl(conf2) | GPINDIS_BIT, conf2);
+	iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2);
 
 	pm_runtime_put(lg->dev);
 }
@@ -147,15 +147,15 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct lp_gpio *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
 	unsigned long flags;
 	u32 value;
-	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
 
 	if (hwirq >= lg->chip.ngpio)
 		return -EINVAL;
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
-	value = inl(reg);
+	value = ioread32(reg);
 
 	/* set both TRIG_SEL and INV bits to 0 for rising edge */
 	if (type & IRQ_TYPE_EDGE_RISING)
@@ -173,7 +173,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 	if (type & IRQ_TYPE_LEVEL_HIGH)
 		value |= TRIG_SEL_BIT | INT_INV_BIT;
 
-	outl(value, reg);
+	iowrite32(value, reg);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
 		irq_set_handler_locked(d, handle_edge_irq);
@@ -187,22 +187,22 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 
 static int lp_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
-	return !!(inl(reg) & IN_LVL_BIT);
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+	return !!(ioread32(reg) & IN_LVL_BIT);
 }
 
 static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
 
 	if (value)
-		outl(inl(reg) | OUT_LVL_BIT, reg);
+		iowrite32(ioread32(reg) | OUT_LVL_BIT, reg);
 	else
-		outl(inl(reg) & ~OUT_LVL_BIT, reg);
+		iowrite32(ioread32(reg) & ~OUT_LVL_BIT, reg);
 
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
@@ -210,11 +210,11 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
-	outl(inl(reg) | DIR_BIT, reg);
+	iowrite32(ioread32(reg) | DIR_BIT, reg);
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 
 	return 0;
@@ -224,13 +224,13 @@ static int lp_gpio_direction_output(struct gpio_chip *chip,
 				      unsigned offset, int value)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
 	lp_gpio_set(chip, offset, value);
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
-	outl(inl(reg) & ~DIR_BIT, reg);
+	iowrite32(ioread32(reg) & ~DIR_BIT, reg);
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 
 	return 0;
@@ -242,7 +242,8 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct lp_gpio *lg = gpiochip_get_data(gc);
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
-	unsigned long reg, ena, pending;
+	void __iomem *reg, *ena;
+	unsigned long pending;
 	u32 base, pin;
 
 	/* check from GPIO controller which pin triggered the interrupt */
@@ -251,13 +252,13 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 		ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
 
 		/* Only interrupts that are enabled */
-		pending = inl(reg) & inl(ena);
+		pending = ioread32(reg) & ioread32(ena);
 
 		for_each_set_bit(pin, &pending, 32) {
 			unsigned irq;
 
 			/* Clear before handling so we don't lose an edge */
-			outl(BIT(pin), reg);
+			iowrite32(BIT(pin), reg);
 
 			irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
 			generic_handle_irq(irq);
@@ -279,11 +280,11 @@ static void lp_irq_enable(struct irq_data *d)
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct lp_gpio *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
-	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
-	outl(inl(reg) | BIT(hwirq % 32), reg);
+	iowrite32(ioread32(reg) | BIT(hwirq % 32), reg);
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
@@ -292,11 +293,11 @@ static void lp_irq_disable(struct irq_data *d)
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct lp_gpio *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
-	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&lg->lock, flags);
-	outl(inl(reg) & ~BIT(hwirq % 32), reg);
+	iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg);
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
@@ -313,16 +314,16 @@ static struct irq_chip lp_irqchip = {
 static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
-	unsigned long reg;
+	void __iomem *reg;
 	unsigned base;
 
 	for (base = 0; base < lg->chip.ngpio; base += 32) {
 		/* disable gpio pin interrupts */
 		reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
-		outl(0, reg);
+		iowrite32(0, reg);
 		/* Clear interrupt status register */
 		reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
-		outl(0xffffffff, reg);
+		iowrite32(0xffffffff, reg);
 	}
 
 	return 0;
@@ -334,7 +335,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	struct gpio_chip *gc;
 	struct resource *io_rc, *irq_rc;
 	struct device *dev = &pdev->dev;
-	unsigned long reg_len;
+	void __iomem *regs;
 	int ret;
 
 	lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL);
@@ -345,21 +346,19 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, lg);
 
 	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-
 	if (!io_rc) {
 		dev_err(dev, "missing IO resources\n");
 		return -EINVAL;
 	}
 
-	lg->reg_base = io_rc->start;
-	reg_len = resource_size(io_rc);
-
-	if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) {
-		dev_err(dev, "failed requesting IO region %pR\n", &io_rc);
+	regs = devm_ioport_map(dev, io_rc->start, resource_size(io_rc));
+	if (!regs) {
+		dev_err(dev, "failed mapping IO region %pR\n", &io_rc);
 		return -EBUSY;
 	}
 
+	lg->regs = regs;
+
 	raw_spin_lock_init(&lg->lock);
 
 	gc = &lg->chip;
@@ -377,6 +376,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc->parent = dev;
 
 	/* set up interrupts  */
+	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (irq_rc && irq_rc->start) {
 		struct gpio_irq_chip *girq;
 
@@ -419,14 +419,14 @@ static int lp_gpio_runtime_resume(struct device *dev)
 static int lp_gpio_resume(struct device *dev)
 {
 	struct lp_gpio *lg = dev_get_drvdata(dev);
-	unsigned long reg;
+	void __iomem *reg;
 	int i;
 
 	/* on some hardware suspend clears input sensing, re-enable it here */
 	for (i = 0; i < lg->chip.ngpio; i++) {
 		if (gpiochip_is_requested(&lg->chip, i) != NULL) {
 			reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2);
-			outl(inl(reg) & ~GPINDIS_BIT, reg);
+			iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg);
 		}
 	}
 	return 0;
-- 
2.24.0


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

* [PATCH v2 11/24] pinctrl: lynxpoint: Convert unsigned to unsigned int
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (9 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 10/24] pinctrl: lynxpoint: Switch to memory mapped IO accessors Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 12/24] pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use Andy Shevchenko
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Simple type conversion with no functional change implied.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 24 +++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 4ed2d4daea19..3c8241ed8bc2 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -82,7 +82,7 @@ struct lp_gpio {
  * LP94_CONFIG2 (gpio 94) ...
  */
 
-static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
+static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
 				 int reg)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
@@ -98,7 +98,7 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
 	return lg->regs + reg + reg_offset;
 }
 
-static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
+static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -131,7 +131,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
 	return 0;
 }
 
-static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
+static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
@@ -142,7 +142,7 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
 	pm_runtime_put(lg->dev);
 }
 
-static int lp_irq_type(struct irq_data *d, unsigned type)
+static int lp_irq_type(struct irq_data *d, unsigned int type)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct lp_gpio *lg = gpiochip_get_data(gc);
@@ -185,13 +185,13 @@ static int lp_irq_type(struct irq_data *d, unsigned type)
 	return 0;
 }
 
-static int lp_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	return !!(ioread32(reg) & IN_LVL_BIT);
 }
 
-static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -207,7 +207,7 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
-static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -220,8 +220,8 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 	return 0;
 }
 
-static int lp_gpio_direction_output(struct gpio_chip *chip,
-				      unsigned offset, int value)
+static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
+				    int value)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -255,7 +255,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 		pending = ioread32(reg) & ioread32(ena);
 
 		for_each_set_bit(pin, &pending, 32) {
-			unsigned irq;
+			unsigned int irq;
 
 			/* Clear before handling so we don't lose an edge */
 			iowrite32(BIT(pin), reg);
@@ -315,7 +315,7 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg;
-	unsigned base;
+	unsigned int base;
 
 	for (base = 0; base < lg->chip.ngpio; base += 32) {
 		/* disable gpio pin interrupts */
@@ -390,7 +390,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 					     GFP_KERNEL);
 		if (!girq->parents)
 			return -ENOMEM;
-		girq->parents[0] = (unsigned)irq_rc->start;
+		girq->parents[0] = (unsigned int)irq_rc->start;
 		girq->default_type = IRQ_TYPE_NONE;
 		girq->handler = handle_bad_irq;
 	}
-- 
2.24.0


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

* [PATCH v2 12/24] pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (10 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 11/24] pinctrl: lynxpoint: Convert unsigned to unsigned int Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 13/24] pinctrl: lynxpoint: Move ->remove closer to ->probe() Andy Shevchenko
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

We may need this function for other features in the pin control driver.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 3c8241ed8bc2..d40360728140 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -98,18 +98,28 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
 	return lg->regs + reg + reg_offset;
 }
 
+static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin)
+{
+	void __iomem *acpi_use;
+
+	acpi_use = lp_gpio_reg(&lg->chip, pin, LP_ACPI_OWNED);
+	if (!acpi_use)
+		return true;
+
+	return !(ioread32(acpi_use) & BIT(pin % 32));
+}
+
 static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
 	struct lp_gpio *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
-	void __iomem *acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
 	u32 value;
 
 	pm_runtime_get(lg->dev); /* should we put if failed */
 
 	/* Fail if BIOS reserved pin for ACPI use */
-	if (!(ioread32(acpi_use) & BIT(offset % 32))) {
+	if (lp_gpio_acpi_use(lg, offset)) {
 		dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset);
 		return -EBUSY;
 	}
-- 
2.24.0


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

* [PATCH v2 13/24] pinctrl: lynxpoint: Move ->remove closer to ->probe()
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (11 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 12/24] pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 14/24] pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines Andy Shevchenko
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Consolidate ->remove and ->probe() callbacks for better maintenance.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index d40360728140..83b5b2590778 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -416,6 +416,12 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int lp_gpio_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
 static int lp_gpio_runtime_suspend(struct device *dev)
 {
 	return 0;
@@ -455,12 +461,6 @@ static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = {
 };
 MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
 
-static int lp_gpio_remove(struct platform_device *pdev)
-{
-	pm_runtime_disable(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver lp_gpio_driver = {
 	.probe          = lp_gpio_probe,
 	.remove         = lp_gpio_remove,
-- 
2.24.0


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

* [PATCH v2 14/24] pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (12 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 13/24] pinctrl: lynxpoint: Move ->remove closer to ->probe() Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 15/24] pinctrl: lynxpoint: Move ownership check to IRQ chip Andy Shevchenko
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Consolidate IRQ routines for better maintenance.

While here, rename lp_irq_type() to lp_irq_set_type() to be in align
with a callback name.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 88 +++++++++++------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 83b5b2590778..19e8f8f1f7aa 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -152,49 +152,6 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset)
 	pm_runtime_put(lg->dev);
 }
 
-static int lp_irq_type(struct irq_data *d, unsigned int type)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
-	u32 hwirq = irqd_to_hwirq(d);
-	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
-	unsigned long flags;
-	u32 value;
-
-	if (hwirq >= lg->chip.ngpio)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&lg->lock, flags);
-	value = ioread32(reg);
-
-	/* set both TRIG_SEL and INV bits to 0 for rising edge */
-	if (type & IRQ_TYPE_EDGE_RISING)
-		value &= ~(TRIG_SEL_BIT | INT_INV_BIT);
-
-	/* TRIG_SEL bit 0, INV bit 1 for falling edge */
-	if (type & IRQ_TYPE_EDGE_FALLING)
-		value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT;
-
-	/* TRIG_SEL bit 1, INV bit 0 for level low */
-	if (type & IRQ_TYPE_LEVEL_LOW)
-		value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT;
-
-	/* TRIG_SEL bit 1, INV bit 1 for level high */
-	if (type & IRQ_TYPE_LEVEL_HIGH)
-		value |= TRIG_SEL_BIT | INT_INV_BIT;
-
-	iowrite32(value, reg);
-
-	if (type & IRQ_TYPE_EDGE_BOTH)
-		irq_set_handler_locked(d, handle_edge_irq);
-	else if (type & IRQ_TYPE_LEVEL_MASK)
-		irq_set_handler_locked(d, handle_level_irq);
-
-	raw_spin_unlock_irqrestore(&lg->lock, flags);
-
-	return 0;
-}
-
 static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -311,13 +268,56 @@ static void lp_irq_disable(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&lg->lock, flags);
 }
 
+static int lp_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct lp_gpio *lg = gpiochip_get_data(gc);
+	u32 hwirq = irqd_to_hwirq(d);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
+	unsigned long flags;
+	u32 value;
+
+	if (hwirq >= lg->chip.ngpio)
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+	value = ioread32(reg);
+
+	/* set both TRIG_SEL and INV bits to 0 for rising edge */
+	if (type & IRQ_TYPE_EDGE_RISING)
+		value &= ~(TRIG_SEL_BIT | INT_INV_BIT);
+
+	/* TRIG_SEL bit 0, INV bit 1 for falling edge */
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT;
+
+	/* TRIG_SEL bit 1, INV bit 0 for level low */
+	if (type & IRQ_TYPE_LEVEL_LOW)
+		value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT;
+
+	/* TRIG_SEL bit 1, INV bit 1 for level high */
+	if (type & IRQ_TYPE_LEVEL_HIGH)
+		value |= TRIG_SEL_BIT | INT_INV_BIT;
+
+	iowrite32(value, reg);
+
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		irq_set_handler_locked(d, handle_edge_irq);
+	else if (type & IRQ_TYPE_LEVEL_MASK)
+		irq_set_handler_locked(d, handle_level_irq);
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	return 0;
+}
+
 static struct irq_chip lp_irqchip = {
 	.name = "LP-GPIO",
 	.irq_mask = lp_irq_mask,
 	.irq_unmask = lp_irq_unmask,
 	.irq_enable = lp_irq_enable,
 	.irq_disable = lp_irq_disable,
-	.irq_set_type = lp_irq_type,
+	.irq_set_type = lp_irq_set_type,
 	.flags = IRQCHIP_SKIP_SET_WAKE,
 };
 
-- 
2.24.0


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

* [PATCH v2 15/24] pinctrl: lynxpoint: Move ownership check to IRQ chip
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (13 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 14/24] pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 16/24] pinctrl: lynxpoint: Implement ->irq_ack() callback Andy Shevchenko
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

There is nothing wrong with requesting pin that owned by ACPI.
The only difference is how interrupt status will be reflected.
It means that in ACPI mode we may not use pin as GPIO-backed IRQ.

Taking above into consideration, move the check from GPIO to IRQ chip
callback.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 19e8f8f1f7aa..ddb201e5d78f 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -118,12 +118,6 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 
 	pm_runtime_get(lg->dev); /* should we put if failed */
 
-	/* Fail if BIOS reserved pin for ACPI use */
-	if (lp_gpio_acpi_use(lg, offset)) {
-		dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset);
-		return -EBUSY;
-	}
-
 	/*
 	 * Reconfigure pin to GPIO mode if needed and issue a warning,
 	 * since we expect firmware to configure it properly.
@@ -280,6 +274,12 @@ static int lp_irq_set_type(struct irq_data *d, unsigned int type)
 	if (hwirq >= lg->chip.ngpio)
 		return -EINVAL;
 
+	/* Fail if BIOS reserved pin for ACPI use */
+	if (lp_gpio_acpi_use(lg, hwirq)) {
+		dev_err(lg->dev, "pin %u can't be used as IRQ\n", hwirq);
+		return -EBUSY;
+	}
+
 	raw_spin_lock_irqsave(&lg->lock, flags);
 	value = ioread32(reg);
 
-- 
2.24.0


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

* [PATCH v2 16/24] pinctrl: lynxpoint: Implement ->irq_ack() callback
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (14 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 15/24] pinctrl: lynxpoint: Move ownership check to IRQ chip Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 17/24] pinctrl: lynxpoint: Implement intel_gpio_get_direction callback Andy Shevchenko
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Instead of playing tricks with registers in the interrupt handler,
utilize the IRQ chip core for ACKing interrupts properly.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index ddb201e5d78f..3b0dfe9a51ba 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -218,9 +218,6 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 		for_each_set_bit(pin, &pending, 32) {
 			unsigned int irq;
 
-			/* Clear before handling so we don't lose an edge */
-			iowrite32(BIT(pin), reg);
-
 			irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
 			generic_handle_irq(irq);
 		}
@@ -228,6 +225,19 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 	chip->irq_eoi(data);
 }
 
+static void lp_irq_ack(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct lp_gpio *lg = gpiochip_get_data(gc);
+	u32 hwirq = irqd_to_hwirq(d);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+	iowrite32(BIT(hwirq % 32), reg);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+}
+
 static void lp_irq_unmask(struct irq_data *d)
 {
 }
@@ -313,6 +323,7 @@ static int lp_irq_set_type(struct irq_data *d, unsigned int type)
 
 static struct irq_chip lp_irqchip = {
 	.name = "LP-GPIO",
+	.irq_ack = lp_irq_ack,
 	.irq_mask = lp_irq_mask,
 	.irq_unmask = lp_irq_unmask,
 	.irq_enable = lp_irq_enable,
-- 
2.24.0


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

* [PATCH v2 17/24] pinctrl: lynxpoint: Implement intel_gpio_get_direction callback
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (15 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 16/24] pinctrl: lynxpoint: Implement ->irq_ack() callback Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 18/24] pinctrl: lynxpoint: Add pin control data structures Andy Shevchenko
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Allows querying GPIO direction from the pad config register.
If the pad is not in GPIO mode, return an error.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 3b0dfe9a51ba..3c1b71204bbe 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -197,6 +197,16 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
 	return 0;
 }
 
+static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
+
+	if (ioread32(reg) & DIR_BIT)
+		return GPIO_LINE_DIRECTION_IN;
+
+	return GPIO_LINE_DIRECTION_OUT;
+}
+
 static void lp_gpio_irq_handler(struct irq_desc *desc)
 {
 	struct irq_data *data = irq_desc_get_irq_data(desc);
@@ -391,6 +401,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc->direction_output = lp_gpio_direction_output;
 	gc->get = lp_gpio_get;
 	gc->set = lp_gpio_set;
+	gc->get_direction = lp_gpio_get_direction;
 	gc->base = -1;
 	gc->ngpio = LP_NUM_GPIO;
 	gc->can_sleep = false;
-- 
2.24.0


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

* [PATCH v2 18/24] pinctrl: lynxpoint: Add pin control data structures
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (16 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 17/24] pinctrl: lynxpoint: Implement intel_gpio_get_direction callback Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver Andy Shevchenko
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

In order to implement pin control for Intel Lynxpoint, we need
data structures in which to store and pass along pin, community
and SoC data information.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 126 +++++++++++++++++++++-
 1 file changed, 124 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 3c1b71204bbe..ea46bd64226d 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -18,6 +18,128 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
+#include "pinctrl-intel.h"
+
+#define COMMUNITY(p, n)			\
+	{				\
+		.pin_base	= (p),	\
+		.npins		= (n),	\
+	}
+
+static const struct pinctrl_pin_desc lptlp_pins[] = {
+	PINCTRL_PIN(0, "GP0_UART1_RXD"),
+	PINCTRL_PIN(1, "GP1_UART1_TXD"),
+	PINCTRL_PIN(2, "GP2_UART1_RTSB"),
+	PINCTRL_PIN(3, "GP3_UART1_CTSB"),
+	PINCTRL_PIN(4, "GP4_I2C0_SDA"),
+	PINCTRL_PIN(5, "GP5_I2C0_SCL"),
+	PINCTRL_PIN(6, "GP6_I2C1_SDA"),
+	PINCTRL_PIN(7, "GP7_I2C1_SCL"),
+	PINCTRL_PIN(8, "GP8"),
+	PINCTRL_PIN(9, "GP9"),
+	PINCTRL_PIN(10, "GP10"),
+	PINCTRL_PIN(11, "GP11_SMBALERTB"),
+	PINCTRL_PIN(12, "GP12_LANPHYPC"),
+	PINCTRL_PIN(13, "GP13"),
+	PINCTRL_PIN(14, "GP14"),
+	PINCTRL_PIN(15, "GP15"),
+	PINCTRL_PIN(16, "GP16_MGPIO9"),
+	PINCTRL_PIN(17, "GP17_MGPIO10"),
+	PINCTRL_PIN(18, "GP18_SRC0CLKRQB"),
+	PINCTRL_PIN(19, "GP19_SRC1CLKRQB"),
+	PINCTRL_PIN(20, "GP20_SRC2CLKRQB"),
+	PINCTRL_PIN(21, "GP21_SRC3CLKRQB"),
+	PINCTRL_PIN(22, "GP22_SRC4CLKRQB_TRST2"),
+	PINCTRL_PIN(23, "GP23_SRC5CLKRQB_TDI2"),
+	PINCTRL_PIN(24, "GP24_MGPIO0"),
+	PINCTRL_PIN(25, "GP25_USBWAKEOUTB"),
+	PINCTRL_PIN(26, "GP26_MGPIO5"),
+	PINCTRL_PIN(27, "GP27_MGPIO6"),
+	PINCTRL_PIN(28, "GP28_MGPIO7"),
+	PINCTRL_PIN(29, "GP29_SLP_WLANB_MGPIO3"),
+	PINCTRL_PIN(30, "GP30_SUSWARNB_SUSPWRDNACK_MGPIO1"),
+	PINCTRL_PIN(31, "GP31_ACPRESENT_MGPIO2"),
+	PINCTRL_PIN(32, "GP32_CLKRUNB"),
+	PINCTRL_PIN(33, "GP33_DEVSLP0"),
+	PINCTRL_PIN(34, "GP34_SATA0XPCIE6L3B_SATA0GP"),
+	PINCTRL_PIN(35, "GP35_SATA1XPCIE6L2B_SATA1GP"),
+	PINCTRL_PIN(36, "GP36_SATA2XPCIE6L1B_SATA2GP"),
+	PINCTRL_PIN(37, "GP37_SATA3XPCIE6L0B_SATA3GP"),
+	PINCTRL_PIN(38, "GP38_DEVSLP1"),
+	PINCTRL_PIN(39, "GP39_DEVSLP2"),
+	PINCTRL_PIN(40, "GP40_OC0B"),
+	PINCTRL_PIN(41, "GP41_OC1B"),
+	PINCTRL_PIN(42, "GP42_OC2B"),
+	PINCTRL_PIN(43, "GP43_OC3B"),
+	PINCTRL_PIN(44, "GP44"),
+	PINCTRL_PIN(45, "GP45_TMS2"),
+	PINCTRL_PIN(46, "GP46_TDO2"),
+	PINCTRL_PIN(47, "GP47"),
+	PINCTRL_PIN(48, "GP48"),
+	PINCTRL_PIN(49, "GP49"),
+	PINCTRL_PIN(50, "GP50"),
+	PINCTRL_PIN(51, "GP51_GSXDOUT"),
+	PINCTRL_PIN(52, "GP52_GSXSLOAD"),
+	PINCTRL_PIN(53, "GP53_GSXDIN"),
+	PINCTRL_PIN(54, "GP54_GSXSRESETB"),
+	PINCTRL_PIN(55, "GP55_GSXCLK"),
+	PINCTRL_PIN(56, "GP56"),
+	PINCTRL_PIN(57, "GP57"),
+	PINCTRL_PIN(58, "GP58"),
+	PINCTRL_PIN(59, "GP59"),
+	PINCTRL_PIN(60, "GP60_SML0ALERTB_MGPIO4"),
+	PINCTRL_PIN(61, "GP61_SUS_STATB"),
+	PINCTRL_PIN(62, "GP62_SUSCLK"),
+	PINCTRL_PIN(63, "GP63_SLP_S5B"),
+	PINCTRL_PIN(64, "GP64_SDIO_CLK"),
+	PINCTRL_PIN(65, "GP65_SDIO_CMD"),
+	PINCTRL_PIN(66, "GP66_SDIO_D0"),
+	PINCTRL_PIN(67, "GP67_SDIO_D1"),
+	PINCTRL_PIN(68, "GP68_SDIO_D2"),
+	PINCTRL_PIN(69, "GP69_SDIO_D3"),
+	PINCTRL_PIN(70, "GP70_SDIO_POWER_EN"),
+	PINCTRL_PIN(71, "GP71_MPHYPC"),
+	PINCTRL_PIN(72, "GP72_BATLOWB"),
+	PINCTRL_PIN(73, "GP73_SML1ALERTB_PCHHOTB_MGPIO8"),
+	PINCTRL_PIN(74, "GP74_SML1DATA_MGPIO12"),
+	PINCTRL_PIN(75, "GP75_SML1CLK_MGPIO11"),
+	PINCTRL_PIN(76, "GP76_BMBUSYB"),
+	PINCTRL_PIN(77, "GP77_PIRQAB"),
+	PINCTRL_PIN(78, "GP78_PIRQBB"),
+	PINCTRL_PIN(79, "GP79_PIRQCB"),
+	PINCTRL_PIN(80, "GP80_PIRQDB"),
+	PINCTRL_PIN(81, "GP81_SPKR"),
+	PINCTRL_PIN(82, "GP82_RCINB"),
+	PINCTRL_PIN(83, "GP83_GSPI0_CSB"),
+	PINCTRL_PIN(84, "GP84_GSPI0_CLK"),
+	PINCTRL_PIN(85, "GP85_GSPI0_MISO"),
+	PINCTRL_PIN(86, "GP86_GSPI0_MOSI"),
+	PINCTRL_PIN(87, "GP87_GSPI1_CSB"),
+	PINCTRL_PIN(88, "GP88_GSPI1_CLK"),
+	PINCTRL_PIN(89, "GP89_GSPI1_MISO"),
+	PINCTRL_PIN(90, "GP90_GSPI1_MOSI"),
+	PINCTRL_PIN(91, "GP91_UART0_RXD"),
+	PINCTRL_PIN(92, "GP92_UART0_TXD"),
+	PINCTRL_PIN(93, "GP93_UART0_RTSB"),
+	PINCTRL_PIN(94, "GP94_UART0_CTSB"),
+};
+
+static const struct intel_community lptlp_communities[] = {
+	COMMUNITY(0, 95),
+};
+
+static const struct intel_pinctrl_soc_data lptlp_soc_data = {
+	.pins		= lptlp_pins,
+	.npins		= ARRAY_SIZE(lptlp_pins),
+	.communities	= lptlp_communities,
+	.ncommunities	= ARRAY_SIZE(lptlp_communities),
+};
+
 /* LynxPoint chipset has support for 95 GPIO pins */
 
 #define LP_NUM_GPIO	95
@@ -477,8 +599,8 @@ static const struct dev_pm_ops lp_gpio_pm_ops = {
 };
 
 static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = {
-	{ "INT33C7", 0 },
-	{ "INT3437", 0 },
+	{ "INT33C7", (kernel_ulong_t)&lptlp_soc_data },
+	{ "INT3437", (kernel_ulong_t)&lptlp_soc_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
-- 
2.24.0


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

* [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (17 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 18/24] pinctrl: lynxpoint: Add pin control data structures Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-10  5:26   ` kbuild test robot
  2019-12-09 13:09 ` [PATCH v2 20/24] pinctrl: lynxpoint: Add pin control operations Andy Shevchenko
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

We may use now available struct intel_pinctrl in the driver.
No functional change implied.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 84 ++++++++++++++++-------
 1 file changed, 60 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index ea46bd64226d..5a8c77c8306b 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -168,13 +168,6 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
 #define GPINDIS_BIT	BIT(2) /* disable input sensing */
 #define GPIWP_BIT	(BIT(0) | BIT(1)) /* weak pull options */
 
-struct lp_gpio {
-	struct gpio_chip	chip;
-	struct device		*dev;
-	raw_spinlock_t		lock;
-	void __iomem		*regs;
-};
-
 /*
  * Lynxpoint gpios are controlled through both bitmapped registers and
  * per gpio specific registers. The bitmapped registers are in chunks of
@@ -204,12 +197,34 @@ struct lp_gpio {
  * LP94_CONFIG2 (gpio 94) ...
  */
 
+static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
+						unsigned int pin)
+{
+	struct intel_community *comm;
+	int i;
+
+	for (i = 0; i < lg->ncommunities; i++) {
+		comm = &lg->communities[i];
+		if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
+			return comm;
+	}
+
+	return NULL;
+}
+
 static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
 				 int reg)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
+	struct intel_community *comm;
 	int reg_offset;
 
+	comm = lp_get_community(lg, offset);
+	if (!comm)
+		return NULL;
+
+	offset -= comm->pin_base;
+
 	if (reg == LP_CONFIG1 || reg == LP_CONFIG2)
 		/* per gpio specific config registers */
 		reg_offset = offset * 8;
@@ -217,10 +232,10 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
 		/* bitmapped registers */
 		reg_offset = (offset / 32) * 4;
 
-	return lg->regs + reg + reg_offset;
+	return comm->regs + reg_offset + reg;
 }
 
-static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin)
+static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
 {
 	void __iomem *acpi_use;
 
@@ -233,7 +248,7 @@ static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin)
 
 static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
 	u32 value;
@@ -259,7 +274,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 
 static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
 
 	/* disable input sensing */
@@ -276,7 +291,7 @@ static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset)
 
 static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
@@ -292,7 +307,7 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
 
 static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
@@ -306,7 +321,7 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
 static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
 				    int value)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
 	unsigned long flags;
 
@@ -333,7 +348,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 {
 	struct irq_data *data = irq_desc_get_irq_data(desc);
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
+	struct intel_pinctrl *lg = gpiochip_get_data(gc);
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	void __iomem *reg, *ena;
 	unsigned long pending;
@@ -360,7 +375,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 static void lp_irq_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
+	struct intel_pinctrl *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
 	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT);
 	unsigned long flags;
@@ -381,7 +396,7 @@ static void lp_irq_mask(struct irq_data *d)
 static void lp_irq_enable(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
+	struct intel_pinctrl *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
 	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
@@ -394,7 +409,7 @@ static void lp_irq_enable(struct irq_data *d)
 static void lp_irq_disable(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
+	struct intel_pinctrl *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
 	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
@@ -407,7 +422,7 @@ static void lp_irq_disable(struct irq_data *d)
 static int lp_irq_set_type(struct irq_data *d, unsigned int type)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct lp_gpio *lg = gpiochip_get_data(gc);
+	struct intel_pinctrl *lg = gpiochip_get_data(gc);
 	u32 hwirq = irqd_to_hwirq(d);
 	void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
 	unsigned long flags;
@@ -466,7 +481,7 @@ static struct irq_chip lp_irqchip = {
 
 static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
 {
-	struct lp_gpio *lg = gpiochip_get_data(chip);
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
 	void __iomem *reg;
 	unsigned int base;
 
@@ -484,18 +499,32 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
 
 static int lp_gpio_probe(struct platform_device *pdev)
 {
-	struct lp_gpio *lg;
+	const struct intel_pinctrl_soc_data *soc;
+	struct intel_pinctrl *lg;
 	struct gpio_chip *gc;
 	struct resource *io_rc, *irq_rc;
 	struct device *dev = &pdev->dev;
 	void __iomem *regs;
+	unsigned int i;
 	int ret;
 
+	soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev);
+	if (!soc)
+		return -ENODEV;
+
 	lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL);
 	if (!lg)
 		return -ENOMEM;
 
 	lg->dev = dev;
+	lg->soc = soc;
+
+	lg->ncommunities = lg->soc->ncommunities;
+	lg->communities = devm_kcalloc(dev, lg->ncommunities,
+				       sizeof(*lg->communities), GFP_KERNEL);
+	if (!lg->communities)
+		return -ENOMEM;
+
 	platform_set_drvdata(pdev, lg);
 
 	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -510,7 +539,14 @@ static int lp_gpio_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	lg->regs = regs;
+	for (i = 0; i < lg->soc->ncommunities; i++) {
+		struct intel_community *comm = &lg->communities[i];
+
+		*comm = lg->soc->communities[i];
+
+		comm->regs = regs;
+		comm->pad_regs = regs + 0x100;
+	}
 
 	raw_spin_lock_init(&lg->lock);
 
@@ -578,7 +614,7 @@ static int lp_gpio_runtime_resume(struct device *dev)
 
 static int lp_gpio_resume(struct device *dev)
 {
-	struct lp_gpio *lg = dev_get_drvdata(dev);
+	struct intel_pinctrl *lg = dev_get_drvdata(dev);
 	void __iomem *reg;
 	int i;
 
-- 
2.24.0


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

* [PATCH v2 20/24] pinctrl: lynxpoint: Add pin control operations
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (18 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 21/24] pinctrl: lynxpoint: Implement ->pin_dbg_show() Andy Shevchenko
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Add implementation for:
    - pin control, group information retrieval: count, name and pins
    - pin muxing:
      - function information (count, name and groups)
      - mux setting
      - GPIO control (enable, disable, set direction)
    - pin configuration:
      - pull disable, up and down
      - any other option is treated as not supported.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 315 +++++++++++++++++++++-
 1 file changed, 314 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 5a8c77c8306b..c209deff9efb 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -146,6 +146,7 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
 
 /* Bitmapped register offsets */
 #define LP_ACPI_OWNED	0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */
+#define LP_IRQ2IOXAPIC	0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */
 #define LP_GC		0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */
 #define LP_INT_STAT	0x80
 #define LP_INT_ENABLE	0x90
@@ -166,7 +167,10 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
 
 /* LP_CONFIG2 reg bits */
 #define GPINDIS_BIT	BIT(2) /* disable input sensing */
-#define GPIWP_BIT	(BIT(0) | BIT(1)) /* weak pull options */
+#define GPIWP_MASK	GENMASK(1, 0)	/* weak pull options */
+#define GPIWP_NONE	0		/* none */
+#define GPIWP_DOWN	1		/* weak pull down */
+#define GPIWP_UP	2		/* weak pull up */
 
 /*
  * Lynxpoint gpios are controlled through both bitmapped registers and
@@ -195,6 +199,8 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = {
  * ...
  * LP94_CONFIG1 (gpio 94) ...
  * LP94_CONFIG2 (gpio 94) ...
+ *
+ * IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55.
  */
 
 static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
@@ -246,6 +252,308 @@ static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
 	return !(ioread32(acpi_use) & BIT(pin % 32));
 }
 
+static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset)
+{
+	void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC);
+	u32 value;
+
+	value = ioread32(ioxapic_use);
+
+	if (offset >= 8 && offset <= 10)
+		return !!(value & BIT(offset -  8 + 0));
+	if (offset >= 13 && offset <= 14)
+		return !!(value & BIT(offset - 13 + 3));
+	if (offset >= 45 && offset <= 55)
+		return !!(value & BIT(offset - 45 + 5));
+
+	return false;
+}
+
+static int lp_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	return lg->soc->ngroups;
+}
+
+static const char *lp_get_group_name(struct pinctrl_dev *pctldev,
+				     unsigned int selector)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	return lg->soc->groups[selector].name;
+}
+
+static int lp_get_group_pins(struct pinctrl_dev *pctldev,
+			     unsigned int selector,
+			     const unsigned int **pins,
+			     unsigned int *num_pins)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins		= lg->soc->groups[selector].pins;
+	*num_pins	= lg->soc->groups[selector].npins;
+
+	return 0;
+}
+
+static const struct pinctrl_ops lptlp_pinctrl_ops = {
+	.get_groups_count	= lp_get_groups_count,
+	.get_group_name		= lp_get_group_name,
+	.get_group_pins		= lp_get_group_pins,
+};
+
+static int lp_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	return lg->soc->nfunctions;
+}
+
+static const char *lp_get_function_name(struct pinctrl_dev *pctldev,
+					unsigned int selector)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	return lg->soc->functions[selector].name;
+}
+
+static int lp_get_function_groups(struct pinctrl_dev *pctldev,
+				  unsigned int selector,
+				  const char * const **groups,
+				  unsigned int *num_groups)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups		= lg->soc->functions[selector].groups;
+	*num_groups	= lg->soc->functions[selector].ngroups;
+
+	return 0;
+}
+
+static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev,
+			     unsigned int function, unsigned int group)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	const struct intel_pingroup *grp = &lg->soc->groups[group];
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+
+	/* Now enable the mux setting for each pin in the group */
+	for (i = 0; i < grp->npins; i++) {
+		void __iomem *reg = lp_gpio_reg(&lg->chip, grp->pins[i], LP_CONFIG1);
+		u32 value;
+
+		value = ioread32(reg);
+
+		value &= ~USE_SEL_MASK;
+		if (grp->modes)
+			value |= grp->modes[i];
+		else
+			value |= grp->mode;
+
+		iowrite32(value, reg);
+	}
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	return 0;
+}
+
+static int lp_gpio_request_enable(struct pinctrl_dev *pctldev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned int pin)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
+	void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
+	unsigned long flags;
+	u32 value;
+
+	pm_runtime_get(lg->dev);
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+
+	/*
+	 * Reconfigure pin to GPIO mode if needed and issue a warning,
+	 * since we expect firmware to configure it properly.
+	 */
+	value = ioread32(reg);
+	if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
+		iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
+		dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin);
+	}
+
+	/* Enable input sensing */
+	iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2);
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	return 0;
+}
+
+static void lp_gpio_disable_free(struct pinctrl_dev *pctldev,
+				 struct pinctrl_gpio_range *range,
+				 unsigned int pin)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+
+	/* Disable input sensing */
+	iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2);
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	pm_runtime_put(lg->dev);
+}
+
+static int lp_gpio_set_direction(struct pinctrl_dev *pctldev,
+				 struct pinctrl_gpio_range *range,
+				 unsigned int pin, bool input)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
+	unsigned long flags;
+	u32 value;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+
+	value = ioread32(reg);
+	value &= ~DIR_BIT;
+	if (input) {
+		value |= DIR_BIT;
+	} else {
+		/*
+		 * Before making any direction modifications, do a check if GPIO
+		 * is set for direct IRQ. On Lynxpoint, setting GPIO to output
+		 * does not make sense, so let's at least warn the caller before
+		 * they shoot themselves in the foot.
+		 */
+		WARN(lp_gpio_ioxapic_use(&lg->chip, pin),
+		     "Potential Error: Setting GPIO to output with IOxAPIC redirection");
+	}
+	iowrite32(value, reg);
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	return 0;
+}
+
+static const struct pinmux_ops lptlp_pinmux_ops = {
+	.get_functions_count	= lp_get_functions_count,
+	.get_function_name	= lp_get_function_name,
+	.get_function_groups	= lp_get_function_groups,
+	.set_mux		= lp_pinmux_set_mux,
+	.gpio_request_enable	= lp_gpio_request_enable,
+	.gpio_disable_free	= lp_gpio_disable_free,
+	.gpio_set_direction	= lp_gpio_set_direction,
+};
+
+static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+			     unsigned long *config)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned long flags;
+	u32 value, pull;
+	u16 arg = 0;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+	value = ioread32(conf2);
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	pull = value & GPIWP_MASK;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pull)
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (pull != GPIWP_DOWN)
+			return -EINVAL;
+
+		arg = 1;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (pull != GPIWP_UP)
+			return -EINVAL;
+
+		arg = 1;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			     unsigned long *configs, unsigned int num_configs)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
+	enum pin_config_param param;
+	unsigned long flags;
+	int i, ret = 0;
+	u32 value;
+
+	raw_spin_lock_irqsave(&lg->lock, flags);
+
+	value = ioread32(conf2);
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			value &= ~GPIWP_MASK;
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			value &= ~GPIWP_MASK;
+			value |= GPIWP_DOWN;
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			value &= ~GPIWP_MASK;
+			value |= GPIWP_UP;
+			break;
+		default:
+			ret = -ENOTSUPP;
+		}
+
+		if (ret)
+			break;
+	}
+
+	if (!ret)
+		iowrite32(value, conf2);
+
+	raw_spin_unlock_irqrestore(&lg->lock, flags);
+
+	return ret;
+}
+
+static const struct pinconf_ops lptlp_pinconf_ops = {
+	.is_generic	= true,
+	.pin_config_get	= lp_pin_config_get,
+	.pin_config_set	= lp_pin_config_set,
+};
+
+static const struct pinctrl_desc lptlp_pinctrl_desc = {
+	.pctlops	= &lptlp_pinctrl_ops,
+	.pmxops		= &lptlp_pinmux_ops,
+	.confops	= &lptlp_pinconf_ops,
+	.owner		= THIS_MODULE,
+};
+
 static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
 	struct intel_pinctrl *lg = gpiochip_get_data(chip);
@@ -525,6 +833,11 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	if (!lg->communities)
 		return -ENOMEM;
 
+	lg->pctldesc           = lptlp_pinctrl_desc;
+	lg->pctldesc.name      = dev_name(dev);
+	lg->pctldesc.pins      = lg->soc->pins;
+	lg->pctldesc.npins     = lg->soc->npins;
+
 	platform_set_drvdata(pdev, lg);
 
 	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
-- 
2.24.0


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

* [PATCH v2 21/24] pinctrl: lynxpoint: Implement ->pin_dbg_show()
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (19 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 20/24] pinctrl: lynxpoint: Add pin control operations Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 22/24] pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback Andy Shevchenko
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

The introduced callback ->pin_dbg_show() is useful for debugging.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index c209deff9efb..bfdd283d2c20 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -297,10 +297,33 @@ static int lp_get_group_pins(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
+static void lp_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+			    unsigned int pin)
+{
+	struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
+	void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
+	void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
+	u32 value, mode;
+
+	value = ioread32(reg);
+
+	mode = value & USE_SEL_MASK;
+	if (mode == USE_SEL_GPIO)
+		seq_puts(s, "GPIO ");
+	else
+		seq_printf(s, "mode %d ", mode);
+
+	seq_printf(s, "0x%08x 0x%08x", value, ioread32(conf2));
+
+	if (lp_gpio_acpi_use(lg, pin))
+		seq_puts(s, " [ACPI]");
+}
+
 static const struct pinctrl_ops lptlp_pinctrl_ops = {
 	.get_groups_count	= lp_get_groups_count,
 	.get_group_name		= lp_get_group_name,
 	.get_group_pins		= lp_get_group_pins,
+	.pin_dbg_show		= lp_pin_dbg_show,
 };
 
 static int lp_get_functions_count(struct pinctrl_dev *pctldev)
-- 
2.24.0


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

* [PATCH v2 22/24] pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (20 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 21/24] pinctrl: lynxpoint: Implement ->pin_dbg_show() Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 23/24] pinctrl: lynxpoint: Switch to pin control API Andy Shevchenko
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

When IRQ chip is instantiated via GPIO library flow, the few functions,
in particular the ACPI event registration mechanism, on some of ACPI based
platforms expect that the pin ranges are initialized to that point.

Add GPIO <-> pin mapping ranges via callback in the GPIO library flow.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index bfdd283d2c20..795a9c7054ca 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -828,6 +828,19 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
 	return 0;
 }
 
+static int lp_gpio_add_pin_ranges(struct gpio_chip *chip)
+{
+	struct intel_pinctrl *lg = gpiochip_get_data(chip);
+	struct device *dev = lg->dev;
+	int ret;
+
+	ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins);
+	if (ret)
+		dev_err(dev, "failed to add GPIO pin range\n");
+
+	return ret;
+}
+
 static int lp_gpio_probe(struct platform_device *pdev)
 {
 	const struct intel_pinctrl_soc_data *soc;
@@ -899,6 +912,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc->base = -1;
 	gc->ngpio = LP_NUM_GPIO;
 	gc->can_sleep = false;
+	gc->add_pin_ranges = lp_gpio_add_pin_ranges;
 	gc->parent = dev;
 
 	/* set up interrupts  */
-- 
2.24.0


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

* [PATCH v2 23/24] pinctrl: lynxpoint: Switch to pin control API
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (21 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 22/24] pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-09 13:09 ` [PATCH v2 24/24] pinctrl: lynxpoint: Update summary in the driver Andy Shevchenko
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

When all preparations are done, we may switch to pin control API.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/Kconfig             |  3 +
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 67 ++++-------------------
 2 files changed, 13 insertions(+), 57 deletions(-)

diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index c2e6bc9e3e04..ee440ec4c94c 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -34,6 +34,9 @@ config PINCTRL_CHERRYVIEW
 config PINCTRL_LYNXPOINT
 	tristate "Intel Lynxpoint pinctrl and GPIO driver"
 	depends on ACPI
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
 	help
diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 795a9c7054ca..774b226f3a4d 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -577,43 +577,6 @@ static const struct pinctrl_desc lptlp_pinctrl_desc = {
 	.owner		= THIS_MODULE,
 };
 
-static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset)
-{
-	struct intel_pinctrl *lg = gpiochip_get_data(chip);
-	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
-	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
-	u32 value;
-
-	pm_runtime_get(lg->dev); /* should we put if failed */
-
-	/*
-	 * Reconfigure pin to GPIO mode if needed and issue a warning,
-	 * since we expect firmware to configure it properly.
-	 */
-	value = ioread32(reg);
-	if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
-		iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
-		dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset);
-	}
-
-	/* enable input sensing */
-	iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2);
-
-
-	return 0;
-}
-
-static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset)
-{
-	struct intel_pinctrl *lg = gpiochip_get_data(chip);
-	void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
-
-	/* disable input sensing */
-	iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2);
-
-	pm_runtime_put(lg->dev);
-}
-
 static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
@@ -638,31 +601,15 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
 
 static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
 {
-	struct intel_pinctrl *lg = gpiochip_get_data(chip);
-	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&lg->lock, flags);
-	iowrite32(ioread32(reg) | DIR_BIT, reg);
-	raw_spin_unlock_irqrestore(&lg->lock, flags);
-
-	return 0;
+	return pinctrl_gpio_direction_input(chip->base + offset);
 }
 
 static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
 				    int value)
 {
-	struct intel_pinctrl *lg = gpiochip_get_data(chip);
-	void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
-	unsigned long flags;
-
 	lp_gpio_set(chip, offset, value);
 
-	raw_spin_lock_irqsave(&lg->lock, flags);
-	iowrite32(ioread32(reg) & ~DIR_BIT, reg);
-	raw_spin_unlock_irqrestore(&lg->lock, flags);
-
-	return 0;
+	return pinctrl_gpio_direction_output(chip->base + offset);
 }
 
 static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
@@ -874,6 +821,12 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	lg->pctldesc.pins      = lg->soc->pins;
 	lg->pctldesc.npins     = lg->soc->npins;
 
+	lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg);
+	if (IS_ERR(lg->pctldev)) {
+		dev_err(dev, "failed to register pinctrl driver\n");
+		return PTR_ERR(lg->pctldev);
+	}
+
 	platform_set_drvdata(pdev, lg);
 
 	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -902,8 +855,8 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc = &lg->chip;
 	gc->label = dev_name(dev);
 	gc->owner = THIS_MODULE;
-	gc->request = lp_gpio_request;
-	gc->free = lp_gpio_free;
+	gc->request = gpiochip_generic_request;
+	gc->free = gpiochip_generic_free;
 	gc->direction_input = lp_gpio_direction_input;
 	gc->direction_output = lp_gpio_direction_output;
 	gc->get = lp_gpio_get;
-- 
2.24.0


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

* [PATCH v2 24/24] pinctrl: lynxpoint: Update summary in the driver
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (22 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 23/24] pinctrl: lynxpoint: Switch to pin control API Andy Shevchenko
@ 2019-12-09 13:09 ` Andy Shevchenko
  2019-12-11 13:19 ` [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Mika Westerberg
  2019-12-13 13:36 ` Linus Walleij
  25 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-09 13:09 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Mika Westerberg
  Cc: Andy Shevchenko

Reflect in the driver that it is now a pin control one.

While here, update copyright years and authors.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 774b226f3a4d..e928742c7181 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -1,9 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * GPIO controller driver for Intel Lynxpoint PCH chipset>
- * Copyright (c) 2012, Intel Corporation.
+ * Intel Lynxpoint PCH pinctrl/GPIO driver
  *
- * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
+ * Copyright (c) 2012, 2019, Intel Corporation
+ * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *          Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  */
 
 #include <linux/acpi.h>
@@ -968,6 +969,7 @@ subsys_initcall(lp_gpio_init);
 module_exit(lp_gpio_exit);
 
 MODULE_AUTHOR("Mathias Nyman (Intel)");
-MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint");
+MODULE_AUTHOR("Andy Shevchenko (Intel)");
+MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:lp_gpio");
-- 
2.24.0


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

* Re: [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
  2019-12-09 13:09 ` [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver Andy Shevchenko
@ 2019-12-10  5:26   ` kbuild test robot
  2019-12-10 13:46     ` Andy Shevchenko
  0 siblings, 1 reply; 32+ messages in thread
From: kbuild test robot @ 2019-12-10  5:26 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 10964 bytes --]

Hi Andy,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on gpio/for-next v5.5-rc1 next-20191209]
[cannot apply to pinctrl/devel]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Andy-Shevchenko/pinctrl-intel-Move-Lynxpoint-to-pin-control-umbrella/20191210-030030
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e42617b825f8073569da76dc4510bfa019b1c35a
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.5.0-1) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

>> drivers/pinctrl/intel/pinctrl-lynxpoint.c:200:56: warning: 'struct intel_pinctrl' declared inside parameter list will not be visible outside of this definition or declaration
    static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
                                                           ^~~~~~~~~~~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_get_community':
>> drivers/pinctrl/intel/pinctrl-lynxpoint.c:206:20: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     for (i = 0; i < lg->ncommunities; i++) {
                       ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_reg':
>> drivers/pinctrl/intel/pinctrl-lynxpoint.c:222:26: error: passing argument 1 of 'lp_get_community' from incompatible pointer type [-Werror=incompatible-pointer-types]
     comm = lp_get_community(lg, offset);
                             ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:200:32: note: expected 'struct intel_pinctrl *' but argument is of type 'struct intel_pinctrl *'
    static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
                                   ^~~~~~~~~~~~~~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: At top level:
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:238:37: warning: 'struct intel_pinctrl' declared inside parameter list will not be visible outside of this definition or declaration
    static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
                                        ^~~~~~~~~~~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_acpi_use':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:242:28: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     acpi_use = lp_gpio_reg(&lg->chip, pin, LP_ACPI_OWNED);
                               ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_request':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:256:19: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     pm_runtime_get(lg->dev); /* should we put if failed */
                      ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_free':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:283:19: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     pm_runtime_put(lg->dev);
                      ^~
   In file included from include/linux/radix-tree.h:16:0,
                    from include/linux/idr.h:15,
                    from include/linux/kernfs.h:13,
                    from include/linux/sysfs.h:16,
                    from include/linux/kobject.h:20,
                    from include/linux/of.h:17,
                    from include/linux/irqdomain.h:35,
                    from include/linux/acpi.h:13,
                    from drivers/pinctrl/intel/pinctrl-lynxpoint.c:9:
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_set':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:298:27: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     raw_spin_lock_irqsave(&lg->lock, flags);
                              ^
   include/linux/spinlock.h:250:34: note: in definition of macro 'raw_spin_lock_irqsave'
      flags = _raw_spin_lock_irqsave(lock); \
                                     ^~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_direction_input':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:314:27: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     raw_spin_lock_irqsave(&lg->lock, flags);
                              ^
   include/linux/spinlock.h:250:34: note: in definition of macro 'raw_spin_lock_irqsave'
      flags = _raw_spin_lock_irqsave(lock); \
                                     ^~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_direction_output':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:330:27: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     raw_spin_lock_irqsave(&lg->lock, flags);
                              ^
   include/linux/spinlock.h:250:34: note: in definition of macro 'raw_spin_lock_irqsave'
      flags = _raw_spin_lock_irqsave(lock); \
                                     ^~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_irq_handler':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:358:26: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     for (base = 0; base < lg->chip.ngpio; base += 32) {
                             ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_irq_ack':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:380:37: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT);
                                        ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_irq_enable':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:401:37: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
                                        ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_irq_disable':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:414:37: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
                                        ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_irq_set_type':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:427:37: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
                                        ^~
>> drivers/pinctrl/intel/pinctrl-lynxpoint.c:435:23: error: passing argument 1 of 'lp_gpio_acpi_use' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (lp_gpio_acpi_use(lg, hwirq)) {
                          ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:238:13: note: expected 'struct intel_pinctrl *' but argument is of type 'struct intel_pinctrl *'
    static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
                ^~~~~~~~~~~~~~~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_irq_init_hw':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:488:26: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     for (base = 0; base < lg->chip.ngpio; base += 32) {
                             ^~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_probe':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:515:32: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL);
                                   ^~~
   drivers/pinctrl/intel/pinctrl-lynxpoint.c: In function 'lp_gpio_resume':
   drivers/pinctrl/intel/pinctrl-lynxpoint.c:622:20: error: dereferencing pointer to incomplete type 'struct intel_pinctrl'
     for (i = 0; i < lg->chip.ngpio; i++) {
                       ^~
   cc1: some warnings being treated as errors

vim +206 drivers/pinctrl/intel/pinctrl-lynxpoint.c

   170	
   171	/*
   172	 * Lynxpoint gpios are controlled through both bitmapped registers and
   173	 * per gpio specific registers. The bitmapped registers are in chunks of
   174	 * 3 x 32bit registers to cover all 95 GPIOs
   175	 *
   176	 * per gpio specific registers consist of two 32bit registers per gpio
   177	 * (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of
   178	 * 190 config registers.
   179	 *
   180	 * A simplified view of the register layout look like this:
   181	 *
   182	 * LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31  (bitmapped registers)
   183	 * LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63
   184	 * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94
   185	 * ...
   186	 * LP_INT_ENABLE[31:0] ...
   187	 * LP_INT_ENABLE[63:32] ...
   188	 * LP_INT_ENABLE[94:64] ...
   189	 * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers)
   190	 * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0
   191	 * LP1_CONFIG1 (gpio 1) config1 reg for gpio 1
   192	 * LP1_CONFIG2 (gpio 1) config2 reg for gpio 1
   193	 * LP2_CONFIG1 (gpio 2) ...
   194	 * LP2_CONFIG2 (gpio 2) ...
   195	 * ...
   196	 * LP94_CONFIG1 (gpio 94) ...
   197	 * LP94_CONFIG2 (gpio 94) ...
   198	 */
   199	
 > 200	static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
   201							unsigned int pin)
   202	{
   203		struct intel_community *comm;
   204		int i;
   205	
 > 206		for (i = 0; i < lg->ncommunities; i++) {
   207			comm = &lg->communities[i];
   208			if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
   209				return comm;
   210		}
   211	
   212		return NULL;
   213	}
   214	
   215	static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
   216					 int reg)
   217	{
   218		struct intel_pinctrl *lg = gpiochip_get_data(chip);
   219		struct intel_community *comm;
   220		int reg_offset;
   221	
 > 222		comm = lp_get_community(lg, offset);
   223		if (!comm)
   224			return NULL;
   225	
   226		offset -= comm->pin_base;
   227	
   228		if (reg == LP_CONFIG1 || reg == LP_CONFIG2)
   229			/* per gpio specific config registers */
   230			reg_offset = offset * 8;
   231		else
   232			/* bitmapped registers */
   233			reg_offset = (offset / 32) * 4;
   234	
   235		return comm->regs + reg_offset + reg;
   236	}
   237	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org Intel Corporation

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 71141 bytes --]

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

* Re: [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
  2019-12-10  5:26   ` kbuild test robot
@ 2019-12-10 13:46     ` Andy Shevchenko
  2019-12-10 13:47       ` Andy Shevchenko
  0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-10 13:46 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

On Tue, Dec 10, 2019 at 01:26:02PM +0800, kbuild test robot wrote:
> Hi Andy,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on linus/master]
> [also build test ERROR on gpio/for-next v5.5-rc1 next-20191209]
> [cannot apply to pinctrl/devel]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system. BTW, we also suggest to use '--base' option to specify the
> base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
> 
> url:    https://github.com/0day-ci/linux/commits/Andy-Shevchenko/pinctrl-intel-Move-Lynxpoint-to-pin-control-umbrella/20191210-030030
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e42617b825f8073569da76dc4510bfa019b1c35a
> config: x86_64-allyesconfig (attached as .config)
> compiler: gcc-7 (Debian 7.5.0-1) 7.5.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 

It's false positive. It requires dependency patch that will be part of the other series.



-- 
With Best Regards,
Andy Shevchenko


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

* Re: [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
  2019-12-10 13:46     ` Andy Shevchenko
@ 2019-12-10 13:47       ` Andy Shevchenko
  0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-10 13:47 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1327 bytes --]

On Tue, Dec 10, 2019 at 03:46:30PM +0200, Andy Shevchenko wrote:
> On Tue, Dec 10, 2019 at 01:26:02PM +0800, kbuild test robot wrote:
> > Hi Andy,
> > 
> > I love your patch! Yet something to improve:
> > 
> > [auto build test ERROR on linus/master]
> > [also build test ERROR on gpio/for-next v5.5-rc1 next-20191209]
> > [cannot apply to pinctrl/devel]
> > [if your patch is applied to the wrong git tree, please drop us a note to help
> > improve the system. BTW, we also suggest to use '--base' option to specify the
> > base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Andy-Shevchenko/pinctrl-intel-Move-Lynxpoint-to-pin-control-umbrella/20191210-030030
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e42617b825f8073569da76dc4510bfa019b1c35a
> > config: x86_64-allyesconfig (attached as .config)
> > compiler: gcc-7 (Debian 7.5.0-1) 7.5.0
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=x86_64 
> 
> It's false positive. It requires dependency patch that will be part of the other series.

If maintainers want me to resend with that patch being the first, I will do
that in the v3.

-- 
With Best Regards,
Andy Shevchenko


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

* Re: [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (23 preceding siblings ...)
  2019-12-09 13:09 ` [PATCH v2 24/24] pinctrl: lynxpoint: Update summary in the driver Andy Shevchenko
@ 2019-12-11 13:19 ` Mika Westerberg
  2019-12-13 13:36 ` Linus Walleij
  25 siblings, 0 replies; 32+ messages in thread
From: Mika Westerberg @ 2019-12-11 13:19 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: Linus Walleij, Bartosz Golaszewski, linux-gpio

On Mon, Dec 09, 2019 at 03:09:02PM +0200, Andy Shevchenko wrote:
> Andy Shevchenko (24):
>   pinctrl: lynxpoint: Move GPIO driver to pin controller folder
>   pinctrl: lynxpoint: Use raw_spinlock for locking
>   pinctrl: lynxpoint: Correct amount of pins
>   pinctrl: lynxpoint: Drop useless assignment
>   pinctrl: lynxpoint: Use %pR to print IO resource
>   pinctrl: lynxpoint: Use standard pattern for memory allocation
>   pinctrl: lynxpoint: Assume 2 bits for mode selector
>   pinctrl: lynxpoint: Relax GPIO request rules
>   pinctrl: lynxpoint: Keep pointer to struct device instead of its
>     container
>   pinctrl: lynxpoint: Switch to memory mapped IO accessors
>   pinctrl: lynxpoint: Convert unsigned to unsigned int
>   pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use
>   pinctrl: lynxpoint: Move ->remove closer to ->probe()
>   pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines
>   pinctrl: lynxpoint: Move ownership check to IRQ chip
>   pinctrl: lynxpoint: Implement ->irq_ack() callback
>   pinctrl: lynxpoint: Implement intel_gpio_get_direction callback
>   pinctrl: lynxpoint: Add pin control data structures
>   pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver
>   pinctrl: lynxpoint: Add pin control operations
>   pinctrl: lynxpoint: Implement ->pin_dbg_show()
>   pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback
>   pinctrl: lynxpoint: Switch to pin control API
>   pinctrl: lynxpoint: Update summary in the driver

Looks great to me! For the whole series,

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>

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

* Re: [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella
  2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
                   ` (24 preceding siblings ...)
  2019-12-11 13:19 ` [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Mika Westerberg
@ 2019-12-13 13:36 ` Linus Walleij
  2019-12-13 14:44   ` Andy Shevchenko
  25 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2019-12-13 13:36 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Bartosz Golaszewski, open list:GPIO SUBSYSTEM, Mika Westerberg

On Mon, Dec 9, 2019 at 2:09 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> Intel Lynxpoint GPIO is actually half way to the Chassis specification
> that has been established starting from Intel Skylake. It has some pin control
> properties we may utilize. To achieve this, move the driver under pin control
> umbrella and do a bunch of clean ups.
>
> The series has been tested on Broadwell Ultrabook where Lynxpoint GPIO
> is exposed to the OS.
>
> It has a dependency to patches in my review branch [1]. That dependency patch
> is supposed to be submitted soon as a part of Baytrail clean up. In the
> mentioned branch the patches are represented in the correct order.
>
> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git/log/?h=review-andy
>
> Changes v2:
> - fixed ordering in Kconfig and Makefile (Mika)
> - finished conversion to pin control

This is some really nice development and just go ahead:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

If you want to make my life simple could you do this:

- One pull request just moving the driver to the pin control
  subsystem. I will pull this into both the pinctrl and the GPIO
  tree.

- One pull request based on top of the last commit in the first
  pull request with just the rest of refactorings and improvements.
  I will just pull this into the pinctrl tree on top of the moved driver.

Yours,
Linus Walleij

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

* Re: [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella
  2019-12-13 13:36 ` Linus Walleij
@ 2019-12-13 14:44   ` Andy Shevchenko
  2019-12-16 10:19     ` Linus Walleij
  0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2019-12-13 14:44 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Bartosz Golaszewski, open list:GPIO SUBSYSTEM, Mika Westerberg

On Fri, Dec 13, 2019 at 02:36:36PM +0100, Linus Walleij wrote:
> On Mon, Dec 9, 2019 at 2:09 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> 
> > Intel Lynxpoint GPIO is actually half way to the Chassis specification
> > that has been established starting from Intel Skylake. It has some pin control
> > properties we may utilize. To achieve this, move the driver under pin control
> > umbrella and do a bunch of clean ups.
> >
> > The series has been tested on Broadwell Ultrabook where Lynxpoint GPIO
> > is exposed to the OS.
> >
> > It has a dependency to patches in my review branch [1]. That dependency patch
> > is supposed to be submitted soon as a part of Baytrail clean up. In the
> > mentioned branch the patches are represented in the correct order.
> >
> > [1]: https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git/log/?h=review-andy
> >
> > Changes v2:
> > - fixed ordering in Kconfig and Makefile (Mika)
> > - finished conversion to pin control
> 
> This is some really nice development and just go ahead:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> If you want to make my life simple could you do this:

I want, though I think above makes it harder. I'll not expecting any patches
against gpio-lynxpoint.c (and if they will be an author should Cc me anyway).
Besides the series nicely grouped on top of prerequisites which are solely
Intel pin control (no need for GPIO). Thus I prefer to send simple 1 PR during
this cycle to pin control subsystem and that's it.

Tell me if you think it won't work.

> - One pull request just moving the driver to the pin control
>   subsystem. I will pull this into both the pinctrl and the GPIO
>   tree.
> 
> - One pull request based on top of the last commit in the first
>   pull request with just the rest of refactorings and improvements.
>   I will just pull this into the pinctrl tree on top of the moved driver.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella
  2019-12-13 14:44   ` Andy Shevchenko
@ 2019-12-16 10:19     ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2019-12-16 10:19 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Bartosz Golaszewski, open list:GPIO SUBSYSTEM, Mika Westerberg

On Fri, Dec 13, 2019 at 3:44 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> > If you want to make my life simple could you do this:
>
> I want, though I think above makes it harder. I'll not expecting any patches
> against gpio-lynxpoint.c (and if they will be an author should Cc me anyway).
> Besides the series nicely grouped on top of prerequisites which are solely
> Intel pin control (no need for GPIO). Thus I prefer to send simple 1 PR during
> this cycle to pin control subsystem and that's it.

Fair enough, if you are convinced that will work then go ahead.

Yours,
Linus Walleij

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

end of thread, other threads:[~2019-12-16 10:19 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-09 13:09 [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 01/24] pinctrl: lynxpoint: Move GPIO driver to pin controller folder Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 02/24] pinctrl: lynxpoint: Use raw_spinlock for locking Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 03/24] pinctrl: lynxpoint: Correct amount of pins Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 04/24] pinctrl: lynxpoint: Drop useless assignment Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 05/24] pinctrl: lynxpoint: Use %pR to print IO resource Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 06/24] pinctrl: lynxpoint: Use standard pattern for memory allocation Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 07/24] pinctrl: lynxpoint: Assume 2 bits for mode selector Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 08/24] pinctrl: lynxpoint: Relax GPIO request rules Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 09/24] pinctrl: lynxpoint: Keep pointer to struct device instead of its container Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 10/24] pinctrl: lynxpoint: Switch to memory mapped IO accessors Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 11/24] pinctrl: lynxpoint: Convert unsigned to unsigned int Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 12/24] pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 13/24] pinctrl: lynxpoint: Move ->remove closer to ->probe() Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 14/24] pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 15/24] pinctrl: lynxpoint: Move ownership check to IRQ chip Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 16/24] pinctrl: lynxpoint: Implement ->irq_ack() callback Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 17/24] pinctrl: lynxpoint: Implement intel_gpio_get_direction callback Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 18/24] pinctrl: lynxpoint: Add pin control data structures Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 19/24] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver Andy Shevchenko
2019-12-10  5:26   ` kbuild test robot
2019-12-10 13:46     ` Andy Shevchenko
2019-12-10 13:47       ` Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 20/24] pinctrl: lynxpoint: Add pin control operations Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 21/24] pinctrl: lynxpoint: Implement ->pin_dbg_show() Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 22/24] pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 23/24] pinctrl: lynxpoint: Switch to pin control API Andy Shevchenko
2019-12-09 13:09 ` [PATCH v2 24/24] pinctrl: lynxpoint: Update summary in the driver Andy Shevchenko
2019-12-11 13:19 ` [PATCH v2 00/24] pinctrl: intel: Move Lynxpoint to pin control umbrella Mika Westerberg
2019-12-13 13:36 ` Linus Walleij
2019-12-13 14:44   ` Andy Shevchenko
2019-12-16 10:19     ` Linus Walleij

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.