Skip to content

Commit 8b844d7

Browse files
committed
Merge branch 'fixup-thunderx-hierarchy' into devel
2 parents 6a77de2 + 9c6722d commit 8b844d7

File tree

6 files changed

+89
-38
lines changed

6 files changed

+89
-38
lines changed

drivers/gpio/gpio-tegra186.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,17 +448,24 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,
448448
return 0;
449449
}
450450

451-
static void tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
452-
struct irq_fwspec *fwspec,
451+
static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
453452
unsigned int parent_hwirq,
454453
unsigned int parent_type)
455454
{
456455
struct tegra_gpio *gpio = gpiochip_get_data(chip);
456+
struct irq_fwspec *fwspec;
457457

458+
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
459+
if (!fwspec)
460+
return NULL;
461+
462+
fwspec->fwnode = chip->irq.parent_domain->fwnode;
458463
fwspec->param_count = 3;
459464
fwspec->param[0] = gpio->soc->instance;
460465
fwspec->param[1] = parent_hwirq;
461466
fwspec->param[2] = parent_type;
467+
468+
return fwspec;
462469
}
463470

464471
static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
@@ -621,7 +628,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
621628
irq->chip = &gpio->intc;
622629
irq->fwnode = of_node_to_fwnode(pdev->dev.of_node);
623630
irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq;
624-
irq->populate_parent_fwspec = tegra186_gpio_populate_parent_fwspec;
631+
irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec;
625632
irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq;
626633
irq->child_irq_domain_ops.translate = tegra186_gpio_irq_domain_translate;
627634
irq->handler = handle_simple_irq;

drivers/gpio/gpio-thunderx.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/module.h>
1616
#include <linux/pci.h>
1717
#include <linux/spinlock.h>
18+
#include <asm-generic/msi.h>
1819

1920

2021
#define GPIO_RX_DAT 0x0
@@ -395,12 +396,32 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
395396
unsigned int *parent_type)
396397
{
397398
struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
398-
399-
*parent = txgpio->base_msi + (2 * child);
399+
struct irq_data *irqd;
400+
unsigned int irq;
401+
402+
irq = txgpio->msix_entries[child].vector;
403+
irqd = irq_domain_get_irq_data(gc->irq.parent_domain, irq);
404+
if (!irqd)
405+
return -EINVAL;
406+
*parent = irqd_to_hwirq(irqd);
400407
*parent_type = IRQ_TYPE_LEVEL_HIGH;
401408
return 0;
402409
}
403410

411+
static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
412+
unsigned int parent_hwirq,
413+
unsigned int parent_type)
414+
{
415+
msi_alloc_info_t *info;
416+
417+
info = kmalloc(sizeof(*info), GFP_KERNEL);
418+
if (!info)
419+
return NULL;
420+
421+
info->hwirq = parent_hwirq;
422+
return info;
423+
}
424+
404425
static int thunderx_gpio_probe(struct pci_dev *pdev,
405426
const struct pci_device_id *id)
406427
{
@@ -515,6 +536,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
515536
girq->parent_domain =
516537
irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
517538
girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq;
539+
girq->populate_parent_alloc_arg = thunderx_gpio_populate_parent_alloc_info;
518540
girq->handler = handle_bad_irq;
519541
girq->default_type = IRQ_TYPE_NONE;
520542

@@ -524,9 +546,15 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
524546

525547
/* Push on irq_data and the domain for each line. */
526548
for (i = 0; i < ngpio; i++) {
527-
err = irq_domain_push_irq(chip->irq.domain,
549+
struct irq_fwspec fwspec;
550+
551+
fwspec.fwnode = of_node_to_fwnode(dev->of_node);
552+
fwspec.param_count = 2;
553+
fwspec.param[0] = i;
554+
fwspec.param[1] = IRQ_TYPE_NONE;
555+
err = irq_domain_push_irq(girq->domain,
528556
txgpio->msix_entries[i].vector,
529-
chip);
557+
&fwspec);
530558
if (err < 0)
531559
dev_err(dev, "irq_domain_push_irq: %d\n", err);
532560
}

drivers/gpio/gpiolib.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
19901990
irq_hw_number_t hwirq;
19911991
unsigned int type = IRQ_TYPE_NONE;
19921992
struct irq_fwspec *fwspec = data;
1993-
struct irq_fwspec parent_fwspec;
1993+
void *parent_arg;
19941994
unsigned int parent_hwirq;
19951995
unsigned int parent_type;
19961996
struct gpio_irq_chip *girq = &gc->irq;
@@ -2029,24 +2029,27 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
20292029
NULL, NULL);
20302030
irq_set_probe(irq);
20312031

2032-
/*
2033-
* Create a IRQ fwspec to send up to the parent irqdomain:
2034-
* specify the hwirq we address on the parent and tie it
2035-
* all together up the chain.
2036-
*/
2037-
parent_fwspec.fwnode = d->parent->fwnode;
20382032
/* This parent only handles asserted level IRQs */
2039-
girq->populate_parent_fwspec(gc, &parent_fwspec, parent_hwirq,
2040-
parent_type);
2033+
parent_arg = girq->populate_parent_alloc_arg(gc, parent_hwirq, parent_type);
2034+
if (!parent_arg)
2035+
return -ENOMEM;
2036+
20412037
chip_info(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
20422038
irq, parent_hwirq);
20432039
irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key);
2044-
ret = irq_domain_alloc_irqs_parent(d, irq, 1, &parent_fwspec);
2040+
ret = irq_domain_alloc_irqs_parent(d, irq, 1, parent_arg);
2041+
/*
2042+
* If the parent irqdomain is msi, the interrupts have already
2043+
* been allocated, so the EEXIST is good.
2044+
*/
2045+
if (irq_domain_is_msi(d->parent) && (ret == -EEXIST))
2046+
ret = 0;
20452047
if (ret)
20462048
chip_err(gc,
20472049
"failed to allocate parent hwirq %d for hwirq %lu\n",
20482050
parent_hwirq, hwirq);
20492051

