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
nexedi
linux
Commits
fae119b6
Commit
fae119b6
authored
Oct 02, 2014
by
Jason Cooper
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'irqchip/gic' into irqchip/core
parents
f7472655
3708d52f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
21 deletions
+66
-21
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic-v3.c
+66
-21
No files found.
drivers/irqchip/irq-gic-v3.c
View file @
fae119b6
...
...
@@ -16,6 +16,7 @@
*/
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/of.h>
...
...
@@ -155,7 +156,7 @@ static void gic_enable_sre(void)
pr_err
(
"GIC: unable to set SRE (disabled at EL2), panic ahead
\n
"
);
}
static
void
gic_enable_redist
(
void
)
static
void
gic_enable_redist
(
bool
enable
)
{
void
__iomem
*
rbase
;
u32
count
=
1000000
;
/* 1s! */
...
...
@@ -163,20 +164,30 @@ static void gic_enable_redist(void)
rbase
=
gic_data_rdist_rd_base
();
/* Wake up this CPU redistributor */
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
if
(
enable
)
/* Wake up this CPU redistributor */
val
&=
~
GICR_WAKER_ProcessorSleep
;
else
val
|=
GICR_WAKER_ProcessorSleep
;
writel_relaxed
(
val
,
rbase
+
GICR_WAKER
);
while
(
readl_relaxed
(
rbase
+
GICR_WAKER
)
&
GICR_WAKER_ChildrenAsleep
)
{
count
--
;
if
(
!
count
)
{
pr_err_ratelimited
(
"redist didn't wake up...
\n
"
);
return
;
if
(
!
enable
)
{
/* Check that GICR_WAKER is writeable */
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
if
(
!
(
val
&
GICR_WAKER_ProcessorSleep
))
return
;
/* No PM support in this redistributor */
}
while
(
count
--
)
{
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
if
(
enable
^
(
val
&
GICR_WAKER_ChildrenAsleep
))
break
;
cpu_relax
();
udelay
(
1
);
};
if
(
!
count
)
pr_err_ratelimited
(
"redistributor failed to %s...
\n
"
,
enable
?
"wakeup"
:
"sleep"
);
}
/*
...
...
@@ -372,6 +383,21 @@ static int gic_populate_rdist(void)
return
-
ENODEV
;
}
static
void
gic_cpu_sys_reg_init
(
void
)
{
/* Enable system registers */
gic_enable_sre
();
/* Set priority mask register */
gic_write_pmr
(
DEFAULT_PMR_VALUE
);
/* EOI deactivates interrupt too (mode 0) */
gic_write_ctlr
(
ICC_CTLR_EL1_EOImode_drop_dir
);
/* ... and let's hit the road... */
gic_write_grpen1
(
1
);
}
static
void
gic_cpu_init
(
void
)
{
void
__iomem
*
rbase
;
...
...
@@ -380,23 +406,14 @@ static void gic_cpu_init(void)
if
(
gic_populate_rdist
())
return
;
gic_enable_redist
();
gic_enable_redist
(
true
);
rbase
=
gic_data_rdist_sgi_base
();
gic_cpu_config
(
rbase
,
gic_redist_wait_for_rwp
);
/* Enable system registers */
gic_enable_sre
();
/* Set priority mask register */
gic_write_pmr
(
DEFAULT_PMR_VALUE
);
/* EOI deactivates interrupt too (mode 0) */
gic_write_ctlr
(
ICC_CTLR_EL1_EOImode_drop_dir
);
/* ... and let's hit the road... */
gic_write_grpen1
(
1
);
/* initialise system registers */
gic_cpu_sys_reg_init
();
}
#ifdef CONFIG_SMP
...
...
@@ -532,6 +549,33 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
#define gic_smp_init() do { } while(0)
#endif
#ifdef CONFIG_CPU_PM
static
int
gic_cpu_pm_notifier
(
struct
notifier_block
*
self
,
unsigned
long
cmd
,
void
*
v
)
{
if
(
cmd
==
CPU_PM_EXIT
)
{
gic_enable_redist
(
true
);
gic_cpu_sys_reg_init
();
}
else
if
(
cmd
==
CPU_PM_ENTER
)
{
gic_write_grpen1
(
0
);
gic_enable_redist
(
false
);
}
return
NOTIFY_OK
;
}
static
struct
notifier_block
gic_cpu_pm_notifier_block
=
{
.
notifier_call
=
gic_cpu_pm_notifier
,
};
static
void
gic_cpu_pm_init
(
void
)
{
cpu_pm_register_notifier
(
&
gic_cpu_pm_notifier_block
);
}
#else
static
inline
void
gic_cpu_pm_init
(
void
)
{
}
#endif
/* CONFIG_CPU_PM */
static
struct
irq_chip
gic_chip
=
{
.
name
=
"GICv3"
,
.
irq_mask
=
gic_mask_irq
,
...
...
@@ -671,6 +715,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
gic_smp_init
();
gic_dist_init
();
gic_cpu_init
();
gic_cpu_pm_init
();
return
0
;
...
...
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