diff options
Diffstat (limited to 'drivers/regulator/gpio-regulator.c')
-rw-r--r-- | drivers/regulator/gpio-regulator.c | 34 |
1 files changed, 22 insertions, 12 deletions
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) { |