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
04e8c5b2
Commit
04e8c5b2
authored
Oct 06, 2020
by
Marc Zyngier
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'irq/qcom-pdc-wakeup' into irq/irqchip-next
Signed-off-by:
Marc Zyngier
<
maz@kernel.org
>
parents
9b64efa8
d7bc63fa
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
81 additions
and
30 deletions
+81
-30
drivers/irqchip/qcom-pdc.c
drivers/irqchip/qcom-pdc.c
+12
-2
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/qcom/pinctrl-msm.c
+6
-5
include/linux/irq.h
include/linux/irq.h
+30
-19
kernel/irq/debugfs.c
kernel/irq/debugfs.c
+3
-0
kernel/irq/pm.c
kernel/irq/pm.c
+30
-4
No files found.
drivers/irqchip/qcom-pdc.c
View file @
04e8c5b2
...
...
@@ -205,7 +205,8 @@ static struct irq_chip qcom_pdc_gic_chip = {
.
irq_set_type
=
qcom_pdc_gic_set_type
,
.
flags
=
IRQCHIP_MASK_ON_SUSPEND
|
IRQCHIP_SET_TYPE_MASKED
|
IRQCHIP_SKIP_SET_WAKE
,
IRQCHIP_SKIP_SET_WAKE
|
IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
,
.
irq_set_vcpu_affinity
=
irq_chip_set_vcpu_affinity_parent
,
.
irq_set_affinity
=
irq_chip_set_affinity_parent
,
};
...
...
@@ -340,7 +341,8 @@ static const struct irq_domain_ops qcom_pdc_gpio_ops = {
static
int
pdc_setup_pin_mapping
(
struct
device_node
*
np
)
{
int
ret
,
n
;
int
ret
,
n
,
i
;
u32
irq_index
,
reg_index
,
val
;
n
=
of_property_count_elems_of_size
(
np
,
"qcom,pdc-ranges"
,
sizeof
(
u32
));
if
(
n
<=
0
||
n
%
3
)
...
...
@@ -369,6 +371,14 @@ static int pdc_setup_pin_mapping(struct device_node *np)
&
pdc_region
[
n
].
cnt
);
if
(
ret
)
return
ret
;
for
(
i
=
0
;
i
<
pdc_region
[
n
].
cnt
;
i
++
)
{
reg_index
=
(
i
+
pdc_region
[
n
].
pin_base
)
>>
5
;
irq_index
=
(
i
+
pdc_region
[
n
].
pin_base
)
&
0x1f
;
val
=
pdc_reg_read
(
IRQ_ENABLE_BANK
,
reg_index
);
val
&=
~
BIT
(
irq_index
);
pdc_reg_write
(
IRQ_ENABLE_BANK
,
reg_index
,
val
);
}
}
return
0
;
...
...
drivers/pinctrl/qcom/pinctrl-msm.c
View file @
04e8c5b2
...
...
@@ -1077,12 +1077,10 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
* when TLMM is powered on. To allow that, enable the GPIO
* summary line to be wakeup capable at GIC.
*/
if
(
d
->
parent_data
)
irq_chip_set_wake_parent
(
d
,
on
);
irq_set_irq_wake
(
pctrl
->
irq
,
on
);
if
(
d
->
parent_data
&&
test_bit
(
d
->
hwirq
,
pctrl
->
skip_wake_irqs
))
return
irq_chip_set_wake_parent
(
d
,
on
);
return
0
;
return
irq_set_irq_wake
(
pctrl
->
irq
,
on
)
;
}
static
int
msm_gpio_irq_reqres
(
struct
irq_data
*
d
)
...
...
@@ -1243,6 +1241,9 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
pctrl
->
irq_chip
.
irq_release_resources
=
msm_gpio_irq_relres
;
pctrl
->
irq_chip
.
irq_set_affinity
=
msm_gpio_irq_set_affinity
;
pctrl
->
irq_chip
.
irq_set_vcpu_affinity
=
msm_gpio_irq_set_vcpu_affinity
;
pctrl
->
irq_chip
.
flags
=
IRQCHIP_MASK_ON_SUSPEND
|
IRQCHIP_SET_TYPE_MASKED
|
IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
;
np
=
of_parse_phandle
(
pctrl
->
dev
->
of_node
,
"wakeup-parent"
,
0
);
if
(
np
)
{
...
...
include/linux/irq.h
View file @
04e8c5b2
...
...
@@ -217,6 +217,8 @@ struct irq_data {
* from actual interrupt context.
* IRQD_AFFINITY_ON_ACTIVATE - Affinity is set on activation. Don't call
* irq_chip::irq_set_affinity() when deactivated.
* IRQD_IRQ_ENABLED_ON_SUSPEND - Interrupt is enabled on suspend by irq pm if
* irqchip have flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND set.
*/
enum
{
IRQD_TRIGGER_MASK
=
0xf
,
...
...
@@ -242,6 +244,7 @@ enum {
IRQD_MSI_NOMASK_QUIRK
=
(
1
<<
27
),
IRQD_HANDLE_ENFORCE_IRQCTX
=
(
1
<<
28
),
IRQD_AFFINITY_ON_ACTIVATE
=
(
1
<<
29
),
IRQD_IRQ_ENABLED_ON_SUSPEND
=
(
1
<<
30
),
};
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
...
...
@@ -321,6 +324,11 @@ static inline bool irqd_is_handle_enforce_irqctx(struct irq_data *d)
return
__irqd_to_state
(
d
)
&
IRQD_HANDLE_ENFORCE_IRQCTX
;
}
static
inline
bool
irqd_is_enabled_on_suspend
(
struct
irq_data
*
d
)
{
return
__irqd_to_state
(
d
)
&
IRQD_IRQ_ENABLED_ON_SUSPEND
;
}
static
inline
bool
irqd_is_wakeup_set
(
struct
irq_data
*
d
)
{
return
__irqd_to_state
(
d
)
&
IRQD_WAKEUP_STATE
;
...
...
@@ -547,27 +555,30 @@ struct irq_chip {
/*
* irq_chip specific flags
*
* IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type()
* IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled
* IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
* IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
* when irq enabled
* IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
* IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
* IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
* IRQCHIP_SUPPORTS_LEVEL_MSI Chip can provide two doorbells for Level MSIs
* IRQCHIP_SUPPORTS_NMI: Chip can deliver NMIs, only for root irqchips
* IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type()
* IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled
* IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
* IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
* when irq enabled
* IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
* IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
* IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
* IRQCHIP_SUPPORTS_LEVEL_MSI: Chip can provide two doorbells for Level MSIs
* IRQCHIP_SUPPORTS_NMI: Chip can deliver NMIs, only for root irqchips
* IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs
* in the suspend path if they are in disabled state
*/
enum
{
IRQCHIP_SET_TYPE_MASKED
=
(
1
<<
0
),
IRQCHIP_EOI_IF_HANDLED
=
(
1
<<
1
),
IRQCHIP_MASK_ON_SUSPEND
=
(
1
<<
2
),
IRQCHIP_ONOFFLINE_ENABLED
=
(
1
<<
3
),
IRQCHIP_SKIP_SET_WAKE
=
(
1
<<
4
),
IRQCHIP_ONESHOT_SAFE
=
(
1
<<
5
),
IRQCHIP_EOI_THREADED
=
(
1
<<
6
),
IRQCHIP_SUPPORTS_LEVEL_MSI
=
(
1
<<
7
),
IRQCHIP_SUPPORTS_NMI
=
(
1
<<
8
),
IRQCHIP_SET_TYPE_MASKED
=
(
1
<<
0
),
IRQCHIP_EOI_IF_HANDLED
=
(
1
<<
1
),
IRQCHIP_MASK_ON_SUSPEND
=
(
1
<<
2
),
IRQCHIP_ONOFFLINE_ENABLED
=
(
1
<<
3
),
IRQCHIP_SKIP_SET_WAKE
=
(
1
<<
4
),
IRQCHIP_ONESHOT_SAFE
=
(
1
<<
5
),
IRQCHIP_EOI_THREADED
=
(
1
<<
6
),
IRQCHIP_SUPPORTS_LEVEL_MSI
=
(
1
<<
7
),
IRQCHIP_SUPPORTS_NMI
=
(
1
<<
8
),
IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
=
(
1
<<
9
),
};
#include <linux/irqdesc.h>
...
...
kernel/irq/debugfs.c
View file @
04e8c5b2
...
...
@@ -57,6 +57,7 @@ static const struct irq_bit_descr irqchip_flags[] = {
BIT_MASK_DESCR
(
IRQCHIP_EOI_THREADED
),
BIT_MASK_DESCR
(
IRQCHIP_SUPPORTS_LEVEL_MSI
),
BIT_MASK_DESCR
(
IRQCHIP_SUPPORTS_NMI
),
BIT_MASK_DESCR
(
IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
),
};
static
void
...
...
@@ -125,6 +126,8 @@ static const struct irq_bit_descr irqdata_states[] = {
BIT_MASK_DESCR
(
IRQD_DEFAULT_TRIGGER_SET
),
BIT_MASK_DESCR
(
IRQD_HANDLE_ENFORCE_IRQCTX
),
BIT_MASK_DESCR
(
IRQD_IRQ_ENABLED_ON_SUSPEND
),
};
static
const
struct
irq_bit_descr
irqdesc_states
[]
=
{
...
...
kernel/irq/pm.c
View file @
04e8c5b2
...
...
@@ -69,12 +69,26 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action)
static
bool
suspend_device_irq
(
struct
irq_desc
*
desc
)
{
unsigned
long
chipflags
=
irq_desc_get_chip
(
desc
)
->
flags
;
struct
irq_data
*
irqd
=
&
desc
->
irq_data
;
if
(
!
desc
->
action
||
irq_desc_is_chained
(
desc
)
||
desc
->
no_suspend_depth
)
return
false
;
if
(
irqd_is_wakeup_set
(
&
desc
->
irq_data
))
{
irqd_set
(
&
desc
->
irq_data
,
IRQD_WAKEUP_ARMED
);
if
(
irqd_is_wakeup_set
(
irqd
))
{
irqd_set
(
irqd
,
IRQD_WAKEUP_ARMED
);
if
((
chipflags
&
IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
)
&&
irqd_irq_disabled
(
irqd
))
{
/*
* Interrupt marked for wakeup is in disabled state.
* Enable interrupt here to unmask/enable in irqchip
* to be able to resume with such interrupts.
*/
__enable_irq
(
desc
);
irqd_set
(
irqd
,
IRQD_IRQ_ENABLED_ON_SUSPEND
);
}
/*
* We return true here to force the caller to issue
* synchronize_irq(). We need to make sure that the
...
...
@@ -93,7 +107,7 @@ static bool suspend_device_irq(struct irq_desc *desc)
* chip level. The chip implementation indicates that with
* IRQCHIP_MASK_ON_SUSPEND.
*/
if
(
irq_desc_get_chip
(
desc
)
->
flags
&
IRQCHIP_MASK_ON_SUSPEND
)
if
(
chip
flags
&
IRQCHIP_MASK_ON_SUSPEND
)
mask_irq
(
desc
);
return
true
;
}
...
...
@@ -137,7 +151,19 @@ EXPORT_SYMBOL_GPL(suspend_device_irqs);
static
void
resume_irq
(
struct
irq_desc
*
desc
)
{
irqd_clear
(
&
desc
->
irq_data
,
IRQD_WAKEUP_ARMED
);
struct
irq_data
*
irqd
=
&
desc
->
irq_data
;
irqd_clear
(
irqd
,
IRQD_WAKEUP_ARMED
);
if
(
irqd_is_enabled_on_suspend
(
irqd
))
{
/*
* Interrupt marked for wakeup was enabled during suspend
* entry. Disable such interrupts to restore them back to
* original state.
*/
__disable_irq
(
desc
);
irqd_clear
(
irqd
,
IRQD_IRQ_ENABLED_ON_SUSPEND
);
}
if
(
desc
->
istate
&
IRQS_SUSPENDED
)
goto
resume
;
...
...
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