diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2018-12-14 14:27:41 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2018-12-14 14:27:41 +0100 |
commit | 493872e074148ae11d5dd5d78453101003829485 (patch) | |
tree | fef09f32750cd42b72a5c8fde4d269c787ed7bc7 /drivers/gpio | |
parent | 21abf103818a4735e80fb0ab03934bed8ae9a028 (diff) | |
parent | aaa21231698c0d326922a325647adf38e4f21db0 (diff) |
Merge tag 'intel-gpio-v4.21-1' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel
intel-gpio for v4.21-1
Use managed resource allocation in pch and sodaville drivers.
Switch to use for_each_set_bit() in IRQ handlers.
Headers clean up.
Sort headers in inclusion block alphabetically for better maintenance.
Convert to SPDX identifier and fixing MODULE_LICENSE() when appropriate.
Additional format fixes to rectify debug and message printing.
There is a commit which had been applied to v4.20-rc4, that's why dup.
- c3bc3ff9e8019fba74ce62bfb501d710c2fca9d3 MAINTAINERS: Do maintain Intel GPIO drivers via separate tree
The following is an automated git shortlog grouped by driver:
ich:
- Convert to use SPDX identifier
- Sort headers alphabetically
- Join string literals back
- Convert pr_<level> to dev_<level>
- Switch to use struct device instead of platform_device
- Simplify error handling in ichx_write_bit()
intel-mid:
- Convert to use SPDX identifier
- Remove linux/module.h and sort headers
lynxpoint:
- Convert to use SPDX identifier
- Remove linux/init.h and sort headers
- Use for_each_set_bit() in IRQ handler
MAINTAINERS:
- Do maintain Intel GPIO drivers via separate tree
merrifield:
- Convert to use SPDX identifier
- Remove linux/init.h
pch:
- Convert to use SPDX identifier
- Sort headers alphabetically
- Remove duplicate assignments
- Remove redundant __func__ from debug print
- Use for_each_set_bit() in IRQ handler
- Convert to dev_pm_ops
- Convert to use managed functions pcim_* and devm_*
sch:
- Convert to use SPDX identifier
- Remove linux/init.h and sort headers
sodaville:
- Convert to use SPDX identifier
- Sort headers alphabetically
- Use for_each_set_bit() in IRQ handler
- Convert to use managed functions pcim_* and devm_*
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-ich.c | 73 | ||||
-rw-r--r-- | drivers/gpio/gpio-intel-mid.c | 16 | ||||
-rw-r--r-- | drivers/gpio/gpio-lynxpoint.c | 44 | ||||
-rw-r--r-- | drivers/gpio/gpio-merrifield.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-pch.c | 165 | ||||
-rw-r--r-- | drivers/gpio/gpio-sch.c | 27 | ||||
-rw-r--r-- | drivers/gpio/gpio-sodaville.c | 73 |
7 files changed, 116 insertions, 288 deletions
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index dba392221042..90bf7742f9b0 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -1,32 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver * * Copyright (C) 2010 Extreme Engineering Solutions. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/bitops.h> +#include <linux/gpio/driver.h> #include <linux/ioport.h> +#include <linux/mfd/lpc_ich.h> #include <linux/module.h> #include <linux/pci.h> -#include <linux/gpio/driver.h> #include <linux/platform_device.h> -#include <linux/mfd/lpc_ich.h> -#include <linux/bitops.h> #define DRV_NAME "gpio_ich" @@ -100,7 +86,7 @@ struct ichx_desc { static struct { spinlock_t lock; - struct platform_device *dev; + struct device *dev; struct gpio_chip chip; struct resource *gpio_base; /* GPIO IO base */ struct resource *pm_base; /* Power Mangagment IO base */ @@ -112,8 +98,7 @@ static struct { static int modparam_gpiobase = -1; /* dynamic */ module_param_named(gpiobase, modparam_gpiobase, int, 0444); -MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " - "which is the default."); +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default."); static int ichx_write_bit(int reg, unsigned nr, int val, int verify) { @@ -121,7 +106,6 @@ static int ichx_write_bit(int reg, unsigned nr, int val, int verify) u32 data, tmp; int reg_nr = nr / 32; int bit = nr & 0x1f; - int ret = 0; spin_lock_irqsave(&ichx_priv.lock, flags); @@ -142,12 +126,10 @@ static int ichx_write_bit(int reg, unsigned nr, int val, int verify) tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], ichx_priv.gpio_base); - if (verify && data != tmp) - ret = -EPERM; spin_unlock_irqrestore(&ichx_priv.lock, flags); - return ret; + return (verify && data != tmp) ? -EPERM : 0; } static int ichx_read_bit(int reg, unsigned nr) @@ -186,10 +168,7 @@ static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) * Try setting pin as an input and verify it worked since many pins * are output-only. */ - if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) - return -EINVAL; - - return 0; + return ichx_write_bit(GPIO_IO_SEL, nr, 1, 1); } static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, @@ -206,10 +185,7 @@ static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, * Try setting pin as an output and verify it worked since many pins * are input-only. */ - if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) - return -EINVAL; - - return 0; + return ichx_write_bit(GPIO_IO_SEL, nr, 0, 1); } static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) @@ -284,7 +260,7 @@ static void ichx_gpiolib_setup(struct gpio_chip *chip) { chip->owner = THIS_MODULE; chip->label = DRV_NAME; - chip->parent = &ichx_priv.dev->dev; + chip->parent = ichx_priv.dev; /* Allow chip-specific overrides of request()/get() */ chip->request = ichx_priv.desc->request ? @@ -407,15 +383,14 @@ static int ichx_gpio_request_regions(struct device *dev, static int ichx_gpio_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct lpc_ich_info *ich_info = dev_get_platdata(dev); struct resource *res_base, *res_pm; int err; - struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); if (!ich_info) return -ENODEV; - ichx_priv.dev = pdev; - switch (ich_info->gpio_version) { case ICH_I3100_GPIO: ichx_priv.desc = &i3100_desc; @@ -445,19 +420,21 @@ static int ichx_gpio_probe(struct platform_device *pdev) return -ENODEV; } + ichx_priv.dev = dev; spin_lock_init(&ichx_priv.lock); + res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); - ichx_priv.use_gpio = ich_info->use_gpio; - err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, - ichx_priv.use_gpio); + err = ichx_gpio_request_regions(dev, res_base, pdev->name, + ich_info->use_gpio); if (err) return err; ichx_priv.gpio_base = res_base; + ichx_priv.use_gpio = ich_info->use_gpio; /* * If necessary, determine the I/O address of ACPI/power management - * registers which are needed to read the the GPE0 register for GPI pins + * registers which are needed to read the GPE0 register for GPI pins * 0 - 15 on some chipsets. */ if (!ichx_priv.desc->uses_gpe0) @@ -465,13 +442,13 @@ static int ichx_gpio_probe(struct platform_device *pdev) res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); if (!res_pm) { - pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); + dev_warn(dev, "ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); goto init; } - if (!devm_request_region(&pdev->dev, res_pm->start, - resource_size(res_pm), pdev->name)) { - pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); + if (!devm_request_region(dev, res_pm->start, resource_size(res_pm), + pdev->name)) { + dev_warn(dev, "ACPI BAR is busy, GPI 0 - 15 unavailable\n"); goto init; } @@ -481,12 +458,12 @@ init: ichx_gpiolib_setup(&ichx_priv.chip); err = gpiochip_add_data(&ichx_priv.chip, NULL); if (err) { - pr_err("Failed to register GPIOs\n"); + dev_err(dev, "Failed to register GPIOs\n"); return err; } - pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, - ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); + dev_info(dev, "GPIO from %d to %d\n", ichx_priv.chip.base, + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1); return 0; } diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c index 028d64c2cb1e..4e803baf980e 100644 --- a/drivers/gpio/gpio-intel-mid.c +++ b/drivers/gpio/gpio-intel-mid.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel MID GPIO driver * * Copyright (c) 2008-2014,2016 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* Supports: @@ -20,12 +12,11 @@ */ #include <linux/delay.h> +#include <linux/gpio/driver.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/gpio/driver.h> #include <linux/kernel.h> -#include <linux/module.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -273,9 +264,8 @@ static const struct pci_device_id intel_gpio_ids[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7), .driver_data = (kernel_ulong_t)&gpio_cloverview_core, }, - { 0 } + { } }; -MODULE_DEVICE_TABLE(pci, intel_gpio_ids); static void intel_mid_irq_handler(struct irq_desc *desc) { diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index ca12d9f96914..31b4a091ab60 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -1,36 +1,22 @@ +// 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> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/types.h> +#include <linux/acpi.h> #include <linux/bitops.h> -#include <linux/interrupt.h> #include <linux/gpio/driver.h> -#include <linux/slab.h> -#include <linux/acpi.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/io.h> +#include <linux/slab.h> +#include <linux/types.h> /* LynxPoint chipset has support for 94 gpio pins */ @@ -240,21 +226,23 @@ 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); - u32 base, pin, mask; 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); - while ((pending = (inl(reg) & inl(ena)))) { + /* Only interrupts that are enabled */ + pending = inl(reg) & inl(ena); + + for_each_set_bit(pin, &pending, 32) { unsigned irq; - pin = __ffs(pending); - mask = BIT(pin); /* Clear before handling so we don't lose an edge */ - outl(mask, reg); + outl(BIT(pin), reg); + irq = irq_find_mapping(lg->chip.irq.domain, base + pin); generic_handle_irq(irq); } @@ -466,5 +454,5 @@ module_exit(lp_gpio_exit); MODULE_AUTHOR("Mathias Nyman (Intel)"); MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:lp_gpio"); diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index 97421bd4a60f..7c659fdaa6d5 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -1,18 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Merrifield SoC GPIO driver * * Copyright (c) 2016 Intel Corporation. * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> #include <linux/bitops.h> #include <linux/gpio/driver.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index ffce0ab912ed..ee79e5f88b5a 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -1,25 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> #include <linux/gpio/driver.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> #include <linux/slab.h> #define PCH_EDGE_FALLING 0 @@ -171,11 +159,10 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) return 0; } -#ifdef CONFIG_PM /* * Save register configuration and disable interrupts. */ -static void pch_gpio_save_reg_conf(struct pch_gpio *chip) +static void __maybe_unused pch_gpio_save_reg_conf(struct pch_gpio *chip) { chip->pch_gpio_reg.ien_reg = ioread32(&chip->reg->ien); chip->pch_gpio_reg.imask_reg = ioread32(&chip->reg->imask); @@ -185,14 +172,13 @@ static void pch_gpio_save_reg_conf(struct pch_gpio *chip) if (chip->ioh == INTEL_EG20T_PCH) chip->pch_gpio_reg.im1_reg = ioread32(&chip->reg->im1); if (chip->ioh == OKISEMI_ML7223n_IOH) - chip->pch_gpio_reg.gpio_use_sel_reg =\ - ioread32(&chip->reg->gpio_use_sel); + chip->pch_gpio_reg.gpio_use_sel_reg = ioread32(&chip->reg->gpio_use_sel); } /* * This function restores the register configuration of the GPIO device. */ -static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) +static void __maybe_unused pch_gpio_restore_reg_conf(struct pch_gpio *chip) { iowrite32(chip->pch_gpio_reg.ien_reg, &chip->reg->ien); iowrite32(chip->pch_gpio_reg.imask_reg, &chip->reg->imask); @@ -204,10 +190,8 @@ static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) if (chip->ioh == INTEL_EG20T_PCH) iowrite32(chip->pch_gpio_reg.im1_reg, &chip->reg->im1); if (chip->ioh == OKISEMI_ML7223n_IOH) - iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, - &chip->reg->gpio_use_sel); + iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, &chip->reg->gpio_use_sel); } -#endif static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { @@ -226,7 +210,6 @@ static void pch_gpio_setup(struct pch_gpio *chip) gpio->get = pch_gpio_get; gpio->direction_output = pch_gpio_direction_output; gpio->set = pch_gpio_set; - gpio->dbg_show = NULL; gpio->base = -1; gpio->ngpio = gpio_pins[chip->ioh]; gpio->can_sleep = false; @@ -250,8 +233,7 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) im_reg = &chip->reg->im1; im_pos = ch - 8; } - dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d\n", - __func__, irq, type, ch, im_pos); + dev_dbg(chip->dev, "irq=%d type=%d ch=%d pos=%d\n", irq, type, ch, im_pos); spin_lock_irqsave(&chip->spinlock, flags); @@ -317,16 +299,13 @@ static void pch_irq_ack(struct irq_data *d) static irqreturn_t pch_gpio_handler(int irq, void *dev_id) { struct pch_gpio *chip = dev_id; - u32 reg_val = ioread32(&chip->reg->istatus); + unsigned long reg_val = ioread32(&chip->reg->istatus); int i, ret = IRQ_NONE; - for (i = 0; i < gpio_pins[chip->ioh]; i++) { - if (reg_val & BIT(i)) { - dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", - __func__, i, irq, reg_val); - generic_handle_irq(chip->irq_base + i); - ret = IRQ_HANDLED; - } + for_each_set_bit(i, ®_val, gpio_pins[chip->ioh]) { + dev_dbg(chip->dev, "[%d]:irq=%d status=0x%lx\n", i, irq, reg_val); + generic_handle_irq(chip->irq_base + i); + ret = IRQ_HANDLED; } return ret; } @@ -367,29 +346,24 @@ static int pch_gpio_probe(struct pci_dev *pdev, int irq_base; u32 msk; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->dev = &pdev->dev; - ret = pci_enable_device(pdev); + ret = pcim_enable_device(pdev); if (ret) { - dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__); - goto err_pci_enable; + dev_err(&pdev->dev, "pci_enable_device FAILED"); + return ret; } - ret = pci_request_regions(pdev, KBUILD_MODNAME); + ret = pcim_iomap_regions(pdev, 1 << 1, KBUILD_MODNAME); if (ret) { dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret); - goto err_request_regions; + return ret; } - chip->base = pci_iomap(pdev, 1, 0); - if (!chip->base) { - dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); - ret = -ENOMEM; - goto err_iomap; - } + chip->base = pcim_iomap_table(pdev)[1]; if (pdev->device == 0x8803) chip->ioh = INTEL_EG20T_PCH; @@ -402,13 +376,11 @@ static int pch_gpio_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, chip); spin_lock_init(&chip->spinlock); pch_gpio_setup(chip); -#ifdef CONFIG_OF_GPIO - chip->gpio.of_node = pdev->dev.of_node; -#endif - ret = gpiochip_add_data(&chip->gpio, chip); + + ret = devm_gpiochip_add_data(&pdev->dev, &chip->gpio, chip); if (ret) { dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n"); - goto err_gpiochip_add; + return ret; } irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, @@ -416,7 +388,7 @@ static int pch_gpio_probe(struct pci_dev *pdev, if (irq_base < 0) { dev_warn(&pdev->dev, "PCH gpio: Failed to get IRQ base num\n"); chip->irq_base = -1; - goto end; + return 0; } chip->irq_base = irq_base; @@ -427,53 +399,17 @@ static int pch_gpio_probe(struct pci_dev *pdev, ret = devm_request_irq(&pdev->dev, pdev->irq, pch_gpio_handler, IRQF_SHARED, KBUILD_MODNAME, chip); - if (ret != 0) { - dev_err(&pdev->dev, - "%s request_irq failed\n", __func__); - goto err_request_irq; + if (ret) { + dev_err(&pdev->dev, "request_irq failed\n"); + return ret; } - ret = pch_gpio_alloc_generic_chip(chip, irq_base, - gpio_pins[chip->ioh]); - if (ret) - goto err_request_irq; - -end: - return 0; - -err_request_irq: - gpiochip_remove(&chip->gpio); - -err_gpiochip_add: - pci_iounmap(pdev, chip->base); - -err_iomap: - pci_release_regions(pdev); - -err_request_regions: - pci_disable_device(pdev); - -err_pci_enable: - kfree(chip); - dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); - return ret; -} - -static void pch_gpio_remove(struct pci_dev *pdev) -{ - struct pch_gpio *chip = pci_get_drvdata(pdev); - - gpiochip_remove(&chip->gpio); - pci_iounmap(pdev, chip->base); - pci_release_regions(pdev); - pci_disable_device(pdev); - kfree(chip); + return pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); } -#ifdef CONFIG_PM -static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused pch_gpio_suspend(struct device *dev) { - s32 ret; + struct pci_dev *pdev = to_pci_dev(dev); struct pch_gpio *chip = pci_get_drvdata(pdev); unsigned long flags; @@ -481,36 +417,15 @@ static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state) pch_gpio_save_reg_conf(chip); spin_unlock_irqrestore(&chip->spinlock, flags); - ret = pci_save_state(pdev); - if (ret) { - dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); - return ret; - } - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_wake(pdev, PCI_D0, 1); - if (ret) - dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); - return 0; } -static int pch_gpio_resume(struct pci_dev *pdev) +static int __maybe_unused pch_gpio_resume(struct device *dev) { - s32 ret; + struct pci_dev *pdev = to_pci_dev(dev); struct pch_gpio *chip = pci_get_drvdata(pdev); unsigned long flags; - ret = pci_enable_wake(pdev, PCI_D0, 0); - - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); - return ret; - } - pci_restore_state(pdev); - spin_lock_irqsave(&chip->spinlock, flags); iowrite32(0x01, &chip->reg->reset); iowrite32(0x00, &chip->reg->reset); @@ -519,10 +434,8 @@ static int pch_gpio_resume(struct pci_dev *pdev) return 0; } -#else -#define pch_gpio_suspend NULL -#define pch_gpio_resume NULL -#endif + +static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); #define PCI_VENDOR_ID_ROHM 0x10DB static const struct pci_device_id pch_gpio_pcidev_id[] = { @@ -538,12 +451,12 @@ static struct pci_driver pch_gpio_driver = { .name = "pch_gpio", .id_table = pch_gpio_pcidev_id, .probe = pch_gpio_probe, - .remove = pch_gpio_remove, - .suspend = pch_gpio_suspend, - .resume = pch_gpio_resume + .driver = { + .pm = &pch_gpio_pm_ops, + }, }; module_pci_driver(pch_gpio_driver); MODULE_DESCRIPTION("PCH GPIO PCI Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index e9878f6ede67..c333046d02b8 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -1,32 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 /* * GPIO interface for Intel Poulsbo SCH * * Copyright (c) 2010 CompuLab Ltd * Author: Denis Turischev <denis@compulab.co.il> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/init.h> +#include <linux/acpi.h> +#include <linux/errno.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/io.h> -#include <linux/errno.h> -#include <linux/acpi.h> -#include <linux/platform_device.h> #include <linux/pci_ids.h> -#include <linux/gpio/driver.h> +#include <linux/platform_device.h> #define GEN 0x00 #define GIO 0x04 @@ -235,5 +222,5 @@ module_platform_driver(sch_gpio_driver); MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:sch_gpio"); diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index f60da83349ef..aed988e78251 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c @@ -1,26 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 /* * GPIO interface for Intel Sodaville SoCs. * * Copyright (c) 2010, 2011 Intel Corporation * * Author: Hans J. Koch <hjk@linutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License 2 as published - * by the Free Software Foundation. - * */ #include <linux/errno.h> +#include <linux/gpio/driver.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> -#include <linux/interrupt.h> #include <linux/kernel.h> +#include <linux/of_irq.h> #include <linux/pci.h> #include <linux/platform_device.h> -#include <linux/of_irq.h> -#include <linux/gpio/driver.h> #define DRV_NAME "sdv_gpio" #define SDV_NUM_PUB_GPIOS 12 @@ -80,18 +76,15 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) { struct sdv_gpio_chip_data *sd = data; - u32 irq_stat = readl(sd->gpio_pub_base + GPSTR); + unsigned long irq_stat = readl(sd->gpio_pub_base + GPSTR); + int irq_bit; irq_stat &= readl(sd->gpio_pub_base + GPIO_INT); if (!irq_stat) return IRQ_NONE; - while (irq_stat) { - u32 irq_bit = __fls(irq_stat); - - irq_stat &= ~BIT(irq_bit); + for_each_set_bit(irq_bit, &irq_stat, 32) generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); - } return IRQ_HANDLED; } @@ -155,8 +148,10 @@ static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, * we unmask & ACK the IRQ before the source of the interrupt is gone * then the interrupt is active again. */ - sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base, - sd->gpio_pub_base, handle_fasteoi_irq); + sd->gc = devm_irq_alloc_generic_chip(&pdev->dev, "sdv-gpio", 1, + sd->irq_base, + sd->gpio_pub_base, + handle_fasteoi_irq); if (!sd->gc) return -ENOMEM; @@ -186,70 +181,52 @@ static int sdv_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { struct sdv_gpio_chip_data *sd; - unsigned long addr; - const void *prop; - int len; int ret; u32 mux_val; - sd = kzalloc(sizeof(struct sdv_gpio_chip_data), GFP_KERNEL); + sd = devm_kzalloc(&pdev->dev, sizeof(*sd), GFP_KERNEL); if (!sd) return -ENOMEM; - ret = pci_enable_device(pdev); + + ret = pcim_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "can't enable device.\n"); - goto done; + return ret; } - ret = pci_request_region(pdev, GPIO_BAR, DRV_NAME); + ret = pcim_iomap_regions(pdev, 1 << GPIO_BAR, DRV_NAME); if (ret) { dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); - goto disable_pci; + return ret; } - addr = pci_resource_start(pdev, GPIO_BAR); - if (!addr) { - ret = -ENODEV; - goto release_reg; - } - sd->gpio_pub_base = ioremap(addr, pci_resource_len(pdev, GPIO_BAR)); + sd->gpio_pub_base = pcim_iomap_table(pdev)[GPIO_BAR]; - prop = of_get_property(pdev->dev.of_node, "intel,muxctl", &len); - if (prop && len == 4) { - mux_val = of_read_number(prop, 1); + ret = of_property_read_u32(pdev->dev.of_node, "intel,muxctl", &mux_val); + if (!ret) writel(mux_val, sd->gpio_pub_base + GPMUXCTL); - } ret = bgpio_init(&sd->chip, &pdev->dev, 4, sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR, NULL, sd->gpio_pub_base + GPOER, NULL, 0); if (ret) - goto unmap; + return ret; + sd->chip.ngpio = SDV_NUM_PUB_GPIOS; - ret = gpiochip_add_data(&sd->chip, sd); + ret = devm_gpiochip_add_data(&pdev->dev, &sd->chip, sd); if (ret < 0) { dev_err(&pdev->dev, "gpiochip_add() failed.\n"); - goto unmap; + return ret; } ret = sdv_register_irqsupport(sd, pdev); if (ret) - goto unmap; + return ret; pci_set_drvdata(pdev, sd); dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n"); return 0; - -unmap: - iounmap(sd->gpio_pub_base); -release_reg: - pci_release_region(pdev, GPIO_BAR); -disable_pci: - pci_disable_device(pdev); -done: - kfree(sd); - return ret; } static const struct pci_device_id sdv_gpio_pci_ids[] = { |