Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xenomai
ipipe-arm
Commits
8a28da04
Commit
8a28da04
authored
Dec 03, 2017
by
Philippe Gerum
Browse files
ARM: imx/gpc: ipipe: enable interrupt pipelining
parent
631ca28d
Changes
1
Hide whitespace changes
Inline
Side-by-side
arch/arm/mach-imx/gpc.c
View file @
8a28da04
...
...
@@ -13,6 +13,7 @@
#include
<linux/io.h>
#include
<linux/irq.h>
#include
<linux/irqchip.h>
#include
<linux/ipipe.h>
#include
<linux/of.h>
#include
<linux/of_address.h>
#include
<linux/of_irq.h>
...
...
@@ -36,6 +37,7 @@
static
void
__iomem
*
gpc_base
;
static
u32
gpc_wake_irqs
[
IMR_NUM
];
static
u32
gpc_saved_imrs
[
IMR_NUM
];
static
IPIPE_DEFINE_RAW_SPINLOCK
(
gpc_lock
);
void
imx_gpc_set_arm_power_up_timing
(
u32
sw2iso
,
u32
sw
)
{
...
...
@@ -68,28 +70,38 @@ void imx_gpc_set_l2_mem_power_in_lpm(bool power_off)
void
imx_gpc_pre_suspend
(
bool
arm_power_off
)
{
void
__iomem
*
reg_imr1
=
gpc_base
+
GPC_IMR1
;
unsigned
long
flags
;
int
i
;
/* Tell GPC to power off ARM core when suspend */
if
(
arm_power_off
)
imx_gpc_set_arm_power_in_lpm
(
arm_power_off
);
flags
=
hard_cond_local_irq_save
();
for
(
i
=
0
;
i
<
IMR_NUM
;
i
++
)
{
gpc_saved_imrs
[
i
]
=
readl_relaxed
(
reg_imr1
+
i
*
4
);
writel_relaxed
(
~
gpc_wake_irqs
[
i
],
reg_imr1
+
i
*
4
);
}
hard_cond_local_irq_restore
(
flags
);
}
void
imx_gpc_post_resume
(
void
)
{
void
__iomem
*
reg_imr1
=
gpc_base
+
GPC_IMR1
;
unsigned
long
flags
;
int
i
;
/* Keep ARM core powered on for other low-power modes */
imx_gpc_set_arm_power_in_lpm
(
false
);
flags
=
hard_cond_local_irq_save
();
for
(
i
=
0
;
i
<
IMR_NUM
;
i
++
)
writel_relaxed
(
gpc_saved_imrs
[
i
],
reg_imr1
+
i
*
4
);
hard_cond_local_irq_restore
(
flags
);
}
static
int
imx_gpc_irq_set_wake
(
struct
irq_data
*
d
,
unsigned
int
on
)
...
...
@@ -111,22 +123,31 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
void
imx_gpc_mask_all
(
void
)
{
void
__iomem
*
reg_imr1
=
gpc_base
+
GPC_IMR1
;
unsigned
long
flags
;
int
i
;
flags
=
hard_cond_local_irq_save
();
for
(
i
=
0
;
i
<
IMR_NUM
;
i
++
)
{
gpc_saved_imrs
[
i
]
=
readl_relaxed
(
reg_imr1
+
i
*
4
);
writel_relaxed
(
~
0
,
reg_imr1
+
i
*
4
);
}
hard_cond_local_irq_restore
(
flags
);
}
void
imx_gpc_restore_all
(
void
)
{
void
__iomem
*
reg_imr1
=
gpc_base
+
GPC_IMR1
;
unsigned
long
flags
;
int
i
;
flags
=
hard_cond_local_irq_save
();
for
(
i
=
0
;
i
<
IMR_NUM
;
i
++
)
writel_relaxed
(
gpc_saved_imrs
[
i
],
reg_imr1
+
i
*
4
);
hard_cond_local_irq_restore
(
flags
);
}
void
imx_gpc_hwirq_unmask
(
unsigned
int
hwirq
)
...
...
@@ -153,16 +174,49 @@ void imx_gpc_hwirq_mask(unsigned int hwirq)
static
void
imx_gpc_irq_unmask
(
struct
irq_data
*
d
)
{
unsigned
long
flags
;
raw_spin_lock_irqsave
(
&
gpc_lock
,
flags
);
imx_gpc_hwirq_unmask
(
d
->
hwirq
);
__ipipe_spin_unlock_irqbegin
(
&
gpc_lock
);
irq_chip_unmask_parent
(
d
);
__ipipe_spin_unlock_irqcomplete
(
flags
);
}
static
void
imx_gpc_irq_mask
(
struct
irq_data
*
d
)
{
unsigned
long
flags
;
raw_spin_lock_irqsave
(
&
gpc_lock
,
flags
);
/* Parent IC will handle virtual locking */
imx_gpc_hwirq_mask
(
d
->
hwirq
);
__ipipe_spin_unlock_irqbegin
(
&
gpc_lock
);
irq_chip_mask_parent
(
d
);
__ipipe_spin_unlock_irqcomplete
(
flags
);
}
#ifdef CONFIG_IPIPE
static
void
imx_gpc_hold_irq
(
struct
irq_data
*
d
)
{
raw_spin_lock
(
&
gpc_lock
);
imx_gpc_hwirq_mask
(
d
->
hwirq
);
raw_spin_unlock
(
&
gpc_lock
);
irq_chip_hold_parent
(
d
);
}
static
void
imx_gpc_release_irq
(
struct
irq_data
*
d
)
{
unsigned
long
flags
;
raw_spin_lock_irqsave
(
&
gpc_lock
,
flags
);
imx_gpc_hwirq_unmask
(
d
->
hwirq
);
raw_spin_unlock_irqrestore
(
&
gpc_lock
,
flags
);
irq_chip_release_parent
(
d
);
}
#endif
/* CONFIG_IPIPE */
static
struct
irq_chip
imx_gpc_chip
=
{
.
name
=
"GPC"
,
.
irq_eoi
=
irq_chip_eoi_parent
,
...
...
@@ -174,6 +228,11 @@ static struct irq_chip imx_gpc_chip = {
#ifdef CONFIG_SMP
.
irq_set_affinity
=
irq_chip_set_affinity_parent
,
#endif
#ifdef CONFIG_IPIPE
.
irq_hold
=
imx_gpc_hold_irq
,
.
irq_release
=
imx_gpc_release_irq
,
#endif
.
flags
=
IRQCHIP_PIPELINE_SAFE
,
};
static
int
imx_gpc_domain_translate
(
struct
irq_domain
*
d
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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