.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * ZTE ZX296702 GPIO driver |
---|
3 | 4 | * |
---|
4 | 5 | * Author: Jun Nie <jun.nie@linaro.org> |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (C) 2015 Linaro Ltd. |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | */ |
---|
12 | 9 | #include <linux/bitops.h> |
---|
13 | 10 | #include <linux/device.h> |
---|
.. | .. |
---|
218 | 215 | { |
---|
219 | 216 | struct device *dev = &pdev->dev; |
---|
220 | 217 | struct zx_gpio *chip; |
---|
221 | | - struct resource *res; |
---|
| 218 | + struct gpio_irq_chip *girq; |
---|
222 | 219 | int irq, id, ret; |
---|
223 | 220 | |
---|
224 | 221 | chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); |
---|
225 | 222 | if (!chip) |
---|
226 | 223 | return -ENOMEM; |
---|
227 | 224 | |
---|
228 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
229 | | - chip->base = devm_ioremap_resource(dev, res); |
---|
| 225 | + chip->base = devm_platform_ioremap_resource(pdev, 0); |
---|
230 | 226 | if (IS_ERR(chip->base)) |
---|
231 | 227 | return PTR_ERR(chip->base); |
---|
232 | 228 | |
---|
233 | | - raw_spin_lock_init(&chip->lock); |
---|
234 | | - if (of_property_read_bool(dev->of_node, "gpio-ranges")) { |
---|
235 | | - chip->gc.request = gpiochip_generic_request; |
---|
236 | | - chip->gc.free = gpiochip_generic_free; |
---|
237 | | - } |
---|
238 | | - |
---|
239 | 229 | id = of_alias_get_id(dev->of_node, "gpio"); |
---|
| 230 | + |
---|
| 231 | + raw_spin_lock_init(&chip->lock); |
---|
| 232 | + chip->gc.request = gpiochip_generic_request; |
---|
| 233 | + chip->gc.free = gpiochip_generic_free; |
---|
240 | 234 | chip->gc.direction_input = zx_direction_input; |
---|
241 | 235 | chip->gc.direction_output = zx_direction_output; |
---|
242 | 236 | chip->gc.get = zx_get_value; |
---|
.. | .. |
---|
247 | 241 | chip->gc.parent = dev; |
---|
248 | 242 | chip->gc.owner = THIS_MODULE; |
---|
249 | 243 | |
---|
250 | | - ret = gpiochip_add_data(&chip->gc, chip); |
---|
251 | | - if (ret) |
---|
252 | | - return ret; |
---|
253 | | - |
---|
254 | 244 | /* |
---|
255 | 245 | * irq_chip support |
---|
256 | 246 | */ |
---|
257 | 247 | writew_relaxed(0xffff, chip->base + ZX_GPIO_IM); |
---|
258 | 248 | writew_relaxed(0, chip->base + ZX_GPIO_IE); |
---|
259 | 249 | irq = platform_get_irq(pdev, 0); |
---|
260 | | - if (irq < 0) { |
---|
261 | | - dev_err(dev, "invalid IRQ\n"); |
---|
262 | | - gpiochip_remove(&chip->gc); |
---|
263 | | - return -ENODEV; |
---|
264 | | - } |
---|
| 250 | + if (irq < 0) |
---|
| 251 | + return irq; |
---|
| 252 | + girq = &chip->gc.irq; |
---|
| 253 | + girq->chip = &zx_irqchip; |
---|
| 254 | + girq->parent_handler = zx_irq_handler; |
---|
| 255 | + girq->num_parents = 1; |
---|
| 256 | + girq->parents = devm_kcalloc(&pdev->dev, 1, |
---|
| 257 | + sizeof(*girq->parents), |
---|
| 258 | + GFP_KERNEL); |
---|
| 259 | + if (!girq->parents) |
---|
| 260 | + return -ENOMEM; |
---|
| 261 | + girq->parents[0] = irq; |
---|
| 262 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 263 | + girq->handler = handle_simple_irq; |
---|
265 | 264 | |
---|
266 | | - ret = gpiochip_irqchip_add(&chip->gc, &zx_irqchip, |
---|
267 | | - 0, handle_simple_irq, |
---|
268 | | - IRQ_TYPE_NONE); |
---|
269 | | - if (ret) { |
---|
270 | | - dev_err(dev, "could not add irqchip\n"); |
---|
271 | | - gpiochip_remove(&chip->gc); |
---|
| 265 | + ret = gpiochip_add_data(&chip->gc, chip); |
---|
| 266 | + if (ret) |
---|
272 | 267 | return ret; |
---|
273 | | - } |
---|
274 | | - gpiochip_set_chained_irqchip(&chip->gc, &zx_irqchip, |
---|
275 | | - irq, zx_irq_handler); |
---|
276 | 268 | |
---|
277 | 269 | platform_set_drvdata(pdev, chip); |
---|
278 | 270 | dev_info(dev, "ZX GPIO chip registered\n"); |
---|