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
e822eac5
Commit
e822eac5
authored
Nov 23, 2018
by
Viresh Kumar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'opp/genpd/required-opps' into opp/linux-next
parents
3e27c79c
534245cc
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
526 additions
and
162 deletions
+526
-162
drivers/base/power/domain.c
drivers/base/power/domain.c
+27
-43
drivers/opp/core.c
drivers/opp/core.c
+191
-70
drivers/opp/of.c
drivers/opp/of.c
+272
-41
drivers/opp/opp.h
drivers/opp/opp.h
+20
-0
include/linux/pm_domain.h
include/linux/pm_domain.h
+4
-4
include/linux/pm_opp.h
include/linux/pm_opp.h
+12
-4
No files found.
drivers/base/power/domain.c
View file @
e822eac5
...
...
@@ -2338,7 +2338,7 @@ EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
struct
device
*
genpd_dev_pm_attach_by_id
(
struct
device
*
dev
,
unsigned
int
index
)
{
struct
device
*
genpd
_dev
;
struct
device
*
virt
_dev
;
int
num_domains
;
int
ret
;
...
...
@@ -2352,31 +2352,31 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
return
NULL
;
/* Allocate and register device on the genpd bus. */
genpd_dev
=
kzalloc
(
sizeof
(
*
genpd
_dev
),
GFP_KERNEL
);
if
(
!
genpd
_dev
)
virt_dev
=
kzalloc
(
sizeof
(
*
virt
_dev
),
GFP_KERNEL
);
if
(
!
virt
_dev
)
return
ERR_PTR
(
-
ENOMEM
);
dev_set_name
(
genpd
_dev
,
"genpd:%u:%s"
,
index
,
dev_name
(
dev
));
genpd
_dev
->
bus
=
&
genpd_bus_type
;
genpd
_dev
->
release
=
genpd_release_dev
;
dev_set_name
(
virt
_dev
,
"genpd:%u:%s"
,
index
,
dev_name
(
dev
));
virt
_dev
->
bus
=
&
genpd_bus_type
;
virt
_dev
->
release
=
genpd_release_dev
;
ret
=
device_register
(
genpd
_dev
);
ret
=
device_register
(
virt
_dev
);
if
(
ret
)
{
kfree
(
genpd
_dev
);
kfree
(
virt
_dev
);
return
ERR_PTR
(
ret
);
}
/* Try to attach the device to the PM domain at the specified index. */
ret
=
__genpd_dev_pm_attach
(
genpd
_dev
,
dev
->
of_node
,
index
,
false
);
ret
=
__genpd_dev_pm_attach
(
virt
_dev
,
dev
->
of_node
,
index
,
false
);
if
(
ret
<
1
)
{
device_unregister
(
genpd
_dev
);
device_unregister
(
virt
_dev
);
return
ret
?
ERR_PTR
(
ret
)
:
NULL
;
}
pm_runtime_enable
(
genpd
_dev
);
genpd_queue_power_off_work
(
dev_to_genpd
(
genpd
_dev
));
pm_runtime_enable
(
virt
_dev
);
genpd_queue_power_off_work
(
dev_to_genpd
(
virt
_dev
));
return
genpd
_dev
;
return
virt
_dev
;
}
EXPORT_SYMBOL_GPL
(
genpd_dev_pm_attach_by_id
);
...
...
@@ -2521,52 +2521,36 @@ int of_genpd_parse_idle_states(struct device_node *dn,
EXPORT_SYMBOL_GPL
(
of_genpd_parse_idle_states
);
/**
* of_genpd_opp_to_performance_state- Gets performance state of device's
* power domain corresponding to a DT node's "required-opps" property.
* pm_genpd_opp_to_performance_state - Gets performance state of the genpd from its OPP node.
*
* @dev: Device for which the performance-state needs to be found.
* @np: DT node where the "required-opps" property is present. This can be
* the device node itself (if it doesn't have an OPP table) or a node
* within the OPP table of a device (if device has an OPP table).
* @genpd_dev: Genpd's device for which the performance-state needs to be found.
* @opp: struct dev_pm_opp of the OPP for which we need to find performance
* state.
*
* Returns performance state
corresponding to the "required-opps" property of
*
a DT node. This calls platform specific genpd->opp_to_performance_state()
*
callback to translate
power domain OPP to performance state.
* Returns performance state
encoded in the OPP of the genpd. This calls
*
platform specific genpd->opp_to_performance_state() callback to translate
* power domain OPP to performance state.
*
* Returns performance state on success and 0 on failure.
*/
unsigned
int
of_genpd_opp_to_performance_state
(
struct
device
*
dev
,
struct
dev
ice_node
*
n
p
)
unsigned
int
pm_genpd_opp_to_performance_state
(
struct
device
*
genpd_
dev
,
struct
dev
_pm_opp
*
op
p
)
{
struct
generic_pm_domain
*
genpd
;
struct
dev_pm_opp
*
opp
;
int
state
=
0
;
struct
generic_pm_domain
*
genpd
=
NULL
;
int
state
;
genpd
=
dev_to_genpd
(
dev
);
if
(
IS_ERR
(
genpd
))
return
0
;
genpd
=
container_of
(
genpd_dev
,
struct
generic_pm_domain
,
dev
);
if
(
unlikely
(
!
genpd
->
set
_performance_state
))
if
(
unlikely
(
!
genpd
->
opp_to
_performance_state
))
return
0
;
genpd_lock
(
genpd
);
opp
=
of_dev_pm_opp_find_required_opp
(
&
genpd
->
dev
,
np
);
if
(
IS_ERR
(
opp
))
{
dev_err
(
dev
,
"Failed to find required OPP: %ld
\n
"
,
PTR_ERR
(
opp
));
goto
unlock
;
}
state
=
genpd
->
opp_to_performance_state
(
genpd
,
opp
);
dev_pm_opp_put
(
opp
);
unlock:
genpd_unlock
(
genpd
);
return
state
;
}
EXPORT_SYMBOL_GPL
(
of
_genpd_opp_to_performance_state
);
EXPORT_SYMBOL_GPL
(
pm
_genpd_opp_to_performance_state
);
static
int
__init
genpd_bus_init
(
void
)
{
...
...
drivers/opp/core.c
View file @
e822eac5
This diff is collapsed.
Click to expand it.
drivers/opp/of.c
View file @
e822eac5
This diff is collapsed.
Click to expand it.
drivers/opp/opp.h
View file @
e822eac5
...
...
@@ -63,6 +63,7 @@ extern struct list_head opp_tables;
* @supplies: Power supplies voltage/current values
* @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
* frequency from any other OPP's frequency.
* @required_opps: List of OPPs that are required by this OPP.
* @opp_table: points back to the opp_table struct this opp belongs to
* @np: OPP's device node.
* @dentry: debugfs dentry pointer (per opp)
...
...
@@ -84,6 +85,7 @@ struct dev_pm_opp {
unsigned
long
clock_latency_ns
;
struct
dev_pm_opp
**
required_opps
;
struct
opp_table
*
opp_table
;
struct
device_node
*
np
;
...
...
@@ -133,6 +135,11 @@ enum opp_table_access {
* @parsed_static_opps: True if OPPs are initialized from DT.
* @shared_opp: OPP is shared between multiple devices.
* @suspend_opp: Pointer to OPP to be used during device suspend.
* @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers.
* @genpd_virt_devs: List of virtual devices for multiple genpd support.
* @required_opp_tables: List of device OPP tables that are required by OPPs in
* this table.
* @required_opp_count: Number of required devices.
* @supported_hw: Array of version number to support.
* @supported_hw_count: Number of elements in supported_hw array.
* @prop_name: A name to postfix to many DT properties, while parsing them.
...
...
@@ -140,6 +147,7 @@ enum opp_table_access {
* @regulators: Supply regulators
* @regulator_count: Number of power supply regulators
* @genpd_performance_state: Device's power domain support performance state.
* @is_genpd: Marks if the OPP table belongs to a genpd.
* @set_opp: Platform specific set_opp callback
* @set_opp_data: Data to be passed to set_opp callback
* @dentry: debugfs dentry pointer of the real device directory (not links).
...
...
@@ -171,6 +179,11 @@ struct opp_table {
enum
opp_table_access
shared_opp
;
struct
dev_pm_opp
*
suspend_opp
;
struct
mutex
genpd_virt_dev_lock
;
struct
device
**
genpd_virt_devs
;
struct
opp_table
**
required_opp_tables
;
unsigned
int
required_opp_count
;
unsigned
int
*
supported_hw
;
unsigned
int
supported_hw_count
;
const
char
*
prop_name
;
...
...
@@ -178,6 +191,7 @@ struct opp_table {
struct
regulator
**
regulators
;
unsigned
int
regulator_count
;
bool
genpd_performance_state
;
bool
is_genpd
;
int
(
*
set_opp
)(
struct
dev_pm_set_opp_data
*
data
);
struct
dev_pm_set_opp_data
*
set_opp_data
;
...
...
@@ -206,10 +220,16 @@ void _put_opp_list_kref(struct opp_table *opp_table);
#ifdef CONFIG_OF
void
_of_init_opp_table
(
struct
opp_table
*
opp_table
,
struct
device
*
dev
,
int
index
);
void
_of_clear_opp_table
(
struct
opp_table
*
opp_table
);
struct
opp_table
*
_managed_opp
(
struct
device
*
dev
,
int
index
);
void
_of_opp_free_required_opps
(
struct
opp_table
*
opp_table
,
struct
dev_pm_opp
*
opp
);
#else
static
inline
void
_of_init_opp_table
(
struct
opp_table
*
opp_table
,
struct
device
*
dev
,
int
index
)
{}
static
inline
void
_of_clear_opp_table
(
struct
opp_table
*
opp_table
)
{}
static
inline
struct
opp_table
*
_managed_opp
(
struct
device
*
dev
,
int
index
)
{
return
NULL
;
}
static
inline
void
_of_opp_free_required_opps
(
struct
opp_table
*
opp_table
,
struct
dev_pm_opp
*
opp
)
{}
#endif
#ifdef CONFIG_DEBUG_FS
...
...
include/linux/pm_domain.h
View file @
e822eac5
...
...
@@ -258,8 +258,8 @@ int of_genpd_add_subdomain(struct of_phandle_args *parent,
struct
generic_pm_domain
*
of_genpd_remove_last
(
struct
device_node
*
np
);
int
of_genpd_parse_idle_states
(
struct
device_node
*
dn
,
struct
genpd_power_state
**
states
,
int
*
n
);
unsigned
int
of_genpd_opp_to_performance_state
(
struct
device
*
dev
,
struct
device_node
*
n
p
);
unsigned
int
pm_genpd_opp_to_performance_state
(
struct
device
*
genpd_
dev
,
struct
dev_pm_opp
*
op
p
);
int
genpd_dev_pm_attach
(
struct
device
*
dev
);
struct
device
*
genpd_dev_pm_attach_by_id
(
struct
device
*
dev
,
...
...
@@ -300,8 +300,8 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
}
static
inline
unsigned
int
of_genpd_opp_to_performance_state
(
struct
device
*
dev
,
struct
dev
ice_node
*
n
p
)
pm_genpd_opp_to_performance_state
(
struct
device
*
genpd_
dev
,
struct
dev
_pm_opp
*
op
p
)
{
return
0
;
}
...
...
include/linux/pm_opp.h
View file @
e822eac5
...
...
@@ -126,6 +126,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
void
dev_pm_opp_put_clkname
(
struct
opp_table
*
opp_table
);
struct
opp_table
*
dev_pm_opp_register_set_opp_helper
(
struct
device
*
dev
,
int
(
*
set_opp
)(
struct
dev_pm_set_opp_data
*
data
));
void
dev_pm_opp_unregister_set_opp_helper
(
struct
opp_table
*
opp_table
);
struct
opp_table
*
dev_pm_opp_set_genpd_virt_dev
(
struct
device
*
dev
,
struct
device
*
virt_dev
,
int
index
);
void
dev_pm_opp_put_genpd_virt_dev
(
struct
opp_table
*
opp_table
,
struct
device
*
virt_dev
);
int
dev_pm_opp_set_rate
(
struct
device
*
dev
,
unsigned
long
target_freq
);
int
dev_pm_opp_set_sharing_cpus
(
struct
device
*
cpu_dev
,
const
struct
cpumask
*
cpumask
);
int
dev_pm_opp_get_sharing_cpus
(
struct
device
*
cpu_dev
,
struct
cpumask
*
cpumask
);
...
...
@@ -272,6 +274,12 @@ static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const
static
inline
void
dev_pm_opp_put_clkname
(
struct
opp_table
*
opp_table
)
{}
static
inline
struct
opp_table
*
dev_pm_opp_set_genpd_virt_dev
(
struct
device
*
dev
,
struct
device
*
virt_dev
,
int
index
)
{
return
ERR_PTR
(
-
ENOTSUPP
);
}
static
inline
void
dev_pm_opp_put_genpd_virt_dev
(
struct
opp_table
*
opp_table
,
struct
device
*
virt_dev
)
{}
static
inline
int
dev_pm_opp_set_rate
(
struct
device
*
dev
,
unsigned
long
target_freq
)
{
return
-
ENOTSUPP
;
...
...
@@ -305,8 +313,8 @@ int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
void
dev_pm_opp_of_cpumask_remove_table
(
const
struct
cpumask
*
cpumask
);
int
dev_pm_opp_of_get_sharing_cpus
(
struct
device
*
cpu_dev
,
struct
cpumask
*
cpumask
);
struct
device_node
*
dev_pm_opp_of_get_opp_desc_node
(
struct
device
*
dev
);
struct
dev_pm_opp
*
of_dev_pm_opp_find_required_opp
(
struct
device
*
dev
,
struct
device_node
*
np
);
struct
device_node
*
dev_pm_opp_get_of_node
(
struct
dev_pm_opp
*
opp
);
unsigned
int
of_get_required_opp_performance_state
(
struct
device_node
*
np
,
int
index
);
#else
static
inline
int
dev_pm_opp_of_add_table
(
struct
device
*
dev
)
{
...
...
@@ -341,13 +349,13 @@ static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device
return
NULL
;
}
static
inline
struct
dev
_pm_opp
*
of_dev_pm_opp_find_required_opp
(
struct
device
*
dev
,
struct
device_node
*
n
p
)
static
inline
struct
dev
ice_node
*
dev_pm_opp_get_of_node
(
struct
dev_pm_opp
*
op
p
)
{
return
NULL
;
}
static
inline
struct
device_node
*
dev_pm_opp_get_of_node
(
struct
dev_pm_opp
*
opp
)
static
inline
unsigned
int
of_get_required_opp_performance_state
(
struct
device_node
*
np
,
int
index
)
{
return
NULL
;
return
0
;
}
#endif
...
...
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