| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2010 Extreme Engineering Solutions. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; if not, write to the Free Software |
|---|
| 18 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 19 | 6 | */ |
|---|
| 20 | 7 | |
|---|
| 21 | | -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| 22 | 8 | |
|---|
| 9 | +#include <linux/bitops.h> |
|---|
| 10 | +#include <linux/gpio/driver.h> |
|---|
| 23 | 11 | #include <linux/ioport.h> |
|---|
| 12 | +#include <linux/mfd/lpc_ich.h> |
|---|
| 24 | 13 | #include <linux/module.h> |
|---|
| 25 | 14 | #include <linux/pci.h> |
|---|
| 26 | | -#include <linux/gpio/driver.h> |
|---|
| 27 | 15 | #include <linux/platform_device.h> |
|---|
| 28 | | -#include <linux/mfd/lpc_ich.h> |
|---|
| 29 | | -#include <linux/bitops.h> |
|---|
| 30 | 16 | |
|---|
| 31 | 17 | #define DRV_NAME "gpio_ich" |
|---|
| 32 | 18 | |
|---|
| .. | .. |
|---|
| 88 | 74 | u32 use_sel_ignore[3]; |
|---|
| 89 | 75 | |
|---|
| 90 | 76 | /* Some chipsets have quirks, let these use their own request/get */ |
|---|
| 91 | | - int (*request)(struct gpio_chip *chip, unsigned offset); |
|---|
| 92 | | - int (*get)(struct gpio_chip *chip, unsigned offset); |
|---|
| 77 | + int (*request)(struct gpio_chip *chip, unsigned int offset); |
|---|
| 78 | + int (*get)(struct gpio_chip *chip, unsigned int offset); |
|---|
| 93 | 79 | |
|---|
| 94 | 80 | /* |
|---|
| 95 | 81 | * Some chipsets don't let reading output values on GPIO_LVL register |
|---|
| .. | .. |
|---|
| 100 | 86 | |
|---|
| 101 | 87 | static struct { |
|---|
| 102 | 88 | spinlock_t lock; |
|---|
| 103 | | - struct platform_device *dev; |
|---|
| 89 | + struct device *dev; |
|---|
| 104 | 90 | struct gpio_chip chip; |
|---|
| 105 | 91 | struct resource *gpio_base; /* GPIO IO base */ |
|---|
| 106 | | - struct resource *pm_base; /* Power Mangagment IO base */ |
|---|
| 92 | + struct resource *pm_base; /* Power Management IO base */ |
|---|
| 107 | 93 | struct ichx_desc *desc; /* Pointer to chipset-specific description */ |
|---|
| 108 | 94 | u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ |
|---|
| 109 | 95 | u8 use_gpio; /* Which GPIO groups are usable */ |
|---|
| .. | .. |
|---|
| 112 | 98 | |
|---|
| 113 | 99 | static int modparam_gpiobase = -1; /* dynamic */ |
|---|
| 114 | 100 | module_param_named(gpiobase, modparam_gpiobase, int, 0444); |
|---|
| 115 | | -MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " |
|---|
| 116 | | - "which is the default."); |
|---|
| 101 | +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default."); |
|---|
| 117 | 102 | |
|---|
| 118 | | -static int ichx_write_bit(int reg, unsigned nr, int val, int verify) |
|---|
| 103 | +static int ichx_write_bit(int reg, unsigned int nr, int val, int verify) |
|---|
| 119 | 104 | { |
|---|
| 120 | 105 | unsigned long flags; |
|---|
| 121 | 106 | u32 data, tmp; |
|---|
| 122 | 107 | int reg_nr = nr / 32; |
|---|
| 123 | 108 | int bit = nr & 0x1f; |
|---|
| 124 | | - int ret = 0; |
|---|
| 125 | 109 | |
|---|
| 126 | 110 | spin_lock_irqsave(&ichx_priv.lock, flags); |
|---|
| 127 | 111 | |
|---|
| .. | .. |
|---|
| 142 | 126 | |
|---|
| 143 | 127 | tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], |
|---|
| 144 | 128 | ichx_priv.gpio_base); |
|---|
| 145 | | - if (verify && data != tmp) |
|---|
| 146 | | - ret = -EPERM; |
|---|
| 147 | 129 | |
|---|
| 148 | 130 | spin_unlock_irqrestore(&ichx_priv.lock, flags); |
|---|
| 149 | 131 | |
|---|
| 150 | | - return ret; |
|---|
| 132 | + return (verify && data != tmp) ? -EPERM : 0; |
|---|
| 151 | 133 | } |
|---|
| 152 | 134 | |
|---|
| 153 | | -static int ichx_read_bit(int reg, unsigned nr) |
|---|
| 135 | +static int ichx_read_bit(int reg, unsigned int nr) |
|---|
| 154 | 136 | { |
|---|
| 155 | 137 | unsigned long flags; |
|---|
| 156 | 138 | u32 data; |
|---|
| .. | .. |
|---|
| 170 | 152 | return !!(data & BIT(bit)); |
|---|
| 171 | 153 | } |
|---|
| 172 | 154 | |
|---|
| 173 | | -static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) |
|---|
| 155 | +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned int nr) |
|---|
| 174 | 156 | { |
|---|
| 175 | 157 | return !!(ichx_priv.use_gpio & BIT(nr / 32)); |
|---|
| 176 | 158 | } |
|---|
| 177 | 159 | |
|---|
| 178 | | -static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr) |
|---|
| 160 | +static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned int nr) |
|---|
| 179 | 161 | { |
|---|
| 180 | | - return ichx_read_bit(GPIO_IO_SEL, nr); |
|---|
| 162 | + if (ichx_read_bit(GPIO_IO_SEL, nr)) |
|---|
| 163 | + return GPIO_LINE_DIRECTION_IN; |
|---|
| 164 | + |
|---|
| 165 | + return GPIO_LINE_DIRECTION_OUT; |
|---|
| 181 | 166 | } |
|---|
| 182 | 167 | |
|---|
| 183 | | -static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) |
|---|
| 168 | +static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned int nr) |
|---|
| 184 | 169 | { |
|---|
| 185 | 170 | /* |
|---|
| 186 | 171 | * Try setting pin as an input and verify it worked since many pins |
|---|
| 187 | 172 | * are output-only. |
|---|
| 188 | 173 | */ |
|---|
| 189 | | - if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) |
|---|
| 190 | | - return -EINVAL; |
|---|
| 191 | | - |
|---|
| 192 | | - return 0; |
|---|
| 174 | + return ichx_write_bit(GPIO_IO_SEL, nr, 1, 1); |
|---|
| 193 | 175 | } |
|---|
| 194 | 176 | |
|---|
| 195 | | -static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, |
|---|
| 177 | +static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned int nr, |
|---|
| 196 | 178 | int val) |
|---|
| 197 | 179 | { |
|---|
| 198 | 180 | /* Disable blink hardware which is available for GPIOs from 0 to 31. */ |
|---|
| .. | .. |
|---|
| 206 | 188 | * Try setting pin as an output and verify it worked since many pins |
|---|
| 207 | 189 | * are input-only. |
|---|
| 208 | 190 | */ |
|---|
| 209 | | - if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) |
|---|
| 210 | | - return -EINVAL; |
|---|
| 211 | | - |
|---|
| 212 | | - return 0; |
|---|
| 191 | + return ichx_write_bit(GPIO_IO_SEL, nr, 0, 1); |
|---|
| 213 | 192 | } |
|---|
| 214 | 193 | |
|---|
| 215 | | -static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) |
|---|
| 194 | +static int ichx_gpio_get(struct gpio_chip *chip, unsigned int nr) |
|---|
| 216 | 195 | { |
|---|
| 217 | 196 | return ichx_read_bit(GPIO_LVL, nr); |
|---|
| 218 | 197 | } |
|---|
| 219 | 198 | |
|---|
| 220 | | -static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) |
|---|
| 199 | +static int ich6_gpio_get(struct gpio_chip *chip, unsigned int nr) |
|---|
| 221 | 200 | { |
|---|
| 222 | 201 | unsigned long flags; |
|---|
| 223 | 202 | u32 data; |
|---|
| .. | .. |
|---|
| 244 | 223 | } |
|---|
| 245 | 224 | } |
|---|
| 246 | 225 | |
|---|
| 247 | | -static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) |
|---|
| 226 | +static int ichx_gpio_request(struct gpio_chip *chip, unsigned int nr) |
|---|
| 248 | 227 | { |
|---|
| 249 | 228 | if (!ichx_gpio_check_available(chip, nr)) |
|---|
| 250 | 229 | return -ENXIO; |
|---|
| .. | .. |
|---|
| 261 | 240 | return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; |
|---|
| 262 | 241 | } |
|---|
| 263 | 242 | |
|---|
| 264 | | -static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) |
|---|
| 243 | +static int ich6_gpio_request(struct gpio_chip *chip, unsigned int nr) |
|---|
| 265 | 244 | { |
|---|
| 266 | 245 | /* |
|---|
| 267 | 246 | * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 |
|---|
| .. | .. |
|---|
| 275 | 254 | return ichx_gpio_request(chip, nr); |
|---|
| 276 | 255 | } |
|---|
| 277 | 256 | |
|---|
| 278 | | -static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) |
|---|
| 257 | +static void ichx_gpio_set(struct gpio_chip *chip, unsigned int nr, int val) |
|---|
| 279 | 258 | { |
|---|
| 280 | 259 | ichx_write_bit(GPIO_LVL, nr, val, 0); |
|---|
| 281 | 260 | } |
|---|
| .. | .. |
|---|
| 284 | 263 | { |
|---|
| 285 | 264 | chip->owner = THIS_MODULE; |
|---|
| 286 | 265 | chip->label = DRV_NAME; |
|---|
| 287 | | - chip->parent = &ichx_priv.dev->dev; |
|---|
| 266 | + chip->parent = ichx_priv.dev; |
|---|
| 288 | 267 | |
|---|
| 289 | 268 | /* Allow chip-specific overrides of request()/get() */ |
|---|
| 290 | 269 | chip->request = ichx_priv.desc->request ? |
|---|
| .. | .. |
|---|
| 407 | 386 | |
|---|
| 408 | 387 | static int ichx_gpio_probe(struct platform_device *pdev) |
|---|
| 409 | 388 | { |
|---|
| 389 | + struct device *dev = &pdev->dev; |
|---|
| 390 | + struct lpc_ich_info *ich_info = dev_get_platdata(dev); |
|---|
| 410 | 391 | struct resource *res_base, *res_pm; |
|---|
| 411 | 392 | int err; |
|---|
| 412 | | - struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); |
|---|
| 413 | 393 | |
|---|
| 414 | 394 | if (!ich_info) |
|---|
| 415 | 395 | return -ENODEV; |
|---|
| 416 | | - |
|---|
| 417 | | - ichx_priv.dev = pdev; |
|---|
| 418 | 396 | |
|---|
| 419 | 397 | switch (ich_info->gpio_version) { |
|---|
| 420 | 398 | case ICH_I3100_GPIO: |
|---|
| .. | .. |
|---|
| 445 | 423 | return -ENODEV; |
|---|
| 446 | 424 | } |
|---|
| 447 | 425 | |
|---|
| 426 | + ichx_priv.dev = dev; |
|---|
| 448 | 427 | spin_lock_init(&ichx_priv.lock); |
|---|
| 428 | + |
|---|
| 449 | 429 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); |
|---|
| 450 | | - ichx_priv.use_gpio = ich_info->use_gpio; |
|---|
| 451 | | - err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, |
|---|
| 452 | | - ichx_priv.use_gpio); |
|---|
| 430 | + err = ichx_gpio_request_regions(dev, res_base, pdev->name, |
|---|
| 431 | + ich_info->use_gpio); |
|---|
| 453 | 432 | if (err) |
|---|
| 454 | 433 | return err; |
|---|
| 455 | 434 | |
|---|
| 456 | 435 | ichx_priv.gpio_base = res_base; |
|---|
| 436 | + ichx_priv.use_gpio = ich_info->use_gpio; |
|---|
| 457 | 437 | |
|---|
| 458 | 438 | /* |
|---|
| 459 | 439 | * If necessary, determine the I/O address of ACPI/power management |
|---|
| 460 | | - * registers which are needed to read the the GPE0 register for GPI pins |
|---|
| 440 | + * registers which are needed to read the GPE0 register for GPI pins |
|---|
| 461 | 441 | * 0 - 15 on some chipsets. |
|---|
| 462 | 442 | */ |
|---|
| 463 | 443 | if (!ichx_priv.desc->uses_gpe0) |
|---|
| .. | .. |
|---|
| 465 | 445 | |
|---|
| 466 | 446 | res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); |
|---|
| 467 | 447 | if (!res_pm) { |
|---|
| 468 | | - pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); |
|---|
| 448 | + dev_warn(dev, "ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); |
|---|
| 469 | 449 | goto init; |
|---|
| 470 | 450 | } |
|---|
| 471 | 451 | |
|---|
| 472 | | - if (!devm_request_region(&pdev->dev, res_pm->start, |
|---|
| 473 | | - resource_size(res_pm), pdev->name)) { |
|---|
| 474 | | - pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); |
|---|
| 452 | + if (!devm_request_region(dev, res_pm->start, resource_size(res_pm), |
|---|
| 453 | + pdev->name)) { |
|---|
| 454 | + dev_warn(dev, "ACPI BAR is busy, GPI 0 - 15 unavailable\n"); |
|---|
| 475 | 455 | goto init; |
|---|
| 476 | 456 | } |
|---|
| 477 | 457 | |
|---|
| .. | .. |
|---|
| 481 | 461 | ichx_gpiolib_setup(&ichx_priv.chip); |
|---|
| 482 | 462 | err = gpiochip_add_data(&ichx_priv.chip, NULL); |
|---|
| 483 | 463 | if (err) { |
|---|
| 484 | | - pr_err("Failed to register GPIOs\n"); |
|---|
| 464 | + dev_err(dev, "Failed to register GPIOs\n"); |
|---|
| 485 | 465 | return err; |
|---|
| 486 | 466 | } |
|---|
| 487 | 467 | |
|---|
| 488 | | - pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, |
|---|
| 489 | | - ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); |
|---|
| 468 | + dev_info(dev, "GPIO from %d to %d\n", ichx_priv.chip.base, |
|---|
| 469 | + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1); |
|---|
| 490 | 470 | |
|---|
| 491 | 471 | return 0; |
|---|
| 492 | 472 | } |
|---|