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
0ed4513c
Commit
0ed4513c
authored
Jul 04, 2019
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/coupled' into regulator-next
parents
65244e5b
d22b85a1
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
287 additions
and
75 deletions
+287
-75
drivers/regulator/core.c
drivers/regulator/core.c
+143
-51
drivers/regulator/of_regulator.c
drivers/regulator/of_regulator.c
+43
-20
include/linux/regulator/coupler.h
include/linux/regulator/coupler.h
+97
-0
include/linux/regulator/driver.h
include/linux/regulator/driver.h
+3
-3
include/linux/regulator/machine.h
include/linux/regulator/machine.h
+1
-1
No files found.
drivers/regulator/core.c
View file @
0ed4513c
This diff is collapsed.
Click to expand it.
drivers/regulator/of_regulator.c
View file @
0ed4513c
...
...
@@ -21,7 +21,8 @@ static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
[
PM_SUSPEND_MAX
]
=
"regulator-state-disk"
,
};
static
void
of_get_regulation_constraints
(
struct
device_node
*
np
,
static
int
of_get_regulation_constraints
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
regulator_init_data
**
init_data
,
const
struct
regulator_desc
*
desc
)
{
...
...
@@ -30,8 +31,13 @@ static void of_get_regulation_constraints(struct device_node *np,
struct
device_node
*
suspend_np
;
unsigned
int
mode
;
int
ret
,
i
,
len
;
int
n_phandles
;
u32
pval
;
n_phandles
=
of_count_phandle_with_args
(
np
,
"regulator-coupled-with"
,
NULL
);
n_phandles
=
max
(
n_phandles
,
0
);
constraints
->
name
=
of_get_property
(
np
,
"regulator-name"
,
NULL
);
if
(
!
of_property_read_u32
(
np
,
"regulator-min-microvolt"
,
&
pval
))
...
...
@@ -163,9 +169,17 @@ static void of_get_regulation_constraints(struct device_node *np,
if
(
!
of_property_read_u32
(
np
,
"regulator-system-load"
,
&
pval
))
constraints
->
system_load
=
pval
;
if
(
!
of_property_read_u32
(
np
,
"regulator-coupled-max-spread"
,
&
pval
))
constraints
->
max_spread
=
pval
;
if
(
n_phandles
)
{
constraints
->
max_spread
=
devm_kzalloc
(
dev
,
sizeof
(
*
constraints
->
max_spread
)
*
n_phandles
,
GFP_KERNEL
);
if
(
!
constraints
->
max_spread
)
return
-
ENOMEM
;
of_property_read_u32_array
(
np
,
"regulator-coupled-max-spread"
,
constraints
->
max_spread
,
n_phandles
);
}
if
(
!
of_property_read_u32
(
np
,
"regulator-max-step-microvolt"
,
&
pval
))
...
...
@@ -242,6 +256,8 @@ static void of_get_regulation_constraints(struct device_node *np,
suspend_state
=
NULL
;
suspend_np
=
NULL
;
}
return
0
;
}
/**
...
...
@@ -267,7 +283,9 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
if
(
!
init_data
)
return
NULL
;
/* Out of memory? */
of_get_regulation_constraints
(
node
,
&
init_data
,
desc
);
if
(
of_get_regulation_constraints
(
dev
,
node
,
&
init_data
,
desc
))
return
NULL
;
return
init_data
;
}
EXPORT_SYMBOL_GPL
(
of_get_regulator_init_data
);
...
...
@@ -473,7 +491,8 @@ int of_get_n_coupled(struct regulator_dev *rdev)
/* Looks for "to_find" device_node in src's "regulator-coupled-with" property */
static
bool
of_coupling_find_node
(
struct
device_node
*
src
,
struct
device_node
*
to_find
)
struct
device_node
*
to_find
,
int
*
index
)
{
int
n_phandles
,
i
;
bool
found
=
false
;
...
...
@@ -495,8 +514,10 @@ static bool of_coupling_find_node(struct device_node *src,
of_node_put
(
tmp
);
if
(
found
)
if
(
found
)
{
*
index
=
i
;
break
;
}
}
return
found
;
...
...
@@ -517,22 +538,23 @@ static bool of_coupling_find_node(struct device_node *src,
*/
bool
of_check_coupling_data
(
struct
regulator_dev
*
rdev
)
{
int
max_spread
=
rdev
->
constraints
->
max_spread
;
struct
device_node
*
node
=
rdev
->
dev
.
of_node
;
int
n_phandles
=
of_get_n_coupled
(
rdev
);
struct
device_node
*
c_node
;
int
index
;
int
i
;
bool
ret
=
true
;
if
(
max_spread
<=
0
)
{
dev_err
(
&
rdev
->
dev
,
"max_spread value invalid
\n
"
);
return
false
;
}
/* iterate over rdev's phandles */
for
(
i
=
0
;
i
<
n_phandles
;
i
++
)
{
int
max_spread
=
rdev
->
constraints
->
max_spread
[
i
];
int
c_max_spread
,
c_n_phandles
;
if
(
max_spread
<=
0
)
{
dev_err
(
&
rdev
->
dev
,
"max_spread value invalid
\n
"
);
return
false
;
}
c_node
=
of_parse_phandle
(
node
,
"regulator-coupled-with"
,
i
);
...
...
@@ -549,22 +571,23 @@ bool of_check_coupling_data(struct regulator_dev *rdev)
goto
clean
;
}
if
(
of_property_read_u32
(
c_node
,
"regulator-coupled-max-spread"
,
&
c_max_spread
))
{
if
(
!
of_coupling_find_node
(
c_node
,
node
,
&
index
))
{
dev_err
(
&
rdev
->
dev
,
"missing 2-way linking for coupled regulators
\n
"
);
ret
=
false
;
goto
clean
;
}
if
(
c_max_spread
!=
max_spread
)
{
dev_err
(
&
rdev
->
dev
,
"coupled regulators max_spread mismatch
\n
"
);
if
(
of_property_read_u32_index
(
c_node
,
"regulator-coupled-max-spread"
,
index
,
&
c_max_spread
))
{
ret
=
false
;
goto
clean
;
}
if
(
!
of_coupling_find_node
(
c_node
,
node
))
{
dev_err
(
&
rdev
->
dev
,
"missing 2-way linking for coupled regulators
\n
"
);
if
(
c_max_spread
!=
max_spread
)
{
dev_err
(
&
rdev
->
dev
,
"coupled regulators max_spread mismatch
\n
"
);
ret
=
false
;
goto
clean
;
}
clean:
...
...
include/linux/regulator/coupler.h
0 → 100644
View file @
0ed4513c
/* SPDX-License-Identifier: GPL-2.0 */
/*
* coupler.h -- SoC Regulator support, coupler API.
*
* Regulator Coupler Interface.
*/
#ifndef __LINUX_REGULATOR_COUPLER_H_
#define __LINUX_REGULATOR_COUPLER_H_
#include <linux/kernel.h>
#include <linux/suspend.h>
struct
regulator_coupler
;
struct
regulator_dev
;
/**
* struct regulator_coupler - customized regulator's coupler
*
* Regulator's coupler allows to customize coupling algorithm.
*
* @list: couplers list entry
* @attach_regulator: Callback invoked on creation of a coupled regulator,
* couples are unresolved at this point. The callee should
* check that it could handle the regulator and return 0 on
* success, -errno on failure and 1 if given regulator is
* not suitable for this coupler (case of having multiple
* regulators in a system). Callback shall be implemented.
* @detach_regulator: Callback invoked on destruction of a coupled regulator.
* This callback is optional and could be NULL.
* @balance_voltage: Callback invoked when voltage of a coupled regulator is
* changing. Called with all of the coupled rdev's being held
* under "consumer lock". The callee should perform voltage
* balancing, changing voltage of the coupled regulators as
* needed. It's up to the coupler to verify the voltage
* before changing it in hardware, i.e. coupler should
* check consumer's min/max and etc. This callback is
* optional and could be NULL, in which case a generic
* voltage balancer will be used.
*/
struct
regulator_coupler
{
struct
list_head
list
;
int
(
*
attach_regulator
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
);
int
(
*
detach_regulator
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
);
int
(
*
balance_voltage
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
,
suspend_state_t
state
);
};
#ifdef CONFIG_REGULATOR
int
regulator_coupler_register
(
struct
regulator_coupler
*
coupler
);
const
char
*
rdev_get_name
(
struct
regulator_dev
*
rdev
);
int
regulator_check_consumers
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
,
suspend_state_t
state
);
int
regulator_check_voltage
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
);
int
regulator_get_voltage_rdev
(
struct
regulator_dev
*
rdev
);
int
regulator_set_voltage_rdev
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
suspend_state_t
state
);
#else
static
inline
int
regulator_coupler_register
(
struct
regulator_coupler
*
coupler
)
{
return
0
;
}
static
inline
const
char
*
rdev_get_name
(
struct
regulator_dev
*
rdev
)
{
return
NULL
;
}
static
inline
int
regulator_check_consumers
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
,
suspend_state_t
state
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_check_voltage
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_get_voltage_rdev
(
struct
regulator_dev
*
rdev
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_set_voltage_rdev
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
suspend_state_t
state
)
{
return
-
EINVAL
;
}
#endif
#endif
include/linux/regulator/driver.h
View file @
0ed4513c
...
...
@@ -12,8 +12,6 @@
#ifndef __LINUX_REGULATOR_DRIVER_H_
#define __LINUX_REGULATOR_DRIVER_H_
#define MAX_COUPLED 2
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
...
...
@@ -429,7 +427,8 @@ struct regulator_config {
* incremented.
*/
struct
coupling_desc
{
struct
regulator_dev
*
coupled_rdevs
[
MAX_COUPLED
];
struct
regulator_dev
**
coupled_rdevs
;
struct
regulator_coupler
*
coupler
;
int
n_resolved
;
int
n_coupled
;
};
...
...
@@ -555,4 +554,5 @@ void regulator_unlock(struct regulator_dev *rdev);
*/
int
regulator_desc_list_voltage_linear_range
(
const
struct
regulator_desc
*
desc
,
unsigned
int
selector
);
#endif
include/linux/regulator/machine.h
View file @
0ed4513c
...
...
@@ -153,7 +153,7 @@ struct regulation_constraints {
int
system_load
;
/* used for coupled regulators */
int
max_spread
;
u32
*
max_spread
;
/* used for changing voltage in steps */
int
max_uV_step
;
...
...
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