Skip to content

Commit d5e2fb3

Browse files
newearth-ssopsiff
authored andcommitted
gpio: phytium: Add wakeup source support for GPIO driver
This patch supports irq_set_wake for phytium GPIO driver. It allows GPIOs to be configured as wakeup sources and wake the system from suspend. Mainline: Open-Source Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn> Signed-off-by: Li Yuze <liyuze@phytium.com.cn> Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
1 parent 783bf02 commit d5e2fb3

4 files changed

Lines changed: 39 additions & 3 deletions

File tree

drivers/gpio/gpio-phytium-core.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/module.h>
1010
#include <linux/bitops.h>
1111
#include <linux/seq_file.h>
12+
#include <linux/interrupt.h>
1213

1314
#include "gpio-phytium-core.h"
1415

@@ -378,6 +379,35 @@ int phytium_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
378379
}
379380
EXPORT_SYMBOL_GPL(phytium_gpio_get_direction);
380381

382+
int phytium_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
383+
{
384+
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
385+
struct phytium_gpio *gpio = gpiochip_get_data(gc);
386+
struct phytium_gpio_ctx *ctx = &gpio->ctx;
387+
irq_hw_number_t bit = irqd_to_hwirq(d);
388+
int ret;
389+
390+
if (gpio->irq[bit])
391+
ret = irq_set_irq_wake(gpio->irq[bit], enable);
392+
else
393+
ret = irq_set_irq_wake(gpio->irq[0], enable);
394+
395+
if (ret < 0)
396+
dev_err(gc->parent, "set gpio irq wake failed!\n");
397+
398+
if (enable) {
399+
ctx->wake_en |= BIT(bit);
400+
if (gpio->is_resuming == 1) {
401+
writel(~ctx->wake_en, gpio->regs + GPIO_INTMASK);
402+
writel(ctx->wake_en, gpio->regs + GPIO_INTEN);
403+
}
404+
} else
405+
ctx->wake_en &= ~BIT(bit);
406+
407+
return 0;
408+
}
409+
EXPORT_SYMBOL_GPL(phytium_gpio_irq_set_wake);
410+
381411
int phytium_gpio_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force)
382412
{
383413
int hwirq = irqd_to_hwirq(d);

drivers/gpio/gpio-phytium-core.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#define NGPIO_MAX 32
3434
#define GPIO_PORT_STRIDE (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
3535

36-
#define PHYTIUM_GPIO_DRIVER_VERSION "1.1.1"
36+
#define PHYTIUM_GPIO_DRIVER_VERSION "1.1.2"
3737

3838
struct pin_loc {
3939
unsigned int port;
@@ -56,6 +56,7 @@ struct phytium_gpio_ctx {
5656
u32 raw_intstatus;
5757
u32 ls_sync;
5858
u32 debounce;
59+
u32 wake_en;
5960
};
6061
#endif
6162

@@ -86,5 +87,6 @@ void phytium_gpio_irq_print_chip(struct irq_data *data, struct seq_file *p);
8687
void phytium_gpio_irq_enable(struct irq_data *d);
8788
void phytium_gpio_irq_disable(struct irq_data *d);
8889
void phytium_gpio_irq_handler(struct irq_desc *desc);
90+
int phytium_gpio_irq_set_wake(struct irq_data *d, unsigned int enable);
8991
int phytium_gpio_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force);
9092
#endif

drivers/gpio/gpio-phytium-pci.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ static const struct irq_chip phytium_gpio_irq_chip = {
2121
.irq_print_chip = phytium_gpio_irq_print_chip,
2222
.irq_enable = phytium_gpio_irq_enable,
2323
.irq_disable = phytium_gpio_irq_disable,
24+
.irq_set_wake = phytium_gpio_irq_set_wake,
2425
.flags = IRQCHIP_IMMUTABLE,
2526
GPIOCHIP_IRQ_RESOURCE_HELPERS,
2627
};
@@ -142,7 +143,8 @@ static int phytium_gpio_pci_suspend(struct device *dev)
142143
gpio->ctx.int_polarity = readl(gpio->regs + GPIO_INT_POLARITY);
143144
gpio->ctx.debounce = readl(gpio->regs + GPIO_DEBOUNCE);
144145

145-
writel(0, gpio->regs + GPIO_INTEN);
146+
writel(~gpio->ctx.wake_en, gpio->regs + GPIO_INTMASK);
147+
writel(gpio->ctx.wake_en, gpio->regs + GPIO_INTEN);
146148
raw_spin_unlock_irqrestore(&gpio->lock, flags);
147149

148150
return 0;

drivers/gpio/gpio-phytium-platform.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static const struct irq_chip phytium_gpio_irq_chip = {
4141
.irq_print_chip = phytium_gpio_irq_print_chip,
4242
.irq_enable = phytium_gpio_irq_enable,
4343
.irq_disable = phytium_gpio_irq_disable,
44+
.irq_set_wake = phytium_gpio_irq_set_wake,
4445
.irq_set_affinity = phytium_gpio_irq_set_affinity,
4546
.flags = IRQCHIP_IMMUTABLE,
4647
GPIOCHIP_IRQ_RESOURCE_HELPERS,
@@ -159,7 +160,8 @@ static int phytium_gpio_suspend(struct device *dev)
159160
gpio->ctx.int_polarity = readl(gpio->regs + GPIO_INT_POLARITY);
160161
gpio->ctx.debounce = readl(gpio->regs + GPIO_DEBOUNCE);
161162

162-
writel(0, gpio->regs + GPIO_INTEN);
163+
writel(~gpio->ctx.wake_en, gpio->regs + GPIO_INTMASK);
164+
writel(gpio->ctx.wake_en, gpio->regs + GPIO_INTEN);
163165
raw_spin_unlock_irqrestore(&gpio->lock, flags);
164166

165167
return 0;

0 commit comments

Comments
 (0)