Browse Source

Merge tag 'regulator-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "This is an extremely quiet release for the regulator subsystem, it's
  all fairly minor fixes and cleanups plus a few new drivers and ddevice
  ID additions:

   - Support for MediaTek MT6380, Ricoh RC5T619 and ST Voltage Reference
     Buffers"

* tag 'regulator-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (24 commits)
  regulator: Add support for stm32-vrefbuf
  regulator: Add STM32 Voltage Reference Buffer
  regulator: pv88090: Exception handling for out of bounds
  regulator: da9063: Return an error code on probe failure
  regulator: rn5t618: add RC5T619 PMIC support
  regulator: ltc3589: constify i2c_device_id
  regulator: fan53555: fix I2C device ids
  regulator: add fixes with MT6397 dt-bindings shouldn't reference driver
  regulator: add fixes with MT6323 dt-bindings shouldn't reference driver
  regulator: add fixes with MT6311 dt-bindings shouldn't reference driver
  regulator: Add document for MediaTek MT6380 regulator
  regulator: mt6380: Add support for MT6380
  regulator: pwm-regulator: Remove unneeded gpiod NULL check
  regulator: core: fix a possible race in disable_work handling
  regulator: fan53555: Use of_device_get_match_data() to simplify probe
  regulator: of: regulator_of_get_init_data() missing of_node_get()
  regulator: pwm-regulator: fix example syntax
  regulator: Convert to using %pOF instead of full_name
  regulator: cpcap: Add OF mode mapping
  regulator: cpcap: Fix standby mode
  ...
Linus Torvalds 8 years ago
parent
commit
fe9e31383e

+ 1 - 1
Documentation/devicetree/bindings/regulator/mt6311-regulator.txt

@@ -1,4 +1,4 @@
-Mediatek MT6311 Regulator Driver
+Mediatek MT6311 Regulator
 
 
 Required properties:
 Required properties:
 - compatible: "mediatek,mt6311-regulator"
 - compatible: "mediatek,mt6311-regulator"

+ 1 - 1
Documentation/devicetree/bindings/regulator/mt6323-regulator.txt

@@ -1,4 +1,4 @@
-Mediatek MT6323 Regulator Driver
+Mediatek MT6323 Regulator
 
 
 All voltage regulators are defined as subnodes of the regulators node. A list
 All voltage regulators are defined as subnodes of the regulators node. A list
 of regulators provided by this controller are defined as subnodes of the
 of regulators provided by this controller are defined as subnodes of the

+ 89 - 0
Documentation/devicetree/bindings/regulator/mt6380-regulator.txt

