in gpio-tqmx86.c [229:328]
static int tqmx86_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct tqmx86_gpio_data *gpio;
struct gpio_chip *chip;
struct gpio_irq_chip *girq;
void __iomem *io_base;
struct resource *res;
int ret, irq;
irq = platform_get_irq_optional(pdev, 0);
if (irq < 0 && irq != -ENXIO)
return irq;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!res) {
dev_err(&pdev->dev, "Cannot get I/O\n");
return -ENODEV;
}
io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
if (!io_base)
return -ENOMEM;
gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
raw_spin_lock_init(&gpio->spinlock);
gpio->io_base = io_base;
tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
platform_set_drvdata(pdev, gpio);
chip = &gpio->chip;
chip->label = "gpio-tqmx86";
chip->owner = THIS_MODULE;
chip->can_sleep = false;
chip->base = -1;
chip->direction_input = tqmx86_gpio_direction_input;
chip->direction_output = tqmx86_gpio_direction_output;
chip->get_direction = tqmx86_gpio_get_direction;
chip->get = tqmx86_gpio_get;
chip->set = tqmx86_gpio_set;
chip->ngpio = TQMX86_NGPIO;
chip->parent = pdev->dev.parent;
pm_runtime_enable(&pdev->dev);
if (irq > 0) {
struct irq_chip *irq_chip = &gpio->irq_chip;
u8 irq_status;
irq_chip->name = chip->label;
irq_chip->parent_device = &pdev->dev;
irq_chip->irq_mask = tqmx86_gpio_irq_mask;
irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
/* Mask all interrupts */
tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
/* Clear all pending interrupts */
irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
girq = &chip->irq;
girq->chip = irq_chip;
girq->parent_handler = tqmx86_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents) {
ret = -ENOMEM;
goto out_pm_dis;
}
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_simple_irq;
girq->init_valid_mask = tqmx86_init_irq_valid_mask;
}
ret = devm_gpiochip_add_data(dev, chip, gpio);
if (ret) {
dev_err(dev, "Could not register GPIO chip\n");
goto out_pm_dis;
}
dev_info(dev, "GPIO functionality initialized with %d pins\n",
chip->ngpio);
return 0;
out_pm_dis:
pm_runtime_disable(&pdev->dev);
return ret;
}