diff --git a/drivers/gpio/gpio-phytium-core.c b/drivers/gpio/gpio-phytium-core.c index dce2fe463991c54a0722524f9f276d8f00ae2cb6..b5ee1770f7e47146e5376cab2fb6ed2e764ede17 100644 --- a/drivers/gpio/gpio-phytium-core.c +++ b/drivers/gpio/gpio-phytium-core.c @@ -259,6 +259,41 @@ int phytium_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) } EXPORT_SYMBOL_GPL(phytium_gpio_irq_set_type); + +int phytium_gpio_irq_request_resources(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + int hwirq = irqd_to_hwirq(d); + int dir; + + dir = phytium_gpio_get_direction(gc, hwirq); + if (dir < 0){ + dev_err(gc->parent, "line %d: get direction failed\n", hwirq); + return -EINVAL; + } + + /* If GPIO is configured as output, switch it to input before + * using it as an interrupt source + */ + if (dir == GPIO_LINE_DIRECTION_OUT) { + dev_warn(gc->parent, + "line %d: GPIO set as output, switching to input for IRQ\n", + hwirq); + phytium_gpio_direction_input(gc, hwirq); + } + + return gpiochip_reqres_irq(gc, hwirq); +} +EXPORT_SYMBOL_GPL(phytium_gpio_irq_request_resources); + +void phytium_gpio_irq_release_resources(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + + gpiochip_relres_irq(gc, irqd_to_hwirq(d)); +} +EXPORT_SYMBOL_GPL(phytium_gpio_irq_release_resources); + void phytium_gpio_irq_enable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); diff --git a/drivers/gpio/gpio-phytium-core.h b/drivers/gpio/gpio-phytium-core.h index f16350d3a2b57f6b1e89b991b5fd2861957cb545..d0d49ff8d02dda16470ac15344f97dc4f71f679e 100644 --- a/drivers/gpio/gpio-phytium-core.h +++ b/drivers/gpio/gpio-phytium-core.h @@ -84,6 +84,8 @@ void phytium_gpio_irq_ack(struct irq_data *d); void phytium_gpio_irq_mask(struct irq_data *d); void phytium_gpio_irq_unmask(struct irq_data *d); int phytium_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type); +int phytium_gpio_irq_request_resources(struct irq_data *d); +void phytium_gpio_irq_release_resources(struct irq_data *d); void phytium_gpio_irq_enable(struct irq_data *d); void phytium_gpio_irq_disable(struct irq_data *d); void phytium_gpio_irq_handler(struct irq_desc *desc); diff --git a/drivers/gpio/gpio-phytium-pci.c b/drivers/gpio/gpio-phytium-pci.c index 2c7113da04b726eee7188848dccd1fd61dfe4ba4..e0914d4545e6d3b219f601e6dd84fddb0a835a22 100644 --- a/drivers/gpio/gpio-phytium-pci.c +++ b/drivers/gpio/gpio-phytium-pci.c @@ -62,6 +62,8 @@ static int phytium_gpio_pci_probe(struct pci_dev *pdev, const struct pci_device_ gpio->irq_chip.irq_mask = phytium_gpio_irq_mask; gpio->irq_chip.irq_unmask = phytium_gpio_irq_unmask; gpio->irq_chip.irq_set_type = phytium_gpio_irq_set_type; + gpio->irq_chip.irq_request_resources = phytium_gpio_irq_request_resources; + gpio->irq_chip.irq_release_resources = phytium_gpio_irq_release_resources; gpio->irq_chip.irq_enable = phytium_gpio_irq_enable; gpio->irq_chip.irq_disable = phytium_gpio_irq_disable; #ifdef CONFIG_SMP diff --git a/drivers/gpio/gpio-phytium-platform.c b/drivers/gpio/gpio-phytium-platform.c index 65fece149ea6b8ac50208a2f9723390591fc6cf2..5bc575c17c6b0ea6d35d9606ee6b5db1341fa2a1 100644 --- a/drivers/gpio/gpio-phytium-platform.c +++ b/drivers/gpio/gpio-phytium-platform.c @@ -79,6 +79,8 @@ static int phytium_gpio_probe(struct platform_device *pdev) gpio->irq_chip.irq_mask = phytium_gpio_irq_mask; gpio->irq_chip.irq_unmask = phytium_gpio_irq_unmask; gpio->irq_chip.irq_set_type = phytium_gpio_irq_set_type; + gpio->irq_chip.irq_request_resources = phytium_gpio_irq_request_resources; + gpio->irq_chip.irq_release_resources = phytium_gpio_irq_release_resources; gpio->irq_chip.irq_enable = phytium_gpio_irq_enable; gpio->irq_chip.irq_disable = phytium_gpio_irq_disable; #ifdef CONFIG_SMP