@@ -0,0 +1,89 @@
+MediaTek MT6380 Regulator
+
+All voltage regulators provided by the MT6380 PMIC are described as the
+subnodes of the MT6380 regulators node. Each regulator is named according
+to its regulator type, buck-<name> and ldo-<name>. The definition for each
+of these nodes is defined using the standard binding for regulators at
+Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are:
+BUCK:
+  buck-core1, buck-vcore, buck-vrf
+LDO:
+  ldo-vm ,ldo-va , ldo-vphy, ldo-vddr, ldo-vt
+
+Example:
+
+	regulators {
+		compatible = "mediatek,mt6380-regulator";
+
+		mt6380_vcpu_reg: buck-vcore1 {
+			regulator-name = "vcore1";
+			regulator-min-microvolt = < 600000>;
+			regulator-max-microvolt = <1393750>;
+			regulator-ramp-delay = <6250>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vcore_reg: buck-vcore {
+			regulator-name = "vcore";
+			regulator-min-microvolt = <600000>;
+			regulator-max-microvolt = <1393750>;
+			regulator-ramp-delay = <6250>;
+		};
+
+		mt6380_vrf_reg: buck-vrf {
+			regulator-name = "vrf";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1575000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vm_reg: ldo-vm {
+			regulator-name = "vm";
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_va_reg: ldo-va {
+			regulator-name = "va";
+			regulator-min-microvolt = <2200000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vphy_reg: ldo-vphy {
+			regulator-name = "vphy";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vddr_reg: ldo-vddr {
+			regulator-name = "vddr";
+			regulator-min-microvolt = <1240000>;
+			regulator-max-microvolt = <1840000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vt_reg: ldo-vt {
+			regulator-name = "vt";
+			regulator-min-microvolt = <2200000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+	};

+ 1 - 1
Documentation/devicetree/bindings/regulator/mt6397-regulator.txt

@@ -1,4 +1,4 @@
-Mediatek MT6397 Regulator Driver
+Mediatek MT6397 Regulator
 
 
 Required properties:
 Required properties:
 - compatible: "mediatek,mt6397-regulator"
 - compatible: "mediatek,mt6397-regulator"

+ 1 - 1
Documentation/devicetree/bindings/regulator/pwm-regulator.txt

@@ -71,7 +71,7 @@ Continuous Voltage With Enable GPIO Example:
 		 * Inverted PWM logic, and the duty cycle range is limited
 		 * Inverted PWM logic, and the duty cycle range is limited
 		 * to 30%-70%.
 		 * to 30%-70%.
 		 */
 		 */
-		pwm-dutycycle-range <700 300>; /* */
+		pwm-dutycycle-range = <700 300>; /* */
 	};
 	};
 
 
 Voltage Table Example:
 Voltage Table Example:

+ 20 - 0
Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt

@@ -0,0 +1,20 @@
+STM32 VREFBUF - Voltage reference buffer
+
+Some STM32 devices embed a voltage reference buffer which can be used as
+voltage reference for ADCs, DACs and also as voltage reference for external
+components through the dedicated VREF+ pin.
+
+Required properties:
+- compatible:		Must be "st,stm32-vrefbuf".
+- reg:			Offset and length of VREFBUF register set.
+- clocks:		Must contain an entry for peripheral clock.
+
+Example:
+	vrefbuf: regulator@58003C00 {
+		compatible = "st,stm32-vrefbuf";
+		reg = <0x58003C00 0x8>;
+		clocks = <&rcc VREF_CK>;
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <2500000>;
+		vdda-supply = <&vdda>;
+	};

+ 23 - 2
drivers/regulator/Kconfig

@@ -559,6 +559,15 @@ config REGULATOR_MT6323
 	  This driver supports the control of different power rails of device
 	  This driver supports the control of different power rails of device
 	  through regulator interface.
 	  through regulator interface.
 
 
+config REGULATOR_MT6380
+	tristate "MediaTek MT6380 PMIC"
+	depends on MTK_PMIC_WRAP
+	help
+	  Say y here to select this option to enable the power regulator of
+	  MediaTek MT6380 PMIC.
+	  This driver supports the control of different power rails of device
+	  through regulator interface.
+
 config REGULATOR_MT6397
 config REGULATOR_MT6397
 	tristate "MediaTek MT6397 PMIC"
 	tristate "MediaTek MT6397 PMIC"
 	depends on MFD_MT6397
 	depends on MFD_MT6397
@@ -700,8 +709,8 @@ config REGULATOR_RN5T618
 	tristate "Ricoh RN5T567/618 voltage regulators"
 	tristate "Ricoh RN5T567/618 voltage regulators"
 	depends on MFD_RN5T618
 	depends on MFD_RN5T618
 	help
 	help
-	  Say y here to support the regulators found on Ricoh RN5T567 or
-	  RN5T618 PMIC.
+	  Say y here to support the regulators found on Ricoh RN5T567,
+	  RN5T618 or RC5T619 PMIC.
 
 
 config REGULATOR_RT5033
 config REGULATOR_RT5033
 	tristate "Richtek RT5033 Regulators"
 	tristate "Richtek RT5033 Regulators"
@@ -746,6 +755,18 @@ config REGULATOR_SKY81452
 	  This driver can also be built as a module. If so, the module
 	  This driver can also be built as a module. If so, the module
 	  will be called sky81452-regulator.
 	  will be called sky81452-regulator.
 
 
+config REGULATOR_STM32_VREFBUF
+	tristate "STMicroelectronics STM32 VREFBUF"
+	depends on ARCH_STM32 || COMPILE_TEST
+	help
+	  This driver supports STMicroelectronics STM32 VREFBUF (voltage
+	  reference buffer) which can be used as voltage reference for
+	  internal ADCs, DACs and also for external components through
+	  dedicated Vref+ pin.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called stm32-vrefbuf.
+
 config REGULATOR_TI_ABB
 config REGULATOR_TI_ABB
 	tristate "TI Adaptive Body Bias on-chip LDO"
 	tristate "TI Adaptive Body Bias on-chip LDO"
 	depends on ARCH_OMAP
 	depends on ARCH_OMAP

+ 2 - 0
drivers/regulator/Makefile

@@ -72,6 +72,7 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
+obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
@@ -94,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-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_STW481X_VMMC) += stw481x-vmmc.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o

+ 6 - 0
drivers/regulator/axp20x-regulator.c

@@ -691,6 +691,9 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
 		    (regulators == axp809_regulators && i == AXP809_DC1SW)) {
 		    (regulators == axp809_regulators && i == AXP809_DC1SW)) {
 			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 						GFP_KERNEL);
 						GFP_KERNEL);
+			if (!new_desc)
+				return -ENOMEM;
+
 			*new_desc = regulators[i];
 			*new_desc = regulators[i];
 			new_desc->supply_name = dcdc1_name;
 			new_desc->supply_name = dcdc1_name;
 			desc = new_desc;
 			desc = new_desc;
@@ -700,6 +703,9 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
 		    (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
 		    (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
 			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
 						GFP_KERNEL);
 						GFP_KERNEL);
+			if (!new_desc)
+				return -ENOMEM;
+
 			*new_desc = regulators[i];
 			*new_desc = regulators[i];
 			new_desc->supply_name = dcdc5_name;
 			new_desc->supply_name = dcdc5_name;
 			desc = new_desc;
 			desc = new_desc;

+ 12 - 4
drivers/regulator/core.c

@@ -204,8 +204,8 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
 	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
 	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
 
 
 	if (!regnode) {
 	if (!regnode) {
-		dev_dbg(dev, "Looking up %s property in node %s failed\n",
-				prop_name, dev->of_node->full_name);
+		dev_dbg(dev, "Looking up %s property in node %pOF failed\n",
+				prop_name, dev->of_node);
 		return NULL;
 		return NULL;
 	}
 	}
 	return regnode;
 	return regnode;
@@ -2396,6 +2396,14 @@ static void regulator_disable_work(struct work_struct *work)
 	count = rdev->deferred_disables;
 	count = rdev->deferred_disables;
 	rdev->deferred_disables = 0;
 	rdev->deferred_disables = 0;
 
 
+	/*
+	 * Workqueue functions queue the new work instance while the previous
+	 * work instance is being processed. Cancel the queued work instance
+	 * as the work instance under processing does the job of the queued
+	 * work instance.
+	 */
+	cancel_delayed_work(&rdev->disable_work);
+
 	for (i = 0; i < count; i++) {
 	for (i = 0; i < count; i++) {
 		ret = _regulator_disable(rdev);
 		ret = _regulator_disable(rdev);
 		if (ret != 0)
 		if (ret != 0)
@@ -2439,10 +2447,10 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
 
 
 	mutex_lock(&rdev->mutex);
 	mutex_lock(&rdev->mutex);
 	rdev->deferred_disables++;
 	rdev->deferred_disables++;
+	mod_delayed_work(system_power_efficient_wq, &rdev->disable_work,
+			 msecs_to_jiffies(ms));
 	mutex_unlock(&rdev->mutex);
 	mutex_unlock(&rdev->mutex);
 
 
-	queue_delayed_work(system_power_efficient_wq, &rdev->disable_work,
-			   msecs_to_jiffies(ms));
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(regulator_disable_deferred);
 EXPORT_SYMBOL_GPL(regulator_disable_deferred);

+ 18 - 3
drivers/regulator/cpcap-regulator.c

@@ -77,6 +77,8 @@
 #define CPCAP_BIT_VAUDIO_MODE0		BIT(1)
 #define CPCAP_BIT_VAUDIO_MODE0		BIT(1)
 #define CPCAP_BIT_V_AUDIO_EN		BIT(0)
 #define CPCAP_BIT_V_AUDIO_EN		BIT(0)
 
 
+#define CPCAP_BIT_AUDIO_NORMAL_MODE	0x00
+
 /*
 /*
  * Off mode configuration bit. Used currently only by SW5 on omap4. There's
  * Off mode configuration bit. Used currently only by SW5 on omap4. There's
  * the following comment in Motorola Linux kernel tree for it:
  * the following comment in Motorola Linux kernel tree for it:
@@ -121,6 +123,7 @@ struct cpcap_regulator {
 		.enable_val = (mode_val),				\
 		.enable_val = (mode_val),				\
 		.disable_val = (off_val),				\
 		.disable_val = (off_val),				\
 		.ramp_delay = (volt_trans_time),			\
 		.ramp_delay = (volt_trans_time),			\
+		.of_map_mode = cpcap_map_mode,				\
 	},								\
 	},								\
 	.assign_reg = (assignment_reg),					\
 	.assign_reg = (assignment_reg),					\
 	.assign_mask = (assignment_mask),				\
 	.assign_mask = (assignment_mask),				\
@@ -211,13 +214,25 @@ static int cpcap_regulator_disable(struct regulator_dev *rdev)
 	return error;
 	return error;
 }
 }
 
 
+static unsigned int cpcap_map_mode(unsigned int mode)
+{
+	switch (mode) {
+	case CPCAP_BIT_AUDIO_NORMAL_MODE:
+		return REGULATOR_MODE_NORMAL;
+	case CPCAP_BIT_AUDIO_LOW_PWR:
+		return REGULATOR_MODE_STANDBY;
+	default:
+		return -EINVAL;
+	}
+}
+
 static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev)
 static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev)
 {
 {
 	int value;
 	int value;
 
 
 	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
 	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
 
 
-	if (!(value & CPCAP_BIT_AUDIO_LOW_PWR))
+	if (value & CPCAP_BIT_AUDIO_LOW_PWR)
 		return REGULATOR_MODE_STANDBY;
 		return REGULATOR_MODE_STANDBY;
 
 
 	return REGULATOR_MODE_NORMAL;
 	return REGULATOR_MODE_NORMAL;
@@ -230,10 +245,10 @@ static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
 
 
 	switch (mode) {
 	switch (mode) {
 	case REGULATOR_MODE_NORMAL:
 	case REGULATOR_MODE_NORMAL:
-		value = CPCAP_BIT_AUDIO_LOW_PWR;
+		value = CPCAP_BIT_AUDIO_NORMAL_MODE;
 		break;
 		break;
 	case REGULATOR_MODE_STANDBY:
 	case REGULATOR_MODE_STANDBY:
-		value = 0;
+		value = CPCAP_BIT_AUDIO_LOW_PWR;
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;

+ 1 - 1
drivers/regulator/da9063-regulator.c

@@ -736,7 +736,7 @@ static int da9063_regulator_probe(struct platform_device *pdev)
 	if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) {
 	if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) {
 		dev_err(&pdev->dev,
 		dev_err(&pdev->dev,
 			"No regulators defined for the platform\n");
 			"No regulators defined for the platform\n");
-		return PTR_ERR(regl_pdata);
+		return -ENODEV;
 	}
 	}
 
 
 	/* Find regulators set for particular device model */
 	/* Find regulators set for particular device model */

+ 6 - 9
drivers/regulator/fan53555.c

@@ -407,14 +407,8 @@ static int fan53555_regulator_probe(struct i2c_client *client,
 
 
 	di->regulator = pdata->regulator;
 	di->regulator = pdata->regulator;
 	if (client->dev.of_node) {
 	if (client->dev.of_node) {
-		const struct of_device_id *match;
-
-		match = of_match_device(of_match_ptr(fan53555_dt_ids),
-					&client->dev);
-		if (!match)
-			return -ENODEV;
-
-		di->vendor = (unsigned long) match->data;
+		di->vendor =
+			(unsigned long)of_device_get_match_data(&client->dev);
 	} else {
 	} else {
 		/* if no ramp constraint set, get the pdata ramp_delay */
 		/* if no ramp constraint set, get the pdata ramp_delay */
 		if (!di->regulator->constraints.ramp_delay) {
 		if (!di->regulator->constraints.ramp_delay) {
@@ -476,7 +470,10 @@ static const struct i2c_device_id fan53555_id[] = {
 		.name = "fan53555",
 		.name = "fan53555",
 		.driver_data = FAN53555_VENDOR_FAIRCHILD
 		.driver_data = FAN53555_VENDOR_FAIRCHILD
 	}, {
 	}, {
-		.name = "syr82x",
+		.name = "syr827",
+		.driver_data = FAN53555_VENDOR_SILERGY
+	}, {
+		.name = "syr828",
 		.driver_data = FAN53555_VENDOR_SILERGY
 		.driver_data = FAN53555_VENDOR_SILERGY
 	},
 	},
 	{ },
 	{ },

+ 1 - 1
drivers/regulator/ltc3589.c

@@ -539,7 +539,7 @@ static int ltc3589_probe(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-static struct i2c_device_id ltc3589_i2c_id[] = {
+static const struct i2c_device_id ltc3589_i2c_id[] = {
 	{ "ltc3589",   LTC3589   },
 	{ "ltc3589",   LTC3589   },
 	{ "ltc3589-1", LTC3589_1 },
 	{ "ltc3589-1", LTC3589_1 },
 	{ "ltc3589-2", LTC3589_2 },
 	{ "ltc3589-2", LTC3589_2 },

+ 1 - 1
drivers/regulator/max1586.c

@@ -169,7 +169,7 @@ static int of_get_max1586_platform_data(struct device *dev,
 
 
 	if (of_property_read_u32(np, "v3-gain",
 	if (of_property_read_u32(np, "v3-gain",
 				 &pdata->v3_gain) < 0) {
 				 &pdata->v3_gain) < 0) {
-		dev_err(dev, "%s has no 'v3-gain' property\n", np->full_name);
+		dev_err(dev, "%pOF has no 'v3-gain' property\n", np);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 

+ 352 - 0
drivers/regulator/mt6380-regulator.c

@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chenglin Xu <chenglin.xu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6380-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+/* PMIC Registers */
+#define MT6380_ALDO_CON_0                         0x0000
+#define MT6380_BTLDO_CON_0                        0x0004
+#define MT6380_COMP_CON_0                         0x0008
+#define MT6380_CPUBUCK_CON_0                      0x000C
+#define MT6380_CPUBUCK_CON_1                      0x0010
+#define MT6380_CPUBUCK_CON_2                      0x0014
+#define MT6380_DDRLDO_CON_0                       0x0018
+#define MT6380_MLDO_CON_0                         0x001C
+#define MT6380_PALDO_CON_0                        0x0020
+#define MT6380_PHYLDO_CON_0                       0x0024
+#define MT6380_SIDO_CON_0                         0x0028
+#define MT6380_SIDO_CON_1                         0x002C
+#define MT6380_SIDO_CON_2                         0x0030
+#define MT6380_SLDO_CON_0                         0x0034
+#define MT6380_TLDO_CON_0                         0x0038
+#define MT6380_STARTUP_CON_0                      0x003C
+#define MT6380_STARTUP_CON_1                      0x0040
+#define MT6380_SMPS_TOP_CON_0                     0x0044
+#define MT6380_SMPS_TOP_CON_1                     0x0048
+#define MT6380_ANA_CTRL_0                         0x0050
+#define MT6380_ANA_CTRL_1                         0x0054
+#define MT6380_ANA_CTRL_2                         0x0058
+#define MT6380_ANA_CTRL_3                         0x005C
+#define MT6380_ANA_CTRL_4                         0x0060
+#define MT6380_SPK_CON9                           0x0064
+#define MT6380_SPK_CON11                          0x0068
+#define MT6380_SPK_CON12                          0x006A
+#define MT6380_CLK_CTRL                           0x0070
+#define MT6380_PINMUX_CTRL                        0x0074
+#define MT6380_IO_CTRL                            0x0078
+#define MT6380_SLP_MODE_CTRL_0                    0x007C
+#define MT6380_SLP_MODE_CTRL_1                    0x0080
+#define MT6380_SLP_MODE_CTRL_2                    0x0084
+#define MT6380_SLP_MODE_CTRL_3                    0x0088
+#define MT6380_SLP_MODE_CTRL_4                    0x008C
+#define MT6380_SLP_MODE_CTRL_5                    0x0090
+#define MT6380_SLP_MODE_CTRL_6                    0x0094
+#define MT6380_SLP_MODE_CTRL_7                    0x0098
+#define MT6380_SLP_MODE_CTRL_8                    0x009C
+#define MT6380_FCAL_CTRL_0                        0x00A0
+#define MT6380_FCAL_CTRL_1                        0x00A4
+#define MT6380_LDO_CTRL_0                         0x00A8
+#define MT6380_LDO_CTRL_1                         0x00AC
+#define MT6380_LDO_CTRL_2                         0x00B0
+#define MT6380_LDO_CTRL_3                         0x00B4
+#define MT6380_LDO_CTRL_4                         0x00B8
+#define MT6380_DEBUG_CTRL_0                       0x00BC
+#define MT6380_EFU_CTRL_0                         0x0200
+#define MT6380_EFU_CTRL_1                         0x0201
+#define MT6380_EFU_CTRL_2                         0x0202
+#define MT6380_EFU_CTRL_3                         0x0203
+#define MT6380_EFU_CTRL_4                         0x0204
+#define MT6380_EFU_CTRL_5                         0x0205
+#define MT6380_EFU_CTRL_6                         0x0206
+#define MT6380_EFU_CTRL_7                         0x0207
+#define MT6380_EFU_CTRL_8                         0x0208
+
+#define MT6380_REGULATOR_MODE_AUTO	0
+#define MT6380_REGULATOR_MODE_FORCE_PWM	1
+
+/*
+ * mt6380 regulators' information
+ *
+ * @desc: standard fields of regulator description
+ * @vselon_reg: Register sections for hardware control mode of bucks
+ * @modeset_reg: Register for controlling the buck/LDO control mode
+ * @modeset_mask: Mask for controlling the buck/LDO control mode
+ */
+struct mt6380_regulator_info {
+	struct regulator_desc desc;
+	u32 vselon_reg;
+	u32 modeset_reg;
+	u32 modeset_mask;
+};
+
+#define MT6380_BUCK(match, vreg, min, max, step, volt_ranges, enreg,	\
+		    vosel, vosel_mask, enbit, voselon, _modeset_reg,	\
+		    _modeset_mask)					\
+[MT6380_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.of_match = of_match_ptr(match),			\
+		.ops = &mt6380_volt_range_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6380_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = ((max) - (min)) / (step) + 1,		\
+		.linear_ranges = volt_ranges,				\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),		\
+		.vsel_reg = vosel,					\
+		.vsel_mask = vosel_mask,				\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+	},								\
+	.vselon_reg = voselon,						\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6380_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel,	\
+		   vosel_mask, _modeset_reg, _modeset_mask)		\
+[MT6380_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.of_match = of_match_ptr(match),			\
+		.ops = &mt6380_volt_table_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6380_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = ARRAY_SIZE(ldo_volt_table),		\
+		.volt_table = ldo_volt_table,				\
+		.vsel_reg = vosel,					\
+		.vsel_mask = vosel_mask,				\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+	},								\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6380_REG_FIXED(match, vreg, enreg, enbit, volt,		\
+			 _modeset_reg, _modeset_mask)			\
+[MT6380_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.of_match = of_match_ptr(match),			\
+		.ops = &mt6380_volt_fixed_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6380_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = 1,					\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+		.min_uV = volt,						\
+	},								\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 0xfe, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range3[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000),
+};
+
+static const u32 ldo_volt_table1[] = {
+	1400000, 1350000, 1300000, 1250000, 1200000, 1150000, 1100000, 1050000,
+};
+
+static const u32 ldo_volt_table2[] = {
+	2200000, 3300000,
+};
+
+static const u32 ldo_volt_table3[] = {
+	1240000, 1390000, 1540000, 1840000,
+};
+
+static const u32 ldo_volt_table4[] = {
+	2200000, 3300000,
+};
+
+static int mt6380_regulator_set_mode(struct regulator_dev *rdev,
+				     unsigned int mode)
+{
+	int ret, val = 0;
+	struct mt6380_regulator_info *info = rdev_get_drvdata(rdev);
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		val = MT6380_REGULATOR_MODE_AUTO;
+		break;
+	case REGULATOR_MODE_FAST:
+		val = MT6380_REGULATOR_MODE_FORCE_PWM;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val <<= ffs(info->modeset_mask) - 1;
+
+	ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+				 info->modeset_mask, val);
+
+	return ret;
+}
+
+static unsigned int mt6380_regulator_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	unsigned int mode;
+	int ret;
+	struct mt6380_regulator_info *info = rdev_get_drvdata(rdev);
+
+	ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
+	if (ret < 0)
+		return ret;
+
+	val &= info->modeset_mask;
+	val >>= ffs(info->modeset_mask) - 1;
+
+	switch (val) {
+	case MT6380_REGULATOR_MODE_AUTO:
+		mode = REGULATOR_MODE_NORMAL;
+		break;
+	case MT6380_REGULATOR_MODE_FORCE_PWM:
+		mode = REGULATOR_MODE_FAST;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return mode;
+}
+
+static const struct regulator_ops mt6380_volt_range_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6380_regulator_set_mode,
+	.get_mode = mt6380_regulator_get_mode,
+};
+
+static const struct regulator_ops mt6380_volt_table_ops = {
+	.list_voltage = regulator_list_voltage_table,
+	.map_voltage = regulator_map_voltage_iterate,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6380_regulator_set_mode,
+	.get_mode = mt6380_regulator_get_mode,
+};
+
+static const struct regulator_ops mt6380_volt_fixed_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6380_regulator_set_mode,
+	.get_mode = mt6380_regulator_get_mode,
+};
+
+/* The array is indexed by id(MT6380_ID_XXX) */
+static struct mt6380_regulator_info mt6380_regulators[] = {
+	MT6380_BUCK("buck-vcore1", VCPU, 600000, 1393750, 6250,
+		    buck_volt_range1, MT6380_ANA_CTRL_3, MT6380_ANA_CTRL_1,
+		    0xfe, 3, MT6380_ANA_CTRL_1,
+		    MT6380_CPUBUCK_CON_0, 0x8000000),
+	MT6380_BUCK("buck-vcore", VCORE, 600000, 1393750, 6250,
+		    buck_volt_range2, MT6380_ANA_CTRL_3, MT6380_ANA_CTRL_2,
+		    0xfe, 2, MT6380_ANA_CTRL_2, MT6380_SIDO_CON_0, 0x1000000),
+	MT6380_BUCK("buck-vrf", VRF, 1200000, 1575000, 25000,
+		    buck_volt_range3, MT6380_ANA_CTRL_3, MT6380_SIDO_CON_0,
+		    0x78, 1, MT6380_SIDO_CON_0, MT6380_SIDO_CON_0, 0x8000),
+	MT6380_LDO("ldo-vm", VMLDO, ldo_volt_table1, MT6380_LDO_CTRL_0,
+		   1, MT6380_MLDO_CON_0, 0xE000, MT6380_ANA_CTRL_1, 0x4000000),
+	MT6380_LDO("ldo-va", VALDO, ldo_volt_table2, MT6380_LDO_CTRL_0,
+		   2, MT6380_ALDO_CON_0, 0x400, MT6380_ALDO_CON_0, 0x20),
+	MT6380_REG_FIXED("ldo-vphy", VPHYLDO, MT6380_LDO_CTRL_0, 7, 1800000,
+			 MT6380_PHYLDO_CON_0, 0x80),
+	MT6380_LDO("ldo-vddr", VDDRLDO, ldo_volt_table3, MT6380_LDO_CTRL_0,
+		   8, MT6380_DDRLDO_CON_0, 0x3000, MT6380_DDRLDO_CON_0, 0x80),
+	MT6380_LDO("ldo-vt", VTLDO, ldo_volt_table4, MT6380_LDO_CTRL_0, 3,
+		   MT6380_TLDO_CON_0, 0x400, MT6380_TLDO_CON_0, 0x20),
+};
+
+static int mt6380_regulator_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	struct regulator_config config = {};
+	struct regulator_dev *rdev;
+	int i;
+
+	for (i = 0; i < MT6380_MAX_REGULATOR; i++) {
+		config.dev = &pdev->dev;
+		config.driver_data = &mt6380_regulators[i];
+		config.regmap = regmap;
+		rdev = devm_regulator_register(&pdev->dev,
+					       &mt6380_regulators[i].desc,
+				&config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "failed to register %s\n",
+				mt6380_regulators[i].desc.name);
+			return PTR_ERR(rdev);
+		}
+	}
+	return 0;
+}
+
+static const struct platform_device_id mt6380_platform_ids[] = {
+	{"mt6380-regulator", 0},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6380_platform_ids);
+
+static const struct of_device_id mt6380_of_match[] = {
+	{ .compatible = "mediatek,mt6380-regulator", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt6380_of_match);
+
+static struct platform_driver mt6380_regulator_driver = {
+	.driver = {
+		.name = "mt6380-regulator",
+		.of_match_table = of_match_ptr(mt6380_of_match),
+	},
+	.probe = mt6380_regulator_probe,
+	.id_table = mt6380_platform_ids,
+};
+
+module_platform_driver(mt6380_regulator_driver);
+
+MODULE_AUTHOR("Chenglin Xu <chenglin.xu@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6380 PMIC");
+MODULE_LICENSE("GPL v2");

+ 1 - 1
drivers/regulator/of_regulator.c

@@ -333,7 +333,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
 		search = of_get_child_by_name(dev->of_node,
 		search = of_get_child_by_name(dev->of_node,
 					      desc->regulators_node);
 					      desc->regulators_node);
 	else
 	else
-		search = dev->of_node;
+		search = of_node_get(dev->of_node);
 
 
 	if (!search) {
 	if (!search) {
 		dev_dbg(dev, "Failed to find regulator container node '%s'\n",
 		dev_dbg(dev, "Failed to find regulator container node '%s'\n",

+ 8 - 3
drivers/regulator/pv88090-regulator.c

@@ -43,7 +43,7 @@ enum {
 struct pv88090_regulator {
 struct pv88090_regulator {
 	struct regulator_desc desc;
 	struct regulator_desc desc;
 	/* Current limiting */
 	/* Current limiting */
-	unsigned	n_current_limits;
+	unsigned int n_current_limits;
 	const int	*current_limits;
 	const int	*current_limits;
 	unsigned int limit_mask;
 	unsigned int limit_mask;
 	unsigned int conf;
 	unsigned int conf;
@@ -398,9 +398,14 @@ static int pv88090_i2c_probe(struct i2c_client *i2c,
 				return ret;
 				return ret;
 
 
 			range = (range >>
 			range = (range >>
-				 (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) &
-				PV88080_BUCK_VRANGE_GAIN_MASK;
+				 (PV88090_BUCK_VRANGE_GAIN_SHIFT + i - 1)) &
+				PV88090_BUCK_VRANGE_GAIN_MASK;
 			index = ((range << 1) | conf2);
 			index = ((range << 1) | conf2);
+			if (index > PV88090_ID_BUCK3) {
+				dev_err(chip->dev,
+					"Invalid index(%d)\n", index);
+				return -EINVAL;
+			}
 
 
 			pv88090_regulator_info[i].desc.min_uV
 			pv88090_regulator_info[i].desc.min_uV
 				= pv88090_buck_vol[index].min_uV;
 				= pv88090_buck_vol[index].min_uV;

+ 4 - 4
drivers/regulator/pv88090-regulator.h

@@ -89,10 +89,10 @@
 #define PV88090_BUCK_VDAC_RANGE_2			0x01
 #define PV88090_BUCK_VDAC_RANGE_2			0x01
 
 
 /* PV88090_REG_BUCK_FOLD_RANGE (addr=0x61) */
 /* PV88090_REG_BUCK_FOLD_RANGE (addr=0x61) */
-#define PV88080_BUCK_VRANGE_GAIN_SHIFT			3
-#define PV88080_BUCK_VRANGE_GAIN_MASK			0x01
+#define PV88090_BUCK_VRANGE_GAIN_SHIFT			3
+#define PV88090_BUCK_VRANGE_GAIN_MASK			0x01
 
 
-#define PV88080_BUCK_VRANGE_GAIN_1			0x00
-#define PV88080_BUCK_VRANGE_GAIN_2			0x01
+#define PV88090_BUCK_VRANGE_GAIN_1			0x00
+#define PV88090_BUCK_VRANGE_GAIN_2			0x01
 
 
 #endif	/* __PV88090_REGISTERS_H__ */
 #endif	/* __PV88090_REGISTERS_H__ */

+ 2 - 4
drivers/regulator/pwm-regulator.c

@@ -122,8 +122,7 @@ static int pwm_regulator_enable(struct regulator_dev *dev)
 {
 {
 	struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
 	struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
 
 
-	if (drvdata->enb_gpio)
-		gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
+	gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
 
 
 	return pwm_enable(drvdata->pwm);
 	return pwm_enable(drvdata->pwm);
 }
 }
@@ -134,8 +133,7 @@ static int pwm_regulator_disable(struct regulator_dev *dev)
 
 
 	pwm_disable(drvdata->pwm);
 	pwm_disable(drvdata->pwm);
 
 
-	if (drvdata->enb_gpio)
-		gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
+	gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 0
drivers/regulator/qcom_rpm-regulator.c

@@ -959,6 +959,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	match = of_match_device(rpm_of_match, &pdev->dev);
 	match = of_match_device(rpm_of_match, &pdev->dev);
+	if (!match) {
+		dev_err(&pdev->dev, "failed to match device\n");
+		return -ENODEV;
+	}
+
 	for (reg = match->data; reg->name; reg++) {
 	for (reg = match->data; reg->name; reg++) {
 		vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 		vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 		if (!vreg)
 		if (!vreg)

+ 5 - 0
drivers/regulator/qcom_smd-regulator.c

@@ -570,6 +570,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	match = of_match_device(rpm_of_match, &pdev->dev);
 	match = of_match_device(rpm_of_match, &pdev->dev);
+	if (!match) {
+		dev_err(&pdev->dev, "failed to match device\n");
+		return -ENODEV;
+	}
+
 	for (reg = match->data; reg->name; reg++) {
 	for (reg = match->data; reg->name; reg++) {
 		vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 		vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 		if (!vreg)
 		if (!vreg)

+ 31 - 4
drivers/regulator/rn5t618-regulator.c

@@ -79,6 +79,29 @@ static struct regulator_desc rn5t618_regulators[] = {
 	REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
 	REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
 };
 };
 
 
+static struct regulator_desc rc5t619_regulators[] = {
+	/* DCDC */
+	REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
+	REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
+	REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500),
+	REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500),
+	REG(DCDC5, DC5CTL, BIT(0), DC5DAC, 0xff, 600000, 3500000, 12500),
+	/* LDO */
+	REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 600000, 3500000, 25000),
+	REG(LDO6, LDOEN1, BIT(5), LDO6DAC, 0x7f, 600000, 3500000, 25000),
+	REG(LDO7, LDOEN1, BIT(6), LDO7DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO8, LDOEN1, BIT(7), LDO8DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO9, LDOEN2, BIT(0), LDO9DAC, 0x7f, 900000, 3500000, 25000),
+	REG(LDO10, LDOEN2, BIT(0), LDO10DAC, 0x7f, 900000, 3500000, 25000),
+	/* LDO RTC */
+	REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000),
+	REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
+};
+
 static int rn5t618_regulator_probe(struct platform_device *pdev)
 static int rn5t618_regulator_probe(struct platform_device *pdev)
 {
 {
 	struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
 	struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
@@ -86,13 +109,20 @@ static int rn5t618_regulator_probe(struct platform_device *pdev)
 	struct regulator_dev *rdev;
 	struct regulator_dev *rdev;
 	struct regulator_desc *regulators;
 	struct regulator_desc *regulators;
 	int i;
 	int i;
+	int num_regulators = 0;
 
 
 	switch (rn5t618->variant) {
 	switch (rn5t618->variant) {
 	case RN5T567:
 	case RN5T567:
 		regulators = rn5t567_regulators;
 		regulators = rn5t567_regulators;
+		num_regulators = ARRAY_SIZE(rn5t567_regulators);
 		break;
 		break;
 	case RN5T618:
 	case RN5T618:
 		regulators = rn5t618_regulators;
 		regulators = rn5t618_regulators;
+		num_regulators = ARRAY_SIZE(rn5t618_regulators);
+		break;
+	case RC5T619:
+		regulators = rc5t619_regulators;
+		num_regulators = ARRAY_SIZE(rc5t619_regulators);
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -101,10 +131,7 @@ static int rn5t618_regulator_probe(struct platform_device *pdev)
 	config.dev = pdev->dev.parent;
 	config.dev = pdev->dev.parent;
 	config.regmap = rn5t618->regmap;
 	config.regmap = rn5t618->regmap;
 
 
-	for (i = 0; i < RN5T618_REG_NUM; i++) {
-		if (!regulators[i].name)
-			continue;
-
+	for (i = 0; i < num_regulators; i++) {
 		rdev = devm_regulator_register(&pdev->dev,
 		rdev = devm_regulator_register(&pdev->dev,
 					       &regulators[i],
 					       &regulators[i],
 					       &config);
 					       &config);

+ 2 - 2
drivers/regulator/s5m8767.c

@@ -590,8 +590,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
 		if (of_property_read_u32(reg_np, "op_mode",
 		if (of_property_read_u32(reg_np, "op_mode",
 				&rmode->mode)) {
 				&rmode->mode)) {
 			dev_warn(iodev->dev,
 			dev_warn(iodev->dev,
-				"no op_mode property property at %s\n",
-				reg_np->full_name);
+				"no op_mode property property at %pOF\n",
+				reg_np);
 
 
 			rmode->mode = S5M8767_OPMODE_NORMAL_MODE;
 			rmode->mode = S5M8767_OPMODE_NORMAL_MODE;
 		}
 		}

+ 202 - 0
drivers/regulator/stm32-vrefbuf.c

@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) STMicroelectronics 2017
+ *
+ * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
+ *
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+/* STM32 VREFBUF registers */
+#define STM32_VREFBUF_CSR		0x00
+
+/* STM32 VREFBUF CSR bitfields */
+#define STM32_VRS			GENMASK(6, 4)
+#define STM32_VRR			BIT(3)
+#define STM32_HIZ			BIT(1)
+#define STM32_ENVR			BIT(0)
+
+struct stm32_vrefbuf {
+	void __iomem *base;
+	struct clk *clk;
+};
+
+static const unsigned int stm32_vrefbuf_voltages[] = {
+	/* Matches resp. VRS = 000b, 001b, 010b, 011b */
+	2500000, 2048000, 1800000, 1500000,
+};
+
+static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
+{
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+	u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
+	int ret;
+
+	val = (val & ~STM32_HIZ) | STM32_ENVR;
+	writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
+
+	/*
+	 * Vrefbuf startup time depends on external capacitor: wait here for
+	 * VRR to be set. That means output has reached expected value.
+	 * ~650us sleep should be enough for caps up to 1.5uF. Use 10ms as
+	 * arbitrary timeout.
+	 */
+	ret = readl_poll_timeout(priv->base + STM32_VREFBUF_CSR, val,
+				 !(val & STM32_VRR), 650, 10000);
+	if (ret) {
+		dev_err(&rdev->dev, "stm32 vrefbuf timed out!\n");
+		val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
+		val = (val & ~STM32_ENVR) | STM32_HIZ;
+		writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
+	}
+
+	return ret;
+}
+
+static int stm32_vrefbuf_disable(struct regulator_dev *rdev)
+{
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+	u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
+
+	val = (val & ~STM32_ENVR) | STM32_HIZ;
+	writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
+
+	return 0;
+}
+
+static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev)
+{
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+
+	return readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
+}
+
+static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev,
+					 unsigned sel)
+{
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+	u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
+
+	val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel);
+	writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
+
+	return 0;
+}
+
+static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+	u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
+
+	return FIELD_GET(STM32_VRS, val);
+}
+
+static const struct regulator_ops stm32_vrefbuf_volt_ops = {
+	.enable		= stm32_vrefbuf_enable,
+	.disable	= stm32_vrefbuf_disable,
+	.is_enabled	= stm32_vrefbuf_is_enabled,
+	.get_voltage_sel = stm32_vrefbuf_get_voltage_sel,
+	.set_voltage_sel = stm32_vrefbuf_set_voltage_sel,
+	.list_voltage	= regulator_list_voltage_table,
+};
+
+static const struct regulator_desc stm32_vrefbuf_regu = {
+	.name = "vref",
+	.supply_name = "vdda",
+	.volt_table = stm32_vrefbuf_voltages,
+	.n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages),
+	.ops = &stm32_vrefbuf_volt_ops,
+	.type = REGULATOR_VOLTAGE,
+	.owner = THIS_MODULE,
+};
+
+static int stm32_vrefbuf_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct stm32_vrefbuf *priv;
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret);
+		return ret;
+	}
+
+	config.dev = &pdev->dev;
+	config.driver_data = priv;
+	config.of_node = pdev->dev.of_node;
+	config.init_data = of_get_regulator_init_data(&pdev->dev,
+						      pdev->dev.of_node,
+						      &stm32_vrefbuf_regu);
+
+	rdev = regulator_register(&stm32_vrefbuf_regu, &config);
+	if (IS_ERR(rdev)) {
+		ret = PTR_ERR(rdev);
+		dev_err(&pdev->dev, "register failed with error %d\n", ret);
+		goto err_clk_dis;
+	}
+	platform_set_drvdata(pdev, rdev);
+
+	return 0;
+
+err_clk_dis:
+	clk_disable_unprepare(priv->clk);
+
+	return ret;
+}
+
+static int stm32_vrefbuf_remove(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+	struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
+
+	regulator_unregister(rdev);
+	clk_disable_unprepare(priv->clk);
+
+	return 0;
+};
+
+static const struct of_device_id stm32_vrefbuf_of_match[] = {
+	{ .compatible = "st,stm32-vrefbuf", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, stm32_vrefbuf_of_match);
+
+static struct platform_driver stm32_vrefbuf_driver = {
+	.probe = stm32_vrefbuf_probe,
+	.remove = stm32_vrefbuf_remove,
+	.driver = {
+		.name  = "stm32-vrefbuf",
+		.of_match_table = of_match_ptr(stm32_vrefbuf_of_match),
+	},
+};
+module_platform_driver(stm32_vrefbuf_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 VREFBUF driver");
+MODULE_ALIAS("platform:stm32-vrefbuf");

+ 2 - 2
drivers/reset/reset-socfpga.c

@@ -109,8 +109,8 @@ static int socfpga_reset_probe(struct platform_device *pdev)
 	 * Do not continue, when we encounter an old DT.
 	 * Do not continue, when we encounter an old DT.
 	 */
 	 */
 	if (!of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) {
 	if (!of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) {
-		dev_err(&pdev->dev, "%s missing #reset-cells property\n",
-			pdev->dev.of_node->full_name);
+		dev_err(&pdev->dev, "%pOF missing #reset-cells property\n",
+			pdev->dev.of_node);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 

+ 6 - 0
include/linux/mfd/rn5t618.h

@@ -226,11 +226,17 @@ enum {
 	RN5T618_DCDC2,
 	RN5T618_DCDC2,
 	RN5T618_DCDC3,
 	RN5T618_DCDC3,
 	RN5T618_DCDC4,
 	RN5T618_DCDC4,
+	RN5T618_DCDC5,
 	RN5T618_LDO1,
 	RN5T618_LDO1,
 	RN5T618_LDO2,
 	RN5T618_LDO2,
 	RN5T618_LDO3,
 	RN5T618_LDO3,
 	RN5T618_LDO4,
 	RN5T618_LDO4,
 	RN5T618_LDO5,
 	RN5T618_LDO5,
+	RN5T618_LDO6,
+	RN5T618_LDO7,
+	RN5T618_LDO8,
+	RN5T618_LDO9,
+	RN5T618_LDO10,
 	RN5T618_LDORTC1,
 	RN5T618_LDORTC1,
 	RN5T618_LDORTC2,
 	RN5T618_LDORTC2,
 	RN5T618_REG_NUM,
 	RN5T618_REG_NUM,

+ 32 - 0
include/linux/regulator/mt6380-regulator.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chenglin Xu <chenglin.xu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_REGULATOR_mt6380_H
+#define __LINUX_REGULATOR_mt6380_H
+
+enum {
+	MT6380_ID_VCPU = 0,
+	MT6380_ID_VCORE,
+	MT6380_ID_VRF,
+	MT6380_ID_VMLDO,
+	MT6380_ID_VALDO,
+	MT6380_ID_VPHYLDO,
+	MT6380_ID_VDDRLDO,
+	MT6380_ID_VTLDO,
+	MT6380_ID_RG_MAX,
+};
+
+#define MT6380_MAX_REGULATOR	MT6380_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_mt6380_H */