pinctrl: intel: Move Lynxpoint to pin control umbrella
Subsystems (3)
cover pinctrl: intel: Move Lynxpoint to pin control umbrella
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.
This is the first step. Next step will be to convert it to the actual pin control driver.
The series has been tested on Harrisbeach Ultrabook where Lynxpoint GPIO is exposed to the OS.
Andy Shevchenko (8):
pinctrl: lynxpoint: Move GPIO driver to pin controller folder
pinctrl: lynxpoint: Use raw_spinlock for locking
pinctrl: lynxpoint: Correct amount of pins
pinctrl: lynxpoint: Keep pointer to struct device instead of its
container
pinctrl: lynxpoint: Use %pR to print IO resource
pinctrl: lynxpoint: Switch to memory mapped IO accessors
pinctrl: lynxpoint: Convert unsigned to unsigned int
pinctrl: lynxpoint: Move ->remove closer to ->probe()
MAINTAINERS | 1 -
drivers/gpio/Kconfig | 8 -
drivers/gpio/Makefile | 1 -
drivers/pinctrl/intel/Kconfig | 10 ++
drivers/pinctrl/intel/Makefile | 1 +
.../intel/pinctrl-lynxpoint.c} | 168 +++++++++---------
6 files changed, 93 insertions(+), 96 deletions(-)
rename drivers/{gpio/gpio-lynxpoint.c => pinctrl/intel/pinctrl-lynxpoint.c} (72%)Signature · 1 line
2.24.0.rc1
PATCH 1/8 pinctrl: lynxpoint: Move GPIO driver to pin controller folder
Move Lynxpoint GPIO driver under Intel pin control umbrella for further transformation to a real pin control driver.
---
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%)MAINTAINERS +0 -1
@@ -8325,7 +8325,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
drivers/gpio/Kconfig +0 -8
@@ -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
drivers/gpio/Makefile +0 -1
@@ -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
drivers/pinctrl/intel/Kconfig +10 -0
@@ -42,6 +42,16 @@ config PINCTRL_MERRIFIELD 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_INTEL tristate select PINMUX
drivers/pinctrl/intel/Makefile +1 -0
@@ -13,5 +13,6 @@ obj-$(CONFIG_PINCTRL_ELKHARTLAKE) += pinctrl-elkhartlake.o obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o +obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o obj-$(CONFIG_PINCTRL_TIGERLAKE) += pinctrl-tigerlake.o
drivers/pinctrl/intel/pinctrl-lynxpoint.c renamed from drivers/gpio/gpio-lynxpoint.c +0 -0
Signature · 1 line
2.24.0.rc1
Mika Westerberg
maintainerRe: [PATCH v1 1/8] pinctrl: lynxpoint: Move GPIO driver to pin controller folder
Quoted 64 lines · 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 <[email protected]>--- 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%)MAINTAINERS +0
-1@@ -8325,7 +8325,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.cdrivers/gpio/Kconfig +0
-8@@ -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" helpdrivers/gpio/Makefile +0
-1@@ -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.odrivers/pinctrl/intel/Kconfig +0
-0@@ -42,6 +42,16 @@ config PINCTRL_MERRIFIELD interface that allows configuring of SoC pins and using them as GPIOs.
drivers/pinctrl/intel/Kconfig config PINCTRL_MERRIFIELD · line 53
Quoted 10 lines
drivers/pinctrl/intel/Kconfig +9
-0+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.
In order to keep the above (non pinctrl-intel.c based drivers) sorted alphabetically, can you move this before PINCTRL_MERRIFIELD?
drivers/pinctrl/intel/Makefile obj-$(CONFIG_PINCTRL_ELKHARTLAKE) += pinctrl-elkhartlake.o · line 16
Quoted 13 lines
drivers/pinctrl/intel/Kconfig +1
-0+ config PINCTRL_INTEL tristate select PINMUXdrivers/pinctrl/intel/Makefile +1
-0@@ -13,5 +13,6 @@ obj-$(CONFIG_PINCTRL_ELKHARTLAKE) += pinctrl-elkhartlake.o obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o +obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o
Here too.
Quoted 8 lines
drivers/pinctrl/intel/Makefile +0
-0obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o obj-$(CONFIG_PINCTRL_TIGERLAKE) += pinctrl-tigerlake.odrivers/pinctrl/intel/pinctrl-lynxpoint.c renamed from drivers/gpio/gpio-lynxpoint.c +0
-0Signature · 1 line
2.24.0.rc1
Re: [PATCH v1 1/8] pinctrl: lynxpoint: Move GPIO driver to pin controller folder
Quoted 4 lines · Mika Westerberg
Quoted 2 lines · Andy Shevchenko
Move Lynxpoint GPIO driver under Intel pin control umbrella for further transformation to a real pin control driver.
Quoted 12 lines
drivers/pinctrl/intel/Kconfig config PINCTRL_MERRIFIELD · line 53
Quoted 9 lines
drivers/pinctrl/intel/Kconfig +9
-0+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.In order to keep the above (non
pinctrl-intel.cbased drivers) sorted alphabetically, can you move this beforePINCTRL_MERRIFIELD?
Fixed in my review branch.
Quoted 3 lines
Quoted 1 line
+obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o
Here too.
Ditto.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v1 1/8] pinctrl: lynxpoint: Move GPIO driver to pin controller folder
In reply to Andy ShevchenkoOn Wed, Nov 6, 2019 at 3:48 PM Andy Shevchenko
<[email protected]> wrote:
This Kconfig symbol goes away:
Quoted 1 line
-config
GPIO_LYNXPOINT
This one appears:
Quoted 1 line
+config
PINCTRL_LYNXPOINT
As long as you're certain this will not cause any problems it's fine by me (thinking people who have old configs etc).
Yours,
Linus Walleij
Re: [PATCH v1 1/8] pinctrl: lynxpoint: Move GPIO driver to pin controller folder
Quoted 5 lines · Linus Walleij
On Wed, Nov 6, 2019 at 3:48 PM Andy Shevchenko
<[email protected]> wrote:This
Kconfigsymbol goes away:
Quoted 8 lines
Quoted 1 line
-config
GPIO_LYNXPOINTThis one appears:
Quoted 1 line
+config
PINCTRL_LYNXPOINTAs long as you're certain this will not cause any problems it's fine by me (thinking people who have old configs etc).
No. it's not a problem as long as people run make oldconfig. We assume that distros do that way and carefully check each new option. So, we consider no problem is here.
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 2/8 pinctrl: lynxpoint: Use raw_spinlock for locking
In reply to Andy ShevchenkoThe 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.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +14 -14
@@ -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 */
@@ -164,7 +164,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type) value |=TRIG_SEL_BIT |INT_INV_BIT ;outl (value, reg); -spin_unlock_irqrestore (&lg->lock, flags); +raw_spin_unlock_irqrestore (&lg->lock, flags);return 0 ; }
@@ -181,14 +181,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)
@@ -197,9 +197,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 ; }
@@ -213,9 +213,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 ; }
@@ -266,9 +266,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)
@@ -279,9 +279,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 = {
@@ -345,7 +345,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);
Signature · 1 line
2.24.0.rc1
PATCH 3/8 pinctrl: lynxpoint: Correct amount of pins
In reply to Andy ShevchenkoWhen 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.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +6 -6
@@ -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
Signature · 1 line
2.24.0.rc1
PATCH 4/8 pinctrl: lynxpoint: Keep pointer to struct device instead of its container
In reply to Andy ShevchenkoThere 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.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +5 -5
@@ -46,7 +46,7 @@struct lp_gpio {struct gpio_chip chip; -struct platform_device *pdev; +struct device *dev;raw_spinlock_t lock;unsigned long reg_base; };
@@ -103,11 +103,11 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)unsigned long conf2 =lp_gpio_reg (chip, offset,LP_CONFIG2 );unsigned long acpi_use =lp_gpio_reg (chip, offset,LP_ACPI_OWNED ); -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 ; }/* Fail if pin is in alternate function mode (not GPIO mode) */
@@ -129,7 +129,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)
@@ -325,7 +325,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 );
Signature · 1 line
2.24.0.rc1
PATCH 5/8 pinctrl: lynxpoint: Use %pR to print IO resource
In reply to Andy ShevchenkoReplace explicit casting by pointer to struct resource with specifier replacement to %pR to print the IO resource.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +1 -2
@@ -340,8 +340,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 ; }
Signature · 1 line
2.24.0.rc1
PATCH 6/8 pinctrl: lynxpoint: Switch to memory mapped IO accessors
In reply to Andy ShevchenkoConvert driver to use memory mapped IO accessors.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 83 +++++++++++------------ 1 file changed, 40 insertions(+), 43 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +40 -43
@@ -48,7 +48,7 @@ struct lp_gpio {struct gpio_chip chip;struct device *dev;raw_spinlock_t lock; -unsigned long reg_base; +void __iomem *regs; };/*
@@ -80,7 +80,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);
@@ -93,29 +93,29 @@ 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 );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 ; }/* Fail if pin is in alternate function mode (not GPIO mode) */ -if (!(inl (reg) &USE_SEL_BIT )) +if (!(ioread32 (reg) &USE_SEL_BIT ))return -ENODEV ;/* enable input sensing */ -outl (inl (conf2) & ~GPINDIS_BIT , conf2); +iowrite32 (ioread32 (conf2) & ~GPINDIS_BIT , conf2);return 0 ;
@@ -124,10 +124,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); }
@@ -137,15 +137,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 )
@@ -163,7 +163,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);raw_spin_unlock_irqrestore (&lg->lock, flags);return 0 ;
@@ -171,22 +171,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); }
@@ -194,11 +194,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 ;
@@ -208,13 +208,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 ;
@@ -226,7 +226,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 */
@@ -235,13 +236,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);
@@ -263,11 +264,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); }
@@ -276,11 +277,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); }
@@ -297,16 +298,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 ;
@@ -318,7 +319,6 @@ 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;int ret = -ENODEV ; lg =devm_kzalloc (dev,sizeof (struct lp_gpio ),GFP_KERNEL );
@@ -329,18 +329,14 @@ 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); + lg->regs =devm_ioport_map (dev, io_rc->start,resource_size (io_rc)); +if (!lg->regs) { +dev_err (dev,"failed mapping IO region %pR\n" , &io_rc);return -EBUSY ; }
@@ -361,6 +357,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;
@@ -403,14 +400,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 ;
Signature · 1 line
2.24.0.rc1
PATCH 7/8 pinctrl: lynxpoint: Convert unsigned to unsigned int
In reply to Andy ShevchenkoSimple type conversion with no functional change implied.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +12 -12
@@ -80,7 +80,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);
@@ -96,7 +96,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 );
@@ -121,7 +121,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 );
@@ -132,7 +132,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);
@@ -169,13 +169,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 );
@@ -191,7 +191,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 );
@@ -204,8 +204,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 );
@@ -239,7 +239,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);
@@ -299,7 +299,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 */
@@ -371,7 +371,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; }
Signature · 1 line
2.24.0.rc1
PATCH 8/8 pinctrl: lynxpoint: Move ->remove closer to ->probe()
In reply to Andy ShevchenkoConsolidate ->remove and ->probe() callbacks for better maintenance.
--- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/pinctrl/intel/pinctrl-lynxpoint.c +6 -6
@@ -387,6 +387,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 ;
@@ -426,12 +432,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,
Signature · 1 line
2.24.0.rc1
Quoted 11 lines · 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.
This is the first step. Next step will be to convert it to the actual pin control driver.
The series has been tested on Harrisbeach Ultrabook where Lynxpoint GPIO is exposed to the OS.
Quoted 10 lines
Andy Shevchenko (8):
pinctrl: lynxpoint: Move GPIO driver to pin controller folder
pinctrl: lynxpoint: Useraw_spinlockfor locking
pinctrl: lynxpoint: Correct amount of pins
pinctrl: lynxpoint: Keep pointer to struct device instead of its
container
pinctrl: lynxpoint: Use %pR to print IO resource
pinctrl: lynxpoint: Switch to memory mapped IO accessors
pinctrl: lynxpoint: Convert unsigned to unsigned int
pinctrl: lynxpoint: Move ->remove closer to ->probe()
I'm a big fan of this refactoring.
Can you send this series as a separate pull request that I can pull into the GPIO tree rather than pin control, or maybe both, once you're pleased with it?
Yours,
Linus Walleij
Quoted 25 lines · Linus Walleij
Quoted 11 lines · 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.
This is the first step. Next step will be to convert it to the actual pin control driver.
The series has been tested on Harrisbeach Ultrabook where Lynxpoint GPIO is exposed to the OS.
Quoted 10 lines
Andy Shevchenko (8):
pinctrl: lynxpoint: Move GPIO driver to pin controller folder
pinctrl: lynxpoint: Useraw_spinlockfor locking
pinctrl: lynxpoint: Correct amount of pins
pinctrl: lynxpoint: Keep pointer to struct device instead of its
container
pinctrl: lynxpoint: Use %pR to print IO resource
pinctrl: lynxpoint: Switch to memory mapped IO accessors
pinctrl: lynxpoint: Convert unsigned to unsigned int
pinctrl: lynxpoint: Move ->remove closer to ->probe()
Quoted 1 line
I'm a big fan of this refactoring.
Glad we are on the same page about it!
Quoted 3 lines
Can you send this series as a separate pull request that I can pull into the GPIO tree rather than pin control, or maybe both, once you're pleased with it?
I have done more and it still requires some work. I will send v2 after merge window being closed.
Signature · 2 lines
With Best Regards, Andy Shevchenko