You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'regulator-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: "Quite a lot of core work this time around, though not 100% successful. We gained support for runtime mode changes thanks to David Collins and improved support for write only regulators (ones where we can't read back the configuration) from Douglas Anderson. There's been quite a bit of work from Linus Walleij on converting from specfying GPIOs by numbers to descriptors. Sadly the testing turned out to be less good than we had hoped and so a lot of this had to be reverted. We also have the start of updates to use coupled regulators from Maciej Purski, unfortunately there are further problems there so the last couple of patches have been reverted. We also have new drivers for BD71837 and SY8106A devices, SAW regulators on Qualcomm SPMI and dropped support for some preproduction chips that never made it to market from the AB8500 driver" * tag 'regulator-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (57 commits) regulator: gpio: Revert ARM: pxa, regulator: fix building ezx e680 regulator: Revert coupled regulator support again regulator: wm8994: Fix shared GPIOs regulator: max77686: Fix shared GPIOs regulator: bd71837: BD71837 PMIC regulator driver regulator: bd71837: Devicetree bindings for BD71837 regulators regulator: gpio: Get enable GPIO using GPIO descriptor regulator: fixed: Convert to use GPIO descriptor only regulator: s2mps11: Fix boot on Odroid XU3 dt-bindings: qcom_spmi: Document SAW support regulator: qcom_spmi: Add support for SAW regulator: tps65090: Pass descriptor instead of GPIO number regulator: s5m8767: Pass descriptor instead of GPIO number regulator: pfuze100: Delete reference to ena_gpio regulator: max8952: Pass descriptor instead of GPIO number regulator: lp8788-ldo: Pass descriptor instead of GPIO number regulator: lm363x: Pass descriptor instead of GPIO number regulator: max8973: Pass descriptor instead of GPIO number regulator: mc13xxx-core: Switch to SPDX identifier ...
This commit is contained in:
@@ -43,7 +43,7 @@ Optional properties:
|
||||
regulator to drive the OTG VBus, rather then
|
||||
as an input pin which signals whether the
|
||||
board is driving OTG VBus or not.
|
||||
(axp221 / axp223 / axp813 only)
|
||||
(axp221 / axp223 / axp803/ axp813 only)
|
||||
|
||||
- x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is
|
||||
wired for master mode. The default is slave mode.
|
||||
@@ -132,6 +132,7 @@ FLDO2 : LDO : fldoin-supply : shared supply
|
||||
LDO_IO0 : LDO : ips-supply : GPIO 0
|
||||
LDO_IO1 : LDO : ips-supply : GPIO 1
|
||||
RTC_LDO : LDO : ips-supply : always on
|
||||
DRIVEVBUS : Enable output : drivevbus-supply : external regulator
|
||||
|
||||
AXP806 regulators, type, and corresponding input supply names:
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ Required properties:
|
||||
Each child node is defined using the standard
|
||||
binding for regulators.
|
||||
|
||||
Optional properties:
|
||||
- rohm,ddr-backup-power : Value to use for DDR-Backup Power (default 0).
|
||||
This is a bitmask that specifies which DDR power
|
||||
rails need to be kept powered when backup mode is
|
||||
entered, for system suspend:
|
||||
- bit 0: DDR0
|
||||
- bit 1: DDR1
|
||||
- bit 2: DDR0C
|
||||
- bit 3: DDR1C
|
||||
These bits match the KEEPON_DDR* bits in the
|
||||
documentation for the "BKUP Mode Cnt" register.
|
||||
- rohm,rstbmode-level: The RSTB signal is configured for level mode, to
|
||||
accommodate a toggle power switch (the RSTBMODE pin is
|
||||
strapped low).
|
||||
- rohm,rstbmode-pulse: The RSTB signal is configured for pulse mode, to
|
||||
accommodate a momentary power switch (the RSTBMODE pin
|
||||
is strapped high).
|
||||
The two properties above are mutually exclusive.
|
||||
|
||||
Example:
|
||||
|
||||
pmic: pmic@30 {
|
||||
@@ -36,6 +55,8 @@ Example:
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
rohm,ddr-backup-power = <0xf>;
|
||||
rohm,rstbmode-pulse;
|
||||
|
||||
regulators {
|
||||
dvfs: dvfs {
|
||||
|
||||
@@ -21,7 +21,7 @@ Each regulator is defined using the standard binding for regulators.
|
||||
|
||||
Example 1: PFUZE100
|
||||
|
||||
pmic: pfuze100@8 {
|
||||
pfuze100: pmic@8 {
|
||||
compatible = "fsl,pfuze100";
|
||||
reg = <0x08>;
|
||||
|
||||
@@ -122,7 +122,7 @@ Example 1: PFUZE100
|
||||
|
||||
Example 2: PFUZE200
|
||||
|
||||
pmic: pfuze200@8 {
|
||||
pfuze200: pmic@8 {
|
||||
compatible = "fsl,pfuze200";
|
||||
reg = <0x08>;
|
||||
|
||||
@@ -216,7 +216,7 @@ Example 2: PFUZE200
|
||||
|
||||
Example 3: PFUZE3000
|
||||
|
||||
pmic: pfuze3000@8 {
|
||||
pfuze3000: pmic@8 {
|
||||
compatible = "fsl,pfuze3000";
|
||||
reg = <0x08>;
|
||||
|
||||
|
||||
@@ -110,6 +110,11 @@ Qualcomm SPMI Regulators
|
||||
Definition: Reference to regulator supplying the input pin, as
|
||||
described in the data sheet.
|
||||
|
||||
- qcom,saw-reg:
|
||||
Usage: optional
|
||||
Value type: <phandle>
|
||||
Description: Reference to syscon node defining the SAW registers.
|
||||
|
||||
|
||||
The regulator node houses sub-nodes for each regulator within the device. Each
|
||||
sub-node is identified using the node's name, with valid values listed for each
|
||||
@@ -201,6 +206,17 @@ see regulator.txt - with additional custom properties described below:
|
||||
2 = 0.55 uA
|
||||
3 = 0.75 uA
|
||||
|
||||
- qcom,saw-slave:
|
||||
Usage: optional
|
||||
Value type: <boo>
|
||||
Description: SAW controlled gang slave. Will not be configured.
|
||||
|
||||
- qcom,saw-leader:
|
||||
Usage: optional
|
||||
Value type: <boo>
|
||||
Description: SAW controlled gang leader. Will be configured as
|
||||
SAW regulator.
|
||||
|
||||
Example:
|
||||
|
||||
regulators {
|
||||
@@ -221,3 +237,32 @@ Example:
|
||||
|
||||
....
|
||||
};
|
||||
|
||||
Example 2:
|
||||
|
||||
saw3: syscon@9A10000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x9A10000 0x1000>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
spm-regulators {
|
||||
compatible = "qcom,pm8994-regulators";
|
||||
qcom,saw-reg = <&saw3>;
|
||||
s8 {
|
||||
qcom,saw-slave;
|
||||
};
|
||||
s9 {
|
||||
qcom,saw-slave;
|
||||
};
|
||||
s10 {
|
||||
qcom,saw-slave;
|
||||
};
|
||||
pm8994_s11_saw: s11 {
|
||||
qcom,saw-leader;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1140000>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -59,6 +59,11 @@ Optional properties:
|
||||
- regulator-initial-mode: initial operating mode. The set of possible operating
|
||||
modes depends on the capabilities of every hardware so each device binding
|
||||
documentation explains which values the regulator supports.
|
||||
- regulator-allowed-modes: list of operating modes that software is allowed to
|
||||
configure for the regulator at run-time. Elements may be specified in any
|
||||
order. The set of possible operating modes depends on the capabilities of
|
||||
every hardware so each device binding document explains which values the
|
||||
regulator supports.
|
||||
- regulator-system-load: Load in uA present on regulator that is not captured by
|
||||
any consumer request.
|
||||
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
|
||||
@@ -68,6 +73,11 @@ Optional properties:
|
||||
0: Disable active discharge.
|
||||
1: Enable active discharge.
|
||||
Absence of this property will leave configuration to default.
|
||||
- regulator-coupled-with: Regulators with which the regulator
|
||||
is coupled. The linkage is 2-way - all coupled regulators should be linked
|
||||
with each other. A regulator should not be coupled with its supplier.
|
||||
- regulator-coupled-max-spread: Max spread between voltages of coupled regulators
|
||||
in microvolts.
|
||||
|
||||
Deprecated properties:
|
||||
- regulator-compatible: If a regulator chip contains multiple
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
ROHM BD71837 Power Management Integrated Circuit (PMIC) regulator bindings
|
||||
|
||||
BD71837MWV is a programmable Power Management
|
||||
IC (PMIC) for powering single-core, dual-core, and
|
||||
quad-core SoC’s such as NXP-i.MX 8M. It is optimized
|
||||
for low BOM cost and compact solution footprint. It
|
||||
integrates 8 Buck regulators and 7 LDO’s to provide all
|
||||
the power rails required by the SoC and the commonly
|
||||
used peripherals.
|
||||
|
||||
Required properties:
|
||||
- regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7"
|
||||
|
||||
List of regulators provided by this controller. BD71837 regulators node
|
||||
should be sub node of the BD71837 MFD node. See BD71837 MFD bindings at
|
||||
Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
|
||||
Regulator nodes should be named to BUCK_<number> and LDO_<number>. The
|
||||
definition for each of these nodes is defined using the standard
|
||||
binding for regulators at
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
Note that if BD71837 starts at RUN state you probably want to use
|
||||
regulator-boot-on at least for BUCK6 and BUCK7 so that those are not
|
||||
disabled by driver at startup. LDO5 and LDO6 are supplied by those and
|
||||
if they are disabled at startup the voltage monitoring for LDO5/LDO6 will
|
||||
cause PMIC to reset.
|
||||
|
||||
The valid names for regulator nodes are:
|
||||
BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7, BUCK8
|
||||
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
|
||||
|
||||
Optional properties:
|
||||
- Any optional property defined in bindings/regulator/regulator.txt
|
||||
|
||||
Example:
|
||||
regulators {
|
||||
buck1: BUCK1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
};
|
||||
buck2: BUCK2 {
|
||||
regulator-name = "buck2";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
};
|
||||
buck3: BUCK3 {
|
||||
regulator-name = "buck3";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck4: BUCK4 {
|
||||
regulator-name = "buck4";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck5: BUCK5 {
|
||||
regulator-name = "buck5";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck6: BUCK6 {
|
||||
regulator-name = "buck6";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck7: BUCK7 {
|
||||
regulator-name = "buck7";
|
||||
regulator-min-microvolt = <1605000>;
|
||||
regulator-max-microvolt = <1995000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck8: BUCK8 {
|
||||
regulator-name = "buck8";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
};
|
||||
|
||||
ldo1: LDO1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
ldo2: LDO2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <900000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
ldo3: LDO3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
ldo4: LDO4 {
|
||||
regulator-name = "ldo4";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
ldo5: LDO5 {
|
||||
regulator-name = "ldo5";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
ldo6: LDO6 {
|
||||
regulator-name = "ldo6";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
ldo7_reg: LDO7 {
|
||||
regulator-name = "ldo7";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
SY8106A Voltage regulator
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "silergy,sy8106a"
|
||||
- reg: I2C slave address - must be <0x65>
|
||||
- silergy,fixed-microvolt - the voltage when I2C regulating is disabled (set
|
||||
by external resistor like a fixed voltage)
|
||||
|
||||
Any property defined as part of the core regulator binding, defined in
|
||||
./regulator.txt, can also be used.
|
||||
|
||||
Example:
|
||||
|
||||
sy8106a {
|
||||
compatible = "silergy,sy8106a";
|
||||
reg = <0x65>;
|
||||
regulator-name = "sy8106a-vdd";
|
||||
silergy,fixed-microvolt = <1200000>;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
@@ -13609,6 +13609,12 @@ S: Supported
|
||||
F: net/switchdev/
|
||||
F: include/net/switchdev.h
|
||||
|
||||
SY8106A REGULATOR DRIVER
|
||||
M: Icenowy Zheng <icenowy@aosc.io>
|
||||
S: Maintained
|
||||
F: drivers/regulator/sy8106a-regulator.c
|
||||
F: Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
|
||||
|
||||
SYNC FILE FRAMEWORK
|
||||
M: Sumit Semwal <sumit.semwal@linaro.org>
|
||||
R: Gustavo Padovan <gustavo@padovan.org>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
|
||||
#include <linux/mfd/wm831x/irq.h>
|
||||
#include <linux/mfd/wm831x/gpio.h>
|
||||
@@ -206,9 +207,6 @@ static const struct i2c_board_info wm1277_devs[] = {
|
||||
};
|
||||
|
||||
static struct arizona_pdata wm5102_reva_pdata = {
|
||||
.ldo1 = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
},
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
.irq_flags = IRQF_TRIGGER_HIGH,
|
||||
.micd_pol_gpio = CODEC_GPIO_BASE + 4,
|
||||
@@ -237,10 +235,16 @@ static struct spi_board_info wm5102_reva_spi_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct arizona_pdata wm5102_pdata = {
|
||||
.ldo1 = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
static struct gpiod_lookup_table wm5102_reva_gpiod_table = {
|
||||
.dev_id = "spi0.1", /* SPI device name */
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 7,
|
||||
"wlf,ldoena", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct arizona_pdata wm5102_pdata = {
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
.irq_flags = IRQF_TRIGGER_HIGH,
|
||||
.micd_pol_gpio = CODEC_GPIO_BASE + 2,
|
||||
@@ -264,6 +268,15 @@ static struct spi_board_info wm5102_spi_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table wm5102_gpiod_table = {
|
||||
.dev_id = "spi0.1", /* SPI device name */
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 7,
|
||||
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct spi_board_info wm5110_spi_devs[] = {
|
||||
[0] = {
|
||||
.modalias = "wm5110",
|
||||
@@ -366,6 +379,9 @@ static int wlf_gf_module_probe(struct i2c_client *i2c,
|
||||
rev == gf_mods[i].rev))
|
||||
break;
|
||||
|
||||
gpiod_add_lookup_table(&wm5102_reva_gpiod_table);
|
||||
gpiod_add_lookup_table(&wm5102_gpiod_table);
|
||||
|
||||
if (i < ARRAY_SIZE(gf_mods)) {
|
||||
dev_info(&i2c->dev, "%s revision %d\n",
|
||||
gf_mods[i].name, rev + 1);
|
||||
|
||||
@@ -29,6 +29,7 @@ static const struct mfd_cell bd9571mwv_cells[] = {
|
||||
|
||||
static const struct regmap_range bd9571mwv_readable_yes_ranges[] = {
|
||||
regmap_reg_range(BD9571MWV_VENDOR_CODE, BD9571MWV_PRODUCT_REVISION),
|
||||
regmap_reg_range(BD9571MWV_BKUP_MODE_CNT, BD9571MWV_BKUP_MODE_CNT),
|
||||
regmap_reg_range(BD9571MWV_AVS_SET_MONI, BD9571MWV_AVS_DVFS_VID(3)),
|
||||
regmap_reg_range(BD9571MWV_VD18_VID, BD9571MWV_VD33_VID),
|
||||
regmap_reg_range(BD9571MWV_DVFS_VINIT, BD9571MWV_DVFS_VINIT),
|
||||
@@ -44,6 +45,7 @@ static const struct regmap_access_table bd9571mwv_readable_table = {
|
||||
};
|
||||
|
||||
static const struct regmap_range bd9571mwv_writable_yes_ranges[] = {
|
||||
regmap_reg_range(BD9571MWV_BKUP_MODE_CNT, BD9571MWV_BKUP_MODE_CNT),
|
||||
regmap_reg_range(BD9571MWV_AVS_VD09_VID(0), BD9571MWV_AVS_VD09_VID(3)),
|
||||
regmap_reg_range(BD9571MWV_DVFS_SETVID, BD9571MWV_DVFS_SETVID),
|
||||
regmap_reg_range(BD9571MWV_GPIO_DIR, BD9571MWV_GPIO_OUT),
|
||||
|
||||
@@ -180,6 +180,17 @@ config REGULATOR_BCM590XX
|
||||
BCM590xx PMUs. This will enable support for the software
|
||||
controllable LDO/Switching regulators.
|
||||
|
||||
config REGULATOR_BD71837
|
||||
tristate "ROHM BD71837 Power Regulator"
|
||||
depends on MFD_BD71837
|
||||
help
|
||||
This driver supports voltage regulators on ROHM BD71837 PMIC.
|
||||
This will enable support for the software controllable buck
|
||||
and LDO regulators.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called bd71837-regulator.
|
||||
|
||||
config REGULATOR_BD9571MWV
|
||||
tristate "ROHM BD9571MWV Regulators"
|
||||
depends on MFD_BD9571MWV
|
||||
@@ -801,6 +812,13 @@ config REGULATOR_STW481X_VMMC
|
||||
This driver supports the internal VMMC regulator in the STw481x
|
||||
PMIC chips.
|
||||
|
||||
config REGULATOR_SY8106A
|
||||
tristate "Silergy SY8106A regulator"
|
||||
depends on I2C && (OF || COMPILE_TEST)
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports SY8106A single output regulator.
|
||||
|
||||
config REGULATOR_TPS51632
|
||||
tristate "TI TPS51632 Power Regulator"
|
||||
depends on I2C
|
||||
|
||||
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
|
||||
@@ -100,6 +101,7 @@ obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
|
||||
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
|
||||
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
|
||||
@@ -125,5 +127,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
|
||||
|
||||
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
||||
|
||||
+1
-1406
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/regulator/arizona-ldo1.h>
|
||||
@@ -198,16 +197,6 @@ static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
|
||||
struct device_node *init_node, *dcvdd_node;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0);
|
||||
if (pdata->ldoena < 0) {
|
||||
dev_warn(config->dev,
|
||||
"LDOENA GPIO property missing/malformed: %d\n",
|
||||
pdata->ldoena);
|
||||
pdata->ldoena = 0;
|
||||
} else {
|
||||
config->ena_gpio_initialized = true;
|
||||
}
|
||||
|
||||
init_node = of_get_child_by_name(np, "ldo1");
|
||||
dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0);
|
||||
|
||||
@@ -264,7 +253,11 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
config.ena_gpio = pdata->ldoena;
|
||||
/* We assume that high output = regulator off */
|
||||
config.ena_gpiod = devm_gpiod_get_optional(&pdev->dev, "wlf,ldoena",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(config.ena_gpiod))
|
||||
return PTR_ERR(config.ena_gpiod);
|
||||
|
||||
if (pdata->init_data)
|
||||
config.init_data = pdata->init_data;
|
||||
|
||||
@@ -721,6 +721,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
case AXP803_ID:
|
||||
regulators = axp803_regulators;
|
||||
nregulators = AXP803_REG_ID_MAX;
|
||||
drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
|
||||
"x-powers,drive-vbus-en");
|
||||
break;
|
||||
case AXP806_ID:
|
||||
regulators = axp806_regulators;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,18 @@
|
||||
|
||||
#include <linux/mfd/bd9571mwv.h>
|
||||
|
||||
struct bd9571mwv_reg {
|
||||
struct bd9571mwv *bd;
|
||||
|
||||
/* DDR Backup Power */
|
||||
u8 bkup_mode_cnt_keepon; /* from "rohm,ddr-backup-power" */
|
||||
u8 bkup_mode_cnt_saved;
|
||||
|
||||
/* Power switch type */
|
||||
bool rstbmode_level;
|
||||
bool rstbmode_pulse;
|
||||
};
|
||||
|
||||
enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS };
|
||||
|
||||
#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\
|
||||
@@ -131,14 +143,99 @@ static struct regulator_desc regulators[] = {
|
||||
0x80, 600000, 10000, 0x3c),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int bd9571mwv_bkup_mode_read(struct bd9571mwv *bd, unsigned int *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(bd->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
|
||||
if (ret) {
|
||||
dev_err(bd->dev, "failed to read backup mode (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd9571mwv_bkup_mode_write(struct bd9571mwv *bd, unsigned int mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(bd->regmap, BD9571MWV_BKUP_MODE_CNT, mode);
|
||||
if (ret) {
|
||||
dev_err(bd->dev, "failed to configure backup mode 0x%x (%d)\n",
|
||||
mode, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd9571mwv_suspend(struct device *dev)
|
||||
{
|
||||
struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
|
||||
unsigned int mode;
|
||||
int ret;
|
||||
|
||||
if (!device_may_wakeup(dev))
|
||||
return 0;
|
||||
|
||||
/* Save DDR Backup Mode */
|
||||
ret = bd9571mwv_bkup_mode_read(bdreg->bd, &mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bdreg->bkup_mode_cnt_saved = mode;
|
||||
|
||||
if (!bdreg->rstbmode_pulse)
|
||||
return 0;
|
||||
|
||||
/* Enable DDR Backup Mode */
|
||||
mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
|
||||
mode |= bdreg->bkup_mode_cnt_keepon;
|
||||
|
||||
if (mode != bdreg->bkup_mode_cnt_saved)
|
||||
return bd9571mwv_bkup_mode_write(bdreg->bd, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd9571mwv_resume(struct device *dev)
|
||||
{
|
||||
struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
|
||||
|
||||
if (!device_may_wakeup(dev))
|
||||
return 0;
|
||||
|
||||
/* Restore DDR Backup Mode */
|
||||
return bd9571mwv_bkup_mode_write(bdreg->bd, bdreg->bkup_mode_cnt_saved);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops bd9571mwv_pm = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
|
||||
};
|
||||
|
||||
#define DEV_PM_OPS &bd9571mwv_pm
|
||||
#else
|
||||
#define DEV_PM_OPS NULL
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static int bd9571mwv_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bd9571mwv *bd = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct bd9571mwv_reg *bdreg;
|
||||
struct regulator_dev *rdev;
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
platform_set_drvdata(pdev, bd);
|
||||
bdreg = devm_kzalloc(&pdev->dev, sizeof(*bdreg), GFP_KERNEL);
|
||||
if (!bdreg)
|
||||
return -ENOMEM;
|
||||
|
||||
bdreg->bd = bd;
|
||||
|
||||
platform_set_drvdata(pdev, bdreg);
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.dev->of_node = bd->dev->of_node;
|
||||
@@ -155,6 +252,33 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
val = 0;
|
||||
of_property_read_u32(bd->dev->of_node, "rohm,ddr-backup-power", &val);
|
||||
if (val & ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK) {
|
||||
dev_err(bd->dev, "invalid %s mode %u\n",
|
||||
"rohm,ddr-backup-power", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
bdreg->bkup_mode_cnt_keepon = val;
|
||||
|
||||
bdreg->rstbmode_level = of_property_read_bool(bd->dev->of_node,
|
||||
"rohm,rstbmode-level");
|
||||
bdreg->rstbmode_pulse = of_property_read_bool(bd->dev->of_node,
|
||||
"rohm,rstbmode-pulse");
|
||||
if (bdreg->rstbmode_level && bdreg->rstbmode_pulse) {
|
||||
dev_err(bd->dev, "only one rohm,rstbmode-* may be specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bdreg->bkup_mode_cnt_keepon) {
|
||||
device_set_wakeup_capable(&pdev->dev, true);
|
||||
/*
|
||||
* Wakeup is enabled by default in pulse mode, but needs
|
||||
* explicit user setup in level mode.
|
||||
*/
|
||||
device_set_wakeup_enable(&pdev->dev, bdreg->rstbmode_pulse);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -167,6 +291,7 @@ MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
|
||||
static struct platform_driver bd9571mwv_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "bd9571mwv-regulator",
|
||||
.pm = DEV_PM_OPS,
|
||||
},
|
||||
.probe = bd9571mwv_regulator_probe,
|
||||
.id_table = bd9571mwv_regulator_id_table,
|
||||
|
||||
+203
-41
@@ -146,6 +146,56 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_lock_nested - lock a single regulator
|
||||
* @rdev: regulator source
|
||||
* @subclass: mutex subclass used for lockdep
|
||||
*
|
||||
* This function can be called many times by one task on
|
||||
* a single regulator and its mutex will be locked only
|
||||
* once. If a task, which is calling this function is other
|
||||
* than the one, which initially locked the mutex, it will
|
||||
* wait on mutex.
|
||||
*/
|
||||
static void regulator_lock_nested(struct regulator_dev *rdev,
|
||||
unsigned int subclass)
|
||||
{
|
||||
if (!mutex_trylock(&rdev->mutex)) {
|
||||
if (rdev->mutex_owner == current) {
|
||||
rdev->ref_cnt++;
|
||||
return;
|
||||
}
|
||||
mutex_lock_nested(&rdev->mutex, subclass);
|
||||
}
|
||||
|
||||
rdev->ref_cnt = 1;
|
||||
rdev->mutex_owner = current;
|
||||
}
|
||||
|
||||
static inline void regulator_lock(struct regulator_dev *rdev)
|
||||
{
|
||||
regulator_lock_nested(rdev, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_unlock - unlock a single regulator
|
||||
* @rdev: regulator_source
|
||||
*
|
||||
* This function unlocks the mutex when the
|
||||
* reference counter reaches 0.
|
||||
*/
|
||||
static void regulator_unlock(struct regulator_dev *rdev)
|
||||
{
|
||||
if (rdev->ref_cnt != 0) {
|
||||
rdev->ref_cnt--;
|
||||
|
||||
if (!rdev->ref_cnt) {
|
||||
rdev->mutex_owner = NULL;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_lock_supply - lock a regulator and its supplies
|
||||
* @rdev: regulator source
|
||||
@@ -155,7 +205,7 @@ static void regulator_lock_supply(struct regulator_dev *rdev)
|
||||
int i;
|
||||
|
||||
for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
|
||||
mutex_lock_nested(&rdev->mutex, i);
|
||||
regulator_lock_nested(rdev, i);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +217,7 @@ static void regulator_unlock_supply(struct regulator_dev *rdev)
|
||||
struct regulator *supply;
|
||||
|
||||
while (1) {
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
supply = rdev->supply;
|
||||
|
||||
if (!rdev->supply)
|
||||
@@ -350,9 +400,9 @@ static ssize_t regulator_uV_show(struct device *dev,
|
||||
struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
ssize_t ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -416,9 +466,9 @@ static ssize_t regulator_state_show(struct device *dev,
|
||||
struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
ssize_t ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
ret = regulator_print_state(buf, _regulator_is_enabled(rdev));
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -526,10 +576,10 @@ static ssize_t regulator_total_uA_show(struct device *dev,
|
||||
struct regulator *regulator;
|
||||
int uA = 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
list_for_each_entry(regulator, &rdev->consumer_list, list)
|
||||
uA += regulator->uA_load;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return sprintf(buf, "%d\n", uA);
|
||||
}
|
||||
static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
|
||||
@@ -886,6 +936,18 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
|
||||
rdev->constraints->min_uV && rdev->constraints->max_uV) {
|
||||
int target_min, target_max;
|
||||
int current_uV = _regulator_get_voltage(rdev);
|
||||
|
||||
if (current_uV == -ENOTRECOVERABLE) {
|
||||
/* This regulator can't be read and must be initted */
|
||||
rdev_info(rdev, "Setting %d-%duV\n",
|
||||
rdev->constraints->min_uV,
|
||||
rdev->constraints->max_uV);
|
||||
_regulator_do_set_voltage(rdev,
|
||||
rdev->constraints->min_uV,
|
||||
rdev->constraints->max_uV);
|
||||
current_uV = _regulator_get_voltage(rdev);
|
||||
}
|
||||
|
||||
if (current_uV < 0) {
|
||||
rdev_err(rdev,
|
||||
"failed to get the current voltage(%d)\n",
|
||||
@@ -1321,7 +1383,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
if (regulator == NULL)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
regulator->rdev = rdev;
|
||||
list_add(®ulator->list, &rdev->consumer_list);
|
||||
|
||||
@@ -1376,12 +1438,12 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
_regulator_is_enabled(rdev))
|
||||
regulator->always_on = true;
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return regulator;
|
||||
overflow_err:
|
||||
list_del(®ulator->list);
|
||||
kfree(regulator);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1770,13 +1832,13 @@ static void _regulator_put(struct regulator *regulator)
|
||||
/* remove any sysfs entries */
|
||||
if (regulator->dev)
|
||||
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
list_del(®ulator->list);
|
||||
|
||||
rdev->open_count--;
|
||||
rdev->exclusive = 0;
|
||||
put_device(&rdev->dev);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
kfree_const(regulator->supply_name);
|
||||
kfree(regulator);
|
||||
@@ -2384,7 +2446,7 @@ static void regulator_disable_work(struct work_struct *work)
|
||||
disable_work.work);
|
||||
int count, i, ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
BUG_ON(!rdev->deferred_disables);
|
||||
|
||||
@@ -2405,7 +2467,7 @@ static void regulator_disable_work(struct work_struct *work)
|
||||
rdev_err(rdev, "Deferred disable failed: %d\n", ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
if (rdev->supply) {
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -2440,11 +2502,11 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
|
||||
if (!ms)
|
||||
return regulator_disable(regulator);
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
rdev->deferred_disables++;
|
||||
mod_delayed_work(system_power_efficient_wq, &rdev->disable_work,
|
||||
msecs_to_jiffies(ms));
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2476,10 +2538,10 @@ static int _regulator_list_voltage(struct regulator_dev *rdev,
|
||||
if (selector >= rdev->desc->n_voltages)
|
||||
return -EINVAL;
|
||||
if (lock)
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
ret = ops->list_voltage(rdev, selector);
|
||||
if (lock)
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
} else if (rdev->is_switch && rdev->supply) {
|
||||
ret = _regulator_list_voltage(rdev->supply->rdev,
|
||||
selector, lock);
|
||||
@@ -3252,7 +3314,7 @@ int regulator_sync_voltage(struct regulator *regulator)
|
||||
struct regulator_voltage *voltage = ®ulator->voltage[PM_SUSPEND_ON];
|
||||
int ret, min_uV, max_uV;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
if (!rdev->desc->ops->set_voltage &&
|
||||
!rdev->desc->ops->set_voltage_sel) {
|
||||
@@ -3281,7 +3343,7 @@ int regulator_sync_voltage(struct regulator *regulator)
|
||||
ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
|
||||
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_sync_voltage);
|
||||
@@ -3374,7 +3436,7 @@ int regulator_set_current_limit(struct regulator *regulator,
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->set_current_limit) {
|
||||
@@ -3389,7 +3451,7 @@ int regulator_set_current_limit(struct regulator *regulator,
|
||||
|
||||
ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_current_limit);
|
||||
@@ -3398,7 +3460,7 @@ static int _regulator_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->get_current_limit) {
|
||||
@@ -3408,7 +3470,7 @@ static int _regulator_get_current_limit(struct regulator_dev *rdev)
|
||||
|
||||
ret = rdev->desc->ops->get_current_limit(rdev);
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3444,7 +3506,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
|
||||
int ret;
|
||||
int regulator_curr_mode;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->set_mode) {
|
||||
@@ -3468,7 +3530,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
|
||||
|
||||
ret = rdev->desc->ops->set_mode(rdev, mode);
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_mode);
|
||||
@@ -3477,7 +3539,7 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->get_mode) {
|
||||
@@ -3487,7 +3549,7 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
|
||||
|
||||
ret = rdev->desc->ops->get_mode(rdev);
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3508,7 +3570,7 @@ static int _regulator_get_error_flags(struct regulator_dev *rdev,
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->get_error_flags) {
|
||||
@@ -3518,7 +3580,7 @@ static int _regulator_get_error_flags(struct regulator_dev *rdev,
|
||||
|
||||
ret = rdev->desc->ops->get_error_flags(rdev, flags);
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3567,10 +3629,10 @@ int regulator_set_load(struct regulator *regulator, int uA_load)
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
regulator->uA_load = uA_load;
|
||||
ret = drms_uA_update(rdev);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3598,7 +3660,7 @@ int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_BYPASS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
if (enable && !regulator->bypass) {
|
||||
rdev->bypass_count++;
|
||||
@@ -3622,7 +3684,7 @@ int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
if (ret == 0)
|
||||
regulator->bypass = enable;
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -4067,6 +4129,96 @@ static int regulator_register_resolve_supply(struct device *dev, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regulator_fill_coupling_array(struct regulator_dev *rdev)
|
||||
{
|
||||
struct coupling_desc *c_desc = &rdev->coupling_desc;
|
||||
int n_coupled = c_desc->n_coupled;
|
||||
struct regulator_dev *c_rdev;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < n_coupled; i++) {
|
||||
/* already resolved */
|
||||
if (c_desc->coupled_rdevs[i])
|
||||
continue;
|
||||
|
||||
c_rdev = of_parse_coupled_regulator(rdev, i - 1);
|
||||
|
||||
if (c_rdev) {
|
||||
c_desc->coupled_rdevs[i] = c_rdev;
|
||||
c_desc->n_resolved++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rdev->coupling_desc.n_resolved < n_coupled)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regulator_register_fill_coupling_array(struct device *dev,
|
||||
void *data)
|
||||
{
|
||||
struct regulator_dev *rdev = dev_to_rdev(dev);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF))
|
||||
return 0;
|
||||
|
||||
if (regulator_fill_coupling_array(rdev))
|
||||
rdev_dbg(rdev, "unable to resolve coupling\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regulator_resolve_coupling(struct regulator_dev *rdev)
|
||||
{
|
||||
int n_phandles;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF))
|
||||
n_phandles = 0;
|
||||
else
|
||||
n_phandles = of_get_n_coupled(rdev);
|
||||
|
||||
if (n_phandles + 1 > MAX_COUPLED) {
|
||||
rdev_err(rdev, "too many regulators coupled\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Every regulator should always have coupling descriptor filled with
|
||||
* at least pointer to itself.
|
||||
*/
|
||||
rdev->coupling_desc.coupled_rdevs[0] = rdev;
|
||||
rdev->coupling_desc.n_coupled = n_phandles + 1;
|
||||
rdev->coupling_desc.n_resolved++;
|
||||
|
||||
/* regulator isn't coupled */
|
||||
if (n_phandles == 0)
|
||||
return 0;
|
||||
|
||||
/* regulator, which can't change its voltage, can't be coupled */
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
|
||||
rdev_err(rdev, "voltage operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (rdev->constraints->max_spread <= 0) {
|
||||
rdev_err(rdev, "wrong max_spread value\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!of_check_coupling_data(rdev))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* After everything has been checked, try to fill rdevs array
|
||||
* with pointers to regulators parsed from device tree. If some
|
||||
* regulators are not registered yet, retry in late init call
|
||||
*/
|
||||
regulator_fill_coupling_array(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_register - register regulator
|
||||
* @regulator_desc: regulator to register
|
||||
@@ -4200,6 +4352,13 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
if (ret < 0)
|
||||
goto wash;
|
||||
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
ret = regulator_resolve_coupling(rdev);
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
|
||||
if (ret != 0)
|
||||
goto wash;
|
||||
|
||||
/* add consumers devices */
|
||||
if (init_data) {
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
@@ -4288,9 +4447,9 @@ static int _regulator_suspend_late(struct device *dev, void *data)
|
||||
suspend_state_t *state = data;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
ret = suspend_set_state(rdev, *state);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -4320,14 +4479,14 @@ static int _regulator_resume_early(struct device *dev, void *data)
|
||||
if (rstate == NULL)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
if (rdev->desc->ops->resume_early &&
|
||||
(rstate->enabled == ENABLE_IN_SUSPEND ||
|
||||
rstate->enabled == DISABLE_IN_SUSPEND))
|
||||
ret = rdev->desc->ops->resume_early(rdev);
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -4629,7 +4788,7 @@ static int __init regulator_late_cleanup(struct device *dev, void *data)
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator_lock(rdev);
|
||||
|
||||
if (rdev->use_count)
|
||||
goto unlock;
|
||||
@@ -4660,7 +4819,7 @@ static int __init regulator_late_cleanup(struct device *dev, void *data)
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
regulator_unlock(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4694,6 +4853,9 @@ static int __init regulator_init_complete(void)
|
||||
class_for_each_device(®ulator_class, NULL, NULL,
|
||||
regulator_late_cleanup);
|
||||
|
||||
class_for_each_device(®ulator_class, NULL, NULL,
|
||||
regulator_register_fill_coupling_array);
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall_sync(regulator_init_complete);
|
||||
|
||||
@@ -222,7 +222,7 @@ static unsigned int cpcap_map_mode(unsigned int mode)
|
||||
case CPCAP_BIT_AUDIO_LOW_PWR:
|
||||
return REGULATOR_MODE_STANDBY;
|
||||
default:
|
||||
return -EINVAL;
|
||||
return REGULATOR_MODE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user