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
fb414e90
Commit
fb414e90
authored
Apr 10, 2015
by
Jason Cooper
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'irqchip/stacked-exynos' into irqchip/core
parents
07c523f1
d4ad0759
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
161 additions
and
22 deletions
+161
-22
Documentation/devicetree/bindings/arm/samsung/pmu.txt
Documentation/devicetree/bindings/arm/samsung/pmu.txt
+17
-0
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos3250.dtsi
+4
-0
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4.dtsi
+4
-0
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5250.dtsi
+4
-0
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5420.dtsi
+4
-0
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/exynos.c
+5
-10
arch/arm/mach-exynos/suspend.c
arch/arm/mach-exynos/suspend.c
+123
-12
No files found.
Documentation/devicetree/bindings/arm/samsung/pmu.txt
View file @
fb414e90
...
...
@@ -29,10 +29,27 @@ Properties:
- clocks : list of phandles and specifiers to all input clocks listed in
clock-names property.
Optional properties:
Some PMUs are capable of behaving as an interrupt controller (mostly
to wake up a suspended PMU). In which case, they can have the
following properties:
- interrupt-controller: indicate that said PMU is an interrupt controller
- #interrupt-cells: must be identical to the that of the parent interrupt
controller.
- interrupt-parent: a phandle indicating which interrupt controller
this PMU signals interrupts to.
Example :
pmu_system_controller: system-controller@10040000 {
compatible = "samsung,exynos5250-pmu", "syscon";
reg = <0x10040000 0x5000>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
#clock-cells = <1>;
clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
"clkout4", "clkout8", "clkout9";
...
...
arch/arm/boot/dts/exynos3250.dtsi
View file @
fb414e90
...
...
@@ -130,6 +130,9 @@ sys_reg: syscon@10010000 {
pmu_system_controller: system-controller@10020000 {
compatible = "samsung,exynos3250-pmu", "syscon";
reg = <0x10020000 0x4000>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
};
mipi_phy: video-phy@10020710 {
...
...
@@ -184,6 +187,7 @@ rtc: rtc@10070000 {
compatible = "samsung,exynos3250-rtc";
reg = <0x10070000 0x100>;
interrupts = <0 73 0>, <0 74 0>;
interrupt-parent = <&pmu_system_controller>;
status = "disabled";
};
...
...
arch/arm/boot/dts/exynos4.dtsi
View file @
fb414e90
...
...
@@ -152,6 +152,9 @@ sys_reg: syscon@10010000 {
pmu_system_controller: system-controller@10020000 {
compatible = "samsung,exynos4210-pmu", "syscon";
reg = <0x10020000 0x4000>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
};
dsi_0: dsi@11C80000 {
...
...
@@ -264,6 +267,7 @@ watchdog@10060000 {
rtc@10070000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupt-parent = <&pmu_system_controller>;
interrupts = <0 44 0>, <0 45 0>;
clocks = <&clock CLK_RTC>;
clock-names = "rtc";
...
...
arch/arm/boot/dts/exynos5250.dtsi
View file @
fb414e90
...
...
@@ -196,6 +196,9 @@ pmu_system_controller: system-controller@10040000 {
clock-names = "clkout16";
clocks = <&clock CLK_FIN_PLL>;
#clock-cells = <1>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
};
sysreg_system_controller: syscon@10050000 {
...
...
@@ -232,6 +235,7 @@ mfc: codec@11000000 {
rtc: rtc@101E0000 {
clocks = <&clock CLK_RTC>;
clock-names = "rtc";
interrupt-parent = <&pmu_system_controller>;
status = "disabled";
};
...
...
arch/arm/boot/dts/exynos5420.dtsi
View file @
fb414e90
...
...
@@ -327,6 +327,7 @@ pinctrl_4: pinctrl@03860000 {
rtc: rtc@101E0000 {
clocks = <&clock CLK_RTC>;
clock-names = "rtc";
interrupt-parent = <&pmu_system_controller>;
status = "disabled";
};
...
...
@@ -769,6 +770,9 @@ pmu_system_controller: system-controller@10040000 {
clock-names = "clkout16";
clocks = <&clock CLK_FIN_PLL>;
#clock-cells = <1>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
};
sysreg_system_controller: syscon@10050000 {
...
...
arch/arm/mach-exynos/exynos.c
View file @
fb414e90
...
...
@@ -166,16 +166,14 @@ static void __init exynos_init_io(void)
exynos_map_io
();
}
/*
* Apparently, these SoCs are not able to wake-up from suspend using
* the PMU. Too bad. Should they suddenly become capable of such a
* feat, the matches below should be moved to suspend.c.
*/
static
const
struct
of_device_id
exynos_dt_pmu_match
[]
=
{
{
.
compatible
=
"samsung,exynos3250-pmu"
},
{
.
compatible
=
"samsung,exynos4210-pmu"
},
{
.
compatible
=
"samsung,exynos4212-pmu"
},
{
.
compatible
=
"samsung,exynos4412-pmu"
},
{
.
compatible
=
"samsung,exynos4415-pmu"
},
{
.
compatible
=
"samsung,exynos5250-pmu"
},
{
.
compatible
=
"samsung,exynos5260-pmu"
},
{
.
compatible
=
"samsung,exynos5410-pmu"
},
{
.
compatible
=
"samsung,exynos5420-pmu"
},
{
/*sentinel*/
},
};
...
...
@@ -186,9 +184,6 @@ static void exynos_map_pmu(void)
np
=
of_find_matching_node
(
NULL
,
exynos_dt_pmu_match
);
if
(
np
)
pmu_base_addr
=
of_iomap
(
np
,
0
);
if
(
!
pmu_base_addr
)
panic
(
"failed to find exynos pmu register
\n
"
);
}
static
void
__init
exynos_init_irq
(
void
)
...
...
arch/arm/mach-exynos/suspend.c
View file @
fb414e90
...
...
@@ -18,7 +18,9 @@
#include <linux/syscore_ops.h>
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/err.h>
#include <linux/regulator/machine.h>
...
...
@@ -43,8 +45,8 @@
#define EXYNOS5420_CPU_STATE 0x28
/**
* struct exynos_wkup_irq -
Exynos GIC to PMU IRQ
mapping
* @hwirq: Hardware IRQ signal of the
GIC
* struct exynos_wkup_irq -
PMU IRQ to mask
mapping
* @hwirq: Hardware IRQ signal of the
PMU
* @mask: Mask in PMU wake-up mask register
*/
struct
exynos_wkup_irq
{
...
...
@@ -93,14 +95,14 @@ static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
};
static
const
struct
exynos_wkup_irq
exynos4_wkup_irq
[]
=
{
{
76
,
BIT
(
1
)
},
/* RTC alarm */
{
77
,
BIT
(
2
)
},
/* RTC tick */
{
44
,
BIT
(
1
)
},
/* RTC alarm */
{
45
,
BIT
(
2
)
},
/* RTC tick */
{
/* sentinel */
},
};
static
const
struct
exynos_wkup_irq
exynos5250_wkup_irq
[]
=
{
{
75
,
BIT
(
1
)
},
/* RTC alarm */
{
76
,
BIT
(
2
)
},
/* RTC tick */
{
43
,
BIT
(
1
)
},
/* RTC alarm */
{
44
,
BIT
(
2
)
},
/* RTC tick */
{
/* sentinel */
},
};
...
...
@@ -167,6 +169,113 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
return
-
ENOENT
;
}
static
struct
irq_chip
exynos_pmu_chip
=
{
.
name
=
"PMU"
,
.
irq_eoi
=
irq_chip_eoi_parent
,
.
irq_mask
=
irq_chip_mask_parent
,
.
irq_unmask
=
irq_chip_unmask_parent
,
.
irq_retrigger
=
irq_chip_retrigger_hierarchy
,
.
irq_set_wake
=
exynos_irq_set_wake
,
#ifdef CONFIG_SMP
.
irq_set_affinity
=
irq_chip_set_affinity_parent
,
#endif
};
static
int
exynos_pmu_domain_xlate
(
struct
irq_domain
*
domain
,
struct
device_node
*
controller
,
const
u32
*
intspec
,
unsigned
int
intsize
,
unsigned
long
*
out_hwirq
,
unsigned
int
*
out_type
)
{
if
(
domain
->
of_node
!=
controller
)
return
-
EINVAL
;
/* Shouldn't happen, really... */
if
(
intsize
!=
3
)
return
-
EINVAL
;
/* Not GIC compliant */
if
(
intspec
[
0
]
!=
0
)
return
-
EINVAL
;
/* No PPI should point to this domain */
*
out_hwirq
=
intspec
[
1
];
*
out_type
=
intspec
[
2
];
return
0
;
}
static
int
exynos_pmu_domain_alloc
(
struct
irq_domain
*
domain
,
unsigned
int
virq
,
unsigned
int
nr_irqs
,
void
*
data
)
{
struct
of_phandle_args
*
args
=
data
;
struct
of_phandle_args
parent_args
;
irq_hw_number_t
hwirq
;
int
i
;
if
(
args
->
args_count
!=
3
)
return
-
EINVAL
;
/* Not GIC compliant */
if
(
args
->
args
[
0
]
!=
0
)
return
-
EINVAL
;
/* No PPI should point to this domain */
hwirq
=
args
->
args
[
1
];
for
(
i
=
0
;
i
<
nr_irqs
;
i
++
)
irq_domain_set_hwirq_and_chip
(
domain
,
virq
+
i
,
hwirq
+
i
,
&
exynos_pmu_chip
,
NULL
);
parent_args
=
*
args
;
parent_args
.
np
=
domain
->
parent
->
of_node
;
return
irq_domain_alloc_irqs_parent
(
domain
,
virq
,
nr_irqs
,
&
parent_args
);
}
static
struct
irq_domain_ops
exynos_pmu_domain_ops
=
{
.
xlate
=
exynos_pmu_domain_xlate
,
.
alloc
=
exynos_pmu_domain_alloc
,
.
free
=
irq_domain_free_irqs_common
,
};
static
int
__init
exynos_pmu_irq_init
(
struct
device_node
*
node
,
struct
device_node
*
parent
)
{
struct
irq_domain
*
parent_domain
,
*
domain
;
if
(
!
parent
)
{
pr_err
(
"%s: no parent, giving up
\n
"
,
node
->
full_name
);
return
-
ENODEV
;
}
parent_domain
=
irq_find_host
(
parent
);
if
(
!
parent_domain
)
{
pr_err
(
"%s: unable to obtain parent domain
\n
"
,
node
->
full_name
);
return
-
ENXIO
;
}
pmu_base_addr
=
of_iomap
(
node
,
0
);
if
(
!
pmu_base_addr
)
{
pr_err
(
"%s: failed to find exynos pmu register
\n
"
,
node
->
full_name
);
return
-
ENOMEM
;
}
domain
=
irq_domain_add_hierarchy
(
parent_domain
,
0
,
0
,
node
,
&
exynos_pmu_domain_ops
,
NULL
);
if
(
!
domain
)
{
iounmap
(
pmu_base_addr
);
return
-
ENOMEM
;
}
return
0
;
}
#define EXYNOS_PMU_IRQ(symbol, name) OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init)
EXYNOS_PMU_IRQ
(
exynos3250_pmu_irq
,
"samsung,exynos3250-pmu"
);
EXYNOS_PMU_IRQ
(
exynos4210_pmu_irq
,
"samsung,exynos4210-pmu"
);
EXYNOS_PMU_IRQ
(
exynos4212_pmu_irq
,
"samsung,exynos4212-pmu"
);
EXYNOS_PMU_IRQ
(
exynos4412_pmu_irq
,
"samsung,exynos4412-pmu"
);
EXYNOS_PMU_IRQ
(
exynos4415_pmu_irq
,
"samsung,exynos4415-pmu"
);
EXYNOS_PMU_IRQ
(
exynos5250_pmu_irq
,
"samsung,exynos5250-pmu"
);
EXYNOS_PMU_IRQ
(
exynos5420_pmu_irq
,
"samsung,exynos5420-pmu"
);
static
int
exynos_cpu_do_idle
(
void
)
{
/* issue the standby signal into the pm unit. */
...
...
@@ -615,17 +724,19 @@ static struct syscore_ops exynos_pm_syscore_ops;
void
__init
exynos_pm_init
(
void
)
{
const
struct
of_device_id
*
match
;
struct
device_node
*
np
;
u32
tmp
;
of_find_matching_node_and_match
(
NULL
,
exynos_pmu_of_device_ids
,
&
match
);
if
(
!
match
)
{
np
=
of_find_matching_node_and_match
(
NULL
,
exynos_pmu_of_device_ids
,
&
match
);
if
(
!
np
)
{
pr_err
(
"Failed to find PMU node
\n
"
);
return
;
}
pm_data
=
(
struct
exynos_pm_data
*
)
match
->
data
;
/* Platform-specific GIC callback */
gic_arch_extn
.
irq_set_wake
=
exynos_irq_set_wake
;
if
(
WARN_ON
(
!
of_find_property
(
np
,
"interrupt-controller"
,
NULL
)))
pr_warn
(
"Outdated DT detected, suspend/resume will NOT work
\n
"
);
pm_data
=
(
struct
exynos_pm_data
*
)
match
->
data
;
/* All wakeup disable */
tmp
=
pmu_raw_readl
(
S5P_WAKEUP_MASK
);
...
...
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