2052+
kfree(parent_arg);
20502053
return ret;
20512054
}
20522055

@@ -2083,8 +2086,8 @@ static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc)
20832086
if (!gc->irq.child_offset_to_irq)
20842087
gc->irq.child_offset_to_irq = gpiochip_child_offset_to_irq_noop;
20852088

2086-
if (!gc->irq.populate_parent_fwspec)
2087-
gc->irq.populate_parent_fwspec =
2089+
if (!gc->irq.populate_parent_alloc_arg)
2090+
gc->irq.populate_parent_alloc_arg =
20882091
gpiochip_populate_parent_fwspec_twocell;
20892092

20902093
gpiochip_hierarchy_setup_domain_ops(&gc->irq.child_irq_domain_ops);
@@ -2110,27 +2113,43 @@ static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)
21102113
return !!gc->irq.parent_domain;
21112114
}
21122115

2113-
void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
2114-
struct irq_fwspec *fwspec,
2116+
void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
21152117
unsigned int parent_hwirq,
21162118
unsigned int parent_type)
21172119
{
2120+
struct irq_fwspec *fwspec;
2121+
2122+
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
2123+
if (!fwspec)
2124+
return NULL;
2125+
2126+
fwspec->fwnode = chip->irq.parent_domain->fwnode;
21182127
fwspec->param_count = 2;
21192128
fwspec->param[0] = parent_hwirq;
21202129
fwspec->param[1] = parent_type;
2130+
2131+
return fwspec;
21212132
}
21222133
EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell);
21232134

2124-
void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
2125-
struct irq_fwspec *fwspec,
2135+
void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
21262136
unsigned int parent_hwirq,
21272137
unsigned int parent_type)
21282138
{
2139+
struct irq_fwspec *fwspec;
2140+
2141+
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
2142+
if (!fwspec)
2143+
return NULL;
2144+
2145+
fwspec->fwnode = chip->irq.parent_domain->fwnode;
21292146
fwspec->param_count = 4;
21302147
fwspec->param[0] = 0;
21312148
fwspec->param[1] = parent_hwirq;
21322149
fwspec->param[2] = 0;
21332150
fwspec->param[3] = parent_type;
2151+
2152+
return fwspec;
21342153
}
21352154
EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell);
21362155

drivers/pinctrl/qcom/pinctrl-spmi-gpio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ static int pmic_gpio_probe(struct platform_device *pdev)
10601060
girq->fwnode = of_node_to_fwnode(state->dev->of_node);
10611061
girq->parent_domain = parent_domain;
10621062
girq->child_to_parent_hwirq = pmic_gpio_child_to_parent_hwirq;
1063-
girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
1063+
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
10641064
girq->child_offset_to_irq = pmic_gpio_child_offset_to_irq;
10651065
girq->child_irq_domain_ops.translate = pmic_gpio_domain_translate;
10661066

drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
794794
girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
795795
girq->parent_domain = parent_domain;
796796
girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;
797-
girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
797+
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
798798
girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;
799799
girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;
800800

include/linux/gpio/driver.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,15 @@ struct gpio_irq_chip {
9494
unsigned int *parent_type);
9595

9696
/**
97-
* @populate_parent_fwspec:
97+
* @populate_parent_alloc_arg :
9898
*
99-
* This optional callback populates the &struct irq_fwspec for the
100-
* parent's IRQ domain. If this is not specified, then
99+
* This optional callback allocates and populates the specific struct
100+
* for the parent's IRQ domain. If this is not specified, then
101101
* &gpiochip_populate_parent_fwspec_twocell will be used. A four-cell
102102
* variant named &gpiochip_populate_parent_fwspec_fourcell is also
103103
* available.
104104
*/
105-
void (*populate_parent_fwspec)(struct gpio_chip *chip,
106-
struct irq_fwspec *fwspec,
105+
void *(*populate_parent_alloc_arg)(struct gpio_chip *chip,
107106
unsigned int parent_hwirq,
108107
unsigned int parent_type);
109108

@@ -537,29 +536,27 @@ struct bgpio_pdata {
537536

538537
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
539538

540-
void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
541-
struct irq_fwspec *fwspec,
539+
void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
542540
unsigned int parent_hwirq,
543541
unsigned int parent_type);
544-
void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
545-
struct irq_fwspec *fwspec,
542+
void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
546543
unsigned int parent_hwirq,
547544
unsigned int parent_type);
548545

549546
#else
550547

551-
static inline void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
552-
struct irq_fwspec *fwspec,
548+
static inline void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
553549
unsigned int parent_hwirq,
554550
unsigned int parent_type)
555551
{
552+
return NULL;
556553
}
557554

558-
static inline void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
559-
struct irq_fwspec *fwspec,
555+
static inline void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
560556
unsigned int parent_hwirq,
561557
unsigned int parent_type)
562558
{
559+
return NULL;
563560
}
564561

565562
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */

0 commit comments

Comments
 (0)