Skip to content

Commit efcdca2

Browse files
thierryredingbrgl
authored andcommitted
gpio: tegra: Convert to gpio_irq_chip
Convert the Tegra GPIO driver to use the gpio_irq_chip infrastructure. This allows a bit of boiler plate to be removed and while at it enables support for hierarchical domains, which is useful to support PMC wake events on Tegra210 and earlier. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
1 parent 4ef018e commit efcdca2

File tree

1 file changed

+146
-72
lines changed

1 file changed

+146
-72
lines changed

drivers/gpio/gpio-tegra.c

Lines changed: 146 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ struct tegra_gpio_info;
6060

6161
struct tegra_gpio_bank {
6262
unsigned int bank;
63-
unsigned int irq;
6463

6564
/*
6665
* IRQ-core code uses raw locking, and thus, nested locking also
@@ -81,7 +80,6 @@ struct tegra_gpio_bank {
8180
u32 dbc_enb[4];
8281
#endif
8382
u32 dbc_cnt[4];
84-
struct tegra_gpio_info *tgi;
8583
};
8684

8785
struct tegra_gpio_soc_config {
@@ -93,12 +91,12 @@ struct tegra_gpio_soc_config {
9391
struct tegra_gpio_info {
9492
struct device *dev;
9593
void __iomem *regs;
96-
struct irq_domain *irq_domain;
9794
struct tegra_gpio_bank *bank_info;
9895
const struct tegra_gpio_soc_config *soc;
9996
struct gpio_chip gc;
10097
struct irq_chip ic;
10198
u32 bank_count;
99+
unsigned int *irqs;
102100
};
103101

104102
static inline void tegra_gpio_writel(struct tegra_gpio_info *tgi,
@@ -274,35 +272,28 @@ static int tegra_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
274272
return tegra_gpio_set_debounce(chip, offset, debounce);
275273
}
276274

277-
static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
278-
{
279-
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
280-
281-
return irq_find_mapping(tgi->irq_domain, offset);
282-
}
283-
284275
static void tegra_gpio_irq_ack(struct irq_data *d)
285276
{
286-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
287-
struct tegra_gpio_info *tgi = bank->tgi;
277+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
278+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
288279
unsigned int gpio = d->hwirq;
289280

290281
tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio));
291282
}
292283

293284
static void tegra_gpio_irq_mask(struct irq_data *d)
294285
{
295-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
296-
struct tegra_gpio_info *tgi = bank->tgi;
286+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
287+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
297288
unsigned int gpio = d->hwirq;
298289

299290
tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0);
300291
}
301292

302293
static void tegra_gpio_irq_unmask(struct irq_data *d)
303294
{
304-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
305-
struct tegra_gpio_info *tgi = bank->tgi;
295+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
296+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
306297
unsigned int gpio = d->hwirq;
307298

308299
tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1);
@@ -311,11 +302,14 @@ static void tegra_gpio_irq_unmask(struct irq_data *d)
311302
static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
312303
{
313304
unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type;
314-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
315-
struct tegra_gpio_info *tgi = bank->tgi;
305+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
306+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
307+
struct tegra_gpio_bank *bank;
316308
unsigned long flags;
317-
u32 val;
318309
int ret;
310+
u32 val;
311+
312+
bank = &tgi->bank_info[GPIO_BANK(d->hwirq)];
319313

320314
switch (type & IRQ_TYPE_SENSE_MASK) {
321315
case IRQ_TYPE_EDGE_RISING:
@@ -367,13 +361,16 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
367361
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
368362
irq_set_handler_locked(d, handle_edge_irq);
369363

370-
return 0;
364+
if (d->parent_data)
365+
ret = irq_chip_set_type_parent(d, type);
366+
367+
return ret;
371368
}
372369

373370
static void tegra_gpio_irq_shutdown(struct irq_data *d)
374371
{
375-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
376-
struct tegra_gpio_info *tgi = bank->tgi;
372+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
373+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
377374
unsigned int gpio = d->hwirq;
378375

379376
tegra_gpio_irq_mask(d);
@@ -382,13 +379,25 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d)
382379

383380
static void tegra_gpio_irq_handler(struct irq_desc *desc)
384381
{
385-
unsigned int port, pin, gpio;
382+
struct tegra_gpio_info *tgi = irq_desc_get_handler_data(desc);
383+
struct irq_chip *chip = irq_desc_get_chip(desc);
384+
struct irq_domain *domain = tgi->gc.irq.domain;
385+
unsigned int irq = irq_desc_get_irq(desc);
386+
struct tegra_gpio_bank *bank = NULL;
387+
unsigned int port, pin, gpio, i;
386388
bool unmasked = false;
387-
u32 lvl;
388389
unsigned long sta;
389-
struct irq_chip *chip = irq_desc_get_chip(desc);
390-
struct tegra_gpio_bank *bank = irq_desc_get_handler_data(desc);
391-
struct tegra_gpio_info *tgi = bank->tgi;
390+
u32 lvl;
391+
392+
for (i = 0; i < tgi->bank_count; i++) {
393+
if (tgi->irqs[i] == irq) {
394+
bank = &tgi->bank_info[i];
395+
break;
396+
}
397+
}
398+
399+
if (WARN_ON(bank == NULL))
400+
return;
392401

393402
chained_irq_enter(chip, desc);
394403

@@ -411,14 +420,44 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc)
411420
chained_irq_exit(chip, desc);
412421
}
413422

414-
generic_handle_irq(irq_find_mapping(tgi->irq_domain,
415-
gpio + pin));
423+
irq = irq_find_mapping(domain, gpio + pin);
424+
if (WARN_ON(irq == 0))
425+
continue;
426+
427+
generic_handle_irq(irq);
416428
}
417429
}
418430

419431
if (!unmasked)
420432
chained_irq_exit(chip, desc);
433+
}
434+
435+
static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip, unsigned int hwirq,
436+
unsigned int type, unsigned int *parent_hwirq,
437+
unsigned int *parent_type)
438+
{
439+
*parent_hwirq = chip->irq.child_offset_to_irq(chip, hwirq);
440+
*parent_type = type;
421441

442+
return 0;
443+
}
444+
445+
static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, unsigned int parent_hwirq,
446+
unsigned int parent_type)
447+
{
448+
struct irq_fwspec *fwspec;
449+
450+
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
451+
if (!fwspec)
452+
return NULL;
453+
454+
fwspec->fwnode = chip->irq.parent_domain->fwnode;
455+
fwspec->param_count = 3;
456+
fwspec->param[0] = 0;
457+
fwspec->param[1] = parent_hwirq;
458+
fwspec->param[2] = parent_type;
459+
460+
return fwspec;
422461
}
423462

424463
#ifdef CONFIG_PM_SLEEP
@@ -497,14 +536,13 @@ static int tegra_gpio_suspend(struct device *dev)
497536

498537
static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
499538
{
500-
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
539+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
540+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
541+
struct tegra_gpio_bank *bank;
501542
unsigned int gpio = d->hwirq;
502543
u32 port, bit, mask;
503-
int err;
504544

505-
err = irq_set_irq_wake(bank->irq, enable);
506-
if (err)
507-
return err;
545+
bank = &tgi->bank_info[GPIO_BANK(d->hwirq)];
508546

509547
port = GPIO_PORT(gpio);
510548
bit = GPIO_BIT(gpio);
@@ -515,10 +553,41 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
515553
else
516554
bank->wake_enb[port] &= ~mask;
517555

556+
if (d->parent_data)
557+
return irq_chip_set_wake_parent(d, enable);
558+
518559
return 0;
519560
}
520561
#endif
521562

563+
static int tegra_gpio_irq_set_affinity(struct irq_data *data, const struct cpumask *dest,
564+
bool force)
565+
{
566+
if (data->parent_data)
567+
return irq_chip_set_affinity_parent(data, dest, force);
568+
569+
return -EINVAL;
570+
}
571+
572+
static int tegra_gpio_irq_request_resources(struct irq_data *d)
573+
{
574+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
575+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
576+
577+
tegra_gpio_enable(tgi, d->hwirq);
578+
579+
return gpiochip_reqres_irq(chip, d->hwirq);
580+
}
581+
582+
static void tegra_gpio_irq_release_resources(struct irq_data *d)
583+
{
584+
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
585+
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
586+
587+
gpiochip_relres_irq(chip, d->hwirq);
588+
tegra_gpio_enable(tgi, d->hwirq);
589+
}
590+
522591
#ifdef CONFIG_DEBUG_FS
523592

524593
#include <linux/debugfs.h>
@@ -568,14 +637,18 @@ static const struct dev_pm_ops tegra_gpio_pm_ops = {
568637
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume)
569638
};
570639

571-
static struct lock_class_key gpio_lock_class;
572-
static struct lock_class_key gpio_request_class;
640+
static const struct of_device_id tegra_pmc_of_match[] = {
641+
{ .compatible = "nvidia,tegra210-pmc", },
642+
{ /* sentinel */ },
643+
};
573644

