From 518a7d333f0382199c81b58afbca62fa37221184 Mon Sep 17 00:00:00 2001 From: Michael Bohan Date: Tue, 20 Mar 2012 15:43:35 -0700 Subject: [PATCH 1/8] copper: regulator-stub: Add devices for Krait Power Control The Krait Power Control devices are used for setting voltage levels per each Krait core. They also can disconnect each individual Krait from the upstream ganged supply. Change-Id: Ia1abd8312dfb67abd5705545f152697aa3c71da6 Signed-off-by: Michael Bohan --- arch/arm/mach-msm/board-copper-regulator.c | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/arm/mach-msm/board-copper-regulator.c b/arch/arm/mach-msm/board-copper-regulator.c index 89878ced24a..94099366b17 100644 --- a/arch/arm/mach-msm/board-copper-regulator.c +++ b/arch/arm/mach-msm/board-copper-regulator.c @@ -138,6 +138,18 @@ VREG_CONSUMERS(LVS2) = { VREG_CONSUMERS(LVS3) = { REGULATOR_SUPPLY("8941_lvs3", NULL), }; +VREG_CONSUMERS(K0) = { + REGULATOR_SUPPLY("krait0", NULL), +}; +VREG_CONSUMERS(K1) = { + REGULATOR_SUPPLY("krait1", NULL), +}; +VREG_CONSUMERS(K2) = { + REGULATOR_SUPPLY("krait2", NULL), +}; +VREG_CONSUMERS(K3) = { + REGULATOR_SUPPLY("krait3", NULL), +}; #define PM8X41_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \ _always_on, _supply_regulator, _hpm_min, _system_uA) \ @@ -189,6 +201,14 @@ VREG_CONSUMERS(LVS3) = { PM8X41_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, \ _always_on, _supply_regulator, 0, 0) +#define KRAIT_PWR(_id, _name, _always_on, _min_uV, _max_uV, \ + _supply_regulator, _hpm_min, _system_uA) \ + PM8X41_VREG_INIT(_id, _name, _min_uV, _max_uV, REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \ + REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \ + REGULATOR_CHANGE_DRMS, _always_on, \ + _supply_regulator, _hpm_min, _system_uA) + /* PM8x41 regulator constraints */ /* ID name a_on min_uV max_uV supply hpm_min sys_uA */ @@ -233,6 +253,12 @@ PM8X41_VS(LVS1, "8941_lvs1", 0, "8941_s3"); PM8X41_VS(LVS2, "8941_lvs2", 0, "8941_s3"); PM8X41_VS(LVS3, "8941_lvs3", 0, "8941_s3"); +/* ID name a_on min_uV max_uV supply hpm_min sys_uA */ +KRAIT_PWR(K0, "krait0", 0, 850000, 1100000, NULL, 100000, 0); +KRAIT_PWR(K1, "krait1", 0, 850000, 1100000, NULL, 100000, 0); +KRAIT_PWR(K2, "krait2", 0, 850000, 1100000, NULL, 100000, 0); +KRAIT_PWR(K3, "krait3", 0, 850000, 1100000, NULL, 100000, 0); + #define VREG_DEVICE(_name, _devid) \ vreg_device_##_name __devinitdata = \ { \ @@ -279,6 +305,10 @@ static struct platform_device VREG_DEVICE(L24, 35); static struct platform_device VREG_DEVICE(LVS1, 36); static struct platform_device VREG_DEVICE(LVS2, 37); static struct platform_device VREG_DEVICE(LVS3, 38); +static struct platform_device VREG_DEVICE(K0, 39); +static struct platform_device VREG_DEVICE(K1, 40); +static struct platform_device VREG_DEVICE(K2, 41); +static struct platform_device VREG_DEVICE(K3, 42); struct platform_device *msm_copper_stub_regulator_devices[] __devinitdata = { &vreg_device_S1B, @@ -319,6 +349,10 @@ struct platform_device *msm_copper_stub_regulator_devices[] __devinitdata = { &vreg_device_LVS1, &vreg_device_LVS2, &vreg_device_LVS3, + &vreg_device_K0, + &vreg_device_K1, + &vreg_device_K2, + &vreg_device_K3, }; int msm_copper_stub_regulator_devices_len __devinitdata = From 2f81201c28edea80eae4ce88216d82682b4bff52 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Mon, 10 Oct 2011 21:49:35 +0530 Subject: [PATCH 2/8] dt: add empty dt helpers for non-dt build Add empty of_device_is_compatible() and of_parse_phandle() for non-dt builds to work. Change-Id: Id91ac5e6f628bb9f7dea5ef57c8727c3f10ee6ce Signed-off-by: Rajendra Nayak Signed-off-by: Grant Likely [mbohan: resolve merge conflict in include/linux/of.h] Signed-off-by: Michael Bohan --- include/linux/of.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/of.h b/include/linux/of.h index b904f7e311e..452ed980625 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -249,6 +249,12 @@ static inline bool of_have_populated_dt(void) #define for_each_child_of_node(parent, child) \ while (0) +static inline int of_device_is_compatible(const struct device_node *device, + const char *name) +{ + return 0; +} + static inline struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) @@ -288,6 +294,13 @@ static inline const void *of_get_property(const struct device_node *node, return NULL; } +static inline struct device_node *of_parse_phandle(struct device_node *np, + const char *phandle_name, + int index) +{ + return NULL; +} + #endif /* CONFIG_OF */ static inline int of_property_read_u32(const struct device_node *np, From a6e279050d1b3623397fdd32971d743f234ea6ca Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Jun 2011 23:36:18 +0100 Subject: [PATCH 3/8] regulator: Properly register dummy regulator driver Recent changes in the driver core appear to mean that the data structures for the driver core are not fully initialised unless the driver is bound. Make sure the driver core knows the dummy driver is in use by binding it to a driver. Change-Id: I56a14e862c1bab334124072e1a850e8cff9afb12 Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood Signed-off-by: Michael Bohan --- drivers/regulator/dummy.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index c7410bde7b5..f6ef6694ab9 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -36,6 +36,29 @@ static struct regulator_desc dummy_desc = { .ops = &dummy_ops, }; +static int __devinit dummy_regulator_probe(struct platform_device *pdev) +{ + int ret; + + dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, + &dummy_initdata, NULL); + if (IS_ERR(dummy_regulator_rdev)) { + ret = PTR_ERR(dummy_regulator_rdev); + pr_err("Failed to register regulator: %d\n", ret); + return ret; + } + + return 0; +} + +static struct platform_driver dummy_regulator_driver = { + .probe = dummy_regulator_probe, + .driver = { + .name = "reg-dummy", + .owner = THIS_MODULE, + }, +}; + static struct platform_device *dummy_pdev; void __init regulator_dummy_init(void) @@ -55,12 +78,9 @@ void __init regulator_dummy_init(void) return; } - dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, - &dummy_initdata, NULL); - if (IS_ERR(dummy_regulator_rdev)) { - ret = PTR_ERR(dummy_regulator_rdev); - pr_err("Failed to register regulator: %d\n", ret); + ret = platform_driver_register(&dummy_regulator_driver); + if (ret != 0) { + pr_err("Failed to register dummy regulator driver: %d\n", ret); platform_device_unregister(dummy_pdev); - return; } } From 5d028cd394fc946677c16acc0fbdbb90313ed33a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 14 Oct 2011 13:36:04 +0100 Subject: [PATCH 4/8] regulator: Constify constraints name There's no need for the API to modify it and having it const makes it easier to use with random strings the board code has. Change-Id: Icd7e600291f281e80f60ef857c22f22cba08bfc1 Signed-off-by: Mark Brown [mbohan: port MSM regulator drivers to new const type] Signed-off-by: Michael Bohan --- arch/arm/mach-msm/proccomm-regulator.c | 2 +- drivers/mfd/pm8018-core.c | 2 +- drivers/mfd/pm8038-core.c | 2 +- drivers/mfd/pm8921-core.c | 2 +- include/linux/regulator/machine.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-msm/proccomm-regulator.c b/arch/arm/mach-msm/proccomm-regulator.c index ba10d3831a7..d1fa15e17fc 100644 --- a/arch/arm/mach-msm/proccomm-regulator.c +++ b/arch/arm/mach-msm/proccomm-regulator.c @@ -196,7 +196,7 @@ static struct regulator_ops proccomm_regulator_ops = { static struct regulator_dev *__devinit create_proccomm_rdev( struct proccomm_regulator_info *info, struct device *parent) { - char *name; + const char *name; struct proccomm_regulator_drvdata *d; struct regulator_dev *rdev; int rc = 0; diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c index f986b5dcadc..0418157761a 100644 --- a/drivers/mfd/pm8018-core.c +++ b/drivers/mfd/pm8018-core.c @@ -284,7 +284,7 @@ static struct pm8xxx_vreg regulator_data[] = { #define MAX_NAME_COMPARISON_LEN 32 static int __devinit match_regulator( - struct pm8xxx_regulator_core_platform_data *core_data, char *name) + struct pm8xxx_regulator_core_platform_data *core_data, const char *name) { int found = 0; int i; diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c index ac574184496..b03b7ac4bbd 100644 --- a/drivers/mfd/pm8038-core.c +++ b/drivers/mfd/pm8038-core.c @@ -326,7 +326,7 @@ static struct pm8xxx_vreg regulator_data[] = { #define MAX_NAME_COMPARISON_LEN 32 static int __devinit match_regulator( - struct pm8xxx_regulator_core_platform_data *core_data, char *name) + struct pm8xxx_regulator_core_platform_data *core_data, const char *name) { int found = 0; int i; diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index 68395e3da51..0f41ba7fc02 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c @@ -448,7 +448,7 @@ static struct pm8xxx_vreg pm8917_regulator_data[] = { #define MAX_NAME_COMPARISON_LEN 32 static int __devinit match_regulator(enum pm8xxx_version version, - struct pm8xxx_regulator_core_platform_data *core_data, char *name) + struct pm8xxx_regulator_core_platform_data *core_data, const char *name) { int found = 0; int i; diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 6804ef3a390..22a832a254c 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -95,7 +95,7 @@ struct regulator_state { */ struct regulation_constraints { - char *name; + const char *name; /* voltage output range (inclusive) - for voltage control */ int min_uV; From 67b54c2342283aff93f94270e8dcc37484c835cf Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 18 Nov 2011 16:47:17 +0530 Subject: [PATCH 5/8] regulator: helper routine to extract regulator_init_data The helper routine is meant to be used by the regulator drivers to extract the regulator_init_data structure from the data that is passed from device tree. 'consumer_supplies' which is part of regulator_init_data is not extracted as the regulator consumer mappings are passed through DT differently, implemented in subsequent patches. Similarly the regulator<-->parent/supply mapping is handled in subsequent patches. Also add documentation for regulator bindings to be used to pass regulator_init_data struct information from device tree. Some of the regulator properties which are linux and board specific, are left out since its not clear if they can be in someway embedded into the kernel or passed in from DT. They will be revisited later. Change-Id: I4f270a41687199032499cd923854a871c4d58ca2 Signed-off-by: Rajendra Nayak Signed-off-by: Mark Brown Signed-off-by: Michael Bohan --- .../bindings/regulator/regulator.txt | 54 +++++++++++++ drivers/regulator/Makefile | 1 + drivers/regulator/of_regulator.c | 81 +++++++++++++++++++ include/linux/regulator/of_regulator.h | 20 +++++ 4 files changed, 156 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/regulator.txt create mode 100644 drivers/regulator/of_regulator.c create mode 100644 include/linux/regulator/of_regulator.h diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt new file mode 100644 index 00000000000..82bef20d4c4 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -0,0 +1,54 @@ +Voltage/Current Regulators + +Optional properties: +- regulator-name: A string used as a descriptive name for regulator outputs +- regulator-min-microvolt: smallest voltage consumers may set +- regulator-max-microvolt: largest voltage consumers may set +- regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops +- regulator-min-microamp: smallest current consumers may set +- regulator-max-microamp: largest current consumers may set +- regulator-always-on: boolean, regulator should never be disabled +- regulator-boot-on: bootloader/firmware enabled regulator +- -supply: phandle to the parent supply/regulator node + +Example: + + xyzreg: regulator@0 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + vin-supply = <&vin>; + }; + +Regulator Consumers: +Consumer nodes can reference one or more of its supplies/ +regulators using the below bindings. + +- -supply: phandle to the regulator node + +These are the same bindings that a regulator in the above +example used to reference its own supply, in which case +its just seen as a special case of a regulator being a +consumer itself. + +Example of a consumer device node (mmc) referencing two +regulators (twl-reg1 and twl-reg2), + + twl-reg1: regulator@0 { + ... + ... + ... + }; + + twl-reg2: regulator@1 { + ... + ... + ... + }; + + mmc: mmc@0x0 { + ... + ... + vmmc-supply = <&twl-reg1>; + vmmcaux-supply = <&twl-reg2>; + }; diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 74b1f718c6e..7e529c728bc 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_REGULATOR) += core.o dummy.o +obj-$(CONFIG_OF) += of_regulator.o obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c new file mode 100644 index 00000000000..76673c784ab --- /dev/null +++ b/drivers/regulator/of_regulator.c @@ -0,0 +1,81 @@ +/* + * OF helpers for regulator framework + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Rajendra Nayak + * + * 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. + */ + +#include +#include +#include + +static void of_get_regulation_constraints(struct device_node *np, + struct regulator_init_data **init_data) +{ + const __be32 *min_uV, *max_uV, *uV_offset; + const __be32 *min_uA, *max_uA; + struct regulation_constraints *constraints = &(*init_data)->constraints; + + constraints->name = of_get_property(np, "regulator-name", NULL); + + min_uV = of_get_property(np, "regulator-min-microvolt", NULL); + if (min_uV) + constraints->min_uV = be32_to_cpu(*min_uV); + max_uV = of_get_property(np, "regulator-max-microvolt", NULL); + if (max_uV) + constraints->max_uV = be32_to_cpu(*max_uV); + + /* Voltage change possible? */ + if (constraints->min_uV != constraints->max_uV) + constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; + + uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL); + if (uV_offset) + constraints->uV_offset = be32_to_cpu(*uV_offset); + min_uA = of_get_property(np, "regulator-min-microamp", NULL); + if (min_uA) + constraints->min_uA = be32_to_cpu(*min_uA); + max_uA = of_get_property(np, "regulator-max-microamp", NULL); + if (max_uA) + constraints->max_uA = be32_to_cpu(*max_uA); + + /* Current change possible? */ + if (constraints->min_uA != constraints->max_uA) + constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT; + + if (of_find_property(np, "regulator-boot-on", NULL)) + constraints->boot_on = true; + + if (of_find_property(np, "regulator-always-on", NULL)) + constraints->always_on = true; + else /* status change should be possible if not always on. */ + constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; +} + +/** + * of_get_regulator_init_data - extract regulator_init_data structure info + * @dev: device requesting for regulator_init_data + * + * Populates regulator_init_data structure by extracting data from device + * tree node, returns a pointer to the populated struture or NULL if memory + * alloc fails. + */ +struct regulator_init_data *of_get_regulator_init_data(struct device *dev) +{ + struct regulator_init_data *init_data; + + if (!dev->of_node) + return NULL; + + init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL); + if (!init_data) + return NULL; /* Out of memory? */ + + of_get_regulation_constraints(dev->of_node, &init_data); + return init_data; +} diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h new file mode 100644 index 00000000000..d83a98d3e3f --- /dev/null +++ b/include/linux/regulator/of_regulator.h @@ -0,0 +1,20 @@ +/* + * OpenFirmware regulator support routines + * + */ + +#ifndef __LINUX_OF_REG_H +#define __LINUX_OF_REG_H + +#if defined(CONFIG_OF) +extern struct regulator_init_data + *of_get_regulator_init_data(struct device *dev); +#else +static inline struct regulator_init_data + *of_get_regulator_init_data(struct device *dev) +{ + return NULL; +} +#endif /* CONFIG_OF */ + +#endif /* __LINUX_OF_REG_H */ From 1dc524082208921f6511d923a34110d960b134f9 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 18 Nov 2011 16:47:18 +0530 Subject: [PATCH 6/8] regulator: adapt fixed regulator driver to dt The fixed regulator driver uses of_get_fixed_voltage_config() to extract fixed_voltage_config structure contents from device tree. Also add documenation for additional bindings for fixed regulators that can be passed through dt. Change-Id: I09411d465beae31b567c334f387563a0ed2877d8 Signed-off-by: Rajendra Nayak Signed-off-by: Mark Brown Signed-off-by: Michael Bohan --- .../bindings/regulator/fixed-regulator.txt | 29 +++++++++ drivers/regulator/fixed.c | 65 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/fixed-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt new file mode 100644 index 00000000000..9cf57fd042d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt @@ -0,0 +1,29 @@ +Fixed Voltage regulators + +Required properties: +- compatible: Must be "regulator-fixed"; + +Optional properties: +- gpio: gpio to use for enable control +- startup-delay-us: startup time in microseconds +- enable-active-high: Polarity of GPIO is Active high +If this property is missing, the default assumed is Active low. + +Any property defined as part of the core regulator +binding, defined in regulator.txt, can also be used. +However a fixed voltage regulator is expected to have the +regulator-min-microvolt and regulator-max-microvolt +to be the same. + +Example: + + abc: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-supply"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio1 16 0>; + startup-delay-us = <70000>; + enable-active-high; + regulator-boot-on + }; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 2fe9d99c9f2..740a9005306 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -26,6 +26,10 @@ #include #include #include +#include +#include +#include +#include struct fixed_voltage_data { struct regulator_desc desc; @@ -37,6 +41,53 @@ struct fixed_voltage_data { bool is_enabled; }; + +/** + * of_get_fixed_voltage_config - extract fixed_voltage_config structure info + * @dev: device requesting for fixed_voltage_config + * + * Populates fixed_voltage_config structure by extracting data from device + * tree node, returns a pointer to the populated structure of NULL if memory + * alloc fails. + */ +struct fixed_voltage_config *of_get_fixed_voltage_config(struct device *dev) +{ + struct fixed_voltage_config *config; + struct device_node *np = dev->of_node; + const __be32 *delay; + struct regulator_init_data *init_data; + + config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), + GFP_KERNEL); + if (!config) + return NULL; + + config->init_data = of_get_regulator_init_data(dev); + init_data = config->init_data; + + config->supply_name = init_data->constraints.name; + if (init_data->constraints.min_uV == init_data->constraints.max_uV) { + config->microvolts = init_data->constraints.min_uV; + } else { + dev_err(dev, + "Fixed regulator specified with variable voltages\n"); + return NULL; + } + + if (init_data->constraints.boot_on) + config->enabled_at_boot = true; + + config->gpio = of_get_named_gpio(np, "gpio", 0); + delay = of_get_property(np, "startup-delay-us", NULL); + if (delay) + config->startup_delay = be32_to_cpu(*delay); + + if (of_find_property(np, "enable-active-high", NULL)) + config->enable_high = true; + + return config; +} + static int fixed_voltage_is_enabled(struct regulator_dev *dev) { struct fixed_voltage_data *data = rdev_get_drvdata(dev); @@ -108,6 +159,9 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) struct fixed_voltage_data *drvdata; int ret; + if (pdev->dev.of_node) + config = of_get_fixed_voltage_config(&pdev->dev); + drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL); if (drvdata == NULL) { dev_err(&pdev->dev, "Failed to allocate device data\n"); @@ -216,12 +270,23 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev) return 0; } +#if defined(CONFIG_OF) +static const struct of_device_id fixed_of_match[] __devinitconst = { + { .compatible = "regulator-fixed", }, + {}, +}; +MODULE_DEVICE_TABLE(of, fixed_of_match); +#else +#define fixed_of_match NULL +#endif + static struct platform_driver regulator_fixed_voltage_driver = { .probe = reg_fixed_voltage_probe, .remove = __devexit_p(reg_fixed_voltage_remove), .driver = { .name = "reg-fixed-voltage", .owner = THIS_MODULE, + .of_match_table = fixed_of_match, }, }; From 11eafc62cd500dcb770d075bc63a9e2f3a9fa692 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 18 Nov 2011 16:47:19 +0530 Subject: [PATCH 7/8] regulator: pass additional of_node to regulator_register() With device tree support for regulators, its needed that the regulator_dev->dev device has the right of_node attached. To be able to do this add an additional parameter to the regulator_register() api, wherein the dt-adapted driver can then pass this additional info onto the regulator core. Change-Id: Idf7c4e532cc06fd00b8182b635d15dcfafb2cef9 Signed-off-by: Rajendra Nayak Signed-off-by: Mark Brown [mbohan: Update regulator_register for msm regulator drivers] Signed-off-by: Michael Bohan --- arch/arm/mach-msm/footswitch-8x60.c | 3 ++- arch/arm/mach-msm/footswitch-pcom.c | 3 ++- arch/arm/mach-msm/proccomm-regulator.c | 2 +- arch/arm/mach-msm/rpm-regulator.c | 2 +- arch/arm/mach-msm/saw-regulator.c | 4 ++-- drivers/regulator/88pm8607.c | 2 +- drivers/regulator/ab3100.c | 2 +- drivers/regulator/ab8500.c | 2 +- drivers/regulator/ad5398.c | 2 +- drivers/regulator/bq24022.c | 2 +- drivers/regulator/core.c | 3 ++- drivers/regulator/da903x.c | 2 +- drivers/regulator/db8500-prcmu.c | 2 +- drivers/regulator/dummy.c | 2 +- drivers/regulator/fixed.c | 2 +- drivers/regulator/gpio-regulator.c | 2 +- drivers/regulator/isl6271a-regulator.c | 2 +- drivers/regulator/lp3971.c | 2 +- drivers/regulator/lp3972.c | 2 +- drivers/regulator/max1586.c | 2 +- drivers/regulator/max8649.c | 2 +- drivers/regulator/max8660.c | 2 +- drivers/regulator/max8925-regulator.c | 2 +- drivers/regulator/max8952.c | 2 +- drivers/regulator/max8997.c | 2 +- drivers/regulator/max8998.c | 2 +- drivers/regulator/mc13783-regulator.c | 2 +- drivers/regulator/mc13892-regulator.c | 2 +- drivers/regulator/pcap-regulator.c | 2 +- drivers/regulator/pcf50633-regulator.c | 2 +- drivers/regulator/pm8058-xo.c | 2 +- drivers/regulator/pm8xxx-regulator.c | 4 ++-- drivers/regulator/pmic8058-regulator.c | 2 +- drivers/regulator/pmic8901-regulator.c | 2 +- drivers/regulator/stub-regulator.c | 2 +- drivers/regulator/tps6105x-regulator.c | 3 ++- drivers/regulator/tps65023-regulator.c | 2 +- drivers/regulator/tps6507x-regulator.c | 2 +- drivers/regulator/tps6524x-regulator.c | 2 +- drivers/regulator/tps6586x-regulator.c | 2 +- drivers/regulator/tps65910-regulator.c | 2 +- drivers/regulator/twl-regulator.c | 2 +- drivers/regulator/wm831x-dcdc.c | 8 ++++---- drivers/regulator/wm831x-isink.c | 2 +- drivers/regulator/wm831x-ldo.c | 6 +++--- drivers/regulator/wm8350-regulator.c | 2 +- drivers/regulator/wm8400-regulator.c | 2 +- drivers/regulator/wm8994-regulator.c | 2 +- include/linux/regulator/driver.h | 2 +- sound/soc/codecs/sgtl5000.c | 2 +- 50 files changed, 61 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c index 4609a4b019c..d5a1d3f6726 100644 --- a/arch/arm/mach-msm/footswitch-8x60.c +++ b/arch/arm/mach-msm/footswitch-8x60.c @@ -653,7 +653,8 @@ static int footswitch_probe(struct platform_device *pdev) regval &= ~RETENTION_BIT; writel_relaxed(regval, fs->gfs_ctl_reg); - fs->rdev = regulator_register(&fs->desc, &pdev->dev, init_data, fs); + fs->rdev = regulator_register(&fs->desc, &pdev->dev, + init_data, fs, NULL); if (IS_ERR(footswitches[pdev->id].rdev)) { pr_err("regulator_register(\"%s\") failed\n", fs->desc.name); diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c index 673253b9085..73cbab1d2f2 100644 --- a/arch/arm/mach-msm/footswitch-pcom.c +++ b/arch/arm/mach-msm/footswitch-pcom.c @@ -266,7 +266,8 @@ static int footswitch_probe(struct platform_device *pdev) if (rc) return rc; - fs->rdev = regulator_register(&fs->desc, &pdev->dev, init_data, fs); + fs->rdev = regulator_register(&fs->desc, &pdev->dev, + init_data, fs, NULL); if (IS_ERR(fs->rdev)) { pr_err("regulator_register(%s) failed\n", fs->desc.name); rc = PTR_ERR(fs->rdev); diff --git a/arch/arm/mach-msm/proccomm-regulator.c b/arch/arm/mach-msm/proccomm-regulator.c index d1fa15e17fc..fff3a11549c 100644 --- a/arch/arm/mach-msm/proccomm-regulator.c +++ b/arch/arm/mach-msm/proccomm-regulator.c @@ -247,7 +247,7 @@ static struct regulator_dev *__devinit create_proccomm_rdev( d->negative = info->negative; d->rdesc.n_voltages = info->n_voltages; - rdev = regulator_register(&d->rdesc, parent, &info->init_data, d); + rdev = regulator_register(&d->rdesc, parent, &info->init_data, d, NULL); if (IS_ERR(rdev)) { rc = PTR_ERR(rdev); diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c index 719ea8ad633..c708df502c7 100644 --- a/arch/arm/mach-msm/rpm-regulator.c +++ b/arch/arm/mach-msm/rpm-regulator.c @@ -1330,7 +1330,7 @@ rpm_vreg_init_regulator(const struct rpm_regulator_init_data *pdata, if (rc) goto bail; - rdev = regulator_register(rdesc, dev, &(pdata->init_data), vreg); + rdev = regulator_register(rdesc, dev, &(pdata->init_data), vreg, NULL); if (IS_ERR(rdev)) { rc = PTR_ERR(rdev); pr_err("regulator_register failed: %s, rc=%d\n", diff --git a/arch/arm/mach-msm/saw-regulator.c b/arch/arm/mach-msm/saw-regulator.c index b11b1fa2cae..c747e5bd36a 100644 --- a/arch/arm/mach-msm/saw-regulator.c +++ b/arch/arm/mach-msm/saw-regulator.c @@ -174,8 +174,8 @@ static int __devinit saw_probe(struct platform_device *pdev) vreg->desc.owner = THIS_MODULE; vreg->uV = MIN_CORE_VOLTAGE; - vreg->rdev = regulator_register(&vreg->desc, &pdev->dev, init_data, - vreg); + vreg->rdev = regulator_register(&vreg->desc, &pdev->dev, + init_data, vreg, NULL); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); pr_err("regulator_register failed, rc=%d.\n", rc); diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index d63fddb0fbb..443f2dffac5 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -426,7 +426,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) /* replace driver_data with info */ info->regulator = regulator_register(&info->desc, &pdev->dev, - pdata, info); + pdata, info, NULL); if (IS_ERR(info->regulator)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 585e4946fe0..042271aace6 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -634,7 +634,7 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) rdev = regulator_register(&ab3100_regulator_desc[i], &pdev->dev, &plfdata->reg_constraints[i], - reg); + reg, NULL); if (IS_ERR(rdev)) { err = PTR_ERR(rdev); diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 02f3c2333c8..8b13b0eeeb7 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -821,7 +821,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* register regulator with framework */ info->regulator = regulator_register(&info->desc, &pdev->dev, - &pdata->regulator[i], info); + &pdata->regulator[i], info, NULL); if (IS_ERR(info->regulator)) { err = PTR_ERR(info->regulator); dev_err(&pdev->dev, "failed to register regulator %s\n", diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index a4be41614ee..483c8093085 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -233,7 +233,7 @@ static int __devinit ad5398_probe(struct i2c_client *client, chip->current_mask = (chip->current_level - 1) << chip->current_offset; chip->rdev = regulator_register(&ad5398_reg, &client->dev, - init_data, chip); + init_data, chip, NULL); if (IS_ERR(chip->rdev)) { ret = PTR_ERR(chip->rdev); dev_err(&client->dev, "failed to register %s %s\n", diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c index 068d488a4f7..dc4a8e68b55 100644 --- a/drivers/regulator/bq24022.c +++ b/drivers/regulator/bq24022.c @@ -106,7 +106,7 @@ static int __init bq24022_probe(struct platform_device *pdev) ret = gpio_direction_output(pdata->gpio_nce, 1); bq24022 = regulator_register(&bq24022_desc, &pdev->dev, - pdata->init_data, pdata); + pdata->init_data, pdata, NULL); if (IS_ERR(bq24022)) { dev_dbg(&pdev->dev, "couldn't register regulator\n"); ret = PTR_ERR(bq24022); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2b58215dde2..ca0fea1b2b7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3080,7 +3080,7 @@ static inline void rdev_init_debugfs(struct regulator_dev *rdev) */ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct device *dev, const struct regulator_init_data *init_data, - void *driver_data) + void *driver_data, struct device_node *of_node) { static atomic_t regulator_no = ATOMIC_INIT(0); struct regulator_dev *rdev; @@ -3140,6 +3140,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, /* register with sysfs */ rdev->dev.class = ®ulator_class; + rdev->dev.of_node = of_node; rdev->dev.parent = dev; dev_set_name(&rdev->dev, "regulator.%d", atomic_inc_return(®ulator_no) - 1); diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 362e0822108..f3064fea5ae 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -536,7 +536,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) ri->desc.ops = &da9030_regulator_ldo1_15_ops; rdev = regulator_register(&ri->desc, &pdev->dev, - pdev->dev.platform_data, ri); + pdev->dev.platform_data, ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 2bb8f451cc0..f88b13db49b 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -485,7 +485,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) /* register with the regulator framework */ info->rdev = regulator_register(&info->desc, &pdev->dev, - init_data, info); + init_data, info, NULL); if (IS_ERR(info->rdev)) { err = PTR_ERR(info->rdev); dev_err(&pdev->dev, "failed to register %s: err %i\n", diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index f6ef6694ab9..910583ffb70 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -41,7 +41,7 @@ static int __devinit dummy_regulator_probe(struct platform_device *pdev) int ret; dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, - &dummy_initdata, NULL); + &dummy_initdata, NULL, NULL); if (IS_ERR(dummy_regulator_rdev)) { ret = PTR_ERR(dummy_regulator_rdev); pr_err("Failed to register regulator: %d\n", ret); diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 740a9005306..906b2658c39 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -233,7 +233,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) } drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, - config->init_data, drvdata); + config->init_data, drvdata, NULL); if (IS_ERR(drvdata->dev)) { ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index b91e32f98b2..1fd390c24cc 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -152,7 +152,7 @@ static int __devinit gpio_vreg_probe(struct platform_device *pdev) vreg->desc.owner = THIS_MODULE; vreg->rdev = regulator_register(&vreg->desc, &pdev->dev, - &pdata->init_data, vreg); + &pdata->init_data, vreg, NULL); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); pr_err("%s: regulator_register failed, rc=%d.\n", vreg->name, diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index e4b3592e817..c1a456c4257 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -170,7 +170,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, for (i = 0; i < 3; i++) { pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev, - init_data, pmic); + init_data, pmic, NULL); if (IS_ERR(pmic->rdev[i])) { dev_err(&i2c->dev, "failed to register %s\n", id->name); err = PTR_ERR(pmic->rdev[i]); diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 0f22ef12601..42b1a303665 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -450,7 +450,7 @@ static int __devinit setup_regulators(struct lp3971 *lp3971, for (i = 0; i < pdata->num_regulators; i++) { struct lp3971_regulator_subdev *reg = &pdata->regulators[i]; lp3971->rdev[i] = regulator_register(®ulators[reg->id], - lp3971->dev, reg->initdata, lp3971); + lp3971->dev, reg->initdata, lp3971, NULL); if (IS_ERR(lp3971->rdev[i])) { err = PTR_ERR(lp3971->rdev[i]); diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index 6aa1b506fb5..939e7f482cf 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -554,7 +554,7 @@ static int __devinit setup_regulators(struct lp3972 *lp3972, for (i = 0; i < pdata->num_regulators; i++) { struct lp3972_regulator_subdev *reg = &pdata->regulators[i]; lp3972->rdev[i] = regulator_register(®ulators[reg->id], - lp3972->dev, reg->initdata, lp3972); + lp3972->dev, reg->initdata, lp3972, NULL); if (IS_ERR(lp3972->rdev[i])) { err = PTR_ERR(lp3972->rdev[i]); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 3f49512c513..40e7a4db285 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -214,7 +214,7 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, } rdev[i] = regulator_register(&max1586_reg[id], &client->dev, pdata->subdevs[i].platform_data, - max1586); + max1586, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(&client->dev, "failed to register %s\n", diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 30eb9e54f7e..14d6d28d6fa 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -347,7 +347,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, } info->regulator = regulator_register(&dcdc_desc, &client->dev, - pdata->regulator, info); + pdata->regulator, info, NULL); if (IS_ERR(info->regulator)) { dev_err(info->dev, "failed to register regulator %s\n", dcdc_desc.name); diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 33f5d9a492e..a838e664569 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -449,7 +449,7 @@ static int __devinit max8660_probe(struct i2c_client *client, rdev[i] = regulator_register(&max8660_reg[id], &client->dev, pdata->subdevs[i].platform_data, - max8660); + max8660, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(&client->dev, "failed to register %s\n", diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index e4dbd667c04..dd5fae9ed2d 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -265,7 +265,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) ri->chip = chip; rdev = regulator_register(&ri->desc, &pdev->dev, - pdata->regulator[pdev->id], ri); + pdata->regulator[pdev->id], ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 486ed8141fc..c4bfd4d016c 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -211,7 +211,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, mutex_init(&max8952->mutex); max8952->rdev = regulator_register(®ulator, max8952->dev, - &pdata->reg_data, max8952); + &pdata->reg_data, max8952, NULL); if (IS_ERR(max8952->rdev)) { ret = PTR_ERR(max8952->rdev); diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index ad6628ca94f..f701ca5b414 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1145,7 +1145,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) regulators[id].n_voltages = 16; rdev[i] = regulator_register(®ulators[id], max8997->dev, - pdata->regulators[i].initdata, max8997); + pdata->regulators[i].initdata, max8997, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(max8997->dev, "regulator init failed for %d\n", diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 41a1495eec2..2d38c2493a0 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -847,7 +847,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) regulators[index].n_voltages = count; } rdev[i] = regulator_register(®ulators[index], max8998->dev, - pdata->regulators[i].initdata, max8998); + pdata->regulators[i].initdata, max8998, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(max8998->dev, "regulator init failed\n"); diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 730f43ad415..8d5822b28ec 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -356,7 +356,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) init_data = &pdata->regulators[i]; priv->regulators[i] = regulator_register( &mc13783_regulators[init_data->id].desc, - &pdev->dev, init_data->init_data, priv); + &pdev->dev, init_data->init_data, priv, NULL); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 3285d41842f..9d82b5c89dd 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -572,7 +572,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) init_data = &pdata->regulators[i]; priv->regulators[i] = regulator_register( &mc13892_regulators[init_data->id].desc, - &pdev->dev, init_data->init_data, priv); + &pdev->dev, init_data->init_data, priv, NULL); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 31f6e11a7f1..a5aab1b08bc 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -277,7 +277,7 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev) void *pcap = dev_get_drvdata(pdev->dev.parent); rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev, - pdev->dev.platform_data, pcap); + pdev->dev.platform_data, pcap, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 69a11d9dd87..1d1c3105629 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -320,7 +320,7 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) pcf = dev_to_pcf50633(pdev->dev.parent); rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - pdev->dev.platform_data, pcf); + pdev->dev.platform_data, pcf, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c index b778660d43b..90093dddd10 100644 --- a/drivers/regulator/pm8058-xo.c +++ b/drivers/regulator/pm8058-xo.c @@ -162,7 +162,7 @@ static int __devinit pm8058_xo_buffer_probe(struct platform_device *pdev) goto bail; xo->rdev = regulator_register(rdesc, &pdev->dev, - &xo->pdata->init_data, xo); + &xo->pdata->init_data, xo, NULL); if (IS_ERR(xo->rdev)) { rc = PTR_ERR(xo->rdev); pr_err("FAIL: regulator_register(%s): rc=%d\n", diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c index fd691f05142..833c5132a89 100644 --- a/drivers/regulator/pm8xxx-regulator.c +++ b/drivers/regulator/pm8xxx-regulator.c @@ -3206,7 +3206,7 @@ static int __devinit pm8xxx_vreg_probe(struct platform_device *pdev) if (!core_data->is_pin_controlled) { vreg->rdev = regulator_register(rdesc, &pdev->dev, - &(pdata->init_data), vreg); + &(pdata->init_data), vreg, NULL); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); vreg->rdev = NULL; @@ -3215,7 +3215,7 @@ static int __devinit pm8xxx_vreg_probe(struct platform_device *pdev) } } else { vreg->rdev_pc = regulator_register(rdesc, &pdev->dev, - &(pdata->init_data), vreg); + &(pdata->init_data), vreg, NULL); if (IS_ERR(vreg->rdev_pc)) { rc = PTR_ERR(vreg->rdev_pc); vreg->rdev_pc = NULL; diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c index e137b0ff3f9..01f4abf01bf 100644 --- a/drivers/regulator/pmic8058-regulator.c +++ b/drivers/regulator/pmic8058-regulator.c @@ -1692,7 +1692,7 @@ static int __devinit pm8058_vreg_probe(struct platform_device *pdev) &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE); vreg->rdev = regulator_register(rdesc, &pdev->dev, - &vreg->pdata->init_data, vreg); + &vreg->pdata->init_data, vreg, NULL); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); pr_err("%s: regulator_register failed for %s, rc=%d\n", diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c index 6fd0a056b35..72894bafe54 100644 --- a/drivers/regulator/pmic8901-regulator.c +++ b/drivers/regulator/pmic8901-regulator.c @@ -954,7 +954,7 @@ static int __devinit pm8901_vreg_probe(struct platform_device *pdev) &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE); vreg->rdev = regulator_register(rdesc, &pdev->dev, - &vreg->pdata->init_data, vreg); + &vreg->pdata->init_data, vreg, NULL); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); pr_err("%s: regulator_register failed for %s, rc=%d\n", diff --git a/drivers/regulator/stub-regulator.c b/drivers/regulator/stub-regulator.c index 5b44c048a8b..6198c4046ed 100644 --- a/drivers/regulator/stub-regulator.c +++ b/drivers/regulator/stub-regulator.c @@ -182,7 +182,7 @@ static int __devinit regulator_stub_probe(struct platform_device *pdev) vreg_priv->voltage = vreg_pdata->init_data.constraints.min_uV; vreg_priv->rdev = regulator_register(rdesc, &pdev->dev, - &(vreg_pdata->init_data), vreg_priv); + &(vreg_pdata->init_data), vreg_priv, NULL); if (IS_ERR(vreg_priv->rdev)) { rc = PTR_ERR(vreg_priv->rdev); vreg_priv->rdev = NULL; diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 1011873896d..d9278da18a9 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -151,7 +151,8 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) /* Register regulator with framework */ tps6105x->regulator = regulator_register(&tps6105x_regulator_desc, &tps6105x->client->dev, - pdata->regulator_data, tps6105x); + pdata->regulator_data, tps6105x, + NULL); if (IS_ERR(tps6105x->regulator)) { ret = PTR_ERR(tps6105x->regulator); dev_err(&tps6105x->client->dev, diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index fbddc15e181..8efb772d6fe 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -507,7 +507,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client, /* Register the regulators */ rdev = regulator_register(&tps->desc[i], &client->dev, - init_data, tps); + init_data, tps, NULL); if (IS_ERR(rdev)) { dev_err(&client->dev, "failed to register %s\n", id->name); diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index bfffabc21ed..0f86e56490a 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -605,7 +605,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) tps->desc[i].owner = THIS_MODULE; rdev = regulator_register(&tps->desc[i], - tps6507x_dev->dev, init_data, tps); + tps6507x_dev->dev, init_data, tps, NULL); if (IS_ERR(rdev)) { dev_err(tps6507x_dev->dev, "failed to register %s regulator\n", diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 9166aa0a9df..70b7b1f4f00 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -651,7 +651,7 @@ static int __devinit pmic_probe(struct spi_device *spi) hw->desc[i].n_voltages = 1; hw->rdev[i] = regulator_register(&hw->desc[i], dev, - init_data, hw); + init_data, hw, NULL); if (IS_ERR(hw->rdev[i])) { ret = PTR_ERR(hw->rdev[i]); hw->rdev[i] = NULL; diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index bb04a75a4c9..6a35c3a999e 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -365,7 +365,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) return err; rdev = regulator_register(&ri->desc, &pdev->dev, - pdev->dev.platform_data, ri); + pdev->dev.platform_data, ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 425aab38981..e436dcde17d 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -939,7 +939,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].owner = THIS_MODULE; rdev = regulator_register(&pmic->desc[i], - tps65910->dev, reg_data, pmic); + tps65910->dev, reg_data, pmic, NULL); if (IS_ERR(rdev)) { dev_err(tps65910->dev, "failed to register %s regulator\n", diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 87fe0f75a56..1c120700973 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1074,7 +1074,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) break; } - rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); + rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index a0982e80985..38bb80de91f 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -556,7 +556,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data); dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, - pdata->dcdc[id], dcdc); + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -744,7 +744,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) dcdc->desc.owner = THIS_MODULE; dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, - pdata->dcdc[id], dcdc); + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -871,7 +871,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) dcdc->desc.owner = THIS_MODULE; dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, - pdata->dcdc[id], dcdc); + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -970,7 +970,7 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev) dcdc->desc.owner = THIS_MODULE; dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, - pdata->epe[id], dcdc); + pdata->epe[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register EPE%d: %d\n", diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 01f27c7f423..d3ad3f5cff4 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -189,7 +189,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) isink->desc.owner = THIS_MODULE; isink->regulator = regulator_register(&isink->desc, &pdev->dev, - pdata->isink[id], isink); + pdata->isink[id], isink, NULL); if (IS_ERR(isink->regulator)) { ret = PTR_ERR(isink->regulator); dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n", diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 2220cf8defb..d0fe56305e3 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -345,7 +345,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) ldo->desc.owner = THIS_MODULE; ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, - pdata->ldo[id], ldo); + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", @@ -609,7 +609,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) ldo->desc.owner = THIS_MODULE; ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, - pdata->ldo[id], ldo); + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", @@ -799,7 +799,7 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) ldo->desc.owner = THIS_MODULE; ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, - pdata->ldo[id], ldo); + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 1bcb22c4409..6894009d815 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1428,7 +1428,7 @@ static int wm8350_regulator_probe(struct platform_device *pdev) /* register regulator */ rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev, pdev->dev.platform_data, - dev_get_drvdata(&pdev->dev)); + dev_get_drvdata(&pdev->dev), NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s\n", wm8350_reg[pdev->id].name); diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 0f12c70bebc..f468f8a5231 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -325,7 +325,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev) struct regulator_dev *rdev; rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - pdev->dev.platform_data, wm8400); + pdev->dev.platform_data, wm8400, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 35b2958d510..6f3132cdcea 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -256,7 +256,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) ldo->is_enabled = true; ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev, - pdata->ldo[id].init_data, ldo); + pdata->ldo[id].init_data, ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm8994->dev, "Failed to register LDO%d: %d\n", diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 6c433b89c80..7444946664f 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -210,7 +210,7 @@ struct regulator_dev { struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct device *dev, const struct regulator_init_data *init_data, - void *driver_data); + void *driver_data, struct device_node *of_node); void regulator_unregister(struct regulator_dev *rdev); int regulator_notifier_call_chain(struct regulator_dev *rdev, diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index c49317c255d..b65fd65cce8 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -832,7 +832,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, ldo->voltage = voltage; ldo->dev = regulator_register(&ldo->desc, codec->dev, - init_data, ldo); + init_data, ldo, NULL); if (IS_ERR(ldo->dev)) { int ret = PTR_ERR(ldo->dev); From 949ebbe52c5e0dad01460b42a478c58fb40396a5 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 18 Nov 2011 16:47:20 +0530 Subject: [PATCH 8/8] regulator: map consumer regulator based on device tree Device nodes in DT can associate themselves with one or more regulators/supply by providing a list of phandles (to regulator nodes) and corresponding supply names. For Example: devicenode: node@0x0 { ... ... vmmc-supply = <®ulator1>; vpll-supply = <®ulator2>; }; The driver would then do a regulator_get(dev, "vmmc"); to get regulator1 and do a regulator_get(dev, "vpll"); to get regulator2. of_get_regulator() extracts the regulator node for a given device, based on the supply name. Use it to look up the regulator for a given consumer from device tree, during a regulator_get(). If not found fallback and lookup through the regulator_map_list instead. Also, since the regulator dt nodes can use the same binding to associate with a parent regulator/supply, allow the drivers to specify a supply_name, which can then be used to lookup dt to find the parent phandle. Change-Id: I124a4ba1a64c1145bdd016d91b9814c29eefeb36 Signed-off-by: Rajendra Nayak Acked-by: Grant Likely Signed-off-by: Mark Brown [mbohan: resolve conflict in drivers/regulator/core.c] Signed-off-by: Michael Bohan --- drivers/regulator/core.c | 79 +++++++++++++++++++++++++++----- include/linux/regulator/driver.h | 2 + 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca0fea1b2b7..3f9beaa4a5f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -128,6 +130,33 @@ static struct regulator *get_device_regulator(struct device *dev) return NULL; } +/** + * of_get_regulator - get a regulator device node based on supply name + * @dev: Device pointer for the consumer (of regulator) device + * @supply: regulator supply name + * + * Extract the regulator device node corresponding to the supply name. + * retruns the device node corresponding to the regulator if found, else + * returns NULL. + */ +static struct device_node *of_get_regulator(struct device *dev, const char *supply) +{ + struct device_node *regnode = NULL; + char prop_name[32]; /* 32 is max size of property name */ + + dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); + + snprintf(prop_name, 32, "%s-supply", supply); + regnode = of_parse_phandle(dev->of_node, prop_name, 0); + + if (!regnode) { + dev_warn(dev, "%s property in node %s references invalid phandle", + prop_name, dev->of_node->full_name); + return NULL; + } + return regnode; +} + /* Platform voltage constraint check */ static int regulator_check_voltage(struct regulator_dev *rdev, int *min_uV, int *max_uV) @@ -1208,6 +1237,30 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev) return rdev->desc->ops->enable_time(rdev); } +static struct regulator_dev *regulator_dev_lookup(struct device *dev, + const char *supply) +{ + struct regulator_dev *r; + struct device_node *node; + + /* first do a dt based lookup */ + if (dev && dev->of_node) { + node = of_get_regulator(dev, supply); + if (node) + list_for_each_entry(r, ®ulator_list, list) + if (r->dev.parent && + node == r->dev.of_node) + return r; + } + + /* if not found, try doing it non-dt way */ + list_for_each_entry(r, ®ulator_list, list) + if (strcmp(rdev_get_name(r), supply) == 0) + return r; + + return NULL; +} + /* Internal regulator request function */ static struct regulator *_regulator_get(struct device *dev, const char *id, int exclusive) @@ -1228,6 +1281,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, mutex_lock(®ulator_list_mutex); + rdev = regulator_dev_lookup(dev, id); + if (rdev) + goto found; + list_for_each_entry(map, ®ulator_map_list, list) { /* If the mapping has a device set up it must match */ if (map->dev_name && @@ -3085,6 +3142,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, static atomic_t regulator_no = ATOMIC_INIT(0); struct regulator_dev *rdev; int ret, i; + const char *supply = NULL; if (regulator_desc == NULL) return ERR_PTR(-EINVAL); @@ -3162,21 +3220,18 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, if (ret < 0) goto scrub; - if (init_data->supply_regulator) { + if (init_data->supply_regulator) + supply = init_data->supply_regulator; + else if (regulator_desc->supply_name) + supply = regulator_desc->supply_name; + + if (supply) { struct regulator_dev *r; - int found = 0; - list_for_each_entry(r, ®ulator_list, list) { - if (strcmp(rdev_get_name(r), - init_data->supply_regulator) == 0) { - found = 1; - break; - } - } + r = regulator_dev_lookup(dev, supply); - if (!found) { - dev_err(dev, "Failed to find supply %s\n", - init_data->supply_regulator); + if (!r) { + dev_err(dev, "Failed to find supply %s\n", supply); ret = -ENODEV; goto scrub; } diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7444946664f..956a33146be 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -153,6 +153,7 @@ enum regulator_type { * this type. * * @name: Identifying name for the regulator. + * @supply_name: Identifying the regulator supply * @id: Numerical identifier for the regulator. * @n_voltages: Number of selectors available for ops.list_voltage(). * @ops: Regulator operations table. @@ -162,6 +163,7 @@ enum regulator_type { */ struct regulator_desc { const char *name; + const char *supply_name; int id; unsigned n_voltages; struct regulator_ops *ops;