diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2020-01-23 15:44:29 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2020-01-23 15:44:29 +0100 |
commit | a1dd4bfb145e88bdc8374a506409f95916bae368 (patch) | |
tree | 703909c8ece9e6016fa55067abae2af6a5decca4 | |
parent | 783e998653b430a159f83552fa263f57bf8e2055 (diff) | |
parent | cd0a32371db73d0b50536a7ca4f036abddff0d1d (diff) |
Merge tag 'intel-pinctrl-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel
intel-pinctrl for v5.6-1
* Tiger Lake appears to have _HID enumeration, thus driver has been updated
* Coffee Lake-S has the same IP as Sunrisepoint, thus ID has been added
* Baytrail has got more clean ups and bug fixes, such as direct IRQ handling
* Lynxpoint GPIO has been converted to true pin control driver
* The common driver now uses IRQ chip enumeration via GPIO chip
The following is an automated git shortlog grouped by driver:
baytrail:
- Replace WARN with dev_info_once when setting direct-irq pin to output
- Do not clear IRQ flags on direct-irq enabled pins
- Reuse struct intel_pinctrl in the driver
- Use local variable to keep device pointer
- Keep pointer to struct device instead of its container
- Use GPIO direction definitions
- Move IRQ valid mask initialization to a dedicated callback
- Group GPIO IRQ chip initialization
- Allocate IRQ chip dynamic
cherryview:
- Use GPIO direction definitions
intel:
- Pass irqchip when adding gpiochip
- Add GPIO <-> pin mapping ranges via callback
- Share struct intel_pinctrl for wider use
- Use GPIO direction definitions
lynxpoint:
- Update summary in the driver
- Switch to pin control API
- Add GPIO <-> pin mapping ranges via callback
- Implement ->pin_dbg_show()
- Add pin control operations
- Reuse struct intel_pinctrl in the driver
- Add pin control data structures
- Implement intel_gpio_get_direction callback
- Implement ->irq_ack() callback
- Move ownership check to IRQ chip
- Move lp_irq_type() closer to IRQ related routines
- Move ->remove closer to ->probe()
- Extract lp_gpio_acpi_use() for future use
- Convert unsigned to unsigned int
- Switch to memory mapped IO accessors
- Keep pointer to struct device instead of its container
- Relax GPIO request rules
- Assume 2 bits for mode selector
- Use standard pattern for memory allocation
- Use %pR to print IO resource
- Drop useless assignment
- Correct amount of pins
- Use raw_spinlock for locking
- Move GPIO driver to pin controller folder
sunrisepoint:
- Add Coffee Lake-S ACPI ID
- Add missing Interrupt Status register offset
tigerlake:
- Tiger Lake uses _HID enumeration
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 8 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-lynxpoint.c | 471 | ||||
-rw-r--r-- | drivers/pinctrl/intel/Kconfig | 13 | ||||
-rw-r--r-- | drivers/pinctrl/intel/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 311 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 5 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 101 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.h | 44 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-lynxpoint.c | 975 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-tigerlake.c | 547 |
13 files changed, 1479 insertions, 1001 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ffa3371bc750..41aa0b04c954 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8347,7 +8347,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/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c deleted file mode 100644 index 490ce7bae25e..000000000000 --- a/drivers/gpio/gpio-lynxpoint.c +++ /dev/null @@ -1,471 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPIO controller driver for Intel Lynxpoint PCH chipset> - * Copyright (c) 2012, Intel Corporation. - * - * Author: Mathias Nyman <mathias.nyman@linux.intel.com> - */ - -#include <linux/acpi.h> -#include <linux/bitops.h> -#include <linux/gpio/driver.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> -#include <linux/slab.h> -#include <linux/types.h> - -/* LynxPoint chipset has support for 94 gpio pins */ - -#define LP_NUM_GPIO 94 - -/* Bitmapped register offsets */ -#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ -#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */ -#define LP_INT_STAT 0x80 -#define LP_INT_ENABLE 0x90 - -/* Each pin has two 32 bit config registers, starting at 0x100 */ -#define LP_CONFIG1 0x100 -#define LP_CONFIG2 0x104 - -/* LP_CONFIG1 reg bits */ -#define OUT_LVL_BIT BIT(31) -#define IN_LVL_BIT BIT(30) -#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 */ - -/* LP_CONFIG2 reg bits */ -#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 platform_device *pdev; - spinlock_t lock; - unsigned long reg_base; -}; - -/* - * 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 - * - * 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. - * - * A simplified view of the register layout look like this: - * - * LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers) - * LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63 - * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94 - * ... - * LP_INT_ENABLE[31:0] ... - * LP_INT_ENABLE[63:31] ... - * 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 - * LP1_CONFIG1 (gpio 1) config1 reg for gpio 1 - * LP1_CONFIG2 (gpio 1) config2 reg for gpio 1 - * LP2_CONFIG1 (gpio 2) ... - * LP2_CONFIG2 (gpio 2) ... - * ... - * LP94_CONFIG1 (gpio 94) ... - * LP94_CONFIG2 (gpio 94) ... - */ - -static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset, - int reg) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - int reg_offset; - - if (reg == LP_CONFIG1 || reg == LP_CONFIG2) - /* per gpio specific config registers */ - reg_offset = offset * 8; - else - /* bitmapped registers */ - reg_offset = (offset / 32) * 4; - - return lg->reg_base + 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); - - pm_runtime_get(&lg->pdev->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); - return -EBUSY; - } - /* Fail if pin is in alternate function mode (not GPIO mode) */ - if (!(inl(reg) & USE_SEL_BIT)) - return -ENODEV; - - /* enable input sensing */ - outl(inl(conf2) & ~GPINDIS_BIT, conf2); - - - return 0; -} - -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); - - /* disable input sensing */ - outl(inl(conf2) | GPINDIS_BIT, conf2); - - pm_runtime_put(&lg->pdev->dev); -} - -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); - unsigned long flags; - u32 value; - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); - - if (hwirq >= lg->chip.ngpio) - return -EINVAL; - - spin_lock_irqsave(&lg->lock, flags); - value = inl(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; - - outl(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); - - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -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); -} - -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); - unsigned long flags; - - 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); -} - -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); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -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); - unsigned long flags; - - lp_gpio_set(chip, offset, value); - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -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 irq_chip *chip = irq_data_get_irq_chip(data); - unsigned long reg, ena, pending; - u32 base, pin; - - /* check from GPIO controller which pin triggered the interrupt */ - for (base = 0; base < lg->chip.ngpio; base += 32) { - reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); - ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); - - /* Only interrupts that are enabled */ - pending = inl(reg) & inl(ena); - - for_each_set_bit(pin, &pending, 32) { - unsigned irq; - - /* Clear before handling so we don't lose an edge */ - outl(BIT(pin), reg); - - irq = irq_find_mapping(lg->chip.irq.domain, base + pin); - generic_handle_irq(irq); - } - } - chip->irq_eoi(data); -} - -static void lp_irq_unmask(struct irq_data *d) -{ -} - -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); - u32 hwirq = irqd_to_hwirq(d); - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); -} - -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); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); -} - -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, - .flags = IRQCHIP_SKIP_SET_WAKE, -}; - -static int lp_gpio_irq_init_hw(struct gpio_chip *chip) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long 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); - /* Clear interrupt status register */ - reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); - outl(0xffffffff, reg); - } - - return 0; -} - -static int lp_gpio_probe(struct platform_device *pdev) -{ - struct lp_gpio *lg; - 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); - if (!lg) - return -ENOMEM; - - lg->pdev = 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 0x%x\n", - (unsigned int)lg->reg_base); - return -EBUSY; - } - - spin_lock_init(&lg->lock); - - gc = &lg->chip; - gc->label = dev_name(dev); - gc->owner = THIS_MODULE; - gc->request = lp_gpio_request; - gc->free = lp_gpio_free; - gc->direction_input = lp_gpio_direction_input; - gc->direction_output = lp_gpio_direction_output; - gc->get = lp_gpio_get; - gc->set = lp_gpio_set; - gc->base = -1; - gc->ngpio = LP_NUM_GPIO; - gc->can_sleep = false; - gc->parent = dev; - - /* set up interrupts */ - if (irq_rc && irq_rc->start) { - struct gpio_irq_chip *girq; - - girq = &gc->irq; - girq->chip = &lp_irqchip; - 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, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - girq->parents[0] = (unsigned)irq_rc->start; - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_bad_irq; - } - - ret = devm_gpiochip_add_data(dev, gc, lg); - if (ret) { - dev_err(dev, "failed adding lp-gpio chip\n"); - return ret; - } - - pm_runtime_enable(dev); - - return 0; -} - -static int lp_gpio_runtime_suspend(struct device *dev) -{ - return 0; -} - -static int lp_gpio_runtime_resume(struct device *dev) -{ - return 0; -} - -static int lp_gpio_resume(struct device *dev) -{ - struct lp_gpio *lg = dev_get_drvdata(dev); - unsigned long 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); - } - } - return 0; -} - -static const struct dev_pm_ops lp_gpio_pm_ops = { - .runtime_suspend = lp_gpio_runtime_suspend, - .runtime_resume = lp_gpio_runtime_resume, - .resume = lp_gpio_resume, -}; - -static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { - { "INT33C7", 0 }, - { "INT3437", 0 }, - { } -}; -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, - .driver = { - .name = "lp_gpio", - .pm = &lp_gpio_pm_ops, - .acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match), - }, -}; - -static int __init lp_gpio_init(void) -{ - return platform_driver_register(&lp_gpio_driver); -} - -static void __exit lp_gpio_exit(void) -{ - platform_driver_unregister(&lp_gpio_driver); -} - -subsys_initcall(lp_gpio_init); -module_exit(lp_gpio_exit); - -MODULE_AUTHOR("Mathias Nyman (Intel)"); -MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:lp_gpio"); diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 6091947a8f51..ee440ec4c94c 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -31,6 +31,19 @@ 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 PINMUX + select PINCONF + select GENERIC_PINCONF + 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/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 55141d5de29e..b409642f168d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -93,7 +93,7 @@ #define BYT_DEFAULT_GPIO_MUX 0 #define BYT_ALTER_GPIO_MUX 1 -struct byt_gpio_pin_context { +struct intel_pad_context { u32 conf0; u32 val; }; @@ -105,16 +105,6 @@ struct byt_gpio_pin_context { .pad_map = (map),\ } -struct byt_gpio { - struct gpio_chip chip; - struct platform_device *pdev; - struct pinctrl_dev *pctl_dev; - struct pinctrl_desc pctl_desc; - const struct intel_pinctrl_soc_data *soc_data; - struct intel_community *communities_copy; - struct byt_gpio_pin_context *saved_context; -}; - /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ static const struct pinctrl_pin_desc byt_score_pins[] = { PINCTRL_PIN(0, "SATA_GP0"), @@ -550,14 +540,14 @@ static const struct intel_pinctrl_soc_data *byt_soc_data[] = { static DEFINE_RAW_SPINLOCK(byt_lock); -static struct intel_community *byt_get_community(struct byt_gpio *vg, +static struct intel_community *byt_get_community(struct intel_pinctrl *vg, unsigned int pin) { struct intel_community *comm; int i; - for (i = 0; i < vg->soc_data->ncommunities; i++) { - comm = vg->communities_copy + i; + for (i = 0; i < vg->ncommunities; i++) { + comm = vg->communities + i; if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) return comm; } @@ -565,7 +555,7 @@ static struct intel_community *byt_get_community(struct byt_gpio *vg, return NULL; } -static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, +static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, int reg) { struct intel_community *comm = byt_get_community(vg, offset); @@ -592,17 +582,17 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, static int byt_get_groups_count(struct pinctrl_dev *pctldev) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->ngroups; + return vg->soc->ngroups; } static const char *byt_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->groups[selector].name; + return vg->soc->groups[selector].name; } static int byt_get_group_pins(struct pinctrl_dev *pctldev, @@ -610,10 +600,10 @@ static int byt_get_group_pins(struct pinctrl_dev *pctldev, const unsigned int **pins, unsigned int *num_pins) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - *pins = vg->soc_data->groups[selector].pins; - *num_pins = vg->soc_data->groups[selector].npins; + *pins = vg->soc->groups[selector].pins; + *num_pins = vg->soc->groups[selector].npins; return 0; } @@ -626,17 +616,17 @@ static const struct pinctrl_ops byt_pinctrl_ops = { static int byt_get_functions_count(struct pinctrl_dev *pctldev) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->nfunctions; + return vg->soc->nfunctions; } static const char *byt_get_function_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->functions[selector].name; + return vg->soc->functions[selector].name; } static int byt_get_function_groups(struct pinctrl_dev *pctldev, @@ -644,15 +634,15 @@ static int byt_get_function_groups(struct pinctrl_dev *pctldev, const char * const **groups, unsigned int *num_groups) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - *groups = vg->soc_data->functions[selector].groups; - *num_groups = vg->soc_data->functions[selector].ngroups; + *groups = vg->soc->functions[selector].groups; + *num_groups = vg->soc->functions[selector].ngroups; return 0; } -static void byt_set_group_simple_mux(struct byt_gpio *vg, +static void byt_set_group_simple_mux(struct intel_pinctrl *vg, const struct intel_pingroup group, unsigned int func) { @@ -667,7 +657,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); if (!padcfg0) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Group %s, pin %i not muxed (no padcfg0)\n", group.name, i); continue; @@ -682,7 +672,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, raw_spin_unlock_irqrestore(&byt_lock, flags); } -static void byt_set_group_mixed_mux(struct byt_gpio *vg, +static void byt_set_group_mixed_mux(struct intel_pinctrl *vg, const struct intel_pingroup group, const unsigned int *func) { @@ -697,7 +687,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); if (!padcfg0) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Group %s, pin %i not muxed (no padcfg0)\n", group.name, i); continue; @@ -715,9 +705,9 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, unsigned int group_selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); - const struct intel_function func = vg->soc_data->functions[func_selector]; - const struct intel_pingroup group = vg->soc_data->groups[group_selector]; + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + const struct intel_function func = vg->soc->functions[func_selector]; + const struct intel_pingroup group = vg->soc->groups[group_selector]; if (group.modes) byt_set_group_mixed_mux(vg, group, group.modes); @@ -729,22 +719,22 @@ static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, return 0; } -static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset) +static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) { /* SCORE pin 92-93 */ - if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && + if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && offset >= 92 && offset <= 93) return BYT_ALTER_GPIO_MUX; /* SUS pin 11-21 */ - if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && + if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && offset >= 11 && offset <= 21) return BYT_ALTER_GPIO_MUX; return BYT_DEFAULT_GPIO_MUX; } -static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) +static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) { void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; @@ -752,7 +742,13 @@ static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + + /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ + if (value & BYT_DIRECT_IRQ_EN) + /* nothing to do */ ; + else + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + writel(value, reg); raw_spin_unlock_irqrestore(&byt_lock, flags); } @@ -761,7 +757,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); u32 value, gpio_mux; unsigned long flags; @@ -784,13 +780,12 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, value |= gpio_mux; writel(value, reg); - dev_warn(&vg->pdev->dev, FW_BUG - "pin %u forcibly re-configured as GPIO\n", offset); + dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset); } raw_spin_unlock_irqrestore(&byt_lock, flags); - pm_runtime_get(&vg->pdev->dev); + pm_runtime_get(vg->dev); return 0; } @@ -799,10 +794,10 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); byt_gpio_clear_triggering(vg, offset); - pm_runtime_put(&vg->pdev->dev); + pm_runtime_put(vg->dev); } static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, @@ -810,7 +805,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, unsigned int offset, bool input) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; @@ -822,15 +817,15 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, value &= ~BYT_DIR_MASK; if (input) value |= BYT_OUTPUT_EN; - else + else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) /* * Before making any direction modifications, do a check if gpio * is set for direct IRQ. On baytrail, setting GPIO to output - * does not make sense, so let's at least warn the caller before + * does not make sense, so let's at least inform the caller before * they shoot themselves in the foot. */ - WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, - "Potential Error: Setting GPIO with direct_irq_en to output"); + dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); + writel(value, val_reg); raw_spin_unlock_irqrestore(&byt_lock, flags); @@ -893,7 +888,7 @@ static int byt_set_pull_strength(u32 *reg, u16 strength) static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, unsigned long *config) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); enum pin_config_param param = pinconf_to_config_param(*config); void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); @@ -978,7 +973,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, unsigned long *configs, unsigned int num_configs) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); unsigned int param, arg; void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); @@ -1012,7 +1007,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, if (val & BYT_INPUT_EN) { val &= ~BYT_INPUT_EN; writel(val, val_reg); - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "pin %u forcibly set to input mode\n", offset); } @@ -1034,7 +1029,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, if (val & BYT_INPUT_EN) { val &= ~BYT_INPUT_EN; writel(val, val_reg); - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "pin %u forcibly set to input mode\n", offset); } @@ -1115,7 +1110,7 @@ static const struct pinctrl_desc byt_pinctrl_desc = { static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 val; @@ -1129,7 +1124,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 old_val; @@ -1148,7 +1143,7 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 value; @@ -1161,9 +1156,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) raw_spin_unlock_irqrestore(&byt_lock, flags); if (!(value & BYT_OUTPUT_EN)) - return 0; + return GPIO_LINE_DIRECTION_OUT; if (!(value & BYT_INPUT_EN)) - return 1; + return GPIO_LINE_DIRECTION_IN; return -EINVAL; } @@ -1188,11 +1183,11 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); int i; u32 conf0, val; - for (i = 0; i < vg->soc_data->npins; i++) { + for (i = 0; i < vg->soc->npins; i++) { const struct intel_community *comm; const char *pull_str = NULL; const char *pull = NULL; @@ -1202,7 +1197,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned int pin; raw_spin_lock_irqsave(&byt_lock, flags); |