574645
static int tegra_gpio_probe(struct platform_device *pdev)
575646
{
576-
struct tegra_gpio_info *tgi;
577647
struct tegra_gpio_bank *bank;
578-
unsigned int gpio, i, j;
648+
struct tegra_gpio_info *tgi;
649+
struct gpio_irq_chip *irq;
650+
struct device_node *np;
651+
unsigned int i, j;
579652
int ret;
580653

581654
tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL);
@@ -604,7 +677,6 @@ static int tegra_gpio_probe(struct platform_device *pdev)
604677
tgi->gc.direction_output = tegra_gpio_direction_output;
605678
tgi->gc.set = tegra_gpio_set;
606679
tgi->gc.get_direction = tegra_gpio_get_direction;
607-
tgi->gc.to_irq = tegra_gpio_to_irq;
608680
tgi->gc.base = 0;
609681
tgi->gc.ngpio = tgi->bank_count * 32;
610682
tgi->gc.parent = &pdev->dev;
@@ -619,6 +691,9 @@ static int tegra_gpio_probe(struct platform_device *pdev)
619691
#ifdef CONFIG_PM_SLEEP
620692
tgi->ic.irq_set_wake = tegra_gpio_irq_set_wake;
621693
#endif
694+
tgi->ic.irq_set_affinity = tegra_gpio_irq_set_affinity;
695+
tgi->ic.irq_request_resources = tegra_gpio_irq_request_resources;
696+
tgi->ic.irq_release_resources = tegra_gpio_irq_release_resources;
622697

