diff options
-rw-r--r-- | Documentation/devicetree/bindings/regulator/gpio-regulator.txt | 4 | ||||
-rw-r--r-- | drivers/base/devres.c | 26 | ||||
-rw-r--r-- | drivers/of/base.c | 32 | ||||
-rw-r--r-- | drivers/regulator/fan53555.c | 13 | ||||
-rw-r--r-- | drivers/regulator/fixed.c | 46 | ||||
-rw-r--r-- | drivers/regulator/gpio-regulator.c | 34 | ||||
-rw-r--r-- | drivers/regulator/helpers.c | 48 | ||||
-rw-r--r-- | drivers/regulator/lp3971.c | 2 | ||||
-rw-r--r-- | drivers/regulator/lp872x.c | 4 | ||||
-rw-r--r-- | drivers/regulator/max14577.c | 8 | ||||
-rw-r--r-- | include/linux/device.h | 1 | ||||
-rw-r--r-- | include/linux/of.h | 76 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 8 |
13 files changed, 224 insertions, 78 deletions
diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt index 63c659800c03..e5cac1e0ca8a 100644 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt | |||
@@ -8,8 +8,12 @@ Required properties: | |||
8 | Optional properties: | 8 | Optional properties: |
9 | - enable-gpio : GPIO to use to enable/disable the regulator. | 9 | - enable-gpio : GPIO to use to enable/disable the regulator. |
10 | - gpios : GPIO group used to control voltage. | 10 | - gpios : GPIO group used to control voltage. |
11 | - gpios-states : gpios pin's initial states array. 0: LOW, 1: HIGH. | ||
12 | defualt is LOW if nothing is specified. | ||
11 | - startup-delay-us : Startup time in microseconds. | 13 | - startup-delay-us : Startup time in microseconds. |
12 | - enable-active-high : Polarity of GPIO is active high (default is low). | 14 | - enable-active-high : Polarity of GPIO is active high (default is low). |
15 | - regulator-type : Specifies what is being regulated, must be either | ||
16 | "voltage" or "current", defaults to current. | ||
13 | 17 | ||
14 | Any property defined as part of the core regulator binding defined in | 18 | Any property defined as part of the core regulator binding defined in |
15 | regulator.txt can also be used. | 19 | regulator.txt can also be used. |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 545c4de412c3..db4e264eecb6 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -791,6 +791,32 @@ void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) | |||
791 | EXPORT_SYMBOL_GPL(devm_kmalloc); | 791 | EXPORT_SYMBOL_GPL(devm_kmalloc); |
792 | 792 | ||
793 | /** | 793 | /** |
794 | * devm_kstrdup - Allocate resource managed space and | ||
795 | * copy an existing string into that. | ||
796 | * @dev: Device to allocate memory for | ||
797 | * @s: the string to duplicate | ||
798 | * @gfp: the GFP mask used in the devm_kmalloc() call when | ||
799 | * allocating memory | ||
800 | * RETURNS: | ||
801 | * Pointer to allocated string on success, NULL on failure. | ||
802 | */ | ||
803 | char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) | ||
804 | { | ||
805 | size_t size; | ||
806 | char *buf; | ||
807 | |||
808 | if (!s) | ||
809 | return NULL; | ||
810 | |||
811 | size = strlen(s) + 1; | ||
812 | buf = devm_kmalloc(dev, size, gfp); | ||
813 | if (buf) | ||
814 | memcpy(buf, s, size); | ||
815 | return buf; | ||
816 | } | ||
817 | EXPORT_SYMBOL_GPL(devm_kstrdup); | ||
818 | |||
819 | /** | ||
794 | * devm_kfree - Resource-managed kfree | 820 | * devm_kfree - Resource-managed kfree |
795 | * @dev: Device this memory belongs to | 821 | * @dev: Device this memory belongs to |
796 | * @p: Memory to free | 822 | * @p: Memory to free |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 89e888a78899..1b95a405628f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -904,6 +904,38 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
904 | EXPORT_SYMBOL(of_find_node_by_phandle); | 904 | EXPORT_SYMBOL(of_find_node_by_phandle); |
905 | 905 | ||
906 | /** | 906 | /** |
907 | * of_property_count_elems_of_size - Count the number of elements in a property | ||
908 | * | ||
909 | * @np: device node from which the property value is to be read. | ||
910 | * @propname: name of the property to be searched. | ||
911 | * @elem_size: size of the individual element | ||
912 | * | ||
913 | * Search for a property in a device node and count the number of elements of | ||
914 | * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | ||
915 | * property does not exist or its length does not match a multiple of elem_size | ||
916 | * and -ENODATA if the property does not have a value. | ||
917 | */ | ||
918 | int of_property_count_elems_of_size(const struct device_node *np, | ||
919 | const char *propname, int elem_size) | ||
920 | { | ||
921 | struct property *prop = of_find_property(np, propname, NULL); | ||
922 | |||
923 | if (!prop) | ||
924 | return -EINVAL; | ||
925 | if (!prop->value) | ||
926 | return -ENODATA; | ||
927 | |||
928 | if (prop->length % elem_size != 0) { | ||
929 | pr_err("size of %s in node %s is not a multiple of %d\n", | ||
930 | propname, np->full_name, elem_size); | ||
931 | return -EINVAL; | ||
932 | } | ||
933 | |||
934 | return prop->length / elem_size; | ||
935 | } | ||
936 | EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | ||
937 | |||
938 | /** | ||
907 | * of_find_property_value_of_size | 939 | * of_find_property_value_of_size |
908 | * | 940 | * |
909 | * @np: device node from which the property value is to be read. | 941 | * @np: device node from which the property value is to be read. |
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 7ca3d9e3b0fe..714fd9a89aa1 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
@@ -90,11 +90,11 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
90 | return 0; | 90 | return 0; |
91 | ret = regulator_map_voltage_linear(rdev, uV, uV); | 91 | ret = regulator_map_voltage_linear(rdev, uV, uV); |
92 | if (ret < 0) | 92 | if (ret < 0) |
93 | return -EINVAL; | 93 | return ret; |
94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, | 94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, |
95 | VSEL_NSEL_MASK, ret); | 95 | VSEL_NSEL_MASK, ret); |
96 | if (ret < 0) | 96 | if (ret < 0) |
97 | return -EINVAL; | 97 | return ret; |
98 | /* Cache the sleep voltage setting. | 98 | /* Cache the sleep voltage setting. |
99 | * Might not be the real voltage which is rounded */ | 99 | * Might not be the real voltage which is rounded */ |
100 | di->sleep_vol_cache = uV; | 100 | di->sleep_vol_cache = uV; |
@@ -244,10 +244,9 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
244 | 244 | ||
245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | 245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), |
246 | GFP_KERNEL); | 246 | GFP_KERNEL); |
247 | if (!di) { | 247 | if (!di) |
248 | dev_err(&client->dev, "Failed to allocate device info data!\n"); | ||
249 | return -ENOMEM; | 248 | return -ENOMEM; |
250 | } | 249 | |
251 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); | 250 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); |
252 | if (IS_ERR(di->regmap)) { | 251 | if (IS_ERR(di->regmap)) { |
253 | dev_err(&client->dev, "Failed to allocate regmap!\n"); | 252 | dev_err(&client->dev, "Failed to allocate regmap!\n"); |
@@ -260,14 +259,14 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
260 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); | 259 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); |
261 | if (ret < 0) { | 260 | if (ret < 0) { |
262 | dev_err(&client->dev, "Failed to get chip ID!\n"); | 261 | dev_err(&client->dev, "Failed to get chip ID!\n"); |
263 | return -ENODEV; | 262 | return ret; |
264 | } | 263 | } |
265 | di->chip_id = val & DIE_ID; | 264 | di->chip_id = val & DIE_ID; |
266 | /* Get chip revision */ | 265 | /* Get chip revision */ |
267 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); | 266 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); |
268 | if (ret < 0) { | 267 | if (ret < 0) { |
269 | dev_err(&client->dev, "Failed to get chip Rev!\n"); | 268 | dev_err(&client->dev, "Failed to get chip Rev!\n"); |
270 | return -ENODEV; | 269 | return ret; |
271 | } | 270 | } |
272 | di->chip_rev = val & DIE_REV; | 271 | di->chip_rev = val & DIE_REV; |
273 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", | 272 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 5ea64b94341c..c61f7e97e4f8 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
@@ -130,17 +130,15 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
130 | 130 | ||
131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), | 131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), |
132 | GFP_KERNEL); | 132 | GFP_KERNEL); |
133 | if (drvdata == NULL) { | 133 | if (!drvdata) |
134 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | 134 | return -ENOMEM; |
135 | ret = -ENOMEM; | ||
136 | goto err; | ||
137 | } | ||
138 | 135 | ||
139 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 136 | drvdata->desc.name = devm_kstrdup(&pdev->dev, |
137 | config->supply_name, | ||
138 | GFP_KERNEL); | ||
140 | if (drvdata->desc.name == NULL) { | 139 | if (drvdata->desc.name == NULL) { |
141 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); | 140 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); |
142 | ret = -ENOMEM; | 141 | return -ENOMEM; |
143 | goto err; | ||
144 | } | 142 | } |
145 | drvdata->desc.type = REGULATOR_VOLTAGE; | 143 | drvdata->desc.type = REGULATOR_VOLTAGE; |
146 | drvdata->desc.owner = THIS_MODULE; | 144 | drvdata->desc.owner = THIS_MODULE; |
@@ -149,13 +147,13 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
149 | drvdata->desc.enable_time = config->startup_delay; | 147 | drvdata->desc.enable_time = config->startup_delay; |
150 | 148 | ||
151 | if (config->input_supply) { | 149 | if (config->input_supply) { |
152 | drvdata->desc.supply_name = kstrdup(config->input_supply, | 150 | drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, |
153 | GFP_KERNEL); | 151 | config->input_supply, |
152 | GFP_KERNEL); | ||
154 | if (!drvdata->desc.supply_name) { | 153 | if (!drvdata->desc.supply_name) { |
155 | dev_err(&pdev->dev, | 154 | dev_err(&pdev->dev, |
156 | "Failed to allocate input supply\n"); | 155 | "Failed to allocate input supply\n"); |
157 | ret = -ENOMEM; | 156 | return -ENOMEM; |
158 | goto err_name; | ||
159 | } | 157 | } |
160 | } | 158 | } |
161 | 159 | ||
@@ -186,11 +184,12 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
186 | cfg.driver_data = drvdata; | 184 | cfg.driver_data = drvdata; |
187 | cfg.of_node = pdev->dev.of_node; | 185 | cfg.of_node = pdev->dev.of_node; |
188 | 186 | ||
189 | drvdata->dev = regulator_register(&drvdata->desc, &cfg); | 187 | drvdata->dev = devm_regulator_register(&pdev->dev, &drvdata->desc, |
188 | &cfg); | ||
190 | if (IS_ERR(drvdata->dev)) { | 189 | if (IS_ERR(drvdata->dev)) { |
191 | ret = PTR_ERR(drvdata->dev); | 190 | ret = PTR_ERR(drvdata->dev); |
192 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); | 191 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); |
193 | goto err_input; | 192 | return ret; |
194 | } | 193 | } |
195 | 194 | ||
196 | platform_set_drvdata(pdev, drvdata); | 195 | platform_set_drvdata(pdev, drvdata); |
@@ -199,24 +198,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
199 | drvdata->desc.fixed_uV); | 198 | drvdata->desc.fixed_uV); |
200 | 199 | ||
201 | return 0; | 200 | return 0; |
202 | |||
203 | err_input: | ||
204 | kfree(drvdata->desc.supply_name); | ||
205 | err_name: | ||
206 | kfree(drvdata->desc.name); | ||
207 | err: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int reg_fixed_voltage_remove(struct platform_device *pdev) | ||
212 | { | ||
213 | struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev); | ||
214 | |||
215 | regulator_unregister(drvdata->dev); | ||
216 | kfree(drvdata->desc.supply_name); | ||
217 | kfree(drvdata->desc.name); | ||
218 | |||
219 | return 0; | ||
220 | } | 201 | } |
221 | 202 | ||
222 | #if defined(CONFIG_OF) | 203 | #if defined(CONFIG_OF) |
@@ -229,7 +210,6 @@ MODULE_DEVICE_TABLE(of, fixed_of_match); | |||
229 | 210 | ||
230 | static struct platform_driver regulator_fixed_voltage_driver = { | 211 | static struct platform_driver regulator_fixed_voltage_driver = { |
231 | .probe = reg_fixed_voltage_probe, | 212 | .probe = reg_fixed_voltage_probe, |
232 | .remove = reg_fixed_voltage_remove, | ||
233 | .driver = { | 213 | .driver = { |
234 | .name = "reg-fixed-voltage", | 214 | .name = "reg-fixed-voltage", |
235 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index c0a1d00b78c9..989b23b377c0 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -136,7 +136,6 @@ static struct gpio_regulator_config * | |||
136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) |
137 | { | 137 | { |
138 | struct gpio_regulator_config *config; | 138 | struct gpio_regulator_config *config; |
139 | struct property *prop; | ||
140 | const char *regtype; | 139 | const char *regtype; |
141 | int proplen, gpio, i; | 140 | int proplen, gpio, i; |
142 | int ret; | 141 | int ret; |
@@ -172,22 +171,35 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
172 | if (!config->gpios) | 171 | if (!config->gpios) |
173 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |
174 | 173 | ||
174 | proplen = of_property_count_u32_elems(np, "gpios-states"); | ||
175 | /* optional property */ | ||
176 | if (proplen < 0) | ||
177 | proplen = 0; | ||
178 | |||
179 | if (proplen > 0 && proplen != config->nr_gpios) { | ||
180 | dev_warn(dev, "gpios <-> gpios-states mismatch\n"); | ||
181 | proplen = 0; | ||
182 | } | ||
183 | |||
175 | for (i = 0; i < config->nr_gpios; i++) { | 184 | for (i = 0; i < config->nr_gpios; i++) { |
176 | gpio = of_get_named_gpio(np, "gpios", i); | 185 | gpio = of_get_named_gpio(np, "gpios", i); |
177 | if (gpio < 0) | 186 | if (gpio < 0) |
178 | break; | 187 | break; |
179 | config->gpios[i].gpio = gpio; | 188 | config->gpios[i].gpio = gpio; |
189 | if (proplen > 0) { | ||
190 | of_property_read_u32_index(np, "gpios-states", i, &ret); | ||
191 | if (ret) | ||
192 | config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; | ||
193 | } | ||
180 | } | 194 | } |
181 | 195 | ||
182 | /* Fetch states. */ | 196 | /* Fetch states. */ |
183 | prop = of_find_property(np, "states", NULL); | 197 | proplen = of_property_count_u32_elems(np, "states"); |
184 | if (!prop) { | 198 | if (proplen < 0) { |
185 | dev_err(dev, "No 'states' property found\n"); | 199 | dev_err(dev, "No 'states' property found\n"); |
186 | return ERR_PTR(-EINVAL); | 200 | return ERR_PTR(-EINVAL); |
187 | } | 201 | } |
188 | 202 | ||
189 | proplen = prop->length / sizeof(int); | ||
190 | |||
191 | config->states = devm_kzalloc(dev, | 203 | config->states = devm_kzalloc(dev, |
192 | sizeof(struct gpio_regulator_state) | 204 | sizeof(struct gpio_regulator_state) |
193 | * (proplen / 2), | 205 | * (proplen / 2), |
@@ -196,10 +208,10 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
196 | return ERR_PTR(-ENOMEM); | 208 | return ERR_PTR(-ENOMEM); |
197 | 209 | ||
198 | for (i = 0; i < proplen / 2; i++) { | 210 | for (i = 0; i < proplen / 2; i++) { |
199 | config->states[i].value = | 211 | of_property_read_u32_index(np, "states", i * 2, |
200 | be32_to_cpup((int *)prop->value + (i * 2)); | 212 | &config->states[i].value); |
201 | config->states[i].gpios = | 213 | of_property_read_u32_index(np, "states", i * 2 + 1, |
202 | be32_to_cpup((int *)prop->value + (i * 2 + 1)); | 214 | &config->states[i].gpios); |
203 | } | 215 | } |
204 | config->nr_states = i; | 216 | config->nr_states = i; |
205 | 217 | ||
@@ -239,10 +251,8 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
239 | 251 | ||
240 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), | 252 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), |
241 | GFP_KERNEL); | 253 | GFP_KERNEL); |
242 | if (drvdata == NULL) { | 254 | if (drvdata == NULL) |
243 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
244 | return -ENOMEM; | 255 | return -ENOMEM; |
245 | } | ||
246 | 256 | ||
247 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 257 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); |
248 | if (drvdata->desc.name == NULL) { | 258 | if (drvdata->desc.name == NULL) { |
diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index e221a271ba56..cbc39096c78d 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c | |||
@@ -37,10 +37,17 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev) | |||
37 | if (ret != 0) | 37 | if (ret != 0) |
38 | return ret; | 38 | return ret; |
39 | 39 | ||
40 | if (rdev->desc->enable_is_inverted) | 40 | val &= rdev->desc->enable_mask; |
41 | return (val & rdev->desc->enable_mask) == 0; | 41 | |
42 | else | 42 | if (rdev->desc->enable_is_inverted) { |
43 | return (val & rdev->desc->enable_mask) != 0; | 43 | if (rdev->desc->enable_val) |
44 | return val != rdev->desc->enable_val; | ||
45 | return val == 0; | ||
46 | } else { | ||
47 | if (rdev->desc->enable_val) | ||
48 | return val == rdev->desc->enable_val; | ||
49 | return val != 0; | ||
50 | } | ||
44 | } | 51 | } |
45 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); | 52 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); |
46 | 53 | ||
@@ -57,10 +64,13 @@ int regulator_enable_regmap(struct regulator_dev *rdev) | |||
57 | { | 64 | { |
58 | unsigned int val; | 65 | unsigned int val; |
59 | 66 | ||
60 | if (rdev->desc->enable_is_inverted) | 67 | if (rdev->desc->enable_is_inverted) { |
61 | val = 0; | 68 | val = rdev->desc->disable_val; |
62 | else | 69 | } else { |
63 | val = rdev->desc->enable_mask; | 70 | val = rdev->desc->enable_val; |
71 | if (!val) | ||
72 | val = rdev->desc->enable_mask; | ||
73 | } | ||
64 | 74 | ||
65 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 75 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
66 | rdev->desc->enable_mask, val); | 76 | rdev->desc->enable_mask, val); |
@@ -80,10 +90,13 @@ int regulator_disable_regmap(struct regulator_dev *rdev) | |||
80 | { | 90 | { |
81 | unsigned int val; | 91 | unsigned int val; |
82 | 92 | ||
83 | if (rdev->desc->enable_is_inverted) | 93 | if (rdev->desc->enable_is_inverted) { |
84 | val = rdev->desc->enable_mask; | 94 | val = rdev->desc->enable_val; |
85 | else | 95 | if (!val) |
86 | val = 0; | 96 | val = rdev->desc->enable_mask; |
97 | } else { | ||
98 | val = rdev->desc->disable_val; | ||
99 | } | ||
87 | 100 | ||
88 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 101 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
89 | rdev->desc->enable_mask, val); | 102 | rdev->desc->enable_mask, val); |
@@ -419,10 +432,13 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |||
419 | { | 432 | { |
420 | unsigned int val; | 433 | unsigned int val; |
421 | 434 | ||
422 | if (enable) | 435 | if (enable) { |
423 | val = rdev->desc->bypass_mask; | 436 | val = rdev->desc->bypass_val_on; |
424 | else | 437 | if (!val) |
425 | val = 0; | 438 | val = rdev->desc->bypass_mask; |
439 | } else { | ||
440 | val = rdev->desc->bypass_val_off; | ||
441 | } | ||
426 | 442 | ||
427 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | 443 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, |
428 | rdev->desc->bypass_mask, val); | 444 | rdev->desc->bypass_mask, val); |
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 3b1102b75071..66fd2330dca0 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
@@ -327,7 +327,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, | |||
327 | return -EIO; | 327 | return -EIO; |
328 | ret = i2c_smbus_read_byte_data(i2c, reg); | 328 | ret = i2c_smbus_read_byte_data(i2c, reg); |
329 | if (ret < 0) | 329 | if (ret < 0) |
330 | return -EIO; | 330 | return ret; |
331 | 331 | ||
332 | *dest = ret; | 332 | *dest = ret; |
333 | return 0; | 333 | return 0; |
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 2e4734ff79fc..2e022aabd951 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c | |||
@@ -211,7 +211,7 @@ static int lp872x_get_timestep_usec(struct lp872x *lp) | |||
211 | 211 | ||
212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); | 212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); |
213 | if (ret) | 213 | if (ret) |
214 | return -EINVAL; | 214 | return ret; |
215 | 215 | ||
216 | val = (val & mask) >> shift; | 216 | val = (val & mask) >> shift; |
217 | if (val >= size) | 217 | if (val >= size) |
@@ -229,7 +229,7 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) | |||
229 | u8 addr, val; | 229 | u8 addr, val; |
230 | 230 | ||
231 | if (time_step_us < 0) | 231 | if (time_step_us < 0) |
232 | return -EINVAL; | 232 | return time_step_us; |
233 | 233 | ||
234 | switch (rid) { | 234 | switch (rid) { |
235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: | 235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index e0619526708c..ed60baaeceec 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * max14577.c - Regulator driver for the Maxim 14577 | 2 | * max14577.c - Regulator driver for the Maxim 14577 |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electronics | 4 | * Copyright (C) 2013,2014 Samsung Electronics |
5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -22,12 +22,6 @@ | |||
22 | #include <linux/mfd/max14577-private.h> | 22 | #include <linux/mfd/max14577-private.h> |
23 | #include <linux/regulator/of_regulator.h> | 23 | #include <linux/regulator/of_regulator.h> |
24 | 24 | ||
25 | struct max14577_regulator { | ||
26 | struct device *dev; | ||
27 | struct max14577 *max14577; | ||
28 | struct regulator_dev **regulators; | ||
29 | }; | ||
30 | |||
31 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) | 25 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) |
32 | { | 26 | { |
33 | int rid = rdev_get_id(rdev); | 27 | int rid = rdev_get_id(rdev); |
diff --git a/include/linux/device.h b/include/linux/device.h index 952b01033c32..ec1b6e21f0ef 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -626,6 +626,7 @@ static inline void *devm_kcalloc(struct device *dev, | |||
626 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); | 626 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); |
627 | } | 627 | } |
628 | extern void devm_kfree(struct device *dev, void *p); | 628 | extern void devm_kfree(struct device *dev, void *p); |
629 | extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp); | ||
629 | 630 | ||
630 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); | 631 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); |
631 | void __iomem *devm_request_and_ioremap(struct device *dev, | 632 | void __iomem *devm_request_and_ioremap(struct device *dev, |
diff --git a/include/linux/of.h b/include/linux/of.h index 435cb995904d..83d1ac80c91e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -198,6 +198,8 @@ extern struct device_node *of_find_node_with_property( | |||
198 | extern struct property *of_find_property(const struct device_node *np, | 198 | extern struct property *of_find_property(const struct device_node *np, |
199 | const char *name, | 199 | const char *name, |
200 | int *lenp); | 200 | int *lenp); |
201 | extern int of_property_count_elems_of_size(const struct device_node *np, | ||
202 | const char *propname, int elem_size); | ||
201 | extern int of_property_read_u32_index(const struct device_node *np, | 203 | extern int of_property_read_u32_index(const struct device_node *np, |
202 | const char *propname, | 204 | const char *propname, |
203 | u32 index, u32 *out_value); | 205 | u32 index, u32 *out_value); |
@@ -390,6 +392,12 @@ static inline struct device_node *of_find_compatible_node( | |||
390 | return NULL; | 392 | return NULL; |
391 | } | 393 | } |
392 | 394 | ||
395 | static inline int of_property_count_elems_of_size(const struct device_node *np, | ||
396 | const char *propname, int elem_size) | ||
397 | { | ||
398 | return -ENOSYS; | ||
399 | } | ||
400 | |||
393 | static inline int of_property_read_u32_index(const struct device_node *np, | 401 | static inline int of_property_read_u32_index(const struct device_node *np, |
394 | const char *propname, u32 index, u32 *out_value) | 402 | const char *propname, u32 index, u32 *out_value) |
395 | { | 403 | { |
@@ -536,6 +544,74 @@ static inline struct device_node *of_find_matching_node( | |||
536 | } | 544 | } |
537 | 545 | ||
538 | /** | 546 | /** |
547 | * of_property_count_u8_elems - Count the number of u8 elements in a property | ||
548 | * | ||
549 | * @np: device node from which the property value is to be read. | ||
550 | * @propname: name of the property to be searched. | ||
551 | * | ||
552 | * Search for a property in a device node and count the number of u8 elements | ||
553 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
554 | * not exist or its length does not match a multiple of u8 and -ENODATA if the | ||
555 | * property does not have a value. | ||
556 | */ | ||
557 | static inline int of_property_count_u8_elems(const struct device_node *np, | ||
558 | const char *propname) | ||
559 | { | ||
560 | return of_property_count_elems_of_size(np, propname, sizeof(u8)); | ||
561 | } | ||
562 | |||
563 | /** | ||
564 | * of_property_count_u16_elems - Count the number of u16 elements in a property | ||
565 | * | ||
566 | * @np: device node from which the property value is to be read. | ||
567 | * @propname: name of the property to be searched. | ||
568 | * | ||
569 | * Search for a property in a device node and count the number of u16 elements | ||
570 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
571 | * not exist or its length does not match a multiple of u16 and -ENODATA if the | ||
572 | * property does not have a value. | ||
573 | */ | ||
574 | static inline int of_property_count_u16_elems(const struct device_node *np, | ||
575 | const char *propname) | ||
576 | { | ||
577 | return of_property_count_elems_of_size(np, propname, sizeof(u16)); | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * of_property_count_u32_elems - Count the number of u32 elements in a property | ||
582 | * | ||
583 | * @np: device node from which the property value is to be read. | ||
584 | * @propname: name of the property to be searched. | ||
585 | * | ||
586 | * Search for a property in a device node and count the number of u32 elements | ||
587 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
588 | * not exist or its length does not match a multiple of u32 and -ENODATA if the | ||
589 | * property does not have a value. | ||
590 | */ | ||
591 | static inline int of_property_count_u32_elems(const struct device_node *np, | ||
592 | const char *propname) | ||
593 | { | ||
594 | return of_property_count_elems_of_size(np, propname, sizeof(u32)); | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * of_property_count_u64_elems - Count the number of u64 elements in a property | ||
599 | * | ||
600 | * @np: device node from which the property value is to be read. | ||
601 | * @propname: name of the property to be searched. | ||
602 | * | ||
603 | * Search for a property in a device node and count the number of u64 elements | ||
604 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
605 | * not exist or its length does not match a multiple of u64 and -ENODATA if the | ||
606 | * property does not have a value. | ||
607 | */ | ||
608 | static inline int of_property_count_u64_elems(const struct device_node *np, | ||
609 | const char *propname) | ||
610 | { | ||
611 | return of_property_count_elems_of_size(np, propname, sizeof(u64)); | ||
612 | } | ||
613 | |||
614 | /** | ||
539 | * of_property_read_bool - Findfrom a property | 615 | * of_property_read_bool - Findfrom a property |
540 | * @np: device node from which the property value is to be read. | 616 | * @np: device node from which the property value is to be read. |
541 | * @propname: name of the property to be searched. | 617 | * @propname: name of the property to be searched. |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9370e65348a4..bbe03a1924c0 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -228,10 +228,14 @@ enum regulator_type { | |||
228 | * output when using regulator_set_voltage_sel_regmap | 228 | * output when using regulator_set_voltage_sel_regmap |
229 | * @enable_reg: Register for control when using regmap enable/disable ops | 229 | * @enable_reg: Register for control when using regmap enable/disable ops |
230 | * @enable_mask: Mask for control when using regmap enable/disable ops | 230 | * @enable_mask: Mask for control when using regmap enable/disable ops |
231 | * @enable_val: Enabling value for control when using regmap enable/disable ops | ||
232 | * @disable_val: Disabling value for control when using regmap enable/disable ops | ||
231 | * @enable_is_inverted: A flag to indicate set enable_mask bits to disable | 233 | * @enable_is_inverted: A flag to indicate set enable_mask bits to disable |
232 | * when using regulator_enable_regmap and friends APIs. | 234 | * when using regulator_enable_regmap and friends APIs. |
233 | * @bypass_reg: Register for control when using regmap set_bypass | 235 | * @bypass_reg: Register for control when using regmap set_bypass |
234 | * @bypass_mask: Mask for control when using regmap set_bypass | 236 | * @bypass_mask: Mask for control when using regmap set_bypass |
237 | * @bypass_val_on: Enabling value for control when using regmap set_bypass | ||
238 | * @bypass_val_off: Disabling value for control when using regmap set_bypass | ||
235 | * | 239 | * |
236 | * @enable_time: Time taken for initial enable of regulator (in uS). | 240 | * @enable_time: Time taken for initial enable of regulator (in uS). |
237 | */ | 241 | */ |
@@ -263,9 +267,13 @@ struct regulator_desc { | |||
263 | unsigned int apply_bit; | 267 | unsigned int apply_bit; |
264 | unsigned int enable_reg; | 268 | unsigned int enable_reg; |
265 | unsigned int enable_mask; | 269 | unsigned int enable_mask; |
270 | unsigned int enable_val; | ||
271 | unsigned int disable_val; | ||
266 | bool enable_is_inverted; | 272 | bool enable_is_inverted; |
267 | unsigned int bypass_reg; | 273 | unsigned int bypass_reg; |
268 | unsigned int bypass_mask; | 274 | unsigned int bypass_mask; |
275 | unsigned int bypass_val_on; | ||
276 | unsigned int bypass_val_off; | ||
269 | 277 | ||
270 | unsigned int enable_time; | 278 | unsigned int enable_time; |
271 | }; | 279 | }; |