Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8b844d78
Commit
8b844d78
authored
Jan 17, 2020
by
Linus Walleij
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fixup-thunderx-hierarchy' into devel
parents
6a77de25
9c6722d8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
89 additions
and
38 deletions
+89
-38
drivers/gpio/gpio-tegra186.c
drivers/gpio/gpio-tegra186.c
+10
-3
drivers/gpio/gpio-thunderx.c
drivers/gpio/gpio-thunderx.c
+32
-4
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.c
+35
-16
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+1
-1
drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+1
-1
include/linux/gpio/driver.h
include/linux/gpio/driver.h
+10
-13
No files found.
drivers/gpio/gpio-tegra186.c
View file @
8b844d78
...
...
@@ -448,17 +448,24 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,
return
0
;
}
static
void
tegra186_gpio_populate_parent_fwspec
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
static
void
*
tegra186_gpio_populate_parent_fwspec
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
struct
tegra_gpio
*
gpio
=
gpiochip_get_data
(
chip
);
struct
irq_fwspec
*
fwspec
;
fwspec
=
kmalloc
(
sizeof
(
*
fwspec
),
GFP_KERNEL
);
if
(
!
fwspec
)
return
NULL
;
fwspec
->
fwnode
=
chip
->
irq
.
parent_domain
->
fwnode
;
fwspec
->
param_count
=
3
;
fwspec
->
param
[
0
]
=
gpio
->
soc
->
instance
;
fwspec
->
param
[
1
]
=
parent_hwirq
;
fwspec
->
param
[
2
]
=
parent_type
;
return
fwspec
;
}
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)
irq
->
chip
=
&
gpio
->
intc
;
irq
->
fwnode
=
of_node_to_fwnode
(
pdev
->
dev
.
of_node
);
irq
->
child_to_parent_hwirq
=
tegra186_gpio_child_to_parent_hwirq
;
irq
->
populate_parent_
fwspec
=
tegra186_gpio_populate_parent_fwspec
;
irq
->
populate_parent_
alloc_arg
=
tegra186_gpio_populate_parent_fwspec
;
irq
->
child_offset_to_irq
=
tegra186_gpio_child_offset_to_irq
;
irq
->
child_irq_domain_ops
.
translate
=
tegra186_gpio_irq_domain_translate
;
irq
->
handler
=
handle_simple_irq
;
...
...
drivers/gpio/gpio-thunderx.c
View file @
8b844d78
...
...
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <asm-generic/msi.h>
#define GPIO_RX_DAT 0x0
...
...
@@ -395,12 +396,32 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
unsigned
int
*
parent_type
)
{
struct
thunderx_gpio
*
txgpio
=
gpiochip_get_data
(
gc
);
*
parent
=
txgpio
->
base_msi
+
(
2
*
child
);
struct
irq_data
*
irqd
;
unsigned
int
irq
;
irq
=
txgpio
->
msix_entries
[
child
].
vector
;
irqd
=
irq_domain_get_irq_data
(
gc
->
irq
.
parent_domain
,
irq
);
if
(
!
irqd
)
return
-
EINVAL
;
*
parent
=
irqd_to_hwirq
(
irqd
);
*
parent_type
=
IRQ_TYPE_LEVEL_HIGH
;
return
0
;
}
static
void
*
thunderx_gpio_populate_parent_alloc_info
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
msi_alloc_info_t
*
info
;
info
=
kmalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
if
(
!
info
)
return
NULL
;
info
->
hwirq
=
parent_hwirq
;
return
info
;
}
static
int
thunderx_gpio_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
{
...
...
@@ -515,6 +536,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
girq
->
parent_domain
=
irq_get_irq_data
(
txgpio
->
msix_entries
[
0
].
vector
)
->
domain
;
girq
->
child_to_parent_hwirq
=
thunderx_gpio_child_to_parent_hwirq
;
girq
->
populate_parent_alloc_arg
=
thunderx_gpio_populate_parent_alloc_info
;
girq
->
handler
=
handle_bad_irq
;
girq
->
default_type
=
IRQ_TYPE_NONE
;
...
...
@@ -524,9 +546,15 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
/* Push on irq_data and the domain for each line. */
for
(
i
=
0
;
i
<
ngpio
;
i
++
)
{
err
=
irq_domain_push_irq
(
chip
->
irq
.
domain
,
struct
irq_fwspec
fwspec
;
fwspec
.
fwnode
=
of_node_to_fwnode
(
dev
->
of_node
);
fwspec
.
param_count
=
2
;
fwspec
.
param
[
0
]
=
i
;
fwspec
.
param
[
1
]
=
IRQ_TYPE_NONE
;
err
=
irq_domain_push_irq
(
girq
->
domain
,
txgpio
->
msix_entries
[
i
].
vector
,
chip
);
&
fwspec
);
if
(
err
<
0
)
dev_err
(
dev
,
"irq_domain_push_irq: %d
\n
"
,
err
);
}
...
...
drivers/gpio/gpiolib.c
View file @
8b844d78
...
...
@@ -1990,7 +1990,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
irq_hw_number_t
hwirq
;
unsigned
int
type
=
IRQ_TYPE_NONE
;
struct
irq_fwspec
*
fwspec
=
data
;
struct
irq_fwspec
parent_fwspec
;
void
*
parent_arg
;
unsigned
int
parent_hwirq
;
unsigned
int
parent_type
;
struct
gpio_irq_chip
*
girq
=
&
gc
->
irq
;
...
...
@@ -2029,24 +2029,27 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
NULL
,
NULL
);
irq_set_probe
(
irq
);
/*
* Create a IRQ fwspec to send up to the parent irqdomain:
* specify the hwirq we address on the parent and tie it
* all together up the chain.
*/
parent_fwspec
.
fwnode
=
d
->
parent
->
fwnode
;
/* This parent only handles asserted level IRQs */
girq
->
populate_parent_fwspec
(
gc
,
&
parent_fwspec
,
parent_hwirq
,
parent_type
);
parent_arg
=
girq
->
populate_parent_alloc_arg
(
gc
,
parent_hwirq
,
parent_type
);
if
(
!
parent_arg
)
return
-
ENOMEM
;
chip_info
(
gc
,
"alloc_irqs_parent for %d parent hwirq %d
\n
"
,
irq
,
parent_hwirq
);
irq_set_lockdep_class
(
irq
,
gc
->
irq
.
lock_key
,
gc
->
irq
.
request_key
);
ret
=
irq_domain_alloc_irqs_parent
(
d
,
irq
,
1
,
&
parent_fwspec
);
ret
=
irq_domain_alloc_irqs_parent
(
d
,
irq
,
1
,
parent_arg
);
/*
* If the parent irqdomain is msi, the interrupts have already
* been allocated, so the EEXIST is good.
*/
if
(
irq_domain_is_msi
(
d
->
parent
)
&&
(
ret
==
-
EEXIST
))
ret
=
0
;
if
(
ret
)
chip_err
(
gc
,
"failed to allocate parent hwirq %d for hwirq %lu
\n
"
,
parent_hwirq
,
hwirq
);
kfree
(
parent_arg
);
return
ret
;
}
...
...
@@ -2083,8 +2086,8 @@ static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc)
if
(
!
gc
->
irq
.
child_offset_to_irq
)
gc
->
irq
.
child_offset_to_irq
=
gpiochip_child_offset_to_irq_noop
;
if
(
!
gc
->
irq
.
populate_parent_
fwspec
)
gc
->
irq
.
populate_parent_
fwspec
=
if
(
!
gc
->
irq
.
populate_parent_
alloc_arg
)
gc
->
irq
.
populate_parent_
alloc_arg
=
gpiochip_populate_parent_fwspec_twocell
;
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)
return
!!
gc
->
irq
.
parent_domain
;
}
void
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
void
*
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
struct
irq_fwspec
*
fwspec
;
fwspec
=
kmalloc
(
sizeof
(
*
fwspec
),
GFP_KERNEL
);
if
(
!
fwspec
)
return
NULL
;
fwspec
->
fwnode
=
chip
->
irq
.
parent_domain
->
fwnode
;
fwspec
->
param_count
=
2
;
fwspec
->
param
[
0
]
=
parent_hwirq
;
fwspec
->
param
[
1
]
=
parent_type
;
return
fwspec
;
}
EXPORT_SYMBOL_GPL
(
gpiochip_populate_parent_fwspec_twocell
);
void
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
void
*
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
struct
irq_fwspec
*
fwspec
;
fwspec
=
kmalloc
(
sizeof
(
*
fwspec
),
GFP_KERNEL
);
if
(
!
fwspec
)
return
NULL
;
fwspec
->
fwnode
=
chip
->
irq
.
parent_domain
->
fwnode
;
fwspec
->
param_count
=
4
;
fwspec
->
param
[
0
]
=
0
;
fwspec
->
param
[
1
]
=
parent_hwirq
;
fwspec
->
param
[
2
]
=
0
;
fwspec
->
param
[
3
]
=
parent_type
;
return
fwspec
;
}
EXPORT_SYMBOL_GPL
(
gpiochip_populate_parent_fwspec_fourcell
);
...
...
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
View file @
8b844d78
...
...
@@ -1060,7 +1060,7 @@ static int pmic_gpio_probe(struct platform_device *pdev)
girq
->
fwnode
=
of_node_to_fwnode
(
state
->
dev
->
of_node
);
girq
->
parent_domain
=
parent_domain
;
girq
->
child_to_parent_hwirq
=
pmic_gpio_child_to_parent_hwirq
;
girq
->
populate_parent_
fwspec
=
gpiochip_populate_parent_fwspec_fourcell
;
girq
->
populate_parent_
alloc_arg
=
gpiochip_populate_parent_fwspec_fourcell
;
girq
->
child_offset_to_irq
=
pmic_gpio_child_offset_to_irq
;
girq
->
child_irq_domain_ops
.
translate
=
pmic_gpio_domain_translate
;
...
...
drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
View file @
8b844d78
...
...
@@ -794,7 +794,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
girq
->
fwnode
=
of_node_to_fwnode
(
pctrl
->
dev
->
of_node
);
girq
->
parent_domain
=
parent_domain
;
girq
->
child_to_parent_hwirq
=
pm8xxx_child_to_parent_hwirq
;
girq
->
populate_parent_
fwspec
=
gpiochip_populate_parent_fwspec_fourcell
;
girq
->
populate_parent_
alloc_arg
=
gpiochip_populate_parent_fwspec_fourcell
;
girq
->
child_offset_to_irq
=
pm8xxx_child_offset_to_irq
;
girq
->
child_irq_domain_ops
.
translate
=
pm8xxx_domain_translate
;
...
...
include/linux/gpio/driver.h
View file @
8b844d78
...
...
@@ -94,16 +94,15 @@ struct gpio_irq_chip {
unsigned
int
*
parent_type
);
/**
* @populate_parent_
fwspec
:
* @populate_parent_
alloc_arg
:
*
* This optional callback
populates the &struct irq_fwspec for the
* parent's IRQ domain. If this is not specified, then
* This optional callback
allocates and populates the specific struct
*
for the
parent's IRQ domain. If this is not specified, then
* &gpiochip_populate_parent_fwspec_twocell will be used. A four-cell
* variant named &gpiochip_populate_parent_fwspec_fourcell is also
* available.
*/
void
(
*
populate_parent_fwspec
)(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
void
*
(
*
populate_parent_alloc_arg
)(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
);
...
...
@@ -537,29 +536,27 @@ struct bgpio_pdata {
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
void
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
void
*
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
);
void
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
void
*
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
);
#else
static
inline
void
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
static
inline
void
*
gpiochip_populate_parent_fwspec_twocell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
return
NULL
;
}
static
inline
void
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
struct
irq_fwspec
*
fwspec
,
static
inline
void
*
gpiochip_populate_parent_fwspec_fourcell
(
struct
gpio_chip
*
chip
,
unsigned
int
parent_hwirq
,
unsigned
int
parent_type
)
{
return
NULL
;
}
#endif
/* CONFIG_IRQ_DOMAIN_HIERARCHY */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment