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
d269a36a
Commit
d269a36a
authored
May 08, 2014
by
Jason Cooper
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'mvebu/soc-pmsu' into mvebu/soc
parents
d0de9323
02e7b067
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
185 additions
and
28 deletions
+185
-28
Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
+6
-8
Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
+14
-0
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/Makefile
+1
-1
arch/arm/mach-mvebu/common.h
arch/arm/mach-mvebu/common.h
+1
-0
arch/arm/mach-mvebu/cpu-reset.c
arch/arm/mach-mvebu/cpu-reset.c
+103
-0
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-mvebu/pmsu.c
+60
-19
No files found.
Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
View file @
d269a36a
...
...
@@ -4,17 +4,15 @@ Available on Marvell SOCs: Armada 370 and Armada XP
Required properties:
- compatible: "marvell,armada-370-xp-pmsu"
- compatible: should be "marvell,armada-370-pmsu", whereas
"marvell,armada-370-xp-pmsu" is deprecated and will be removed
- reg: Should contain PMSU registers location and length. First pair
for the per-CPU SW Reset Control registers, second pair for the
Power Management Service Unit.
- reg: Should contain PMSU registers location and length.
Example:
armada-370-xp-pmsu@d0022000 {
compatible = "marvell,armada-370-xp-pmsu";
reg = <0xd0022100 0x430>,
<0xd0020800 0x20>;
armada-370-xp-pmsu@22000 {
compatible = "marvell,armada-370-pmsu";
reg = <0x22000 0x1000>;
};
Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
0 → 100644
View file @
d269a36a
Marvell Armada CPU reset controller
===================================
Required properties:
- compatible: Should be "marvell,armada-370-cpu-reset".
- reg: should be register base and length as documented in the
datasheet for the CPU reset registers
cpurst: cpurst@20800 {
compatible = "marvell,armada-370-cpu-reset";
reg = <0x20800 0x20>;
};
arch/arm/mach-mvebu/Makefile
View file @
d269a36a
...
...
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
AFLAGS_coherency_ll.o
:=
-Wa
,-march
=
armv7-a
obj-y
+=
system-controller.o mvebu-soc-id.o
obj-y
+=
system-controller.o mvebu-soc-id.o
cpu-reset.o
obj-$(CONFIG_MACH_MVEBU_V7)
+=
board-v7.o
obj-$(CONFIG_MACH_DOVE)
+=
dove.o
obj-$(CONFIG_ARCH_MVEBU)
+=
coherency.o coherency_ll.o pmsu.o
...
...
arch/arm/mach-mvebu/common.h
View file @
d269a36a
...
...
@@ -18,6 +18,7 @@
#include <linux/reboot.h>
void
mvebu_restart
(
enum
reboot_mode
mode
,
const
char
*
cmd
);
int
mvebu_cpu_reset_deassert
(
int
cpu
);
void
armada_xp_cpu_die
(
unsigned
int
cpu
);
...
...
arch/arm/mach-mvebu/cpu-reset.c
0 → 100644
View file @
d269a36a
/*
* Copyright (C) 2014 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#define pr_fmt(fmt) "mvebu-cpureset: " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/resource.h>
#include "armada-370-xp.h"
static
void
__iomem
*
cpu_reset_base
;
static
size_t
cpu_reset_size
;
#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
#define CPU_RESET_ASSERT BIT(0)
int
mvebu_cpu_reset_deassert
(
int
cpu
)
{
u32
reg
;
if
(
!
cpu_reset_base
)
return
-
ENODEV
;
if
(
CPU_RESET_OFFSET
(
cpu
)
>=
cpu_reset_size
)
return
-
EINVAL
;
reg
=
readl
(
cpu_reset_base
+
CPU_RESET_OFFSET
(
cpu
));
reg
&=
~
CPU_RESET_ASSERT
;
writel
(
reg
,
cpu_reset_base
+
CPU_RESET_OFFSET
(
cpu
));
return
0
;
}
static
int
mvebu_cpu_reset_map
(
struct
device_node
*
np
,
int
res_idx
)
{
struct
resource
res
;
if
(
of_address_to_resource
(
np
,
res_idx
,
&
res
))
{
pr_err
(
"unable to get resource
\n
"
);
return
-
ENOENT
;
}
if
(
!
request_mem_region
(
res
.
start
,
resource_size
(
&
res
),
np
->
full_name
))
{
pr_err
(
"unable to request region
\n
"
);
return
-
EBUSY
;
}
cpu_reset_base
=
ioremap
(
res
.
start
,
resource_size
(
&
res
));
if
(
!
cpu_reset_base
)
{
pr_err
(
"unable to map registers
\n
"
);
release_mem_region
(
res
.
start
,
resource_size
(
&
res
));
return
-
ENOMEM
;
}
cpu_reset_size
=
resource_size
(
&
res
);
return
0
;
}
int
__init
mvebu_cpu_reset_init
(
void
)
{
struct
device_node
*
np
;
int
res_idx
;
int
ret
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,armada-370-cpu-reset"
);
if
(
np
)
{
res_idx
=
0
;
}
else
{
/*
* This code is kept for backward compatibility with
* old Device Trees.
*/
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,armada-370-xp-pmsu"
);
if
(
np
)
{
pr_warn
(
FW_WARN
"deprecated pmsu binding
\n
"
);
res_idx
=
1
;
}
}
/* No reset node found */
if
(
!
np
)
return
-
ENODEV
;
ret
=
mvebu_cpu_reset_map
(
np
,
res_idx
);
of_node_put
(
np
);
return
ret
;
}
early_initcall
(
mvebu_cpu_reset_init
);
arch/arm/mach-mvebu/pmsu.c
View file @
d269a36a
...
...
@@ -16,44 +16,56 @@
* other SOC units
*/
#define pr_fmt(fmt) "mvebu-pmsu: " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/resource.h>
#include <asm/smp_plat.h>
#include "common.h"
#include "pmsu.h"
static
void
__iomem
*
pmsu_mp_base
;
static
void
__iomem
*
pmsu_reset_base
;
#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8)
#define PMSU_BASE_OFFSET 0x100
#define PMSU_REG_SIZE 0x1000
#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x124)
static
struct
of_device_id
of_pmsu_table
[]
=
{
{.
compatible
=
"marvell,armada-370-xp-pmsu"
},
{
.
compatible
=
"marvell,armada-370-pmsu"
,
},
{
.
compatible
=
"marvell,armada-370-xp-pmsu"
,
},
{
/* end of list */
},
};
static
void
mvebu_pmsu_set_cpu_boot_addr
(
int
hw_cpu
,
void
*
boot_addr
)
{
writel
(
virt_to_phys
(
boot_addr
),
pmsu_mp_base
+
PMSU_BOOT_ADDR_REDIRECT_OFFSET
(
hw_cpu
));
}
#ifdef CONFIG_SMP
int
armada_xp_boot_cpu
(
unsigned
int
cpu_id
,
void
*
boot_addr
)
{
int
reg
,
hw_cpu
;
int
hw_cpu
,
ret
;
if
(
!
pmsu_mp_base
||
!
pmsu_reset_base
)
{
if
(
!
pmsu_mp_base
)
{
pr_warn
(
"Can't boot CPU. PMSU is uninitialized
\n
"
);
return
1
;
return
-
ENODEV
;
}
hw_cpu
=
cpu_logical_map
(
cpu_id
);
writel
(
virt_to_phys
(
boot_addr
),
pmsu_mp_base
+
PMSU_BOOT_ADDR_REDIRECT_OFFSET
(
hw_cpu
));
mvebu_pmsu_set_cpu_boot_addr
(
hw_cpu
,
boot_addr
);
/* Release CPU from reset by clearing reset bit*/
reg
=
readl
(
pmsu_reset_base
+
PMSU_RESET_CTL_OFFSET
(
hw_cpu
));
reg
&=
(
~
0x1
);
writel
(
reg
,
pmsu_reset_base
+
PMSU_RESET_CTL_OFFSET
(
hw_cpu
));
ret
=
mvebu_cpu_reset_deassert
(
hw_cpu
);
if
(
ret
)
{
pr_warn
(
"unable to boot CPU: %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
...
...
@@ -62,16 +74,45 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
static
int
__init
armada_370_xp_pmsu_init
(
void
)
{
struct
device_node
*
np
;
struct
resource
res
;
int
ret
=
0
;
np
=
of_find_matching_node
(
NULL
,
of_pmsu_table
);
if
(
np
)
{
if
(
!
np
)
return
0
;
pr_info
(
"Initializing Power Management Service Unit
\n
"
);
pmsu_mp_base
=
of_iomap
(
np
,
0
);
pmsu_reset_base
=
of_iomap
(
np
,
1
);
of_node_put
(
np
);
if
(
of_address_to_resource
(
np
,
0
,
&
res
))
{
pr_err
(
"unable to get resource
\n
"
);
ret
=
-
ENOENT
;
goto
out
;
}
return
0
;
if
(
of_device_is_compatible
(
np
,
"marvell,armada-370-xp-pmsu"
))
{
pr_warn
(
FW_WARN
"deprecated pmsu binding
\n
"
);
res
.
start
=
res
.
start
-
PMSU_BASE_OFFSET
;
res
.
end
=
res
.
start
+
PMSU_REG_SIZE
-
1
;
}
if
(
!
request_mem_region
(
res
.
start
,
resource_size
(
&
res
),
np
->
full_name
))
{
pr_err
(
"unable to request region
\n
"
);
ret
=
-
EBUSY
;
goto
out
;
}
pmsu_mp_base
=
ioremap
(
res
.
start
,
resource_size
(
&
res
));
if
(
!
pmsu_mp_base
)
{
pr_err
(
"unable to map registers
\n
"
);
release_mem_region
(
res
.
start
,
resource_size
(
&
res
));
ret
=
-
ENOMEM
;
goto
out
;
}
out:
of_node_put
(
np
);
return
ret
;
}
early_initcall
(
armada_370_xp_pmsu_init
);
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