| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Intel MID GPIO driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2008-2014,2016 Intel Corporation. |
|---|
| 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 version 2 as |
|---|
| 8 | | - * published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | /* Supports: |
|---|
| .. | .. |
|---|
| 20 | 12 | */ |
|---|
| 21 | 13 | |
|---|
| 22 | 14 | #include <linux/delay.h> |
|---|
| 15 | +#include <linux/gpio/driver.h> |
|---|
| 23 | 16 | #include <linux/init.h> |
|---|
| 24 | 17 | #include <linux/interrupt.h> |
|---|
| 25 | 18 | #include <linux/io.h> |
|---|
| 26 | | -#include <linux/gpio/driver.h> |
|---|
| 27 | 19 | #include <linux/kernel.h> |
|---|
| 28 | | -#include <linux/module.h> |
|---|
| 29 | 20 | #include <linux/pci.h> |
|---|
| 30 | 21 | #include <linux/platform_device.h> |
|---|
| 31 | 22 | #include <linux/pm_runtime.h> |
|---|
| .. | .. |
|---|
| 273 | 264 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7), |
|---|
| 274 | 265 | .driver_data = (kernel_ulong_t)&gpio_cloverview_core, |
|---|
| 275 | 266 | }, |
|---|
| 276 | | - { 0 } |
|---|
| 267 | + { } |
|---|
| 277 | 268 | }; |
|---|
| 278 | | -MODULE_DEVICE_TABLE(pci, intel_gpio_ids); |
|---|
| 279 | 269 | |
|---|
| 280 | 270 | static void intel_mid_irq_handler(struct irq_desc *desc) |
|---|
| 281 | 271 | { |
|---|
| .. | .. |
|---|
| 303 | 293 | chip->irq_eoi(data); |
|---|
| 304 | 294 | } |
|---|
| 305 | 295 | |
|---|
| 306 | | -static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv) |
|---|
| 296 | +static int intel_mid_irq_init_hw(struct gpio_chip *chip) |
|---|
| 307 | 297 | { |
|---|
| 298 | + struct intel_mid_gpio *priv = gpiochip_get_data(chip); |
|---|
| 308 | 299 | void __iomem *reg; |
|---|
| 309 | 300 | unsigned base; |
|---|
| 310 | 301 | |
|---|
| .. | .. |
|---|
| 319 | 310 | reg = gpio_reg(&priv->chip, base, GEDR); |
|---|
| 320 | 311 | writel(~0, reg); |
|---|
| 321 | 312 | } |
|---|
| 313 | + |
|---|
| 314 | + return 0; |
|---|
| 322 | 315 | } |
|---|
| 323 | 316 | |
|---|
| 324 | 317 | static int __maybe_unused intel_gpio_runtime_idle(struct device *dev) |
|---|
| .. | .. |
|---|
| 339 | 332 | u32 gpio_base; |
|---|
| 340 | 333 | u32 irq_base; |
|---|
| 341 | 334 | int retval; |
|---|
| 335 | + struct gpio_irq_chip *girq; |
|---|
| 342 | 336 | struct intel_mid_gpio_ddata *ddata = |
|---|
| 343 | 337 | (struct intel_mid_gpio_ddata *)id->driver_data; |
|---|
| 344 | 338 | |
|---|
| .. | .. |
|---|
| 379 | 373 | |
|---|
| 380 | 374 | spin_lock_init(&priv->lock); |
|---|
| 381 | 375 | |
|---|
| 376 | + girq = &priv->chip.irq; |
|---|
| 377 | + girq->chip = &intel_mid_irqchip; |
|---|
| 378 | + girq->init_hw = intel_mid_irq_init_hw; |
|---|
| 379 | + girq->parent_handler = intel_mid_irq_handler; |
|---|
| 380 | + girq->num_parents = 1; |
|---|
| 381 | + girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, |
|---|
| 382 | + sizeof(*girq->parents), |
|---|
| 383 | + GFP_KERNEL); |
|---|
| 384 | + if (!girq->parents) |
|---|
| 385 | + return -ENOMEM; |
|---|
| 386 | + girq->parents[0] = pdev->irq; |
|---|
| 387 | + girq->first = irq_base; |
|---|
| 388 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 389 | + girq->handler = handle_simple_irq; |
|---|
| 390 | + |
|---|
| 382 | 391 | pci_set_drvdata(pdev, priv); |
|---|
| 392 | + |
|---|
| 383 | 393 | retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); |
|---|
| 384 | 394 | if (retval) { |
|---|
| 385 | 395 | dev_err(&pdev->dev, "gpiochip_add error %d\n", retval); |
|---|
| 386 | 396 | return retval; |
|---|
| 387 | 397 | } |
|---|
| 388 | | - |
|---|
| 389 | | - retval = gpiochip_irqchip_add(&priv->chip, |
|---|
| 390 | | - &intel_mid_irqchip, |
|---|
| 391 | | - irq_base, |
|---|
| 392 | | - handle_simple_irq, |
|---|
| 393 | | - IRQ_TYPE_NONE); |
|---|
| 394 | | - if (retval) { |
|---|
| 395 | | - dev_err(&pdev->dev, |
|---|
| 396 | | - "could not connect irqchip to gpiochip\n"); |
|---|
| 397 | | - return retval; |
|---|
| 398 | | - } |
|---|
| 399 | | - |
|---|
| 400 | | - intel_mid_irq_init_hw(priv); |
|---|
| 401 | | - |
|---|
| 402 | | - gpiochip_set_chained_irqchip(&priv->chip, |
|---|
| 403 | | - &intel_mid_irqchip, |
|---|
| 404 | | - pdev->irq, |
|---|
| 405 | | - intel_mid_irq_handler); |
|---|
| 406 | 398 | |
|---|
| 407 | 399 | pm_runtime_put_noidle(&pdev->dev); |
|---|
| 408 | 400 | pm_runtime_allow(&pdev->dev); |
|---|