623698
platform_set_drvdata(pdev, tgi);
624699

@@ -630,11 +705,9 @@ static int tegra_gpio_probe(struct platform_device *pdev)
630705
if (!tgi->bank_info)
631706
return -ENOMEM;
632707

633-
tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
634-
tgi->gc.ngpio,
635-
&irq_domain_simple_ops, NULL);
636-
if (!tgi->irq_domain)
637-
return -ENODEV;
708+
tgi->irqs = devm_kcalloc(&pdev->dev, tgi->bank_count, sizeof(*tgi->irqs), GFP_KERNEL);
709+
if (!tgi->irqs)
710+
return -ENOMEM;
638711

639712
for (i = 0; i < tgi->bank_count; i++) {
640713
ret = platform_get_irq(pdev, i);
@@ -643,8 +716,34 @@ static int tegra_gpio_probe(struct platform_device *pdev)
643716

644717
bank = &tgi->bank_info[i];
645718
bank->bank = i;
646-
bank->irq = ret;
647-
bank->tgi = tgi;
719+
720+
tgi->irqs[i] = ret;
721+
722+
for (j = 0; j < 4; j++) {
723+
raw_spin_lock_init(&bank->lvl_lock[j]);
724+
spin_lock_init(&bank->dbc_lock[j]);
725+
}
726+
}
727+
728+
irq = &tgi->gc.irq;
729+
irq->chip = &tgi->ic;
730+
irq->fwnode = of_node_to_fwnode(pdev->dev.of_node);
731+
irq->child_to_parent_hwirq = tegra_gpio_child_to_parent_hwirq;
732+
irq->populate_parent_alloc_arg = tegra_gpio_populate_parent_fwspec;
733+
irq->handler = handle_simple_irq;
734+
irq->default_type = IRQ_TYPE_NONE;
735+
irq->parent_handler = tegra_gpio_irq_handler;
736+
irq->parent_handler_data = tgi;
737+
irq->num_parents = tgi->bank_count;
738+
irq->parents = tgi->irqs;
739+
740+
np = of_find_matching_node(NULL, tegra_pmc_of_match);
741+
if (np) {
742+
irq->parent_domain = irq_find_host(np);
743+
of_node_put(np);
744+
745+
if (!irq->parent_domain)
746+
return -EPROBE_DEFER;
648747
}
649748

650749
tgi->regs = devm_platform_ioremap_resource(pdev, 0);
@@ -660,33 +759,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
660759
}
661760

662761
ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi);
663-
if (ret < 0) {
664-
irq_domain_remove(tgi->irq_domain);
762+
if (ret < 0)
665763
return ret;
666-
}
667-
668-
for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) {
669-
int irq = irq_create_mapping(tgi->irq_domain, gpio);
670-
/* No validity check; all Tegra GPIOs are valid IRQs */
671-
672-
bank = &tgi->bank_info[GPIO_BANK(gpio)];
673-
674-
irq_set_chip_data(irq, bank);
675-
irq_set_lockdep_class(irq, &gpio_lock_class, &gpio_request_class);
676-
irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq);
677-
}
678-
679-
for (i = 0; i < tgi->bank_count; i++) {
680-
bank = &tgi->bank_info[i];
681-
682-
irq_set_chained_handler_and_data(bank->irq,
683-
tegra_gpio_irq_handler, bank);
684-
685-
for (j = 0; j < 4; j++) {
686-
raw_spin_lock_init(&bank->lvl_lock[j]);
687-
spin_lock_init(&bank->dbc_lock[j]);
688-
}
689-
}
690764

691765
tegra_gpio_debuginit(tgi);
692766

0 commit comments

Comments
 (0)