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
31f18230
Commit
31f18230
authored
Nov 08, 2017
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pm-domains' into pm-qos
parents
20f97caf
704d2ce6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
223 additions
and
121 deletions
+223
-121
arch/arm/mach-shmobile/pm-rmobile.c
arch/arm/mach-shmobile/pm-rmobile.c
+1
-7
drivers/base/power/domain.c
drivers/base/power/domain.c
+153
-64
drivers/base/power/domain_governor.c
drivers/base/power/domain_governor.c
+49
-22
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/mediatek/mtk-scpsys.c
+2
-12
drivers/soc/rockchip/pm_domains.c
drivers/soc/rockchip/pm_domains.c
+2
-12
include/linux/pm_domain.h
include/linux/pm_domain.h
+16
-4
No files found.
arch/arm/mach-shmobile/pm-rmobile.c
View file @
31f18230
...
@@ -120,18 +120,12 @@ static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
...
@@ -120,18 +120,12 @@ static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
return
__rmobile_pd_power_up
(
to_rmobile_pd
(
genpd
),
true
);
return
__rmobile_pd_power_up
(
to_rmobile_pd
(
genpd
),
true
);
}
}
static
bool
rmobile_pd_active_wakeup
(
struct
device
*
dev
)
{
return
true
;
}
static
void
rmobile_init_pm_domain
(
struct
rmobile_pm_domain
*
rmobile_pd
)
static
void
rmobile_init_pm_domain
(
struct
rmobile_pm_domain
*
rmobile_pd
)
{
{
struct
generic_pm_domain
*
genpd
=
&
rmobile_pd
->
genpd
;
struct
generic_pm_domain
*
genpd
=
&
rmobile_pd
->
genpd
;
struct
dev_power_governor
*
gov
=
rmobile_pd
->
gov
;
struct
dev_power_governor
*
gov
=
rmobile_pd
->
gov
;
genpd
->
flags
|=
GENPD_FLAG_PM_CLK
;
genpd
->
flags
|=
GENPD_FLAG_PM_CLK
|
GENPD_FLAG_ACTIVE_WAKEUP
;
genpd
->
dev_ops
.
active_wakeup
=
rmobile_pd_active_wakeup
;
genpd
->
power_off
=
rmobile_pd_power_down
;
genpd
->
power_off
=
rmobile_pd_power_down
;
genpd
->
power_on
=
rmobile_pd_power_up
;
genpd
->
power_on
=
rmobile_pd_power_up
;
genpd
->
attach_dev
=
cpg_mstp_attach_dev
;
genpd
->
attach_dev
=
cpg_mstp_attach_dev
;
...
...
drivers/base/power/domain.c
View file @
31f18230
...
@@ -124,6 +124,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
...
@@ -124,6 +124,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
#define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE)
#define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE)
#define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE)
#define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE)
#define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
#define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
static
inline
bool
irq_safe_dev_in_no_sleep_domain
(
struct
device
*
dev
,
static
inline
bool
irq_safe_dev_in_no_sleep_domain
(
struct
device
*
dev
,
const
struct
generic_pm_domain
*
genpd
)
const
struct
generic_pm_domain
*
genpd
)
...
@@ -237,6 +238,95 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd)
...
@@ -237,6 +238,95 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd)
static
inline
void
genpd_update_accounting
(
struct
generic_pm_domain
*
genpd
)
{}
static
inline
void
genpd_update_accounting
(
struct
generic_pm_domain
*
genpd
)
{}
#endif
#endif
/**
* dev_pm_genpd_set_performance_state- Set performance state of device's power
* domain.
*
* @dev: Device for which the performance-state needs to be set.
* @state: Target performance state of the device. This can be set as 0 when the
* device doesn't have any performance state constraints left (And so
* the device wouldn't participate anymore to find the target
* performance state of the genpd).
*
* It is assumed that the users guarantee that the genpd wouldn't be detached
* while this routine is getting called.
*
* Returns 0 on success and negative error values on failures.
*/
int
dev_pm_genpd_set_performance_state
(
struct
device
*
dev
,
unsigned
int
state
)
{
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain_data
*
gpd_data
,
*
pd_data
;
struct
pm_domain_data
*
pdd
;
unsigned
int
prev
;
int
ret
=
0
;
genpd
=
dev_to_genpd
(
dev
);
if
(
IS_ERR
(
genpd
))
return
-
ENODEV
;
if
(
unlikely
(
!
genpd
->
set_performance_state
))
return
-
EINVAL
;
if
(
unlikely
(
!
dev
->
power
.
subsys_data
||
!
dev
->
power
.
subsys_data
->
domain_data
))
{
WARN_ON
(
1
);
return
-
EINVAL
;
}
genpd_lock
(
genpd
);
gpd_data
=
to_gpd_data
(
dev
->
power
.
subsys_data
->
domain_data
);
prev
=
gpd_data
->
performance_state
;
gpd_data
->
performance_state
=
state
;
/* New requested state is same as Max requested state */
if
(
state
==
genpd
->
performance_state
)
goto
unlock
;
/* New requested state is higher than Max requested state */
if
(
state
>
genpd
->
performance_state
)
goto
update_state
;
/* Traverse all devices within the domain */
list_for_each_entry
(
pdd
,
&
genpd
->
dev_list
,
list_node
)
{
pd_data
=
to_gpd_data
(
pdd
);
if
(
pd_data
->
performance_state
>
state
)
state
=
pd_data
->
performance_state
;
}
if
(
state
==
genpd
->
performance_state
)
goto
unlock
;
/*
* We aren't propagating performance state changes of a subdomain to its
* masters as we don't have hardware that needs it. Over that, the
* performance states of subdomain and its masters may not have
* one-to-one mapping and would require additional information. We can
* get back to this once we have hardware that needs it. For that
* reason, we don't have to consider performance state of the subdomains
* of genpd here.
*/
update_state:
if
(
genpd_status_on
(
genpd
))
{
ret
=
genpd
->
set_performance_state
(
genpd
,
state
);
if
(
ret
)
{
gpd_data
->
performance_state
=
prev
;
goto
unlock
;
}
}
genpd
->
performance_state
=
state
;
unlock:
genpd_unlock
(
genpd
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
dev_pm_genpd_set_performance_state
);
static
int
_genpd_power_on
(
struct
generic_pm_domain
*
genpd
,
bool
timed
)
static
int
_genpd_power_on
(
struct
generic_pm_domain
*
genpd
,
bool
timed
)
{
{
unsigned
int
state_idx
=
genpd
->
state_idx
;
unsigned
int
state_idx
=
genpd
->
state_idx
;
...
@@ -256,6 +346,15 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
...
@@ -256,6 +346,15 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
return
ret
;
return
ret
;
elapsed_ns
=
ktime_to_ns
(
ktime_sub
(
ktime_get
(),
time_start
));
elapsed_ns
=
ktime_to_ns
(
ktime_sub
(
ktime_get
(),
time_start
));
if
(
unlikely
(
genpd
->
set_performance_state
))
{
ret
=
genpd
->
set_performance_state
(
genpd
,
genpd
->
performance_state
);
if
(
ret
)
{
pr_warn
(
"%s: Failed to set performance state %d (%d)
\n
"
,
genpd
->
name
,
genpd
->
performance_state
,
ret
);
}
}
if
(
elapsed_ns
<=
genpd
->
states
[
state_idx
].
power_on_latency_ns
)
if
(
elapsed_ns
<=
genpd
->
states
[
state_idx
].
power_on_latency_ns
)
return
ret
;
return
ret
;
...
@@ -747,11 +846,7 @@ late_initcall(genpd_power_off_unused);
...
@@ -747,11 +846,7 @@ late_initcall(genpd_power_off_unused);
#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_GENERIC_DOMAINS_OF)
#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_GENERIC_DOMAINS_OF)
/**
static
bool
genpd_present
(
const
struct
generic_pm_domain
*
genpd
)
* pm_genpd_present - Check if the given PM domain has been initialized.
* @genpd: PM domain to check.
*/
static
bool
pm_genpd_present
(
const
struct
generic_pm_domain
*
genpd
)
{
{
const
struct
generic_pm_domain
*
gpd
;
const
struct
generic_pm_domain
*
gpd
;
...
@@ -769,12 +864,6 @@ static bool pm_genpd_present(const struct generic_pm_domain *genpd)
...
@@ -769,12 +864,6 @@ static bool pm_genpd_present(const struct generic_pm_domain *genpd)
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM_SLEEP
static
bool
genpd_dev_active_wakeup
(
const
struct
generic_pm_domain
*
genpd
,
struct
device
*
dev
)
{
return
GENPD_DEV_CALLBACK
(
genpd
,
bool
,
active_wakeup
,
dev
);
}
/**
/**
* genpd_sync_power_off - Synchronously power off a PM domain and its masters.
* genpd_sync_power_off - Synchronously power off a PM domain and its masters.
* @genpd: PM domain to power off, if possible.
* @genpd: PM domain to power off, if possible.
...
@@ -861,7 +950,7 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
...
@@ -861,7 +950,7 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
* @genpd: PM domain the device belongs to.
* @genpd: PM domain the device belongs to.
*
*
* There are two cases in which a device that can wake up the system from sleep
* There are two cases in which a device that can wake up the system from sleep
* states should be resumed by
pm_
genpd_prepare(): (1) if the device is enabled
* states should be resumed by genpd_prepare(): (1) if the device is enabled
* to wake up the system and it has to remain active for this purpose while the
* to wake up the system and it has to remain active for this purpose while the
* system is in the sleep state and (2) if the device is not enabled to wake up
* system is in the sleep state and (2) if the device is not enabled to wake up
* the system from sleep states and it generally doesn't generate wakeup signals
* the system from sleep states and it generally doesn't generate wakeup signals
...
@@ -879,12 +968,12 @@ static bool resume_needed(struct device *dev,
...
@@ -879,12 +968,12 @@ static bool resume_needed(struct device *dev,
if
(
!
device_can_wakeup
(
dev
))
if
(
!
device_can_wakeup
(
dev
))
return
false
;
return
false
;
active_wakeup
=
genpd_
dev_active_wakeup
(
genpd
,
dev
);
active_wakeup
=
genpd_
is_active_wakeup
(
genpd
);
return
device_may_wakeup
(
dev
)
?
active_wakeup
:
!
active_wakeup
;
return
device_may_wakeup
(
dev
)
?
active_wakeup
:
!
active_wakeup
;
}
}
/**
/**
*
pm_
genpd_prepare - Start power transition of a device in a PM domain.
* genpd_prepare - Start power transition of a device in a PM domain.
* @dev: Device to start the transition of.
* @dev: Device to start the transition of.
*
*
* Start a power transition of a device (during a system-wide power transition)
* Start a power transition of a device (during a system-wide power transition)
...
@@ -892,7 +981,7 @@ static bool resume_needed(struct device *dev,
...
@@ -892,7 +981,7 @@ static bool resume_needed(struct device *dev,
* an object of type struct generic_pm_domain representing a PM domain
* an object of type struct generic_pm_domain representing a PM domain
* consisting of I/O devices.
* consisting of I/O devices.
*/
*/
static
int
pm_
genpd_prepare
(
struct
device
*
dev
)
static
int
genpd_prepare
(
struct
device
*
dev
)
{
{
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
int
ret
;
int
ret
;
...
@@ -948,7 +1037,7 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
...
@@ -948,7 +1037,7 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
if
(
IS_ERR
(
genpd
))
if
(
IS_ERR
(
genpd
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
dev
->
power
.
wakeup_path
&&
genpd_
dev_active_wakeup
(
genpd
,
dev
))
if
(
dev
->
power
.
wakeup_path
&&
genpd_
is_active_wakeup
(
genpd
))
return
0
;
return
0
;
if
(
poweroff
)
if
(
poweroff
)
...
@@ -973,13 +1062,13 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
...
@@ -973,13 +1062,13 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
}
}
/**
/**
*
pm_
genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
* genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
* @dev: Device to suspend.
* @dev: Device to suspend.
*
*
* Stop the device and remove power from the domain if all devices in it have
* Stop the device and remove power from the domain if all devices in it have
* been stopped.
* been stopped.
*/
*/
static
int
pm_
genpd_suspend_noirq
(
struct
device
*
dev
)
static
int
genpd_suspend_noirq
(
struct
device
*
dev
)
{
{
dev_dbg
(
dev
,
"%s()
\n
"
,
__func__
);
dev_dbg
(
dev
,
"%s()
\n
"
,
__func__
);
...
@@ -987,12 +1076,12 @@ static int pm_genpd_suspend_noirq(struct device *dev)
...
@@ -987,12 +1076,12 @@ static int pm_genpd_suspend_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_resume_noirq - Start of resume of device in an I/O PM domain.
* genpd_resume_noirq - Start of resume of device in an I/O PM domain.
* @dev: Device to resume.
* @dev: Device to resume.
*
*
* Restore power to the device's PM domain, if necessary, and start the device.
* Restore power to the device's PM domain, if necessary, and start the device.
*/
*/
static
int
pm_
genpd_resume_noirq
(
struct
device
*
dev
)
static
int
genpd_resume_noirq
(
struct
device
*
dev
)
{
{
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1003,7 +1092,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
...
@@ -1003,7 +1092,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
if
(
IS_ERR
(
genpd
))
if
(
IS_ERR
(
genpd
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
dev
->
power
.
wakeup_path
&&
genpd_
dev_active_wakeup
(
genpd
,
dev
))
if
(
dev
->
power
.
wakeup_path
&&
genpd_
is_active_wakeup
(
genpd
))
return
0
;
return
0
;
genpd_lock
(
genpd
);
genpd_lock
(
genpd
);
...
@@ -1022,7 +1111,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
...
@@ -1022,7 +1111,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
* genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
* @dev: Device to freeze.
* @dev: Device to freeze.
*
*
* Carry out a late freeze of a device under the assumption that its
* Carry out a late freeze of a device under the assumption that its
...
@@ -1030,7 +1119,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
...
@@ -1030,7 +1119,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
* struct generic_pm_domain representing a power domain consisting of I/O
* struct generic_pm_domain representing a power domain consisting of I/O
* devices.
* devices.
*/
*/
static
int
pm_
genpd_freeze_noirq
(
struct
device
*
dev
)
static
int
genpd_freeze_noirq
(
struct
device
*
dev
)
{
{
const
struct
generic_pm_domain
*
genpd
;
const
struct
generic_pm_domain
*
genpd
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1052,13 +1141,13 @@ static int pm_genpd_freeze_noirq(struct device *dev)
...
@@ -1052,13 +1141,13 @@ static int pm_genpd_freeze_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
* genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
* @dev: Device to thaw.
* @dev: Device to thaw.
*
*
* Start the device, unless power has been removed from the domain already
* Start the device, unless power has been removed from the domain already
* before the system transition.
* before the system transition.
*/
*/
static
int
pm_
genpd_thaw_noirq
(
struct
device
*
dev
)
static
int
genpd_thaw_noirq
(
struct
device
*
dev
)
{
{
const
struct
generic_pm_domain
*
genpd
;
const
struct
generic_pm_domain
*
genpd
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1079,14 +1168,14 @@ static int pm_genpd_thaw_noirq(struct device *dev)
...
@@ -1079,14 +1168,14 @@ static int pm_genpd_thaw_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_poweroff_noirq - Completion of hibernation of device in an
* genpd_poweroff_noirq - Completion of hibernation of device in an
* I/O PM domain.
* I/O PM domain.
* @dev: Device to poweroff.
* @dev: Device to poweroff.
*
*
* Stop the device and remove power from the domain if all devices in it have
* Stop the device and remove power from the domain if all devices in it have
* been stopped.
* been stopped.
*/
*/
static
int
pm_
genpd_poweroff_noirq
(
struct
device
*
dev
)
static
int
genpd_poweroff_noirq
(
struct
device
*
dev
)
{
{
dev_dbg
(
dev
,
"%s()
\n
"
,
__func__
);
dev_dbg
(
dev
,
"%s()
\n
"
,
__func__
);
...
@@ -1094,13 +1183,13 @@ static int pm_genpd_poweroff_noirq(struct device *dev)
...
@@ -1094,13 +1183,13 @@ static int pm_genpd_poweroff_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_restore_noirq - Start of restore of device in an I/O PM domain.
* genpd_restore_noirq - Start of restore of device in an I/O PM domain.
* @dev: Device to resume.
* @dev: Device to resume.
*
*
* Make sure the domain will be in the same power state as before the
* Make sure the domain will be in the same power state as before the
* hibernation the system is resuming from and start the device if necessary.
* hibernation the system is resuming from and start the device if necessary.
*/
*/
static
int
pm_
genpd_restore_noirq
(
struct
device
*
dev
)
static
int
genpd_restore_noirq
(
struct
device
*
dev
)
{
{
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1137,7 +1226,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
...
@@ -1137,7 +1226,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
}
}
/**
/**
*
pm_
genpd_complete - Complete power transition of a device in a power domain.
* genpd_complete - Complete power transition of a device in a power domain.
* @dev: Device to complete the transition of.
* @dev: Device to complete the transition of.
*
*
* Complete a power transition of a device (during a system-wide power
* Complete a power transition of a device (during a system-wide power
...
@@ -1145,7 +1234,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
...
@@ -1145,7 +1234,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
* domain member of an object of type struct generic_pm_domain representing
* domain member of an object of type struct generic_pm_domain representing
* a power domain consisting of I/O devices.
* a power domain consisting of I/O devices.
*/
*/
static
void
pm_
genpd_complete
(
struct
device
*
dev
)
static
void
genpd_complete
(
struct
device
*
dev
)
{
{
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
...
@@ -1178,7 +1267,7 @@ static void genpd_syscore_switch(struct device *dev, bool suspend)
...
@@ -1178,7 +1267,7 @@ static void genpd_syscore_switch(struct device *dev, bool suspend)
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
genpd
=
dev_to_genpd
(
dev
);
genpd
=
dev_to_genpd
(
dev
);
if
(
!
pm_
genpd_present
(
genpd
))
if
(
!
genpd_present
(
genpd
))
return
;
return
;
if
(
suspend
)
{
if
(
suspend
)
{
...
@@ -1204,14 +1293,14 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
...
@@ -1204,14 +1293,14 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
#else
/* !CONFIG_PM_SLEEP */
#else
/* !CONFIG_PM_SLEEP */
#define
pm_
genpd_prepare NULL
#define genpd_prepare NULL
#define
pm_genpd_suspend_noirq
NULL
#define
genpd_suspend_noirq
NULL
#define
pm_genpd_resume_noirq
NULL
#define
genpd_resume_noirq
NULL
#define
pm_genpd_freeze_noirq
NULL
#define
genpd_freeze_noirq
NULL
#define
pm_genpd_thaw_noirq
NULL
#define
genpd_thaw_noirq
NULL
#define
pm_genpd_poweroff_noirq
NULL
#define
genpd_poweroff_noirq
NULL
#define
pm_genpd_restore_noirq
NULL
#define
genpd_restore_noirq
NULL
#define
pm_
genpd_complete NULL
#define genpd_complete NULL
#endif
/* CONFIG_PM_SLEEP */
#endif
/* CONFIG_PM_SLEEP */
...
@@ -1237,7 +1326,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
...
@@ -1237,7 +1326,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
gpd_data
->
base
.
dev
=
dev
;
gpd_data
->
base
.
dev
=
dev
;
gpd_data
->
td
.
constraint_changed
=
true
;
gpd_data
->
td
.
constraint_changed
=
true
;
gpd_data
->
td
.
effective_constraint_ns
=
-
1
;
gpd_data
->
td
.
effective_constraint_ns
=
0
;
gpd_data
->
nb
.
notifier_call
=
genpd_dev_pm_qos_notifier
;
gpd_data
->
nb
.
notifier_call
=
genpd_dev_pm_qos_notifier
;
spin_lock_irq
(
&
dev
->
power
.
lock
);
spin_lock_irq
(
&
dev
->
power
.
lock
);
...
@@ -1572,14 +1661,14 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
...
@@ -1572,14 +1661,14 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
genpd
->
accounting_time
=
ktime_get
();
genpd
->
accounting_time
=
ktime_get
();
genpd
->
domain
.
ops
.
runtime_suspend
=
genpd_runtime_suspend
;
genpd
->
domain
.
ops
.
runtime_suspend
=
genpd_runtime_suspend
;
genpd
->
domain
.
ops
.
runtime_resume
=
genpd_runtime_resume
;
genpd
->
domain
.
ops
.
runtime_resume
=
genpd_runtime_resume
;
genpd
->
domain
.
ops
.
prepare
=
pm_
genpd_prepare
;
genpd
->
domain
.
ops
.
prepare
=
genpd_prepare
;
genpd
->
domain
.
ops
.
suspend_noirq
=
pm_
genpd_suspend_noirq
;
genpd
->
domain
.
ops
.
suspend_noirq
=
genpd_suspend_noirq
;
genpd
->
domain
.
ops
.
resume_noirq
=
pm_
genpd_resume_noirq
;
genpd
->
domain
.
ops
.
resume_noirq
=
genpd_resume_noirq
;
genpd
->
domain
.
ops
.
freeze_noirq
=
pm_
genpd_freeze_noirq
;
genpd
->
domain
.
ops
.
freeze_noirq
=
genpd_freeze_noirq
;
genpd
->
domain
.
ops
.
thaw_noirq
=
pm_
genpd_thaw_noirq
;
genpd
->
domain
.
ops
.
thaw_noirq
=
genpd_thaw_noirq
;
genpd
->
domain
.
ops
.
poweroff_noirq
=
pm_
genpd_poweroff_noirq
;
genpd
->
domain
.
ops
.
poweroff_noirq
=
genpd_poweroff_noirq
;
genpd
->
domain
.
ops
.
restore_noirq
=
pm_
genpd_restore_noirq
;
genpd
->
domain
.
ops
.
restore_noirq
=
genpd_restore_noirq
;
genpd
->
domain
.
ops
.
complete
=
pm_
genpd_complete
;
genpd
->
domain
.
ops
.
complete
=
genpd_complete
;
if
(
genpd
->
flags
&
GENPD_FLAG_PM_CLK
)
{
if
(
genpd
->
flags
&
GENPD_FLAG_PM_CLK
)
{
genpd
->
dev_ops
.
stop
=
pm_clk_suspend
;
genpd
->
dev_ops
.
stop
=
pm_clk_suspend
;
...
@@ -1793,7 +1882,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
...
@@ -1793,7 +1882,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
mutex_lock
(
&
gpd_list_lock
);
mutex_lock
(
&
gpd_list_lock
);
if
(
pm_
genpd_present
(
genpd
))
{
if
(
genpd_present
(
genpd
))
{
ret
=
genpd_add_provider
(
np
,
genpd_xlate_simple
,
genpd
);
ret
=
genpd_add_provider
(
np
,
genpd_xlate_simple
,
genpd
);
if
(
!
ret
)
{
if
(
!
ret
)
{
genpd
->
provider
=
&
np
->
fwnode
;
genpd
->
provider
=
&
np
->
fwnode
;
...
@@ -1829,7 +1918,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
...
@@ -1829,7 +1918,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
for
(
i
=
0
;
i
<
data
->
num_domains
;
i
++
)
{
for
(
i
=
0
;
i
<
data
->
num_domains
;
i
++
)
{
if
(
!
data
->
domains
[
i
])
if
(
!
data
->
domains
[
i
])
continue
;
continue
;
if
(
!
pm_
genpd_present
(
data
->
domains
[
i
]))
if
(
!
genpd_present
(
data
->
domains
[
i
]))
goto
error
;
goto
error
;
data
->
domains
[
i
]
->
provider
=
&
np
->
fwnode
;
data
->
domains
[
i
]
->
provider
=
&
np
->
fwnode
;
...
@@ -2272,7 +2361,7 @@ EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
...
@@ -2272,7 +2361,7 @@ EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/kobject.h>
static
struct
dentry
*
pm_
genpd_debugfs_dir
;
static
struct
dentry
*
genpd_debugfs_dir
;
/*
/*
* TODO: This function is a slightly modified version of rtpm_status_show
* TODO: This function is a slightly modified version of rtpm_status_show
...
@@ -2300,8 +2389,8 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev)
...
@@ -2300,8 +2389,8 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev)
seq_puts
(
s
,
p
);
seq_puts
(
s
,
p
);
}
}
static
int
pm_
genpd_summary_one
(
struct
seq_file
*
s
,
static
int
genpd_summary_one
(
struct
seq_file
*
s
,
struct
generic_pm_domain
*
genpd
)
struct
generic_pm_domain
*
genpd
)
{
{
static
const
char
*
const
status_lookup
[]
=
{
static
const
char
*
const
status_lookup
[]
=
{
[
GPD_STATE_ACTIVE
]
=
"on"
,
[
GPD_STATE_ACTIVE
]
=
"on"
,
...
@@ -2371,7 +2460,7 @@ static int genpd_summary_show(struct seq_file *s, void *data)
...
@@ -2371,7 +2460,7 @@ static int genpd_summary_show(struct seq_file *s, void *data)
return
-
ERESTARTSYS
;
return
-
ERESTARTSYS
;
list_for_each_entry
(
genpd
,
&
gpd_list
,
gpd_list_node
)
{
list_for_each_entry
(
genpd
,
&
gpd_list
,
gpd_list_node
)
{
ret
=
pm_
genpd_summary_one
(
s
,
genpd
);
ret
=
genpd_summary_one
(
s
,
genpd
);
if
(
ret
)
if
(
ret
)
break
;
break
;
}
}
...
@@ -2557,23 +2646,23 @@ define_genpd_debugfs_fops(active_time);
...
@@ -2557,23 +2646,23 @@ define_genpd_debugfs_fops(active_time);
define_genpd_debugfs_fops
(
total_idle_time
);
define_genpd_debugfs_fops
(
total_idle_time
);
define_genpd_debugfs_fops
(
devices
);
define_genpd_debugfs_fops
(
devices
);
static
int
__init
pm_
genpd_debug_init
(
void
)
static
int
__init
genpd_debug_init
(
void
)
{
{
struct
dentry
*
d
;
struct
dentry
*
d
;
struct
generic_pm_domain
*
genpd
;
struct
generic_pm_domain
*
genpd
;
pm_
genpd_debugfs_dir
=
debugfs_create_dir
(
"pm_genpd"
,
NULL
);
genpd_debugfs_dir
=
debugfs_create_dir
(
"pm_genpd"
,
NULL
);
if
(
!
pm_
genpd_debugfs_dir
)
if
(
!
genpd_debugfs_dir
)
return
-
ENOMEM
;
return
-
ENOMEM
;
d
=
debugfs_create_file
(
"pm_genpd_summary"
,
S_IRUGO
,
d
=
debugfs_create_file
(
"pm_genpd_summary"
,
S_IRUGO
,
pm_
genpd_debugfs_dir
,
NULL
,
&
genpd_summary_fops
);
genpd_debugfs_dir
,
NULL
,
&
genpd_summary_fops
);
if
(
!
d
)
if
(
!
d
)
return
-
ENOMEM
;
return
-
ENOMEM
;
list_for_each_entry
(
genpd
,
&
gpd_list
,
gpd_list_node
)
{
list_for_each_entry
(
genpd
,
&
gpd_list
,
gpd_list_node
)
{
d
=
debugfs_create_dir
(
genpd
->
name
,
pm_
genpd_debugfs_dir
);
d
=
debugfs_create_dir
(
genpd
->
name
,
genpd_debugfs_dir
);
if
(
!
d
)
if
(
!
d
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -2593,11 +2682,11 @@ static int __init pm_genpd_debug_init(void)
...
@@ -2593,11 +2682,11 @@ static int __init pm_genpd_debug_init(void)
return
0
;
return
0
;
}
}
late_initcall
(
pm_
genpd_debug_init
);
late_initcall
(
genpd_debug_init
);
static
void
__exit
pm_
genpd_debug_exit
(
void
)
static
void
__exit
genpd_debug_exit
(
void
)
{
{
debugfs_remove_recursive
(
pm_
genpd_debugfs_dir
);
debugfs_remove_recursive
(
genpd_debugfs_dir
);
}
}
__exitcall
(
pm_
genpd_debug_exit
);
__exitcall
(
genpd_debug_exit
);
#endif
/* CONFIG_DEBUG_FS */
#endif
/* CONFIG_DEBUG_FS */
drivers/base/power/domain_governor.c
View file @
31f18230
...
@@ -14,22 +14,33 @@
...
@@ -14,22 +14,33 @@
static
int
dev_update_qos_constraint
(
struct
device
*
dev
,
void
*
data
)
static
int
dev_update_qos_constraint
(
struct
device
*
dev
,
void
*
data
)
{
{
s64
*
constraint_ns_p
=
data
;
s64
*
constraint_ns_p
=
data
;
s
32
constraint_ns
=
-
1
;
s
64
constraint_ns
;
if
(
dev
->
power
.
subsys_data
&&
dev
->
power
.
subsys_data
->
domain_data
)
if
(
dev
->
power
.
subsys_data
&&
dev
->
power
.
subsys_data
->
domain_data
)
{
/*
* Only take suspend-time QoS constraints of devices into
* account, because constraints updated after the device has
* been suspended are not guaranteed to be taken into account
* anyway. In order for them to take effect, the device has to
* be resumed and suspended again.
*/
constraint_ns
=
dev_gpd_data
(
dev
)
->
td
.
effective_constraint_ns
;
constraint_ns
=
dev_gpd_data
(
dev
)
->
td
.
effective_constraint_ns
;
}
else
{
if
(
constraint_ns
<
0
)
{
/*
* The child is not in a domain and there's no info on its
* suspend/resume latencies, so assume them to be negligible and
* take its current PM QoS constraint (that's the only thing
* known at this point anyway).
*/
constraint_ns
=
dev_pm_qos_read_value
(
dev
);
constraint_ns
=
dev_pm_qos_read_value
(
dev
);
constraint_ns
*=
NSEC_PER_USEC
;
if
(
constraint_ns
>
0
)
constraint_ns
*=
NSEC_PER_USEC
;
}
}
/* 0 means "no constraint" */
if
(
constraint_ns
==
0
)
if
(
constraint_ns
==
0
)
return
0
;
return
0
;
/*
* constraint_ns cannot be negative here, because the device has been
* suspended.
*/
if
(
constraint_ns
<
*
constraint_ns_p
||
*
constraint_ns_p
==
0
)
if
(
constraint_ns
<
*
constraint_ns_p
||
*
constraint_ns_p
==
0
)
*
constraint_ns_p
=
constraint_ns
;
*
constraint_ns_p
=
constraint_ns
;
...
@@ -76,14 +87,32 @@ static bool default_suspend_ok(struct device *dev)
...
@@ -76,14 +87,32 @@ static bool default_suspend_ok(struct device *dev)
device_for_each_child
(
dev
,
&
constraint_ns
,
device_for_each_child
(
dev
,
&
constraint_ns
,
dev_update_qos_constraint
);
dev_update_qos_constraint
);
if
(
constraint_ns
>
0
)
{
if
(
constraint_ns
==
0
)
{
/* "No restriction", so the device is allowed to suspend. */
td
->
effective_constraint_ns
=
0
;
td
->
cached_suspend_ok
=
true
;
}
else
if
(
constraint_ns
<
0
)
{
/*
* This triggers if one of the children that don't belong to a
* domain has a negative PM QoS constraint and it's better not
* to suspend then. effective_constraint_ns is negative already
* and cached_suspend_ok is false, so bail out.
*/
return
false
;
}
else
{
constraint_ns
-=
td
->
suspend_latency_ns
+
constraint_ns
-=
td
->
suspend_latency_ns
+
td
->
resume_latency_ns
;
td
->
resume_latency_ns
;
if
(
constraint_ns
==
0
)
/*
* effective_constraint_ns is negative already and
* cached_suspend_ok is false, so if the computed value is not
* positive, return right away.
*/
if
(
constraint_ns
<=
0
)
return
false
;
return
false
;
td
->
effective_constraint_ns
=
constraint_ns
;
td
->
cached_suspend_ok
=
true
;
}
}
td
->
effective_constraint_ns
=
constraint_ns
;
td
->
cached_suspend_ok
=
constraint_ns
>=
0
;
/*
/*
* The children have been suspended already, so we don't need to take
* The children have been suspended already, so we don't need to take
...
@@ -144,18 +173,16 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
...
@@ -144,18 +173,16 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
*/
*/
td
=
&
to_gpd_data
(
pdd
)
->
td
;
td
=
&
to_gpd_data
(
pdd
)
->
td
;
constraint_ns
=
td
->
effective_constraint_ns
;
constraint_ns
=
td
->
effective_constraint_ns
;
/* default_suspend_ok() need not be called before us. */
/*
if
(
constraint_ns
<
0
)
{
* Negative values mean "no suspend at all" and this runs only
constraint_ns
=
dev_pm_qos_read_value
(
pdd
->
dev
);
* when all devices in the domain are suspended, so it must be
constraint_ns
*=
NSEC_PER_USEC
;
* 0 at least.
}
*
* 0 means "no constraint"
*/
if
(
constraint_ns
==
0
)
if
(
constraint_ns
==
0
)
continue
;
continue
;
/*
* constraint_ns cannot be negative here, because the device has
* been suspended.
*/
if
(
constraint_ns
<=
off_on_time_ns
)
if
(
constraint_ns
<=
off_on_time_ns
)
return
false
;
return
false
;
...
...
drivers/soc/mediatek/mtk-scpsys.c
View file @
31f18230
...
@@ -361,17 +361,6 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
...
@@ -361,17 +361,6 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
return
ret
;
return
ret
;
}
}
static
bool
scpsys_active_wakeup
(
struct
device
*
dev
)
{
struct
generic_pm_domain
*
genpd
;
struct
scp_domain
*
scpd
;
genpd
=
pd_to_genpd
(
dev
->
pm_domain
);
scpd
=
container_of
(
genpd
,
struct
scp_domain
,
genpd
);
return
scpd
->
data
->
active_wakeup
;
}
static
void
init_clks
(
struct
platform_device
*
pdev
,
struct
clk
**
clk
)
static
void
init_clks
(
struct
platform_device
*
pdev
,
struct
clk
**
clk
)
{
{
int
i
;
int
i
;
...
@@ -466,7 +455,8 @@ static struct scp *init_scp(struct platform_device *pdev,
...
@@ -466,7 +455,8 @@ static struct scp *init_scp(struct platform_device *pdev,
genpd
->
name
=
data
->
name
;
genpd
->
name
=
data
->
name
;
genpd
->
power_off
=
scpsys_power_off
;
genpd
->
power_off
=
scpsys_power_off
;
genpd
->
power_on
=
scpsys_power_on
;
genpd
->
power_on
=
scpsys_power_on
;
genpd
->
dev_ops
.
active_wakeup
=
scpsys_active_wakeup
;
if
(
scpd
->
data
->
active_wakeup
)
genpd
->
flags
|=
GENPD_FLAG_ACTIVE_WAKEUP
;
}
}
return
scp
;
return
scp
;
...
...
drivers/soc/rockchip/pm_domains.c
View file @
31f18230
...
@@ -358,17 +358,6 @@ static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
...
@@ -358,17 +358,6 @@ static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
pm_clk_destroy
(
dev
);
pm_clk_destroy
(
dev
);
}
}
static
bool
rockchip_active_wakeup
(
struct
device
*
dev
)
{
struct
generic_pm_domain
*
genpd
;
struct
rockchip_pm_domain
*
pd
;
genpd
=
pd_to_genpd
(
dev
->
pm_domain
);
pd
=
container_of
(
genpd
,
struct
rockchip_pm_domain
,
genpd
);
return
pd
->
info
->
active_wakeup
;
}
static
int
rockchip_pm_add_one_domain
(
struct
rockchip_pmu
*
pmu
,
static
int
rockchip_pm_add_one_domain
(
struct
rockchip_pmu
*
pmu
,
struct
device_node
*
node
)
struct
device_node
*
node
)
{
{
...
@@ -489,8 +478,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
...
@@ -489,8 +478,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
pd
->
genpd
.
power_on
=
rockchip_pd_power_on
;
pd
->
genpd
.
power_on
=
rockchip_pd_power_on
;
pd
->
genpd
.
attach_dev
=
rockchip_pd_attach_dev
;
pd
->
genpd
.
attach_dev
=
rockchip_pd_attach_dev
;
pd
->
genpd
.
detach_dev
=
rockchip_pd_detach_dev
;
pd
->
genpd
.
detach_dev
=
rockchip_pd_detach_dev
;
pd
->
genpd
.
dev_ops
.
active_wakeup
=
rockchip_active_wakeup
;
pd
->
genpd
.
flags
=
GENPD_FLAG_PM_CLK
;
pd
->
genpd
.
flags
=
GENPD_FLAG_PM_CLK
;
if
(
pd_info
->
active_wakeup
)
pd
->
genpd
.
flags
|=
GENPD_FLAG_ACTIVE_WAKEUP
;
pm_genpd_init
(
&
pd
->
genpd
,
NULL
,
false
);
pm_genpd_init
(
&
pd
->
genpd
,
NULL
,
false
);
pmu
->
genpd_data
.
domains
[
id
]
=
&
pd
->
genpd
;
pmu
->
genpd_data
.
domains
[
id
]
=
&
pd
->
genpd
;
...
...
include/linux/pm_domain.h
View file @
31f18230
...
@@ -18,9 +18,10 @@
...
@@ -18,9 +18,10 @@
#include <linux/spinlock.h>
#include <linux/spinlock.h>
/* Defines used for the flags field in the struct generic_pm_domain */
/* Defines used for the flags field in the struct generic_pm_domain */
#define GENPD_FLAG_PM_CLK (1U << 0)
/* PM domain uses PM clk */
#define GENPD_FLAG_PM_CLK (1U << 0)
/* PM domain uses PM clk */
#define GENPD_FLAG_IRQ_SAFE (1U << 1)
/* PM domain operates in atomic */
#define GENPD_FLAG_IRQ_SAFE (1U << 1)
/* PM domain operates in atomic */
#define GENPD_FLAG_ALWAYS_ON (1U << 2)
/* PM domain is always powered on */
#define GENPD_FLAG_ALWAYS_ON (1U << 2)
/* PM domain is always powered on */
#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3)
/* Keep devices active if wakeup */
enum
gpd_status
{
enum
gpd_status
{
GPD_STATE_ACTIVE
=
0
,
/* PM domain is active */
GPD_STATE_ACTIVE
=
0
,
/* PM domain is active */
...
@@ -35,7 +36,6 @@ struct dev_power_governor {
...
@@ -35,7 +36,6 @@ struct dev_power_governor {
struct
gpd_dev_ops
{
struct
gpd_dev_ops
{
int
(
*
start
)(
struct
device
*
dev
);
int
(
*
start
)(
struct
device
*
dev
);
int
(
*
stop
)(
struct
device
*
dev
);
int
(
*
stop
)(
struct
device
*
dev
);
bool
(
*
active_wakeup
)(
struct
device
*
dev
);
};
};
struct
genpd_power_state
{
struct
genpd_power_state
{
...
@@ -64,8 +64,11 @@ struct generic_pm_domain {
...
@@ -64,8 +64,11 @@ struct generic_pm_domain {
unsigned
int
device_count
;
/* Number of devices */
unsigned
int
device_count
;
/* Number of devices */
unsigned
int
suspended_count
;
/* System suspend device counter */
unsigned
int
suspended_count
;
/* System suspend device counter */
unsigned
int
prepared_count
;
/* Suspend counter of prepared devices */
unsigned
int
prepared_count
;
/* Suspend counter of prepared devices */
unsigned
int
performance_state
;
/* Aggregated max performance state */
int
(
*
power_off
)(
struct
generic_pm_domain
*
domain
);
int
(
*
power_off
)(
struct
generic_pm_domain
*
domain
);
int
(
*
power_on
)(
struct
generic_pm_domain
*
domain
);
int
(
*
power_on
)(
struct
generic_pm_domain
*
domain
);
int
(
*
set_performance_state
)(
struct
generic_pm_domain
*
genpd
,
unsigned
int
state
);
struct
gpd_dev_ops
dev_ops
;
struct
gpd_dev_ops
dev_ops
;
s64
max_off_time_ns
;
/* Maximum allowed "suspended" time. */
s64
max_off_time_ns
;
/* Maximum allowed "suspended" time. */
bool
max_off_time_changed
;
bool
max_off_time_changed
;
...
@@ -121,6 +124,7 @@ struct generic_pm_domain_data {
...
@@ -121,6 +124,7 @@ struct generic_pm_domain_data {
struct
pm_domain_data
base
;
struct
pm_domain_data
base
;
struct
gpd_timing_data
td
;
struct
gpd_timing_data
td
;
struct
notifier_block
nb
;
struct
notifier_block
nb
;
unsigned
int
performance_state
;
void
*
data
;
void
*
data
;
};
};
...
@@ -148,6 +152,8 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
...
@@ -148,6 +152,8 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
extern
int
pm_genpd_init
(
struct
generic_pm_domain
*
genpd
,
extern
int
pm_genpd_init
(
struct
generic_pm_domain
*
genpd
,
struct
dev_power_governor
*
gov
,
bool
is_off
);
struct
dev_power_governor
*
gov
,
bool
is_off
);
extern
int
pm_genpd_remove
(
struct
generic_pm_domain
*
genpd
);
extern
int
pm_genpd_remove
(
struct
generic_pm_domain
*
genpd
);
extern
int
dev_pm_genpd_set_performance_state
(
struct
device
*
dev
,
unsigned
int
state
);
extern
struct
dev_power_governor
simple_qos_governor
;
extern
struct
dev_power_governor
simple_qos_governor
;
extern
struct
dev_power_governor
pm_domain_always_on_gov
;
extern
struct
dev_power_governor
pm_domain_always_on_gov
;
...
@@ -188,6 +194,12 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
...
@@ -188,6 +194,12 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
return
-
ENOTSUPP
;
return
-
ENOTSUPP
;
}
}
static
inline
int
dev_pm_genpd_set_performance_state
(
struct
device
*
dev
,
unsigned
int
state
)
{
return
-
ENOTSUPP
;
}
#define simple_qos_governor (*(struct dev_power_governor *)(NULL))
#define simple_qos_governor (*(struct dev_power_governor *)(NULL))
#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
#endif
#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