From cd22a965c46e249843c049cbbfe3d9f12270ea2b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Apr 2012 09:54:24 +0100 Subject: regulator: da9052: Directly include of.h Reported-by: Stephen Rothwell Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 2678cbe..eaa91cc5 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -20,6 +20,7 @@ #include #include #ifdef CONFIG_OF +#include #include #endif -- cgit v0.10.2 From 98d8618af37728f6e18e84110ddb99987b47dd12 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 24 Mar 2012 15:19:49 +0530 Subject: mfd: add irq domain support for max8997 interrupts Add irq domain support for max8997 interrupts. The reverse mapping method used is linear mapping since the sub-drivers of max8997 such as regulator and charger drivers can use the max8997 irq_domain to get the linux irq number for max8997 interrupts. All uses of irq_base in platform data and max8997 driver private data are removed. Signed-off-by: Thomas Abraham Acked-by: MyungJoo Ham Acked-by: Grant Likely Acked-by: Samuel Ortiz Signed-off-by: Mark Brown diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index b3982c8..0b48d6a 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -1079,12 +1079,8 @@ static struct platform_device nuri_max8903_device = { static void __init nuri_power_init(void) { int gpio; - int irq_base = IRQ_GPIO_END + 1; int ta_en = 0; - nuri_max8997_pdata.irq_base = irq_base; - irq_base += MAX8997_IRQ_NR; - gpio = EXYNOS4_GPX0(7); gpio_request(gpio, "AP_PMIC_IRQ"); s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 878d4c9..600368f 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = { .buck1_gpiodvs = false, .buck2_gpiodvs = false, .buck5_gpiodvs = false, - .irq_base = IRQ_GPIO_END + 1, .ignore_gpiodvs_side_effect = true, .buck125_default_idx = 0x0, diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c index 09274cf..00390a1 100644 --- a/drivers/mfd/max8997-irq.c +++ b/drivers/mfd/max8997-irq.c @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data) static const inline struct max8997_irq_data * irq_to_max8997_irq(struct max8997_dev *max8997, int irq) { - return &max8997_irqs[irq - max8997->irq_base]; + struct irq_data *data = irq_get_irq_data(irq); + return &max8997_irqs[data->hwirq]; } static void max8997_irq_mask(struct irq_data *data) @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; u8 irq_src; int ret; - int i; + int i, cur_irq; ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); if (ret < 0) { @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) /* Report */ for (i = 0; i < MAX8997_IRQ_NR; i++) { - if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) - handle_nested_irq(max8997->irq_base + i); + if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) { + cur_irq = irq_find_mapping(max8997->irq_domain, i); + if (cur_irq) + handle_nested_irq(cur_irq); + } } return IRQ_HANDLED; @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) int max8997_irq_resume(struct max8997_dev *max8997) { - if (max8997->irq && max8997->irq_base) - max8997_irq_thread(max8997->irq_base, max8997); + if (max8997->irq && max8997->irq_domain) + max8997_irq_thread(0, max8997); + return 0; +} + +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + struct max8997_dev *max8997 = d->host_data; + + irq_set_chip_data(irq, max8997); + irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq); + irq_set_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + irq_set_noprobe(irq); +#endif return 0; } +static struct irq_domain_ops max8997_irq_domain_ops = { + .map = max8997_irq_domain_map, +}; + int max8997_irq_init(struct max8997_dev *max8997) { + struct irq_domain *domain; int i; - int cur_irq; int ret; u8 val; if (!max8997->irq) { dev_warn(max8997->dev, "No interrupt specified.\n"); - max8997->irq_base = 0; - return 0; - } - - if (!max8997->irq_base) { - dev_err(max8997->dev, "No interrupt base specified.\n"); return 0; } @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997) true : false; } - /* Register with genirq */ - for (i = 0; i < MAX8997_IRQ_NR; i++) { - cur_irq = i + max8997->irq_base; - irq_set_chip_data(cur_irq, max8997); - irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif + domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR, + &max8997_irq_domain_ops, &max8997); + if (!domain) { + dev_err(max8997->dev, "could not create irq domain\n"); + return -ENODEV; } ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index cb83a7a..20ecad3 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c, if (!pdata) goto err; - max8997->irq_base = pdata->irq_base; max8997->ono = pdata->ono; mutex_init(&max8997->iolock); diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 3f4deb6..830152c 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -23,6 +23,8 @@ #define __LINUX_MFD_MAX8997_PRIV_H #include +#include +#include #define MAX8997_REG_INVALID (0xff) @@ -325,7 +327,7 @@ struct max8997_dev { int irq; int ono; - int irq_base; + struct irq_domain *irq_domain; struct mutex irqlock; int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 28726dd..24b1a76 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -204,7 +204,6 @@ struct max8997_led_platform_data { struct max8997_platform_data { /* IRQ */ - int irq_base; int ono; int wakeup; -- cgit v0.10.2 From 575f690dc4973027ce7e93360678681d09f65fac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 17 Apr 2012 18:06:50 +0800 Subject: regulator: max8660: Fix a memory leak due to missing devm_kzalloc conversion commit 4d26f7 "regulator: max8660: Use devm_kzalloc()" missed to replace kzalloc by devm_kzalloc. Fix it. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 9997cfb..5d56817 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -370,7 +370,7 @@ static int __devinit max8660_probe(struct i2c_client *client, return -EINVAL; } - max8660 = kzalloc(sizeof(struct max8660) + + max8660 = devm_kzalloc(&client->dev, sizeof(struct max8660) + sizeof(struct regulator_dev *) * MAX8660_V_END, GFP_KERNEL); if (!max8660) -- cgit v0.10.2 From 82b719b11fd750188c125078ad6a6c0d23219dfb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Apr 2012 14:51:47 +0100 Subject: mfd: Revert "mfd: add irq domain support for max8997 interrupts" This reverts commit 98d8618af37728f6e18e84110ddb99987b47dd12 as it breaks the build of the muic driver. Reported-by: Stephen Rothwell Signed-off-by: Mark Brown diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index 0b48d6a..b3982c8 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -1079,8 +1079,12 @@ static struct platform_device nuri_max8903_device = { static void __init nuri_power_init(void) { int gpio; + int irq_base = IRQ_GPIO_END + 1; int ta_en = 0; + nuri_max8997_pdata.irq_base = irq_base; + irq_base += MAX8997_IRQ_NR; + gpio = EXYNOS4_GPX0(7); gpio_request(gpio, "AP_PMIC_IRQ"); s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 600368f..878d4c9 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -424,6 +424,7 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = { .buck1_gpiodvs = false, .buck2_gpiodvs = false, .buck5_gpiodvs = false, + .irq_base = IRQ_GPIO_END + 1, .ignore_gpiodvs_side_effect = true, .buck125_default_idx = 0x0, diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c index 00390a1..09274cf 100644 --- a/drivers/mfd/max8997-irq.c +++ b/drivers/mfd/max8997-irq.c @@ -142,8 +142,7 @@ static void max8997_irq_sync_unlock(struct irq_data *data) static const inline struct max8997_irq_data * irq_to_max8997_irq(struct max8997_dev *max8997, int irq) { - struct irq_data *data = irq_get_irq_data(irq); - return &max8997_irqs[data->hwirq]; + return &max8997_irqs[irq - max8997->irq_base]; } static void max8997_irq_mask(struct irq_data *data) @@ -183,7 +182,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; u8 irq_src; int ret; - int i, cur_irq; + int i; ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); if (ret < 0) { @@ -270,11 +269,8 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) /* Report */ for (i = 0; i < MAX8997_IRQ_NR; i++) { - if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) { - cur_irq = irq_find_mapping(max8997->irq_domain, i); - if (cur_irq) - handle_nested_irq(cur_irq); - } + if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) + handle_nested_irq(max8997->irq_base + i); } return IRQ_HANDLED; @@ -282,40 +278,26 @@ static irqreturn_t max8997_irq_thread(int irq, void *data) int max8997_irq_resume(struct max8997_dev *max8997) { - if (max8997->irq && max8997->irq_domain) - max8997_irq_thread(0, max8997); - return 0; -} - -static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - struct max8997_dev *max8997 = d->host_data; - - irq_set_chip_data(irq, max8997); - irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif + if (max8997->irq && max8997->irq_base) + max8997_irq_thread(max8997->irq_base, max8997); return 0; } -static struct irq_domain_ops max8997_irq_domain_ops = { - .map = max8997_irq_domain_map, -}; - int max8997_irq_init(struct max8997_dev *max8997) { - struct irq_domain *domain; int i; + int cur_irq; int ret; u8 val; if (!max8997->irq) { dev_warn(max8997->dev, "No interrupt specified.\n"); + max8997->irq_base = 0; + return 0; + } + + if (!max8997->irq_base) { + dev_err(max8997->dev, "No interrupt base specified.\n"); return 0; } @@ -345,11 +327,18 @@ int max8997_irq_init(struct max8997_dev *max8997) true : false; } - domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR, - &max8997_irq_domain_ops, &max8997); - if (!domain) { - dev_err(max8997->dev, "could not create irq domain\n"); - return -ENODEV; + /* Register with genirq */ + for (i = 0; i < MAX8997_IRQ_NR; i++) { + cur_irq = i + max8997->irq_base; + irq_set_chip_data(cur_irq, max8997); + irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, + handle_edge_irq); + irq_set_nested_thread(cur_irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(cur_irq, IRQF_VALID); +#else + irq_set_noprobe(cur_irq); +#endif } ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 20ecad3..cb83a7a 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -143,6 +143,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c, if (!pdata) goto err; + max8997->irq_base = pdata->irq_base; max8997->ono = pdata->ono; mutex_init(&max8997->iolock); diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 830152c..3f4deb6 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -23,8 +23,6 @@ #define __LINUX_MFD_MAX8997_PRIV_H #include -#include -#include #define MAX8997_REG_INVALID (0xff) @@ -327,7 +325,7 @@ struct max8997_dev { int irq; int ono; - struct irq_domain *irq_domain; + int irq_base; struct mutex irqlock; int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 24b1a76..28726dd 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -204,6 +204,7 @@ struct max8997_led_platform_data { struct max8997_platform_data { /* IRQ */ + int irq_base; int ono; int wakeup; -- cgit v0.10.2 From 9e96b3a7ade72cb66b95f2ad3c849bab702ed87b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 11 Apr 2012 22:56:11 +0800 Subject: regulator: Convert max8997 to get_voltage_sel Also rename get_current_limit and set_current_limit callbacks to max8997_get_current_limit and max8997_set_current_limit for better readability. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index db09244..56402e8 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -382,7 +382,7 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev, return 0; } -static int max8997_get_voltage(struct regulator_dev *rdev) +static int max8997_get_voltage_sel(struct regulator_dev *rdev) { struct max8997_data *max8997 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8997->iodev->i2c; @@ -400,15 +400,7 @@ static int max8997_get_voltage(struct regulator_dev *rdev) val >>= shift; val &= mask; - if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage) - return rdev->desc->ops->list_voltage(rdev, val); - - /* - * max8997_list_voltage returns value for any rdev with voltage_map, - * which works for "CHARGER" and "CHARGER TOPOFF" that do not have - * list_voltage ops (they are current regulators). - */ - return max8997_list_voltage(rdev, val); + return val; } static inline int max8997_get_voltage_proper_val( @@ -786,7 +778,7 @@ static struct regulator_ops max8997_ldo_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage = max8997_get_voltage, + .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_ldobuck, .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, @@ -797,7 +789,7 @@ static struct regulator_ops max8997_buck_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage = max8997_get_voltage, + .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_buck, .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, @@ -817,7 +809,7 @@ static struct regulator_ops max8997_safeout_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage = max8997_get_voltage, + .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_safeout, .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, @@ -825,31 +817,50 @@ static struct regulator_ops max8997_safeout_ops = { static struct regulator_ops max8997_fixedstate_ops = { .list_voltage = max8997_list_voltage_charger_cv, - .get_voltage = max8997_get_voltage, + .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_charger_cv, }; -static int max8997_set_voltage_ldobuck_wrap(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int max8997_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) { unsigned dummy; + int rid = rdev_get_id(rdev); + + if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF) + return -EINVAL; - return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV, &dummy); + /* Reuse max8997_set_voltage_ldobuck to set current_limit. */ + return max8997_set_voltage_ldobuck(rdev, min_uA, max_uA, &dummy); } +static int max8997_get_current_limit(struct regulator_dev *rdev) +{ + int sel, rid = rdev_get_id(rdev); + + if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF) + return -EINVAL; + + sel = max8997_get_voltage_sel(rdev); + if (sel < 0) + return sel; + + /* Reuse max8997_list_voltage to get current_limit. */ + return max8997_list_voltage(rdev, sel); +} static struct regulator_ops max8997_charger_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_current_limit = max8997_get_voltage, - .set_current_limit = max8997_set_voltage_ldobuck_wrap, + .get_current_limit = max8997_get_current_limit, + .set_current_limit = max8997_set_current_limit, }; static struct regulator_ops max8997_charger_fixedstate_ops = { .is_enabled = max8997_reg_is_enabled, - .get_current_limit = max8997_get_voltage, - .set_current_limit = max8997_set_voltage_ldobuck_wrap, + .get_current_limit = max8997_get_current_limit, + .set_current_limit = max8997_set_current_limit, }; #define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\ -- cgit v0.10.2 From 62bc4d4a702654cf5aefbb32c766991fb45bf15a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 11 Apr 2012 22:58:03 +0800 Subject: regulator: Convert max8997 to set_voltage_time_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 56402e8..ec99bd3 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -489,9 +489,7 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, int min_vol = min_uV / 1000, max_vol = max_uV / 1000; const struct voltage_map_desc *desc; int rid = rdev_get_id(rdev); - int reg, shift = 0, mask, ret; - int i; - u8 org; + int i, reg, shift, mask, ret; switch (rid) { case MAX8997_LDO1 ... MAX8997_LDO21: @@ -520,21 +518,50 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, if (ret) return ret; - max8997_read_reg(i2c, reg, &org); - org = (org & mask) >> shift; - ret = max8997_update_reg(i2c, reg, i << shift, mask << shift); *selector = i; - if (rid == MAX8997_BUCK1 || rid == MAX8997_BUCK2 || - rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) { - /* If the voltage is increasing */ - if (org < i) - udelay(DIV_ROUND_UP(desc->step * (i - org), - max8997->ramp_delay)); + return ret; +} + +static int max8997_set_voltage_ldobuck_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector) +{ + struct max8997_data *max8997 = rdev_get_drvdata(rdev); + int rid = rdev_get_id(rdev); + const struct voltage_map_desc *desc = reg_voltage_map[rid]; + + /* Delay is required only if the voltage is increasing */ + if (old_selector >= new_selector) + return 0; + + /* No need to delay if gpio_dvs_mode */ + switch (rid) { + case MAX8997_BUCK1: + if (max8997->buck1_gpiodvs) + return 0; + break; + case MAX8997_BUCK2: + if (max8997->buck2_gpiodvs) + return 0; + break; + case MAX8997_BUCK5: + if (max8997->buck5_gpiodvs) + return 0; + break; + } + + switch (rid) { + case MAX8997_BUCK1: + case MAX8997_BUCK2: + case MAX8997_BUCK4: + case MAX8997_BUCK5: + return DIV_ROUND_UP(desc->step * (new_selector - old_selector), + max8997->ramp_delay); } - return ret; + return 0; } /* @@ -780,6 +807,7 @@ static struct regulator_ops max8997_ldo_ops = { .disable = max8997_reg_disable, .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_ldobuck, + .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -791,6 +819,7 @@ static struct regulator_ops max8997_buck_ops = { .disable = max8997_reg_disable, .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_buck, + .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; -- cgit v0.10.2 From 5abe0c4005dea3a67051eb1942916f9d0f6a1796 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 18 Apr 2012 09:34:34 +0800 Subject: regulator: userspace-consumer: Convert to use devm_* APIs Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c index 518667e..a7c8deb 100644 --- a/drivers/regulator/userspace-consumer.c +++ b/drivers/regulator/userspace-consumer.c @@ -115,7 +115,9 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL); + drvdata = devm_kzalloc(&pdev->dev, + sizeof(struct userspace_consumer_data), + GFP_KERNEL); if (drvdata == NULL) return -ENOMEM; @@ -125,16 +127,16 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) mutex_init(&drvdata->lock); - ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies, - drvdata->supplies); + ret = devm_regulator_bulk_get(&pdev->dev, drvdata->num_supplies, + drvdata->supplies); if (ret) { dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret); - goto err_alloc_supplies; + return ret; } ret = sysfs_create_group(&pdev->dev.kobj, &attr_group); if (ret != 0) - goto err_create_attrs; + return ret; if (pdata->init_on) { ret = regulator_bulk_enable(drvdata->num_supplies, @@ -154,11 +156,6 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) err_enable: sysfs_remove_group(&pdev->dev.kobj, &attr_group); -err_create_attrs: - regulator_bulk_free(drvdata->num_supplies, drvdata->supplies); - -err_alloc_supplies: - kfree(drvdata); return ret; } @@ -171,9 +168,6 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev) if (data->enabled) regulator_bulk_disable(data->num_supplies, data->supplies); - regulator_bulk_free(data->num_supplies, data->supplies); - kfree(data); - return 0; } -- cgit v0.10.2 From a81edbdeb68bbecb3ee2888da7a83662ae69c9f3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 18 Apr 2012 09:35:35 +0800 Subject: regulator: virtual: Convert to use devm_* APIs Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index ee0b161..f74a68f 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -291,18 +291,19 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) struct virtual_consumer_data *drvdata; int ret; - drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct virtual_consumer_data), + GFP_KERNEL); if (drvdata == NULL) return -ENOMEM; mutex_init(&drvdata->lock); - drvdata->regulator = regulator_get(&pdev->dev, reg_id); + drvdata->regulator = devm_regulator_get(&pdev->dev, reg_id); if (IS_ERR(drvdata->regulator)) { ret = PTR_ERR(drvdata->regulator); dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n", reg_id, ret); - goto err; + return ret; } ret = sysfs_create_group(&pdev->dev.kobj, @@ -310,7 +311,7 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) if (ret != 0) { dev_err(&pdev->dev, "Failed to create attribute group: %d\n", ret); - goto err_regulator; + return ret; } drvdata->mode = regulator_get_mode(drvdata->regulator); @@ -318,12 +319,6 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) platform_set_drvdata(pdev, drvdata); return 0; - -err_regulator: - regulator_put(drvdata->regulator); -err: - kfree(drvdata); - return ret; } static int __devexit regulator_virtual_remove(struct platform_device *pdev) @@ -334,9 +329,6 @@ static int __devexit regulator_virtual_remove(struct platform_device *pdev) if (drvdata->enabled) regulator_disable(drvdata->regulator); - regulator_put(drvdata->regulator); - - kfree(drvdata); platform_set_drvdata(pdev, NULL); -- cgit v0.10.2 From a67f7e6b601ab55067d02de42e89be34c4b6f345 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 19 Apr 2012 11:15:58 +0800 Subject: regulator: 88pm8607: Fix writting value to vol_reg in pm8607_set_voltage_sel commit 4ca1e1d "regulator: Convert 88pm8607 to set_voltage_sel" accidentally changed the value writing to vol_reg. What we want is to write val instead of selector to vol_reg. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index d04fbe9..06d9c4b 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -232,7 +232,7 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) val = (uint8_t)(selector << info->vol_shift); mask = (rdev->desc->n_voltages - 1) << info->vol_shift; - ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, selector); + ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val); if (ret) return ret; switch (info->desc.id) { -- cgit v0.10.2 From 85960e7b3a212e5a895ba5b341cb4a18d0225a89 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 19 Apr 2012 09:03:45 +0800 Subject: regulator: virtual: Replace strict_strtol with kstrtol strict_strtol is deprecated and results in a checkpatch warning. Replace it with kstrtol. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index f74a68f..c038e74 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -121,7 +121,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) != 0) + if (kstrtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -147,7 +147,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) != 0) + if (kstrtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -173,7 +173,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) != 0) + if (kstrtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -199,7 +199,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) != 0) + if (kstrtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); -- cgit v0.10.2 From 7c842a1d244cb70d0ef85f47141f0f6f432f2521 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 20 Apr 2012 18:33:52 +0800 Subject: regulator: tps6507x: Convert to get_voltage_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 8e432004b..ef885ac 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -283,7 +283,7 @@ static int tps6507x_pmic_disable(struct regulator_dev *dev) 1 << shift); } -static int tps6507x_pmic_get_voltage(struct regulator_dev *dev) +static int tps6507x_pmic_get_voltage_sel(struct regulator_dev *dev) { struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, rid = rdev_get_id(dev); @@ -325,7 +325,7 @@ static int tps6507x_pmic_get_voltage(struct regulator_dev *dev) return data; data &= mask; - return tps->info[rid]->table[data] * 1000; + return data; } static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, @@ -395,7 +395,7 @@ static struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, - .get_voltage = tps6507x_pmic_get_voltage, + .get_voltage_sel = tps6507x_pmic_get_voltage_sel, .set_voltage_sel = tps6507x_pmic_set_voltage_sel, .list_voltage = tps6507x_pmic_list_voltage, }; -- cgit v0.10.2 From b9b49af5efa405f3c394a6395e79092c785999a3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 20 Apr 2012 18:36:14 +0800 Subject: regulator: max8952: Convert to get_voltage_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index c0ab4dd..62ae140 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -69,11 +69,6 @@ static int max8952_write_reg(struct max8952_data *max8952, return i2c_smbus_write_byte_data(max8952->client, reg, value); } -static int max8952_voltage(struct max8952_data *max8952, u8 mode) -{ - return (max8952->pdata->dvs_mode[mode] * 10 + 770) * 1000; -} - static int max8952_list_voltage(struct regulator_dev *rdev, unsigned int selector) { @@ -82,7 +77,7 @@ static int max8952_list_voltage(struct regulator_dev *rdev, if (rdev_get_id(rdev) != 0) return -EINVAL; - return max8952_voltage(max8952, selector); + return (max8952->pdata->dvs_mode[selector] * 10 + 770) * 1000; } static int max8952_is_enabled(struct regulator_dev *rdev) @@ -117,7 +112,7 @@ static int max8952_disable(struct regulator_dev *rdev) return 0; } -static int max8952_get_voltage(struct regulator_dev *rdev) +static int max8952_get_voltage_sel(struct regulator_dev *rdev) { struct max8952_data *max8952 = rdev_get_drvdata(rdev); u8 vid = 0; @@ -127,7 +122,7 @@ static int max8952_get_voltage(struct regulator_dev *rdev) if (max8952->vid1) vid += 2; - return max8952_voltage(max8952, vid); + return vid; } static int max8952_set_voltage_sel(struct regulator_dev *rdev, @@ -154,7 +149,7 @@ static struct regulator_ops max8952_ops = { .is_enabled = max8952_is_enabled, .enable = max8952_enable, .disable = max8952_disable, - .get_voltage = max8952_get_voltage, + .get_voltage_sel = max8952_get_voltage_sel, .set_voltage_sel = max8952_set_voltage_sel, .set_suspend_disable = max8952_disable, }; -- cgit v0.10.2 From 94e85a3c5d702a4ce96b7a9b883c949a08ebd93c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 13 Apr 2012 09:30:05 +0800 Subject: regulator: s5m8767: Use DIV_ROUND_UP to calculate selector Integer division may truncate the result. Use DIV_ROUND_UP to ensure new voltage setting falls within specified range. Also properly handle the case min_vol < desc->min to ensure we don't return negative value for selector. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index cb53187..ebe72d0 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -347,7 +347,10 @@ static int s5m8767_convert_voltage_to_sel( if (max_vol < desc->min || min_vol > desc->max) return -EINVAL; - selector = (min_vol - desc->min) / desc->step; + if (min_vol < desc->min) + min_vol = desc->min; + + selector = DIV_ROUND_UP(min_vol - desc->min, desc->step); if (desc->min + desc->step * selector > max_vol) return -EINVAL; -- cgit v0.10.2 From c245c087c50eabe284b22f7d5a8abc12427d29a7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 17 Apr 2012 23:48:27 +0800 Subject: regulator: max8997: Remove is_enabled callback implementation for max8997_charger_fixedstate_ops If is_enabled callback is not implemented, the core assumes that the regulator is on. This is simpler than having a hack to retrun 1 in max8997_reg_is_enabled() if max8997_get_enable_register() returns -EINVAL. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index ec99bd3..d106b74 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -278,9 +278,7 @@ static int max8997_reg_is_enabled(struct regulator_dev *rdev) u8 val; ret = max8997_get_enable_register(rdev, ®, &mask, &pattern); - if (ret == -EINVAL) - return 1; /* "not controllable" */ - else if (ret) + if (ret) return ret; ret = max8997_read_reg(i2c, reg, &val); @@ -887,7 +885,6 @@ static struct regulator_ops max8997_charger_ops = { }; static struct regulator_ops max8997_charger_fixedstate_ops = { - .is_enabled = max8997_reg_is_enabled, .get_current_limit = max8997_get_current_limit, .set_current_limit = max8997_set_current_limit, }; -- cgit v0.10.2 From 23b7d09a3f50191a72ca70708a541b05e422e388 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 17 Apr 2012 23:49:28 +0800 Subject: regulator: max8997: Remove empty set_suspend_enable callback implementation Since commit 8ac0e95 "regulator: core: Support setting suspend_[mode|voltage] if set_suspend_[en|dis]able is NULL", now the regulator core can properly handle the case set_suspend_enable callback is NULL. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index d106b74..ccfd6f3 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -766,11 +766,6 @@ static int max8997_set_voltage_safeout(struct regulator_dev *rdev, return ret; } -static int max8997_reg_enable_suspend(struct regulator_dev *rdev) -{ - return 0; -} - static int max8997_reg_disable_suspend(struct regulator_dev *rdev) { struct max8997_data *max8997 = rdev_get_drvdata(rdev); @@ -806,7 +801,6 @@ static struct regulator_ops max8997_ldo_ops = { .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_ldobuck, .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, - .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -818,7 +812,6 @@ static struct regulator_ops max8997_buck_ops = { .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_buck, .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, - .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -827,7 +820,6 @@ static struct regulator_ops max8997_fixedvolt_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -838,7 +830,6 @@ static struct regulator_ops max8997_safeout_ops = { .disable = max8997_reg_disable, .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_safeout, - .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; -- cgit v0.10.2 From 6c9eeb0f5cac0d9fd05c138f1eec86a7f70630ce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 18 Apr 2012 08:52:28 +0800 Subject: regulator: Remove unneeded include of linux/delay.h from regulator drivers All the drivers that need delay for the regulator voltage output voltage to stabilize after being enabled or after being set to a new value has been converted to implement enable_time and set_voltage_time_sel callbacks. Then regulator core will take care of the necessary delay. For the drivers that don't need the delay, don't need to include linux/delay.h. This patch removes the unneeded include of linux/delay.h in regulator drivers. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 7f000d6..06776ca 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index ce61925..e2062ad 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index b47b005a..bd437c1 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index f93b06b..9997d7a 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -30,7 +30,6 @@ #include #include #include -#include #include struct gpio_regulator_data { diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 60044c3..5caaf1f 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #define ISL6271A_VOLTAGE_MIN 850000 diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index ccfd6f3..90e2112 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -22,7 +22,6 @@ */ #include -#include #include #include #include diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 4ca22f9..052ee35 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index b567c9e..fb87c1b 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -23,7 +23,6 @@ */ #include -#include #include #include #include diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index ebe72d0..cf12e635 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index 0657c98..20fef1d 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 2db7149..26ce7a1 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index ef885ac..da38be1 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 6bbf760..e7b92f1 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index fe66a2c..3d9c54f 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index af335dd..7312e36 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 7385b27..fffacb4 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 8ae5767ba1c4e149ee9970aa7a4e9bf6b251bb77 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 19 Apr 2012 09:44:13 +0800 Subject: regulator: max8997: Convert ot use devm_kzalloc Also simplify the error handling to start unwind from the place regulator_register fails. No need to check rdev[i] is NULL or not before calling regulator_unregister. regulator_unregister is safe if rdev is NULL, Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 90e2112..b88551b 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -949,16 +949,15 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) return -ENODEV; } - max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL); + max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data), + GFP_KERNEL); if (!max8997) return -ENOMEM; size = sizeof(struct regulator_dev *) * pdata->num_regulators; - max8997->rdev = kzalloc(size, GFP_KERNEL); - if (!max8997->rdev) { - kfree(max8997); + max8997->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!max8997->rdev) return -ENOMEM; - } rdev = max8997->rdev; max8997->dev = &pdev->dev; @@ -982,7 +981,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck1_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_alloc; + goto err_out; max8997->buck2_vol[i] = ret = max8997_get_voltage_proper_val( @@ -991,7 +990,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck2_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_alloc; + goto err_out; max8997->buck5_vol[i] = ret = max8997_get_voltage_proper_val( @@ -1000,7 +999,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck5_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_alloc; + goto err_out; if (max_buck1 < max8997->buck1_vol[i]) max_buck1 = max8997->buck1_vol[i]; @@ -1033,7 +1032,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) !gpio_is_valid(pdata->buck125_gpios[2])) { dev_err(&pdev->dev, "GPIO NOT VALID\n"); ret = -EINVAL; - goto err_alloc; + goto err_out; } ret = gpio_request(pdata->buck125_gpios[0], @@ -1042,7 +1041,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Duplicated gpio request" " on SET1\n"); else if (ret) - goto err_alloc; + goto err_out; else gpio1set = true; @@ -1054,7 +1053,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) else if (ret) { if (gpio1set) gpio_free(pdata->buck125_gpios[0]); - goto err_alloc; + goto err_out; } else gpio2set = true; @@ -1068,7 +1067,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) gpio_free(pdata->buck125_gpios[0]); if (gpio2set) gpio_free(pdata->buck125_gpios[1]); - goto err_alloc; + goto err_out; } gpio_direction_output(pdata->buck125_gpios[0], @@ -1137,13 +1136,9 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) return 0; err: - for (i = 0; i < max8997->num_regulators; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); -err_alloc: - kfree(max8997->rdev); - kfree(max8997); - + while (--i >= 0) + regulator_unregister(rdev[i]); +err_out: return ret; } @@ -1154,12 +1149,7 @@ static int __devexit max8997_pmic_remove(struct platform_device *pdev) int i; for (i = 0; i < max8997->num_regulators; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - - kfree(max8997->rdev); - kfree(max8997); - + regulator_unregister(rdev[i]); return 0; } -- cgit v0.10.2 From 0f80ea1499ae047dcaa29ccecfe0d58bb229c4e9 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 19 Apr 2012 09:47:37 +0800 Subject: regulator: max8998: Convert ot use devm_kzalloc Also simplify the error handling to start unwind from the place regulator_register fails. No need to check rdev[i] is NULL or not before calling regulator_unregister. regulator_unregister is safe if rdev is NULL, Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 052ee35..18bb58b 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -718,16 +718,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) return -ENODEV; } - max8998 = kzalloc(sizeof(struct max8998_data), GFP_KERNEL); + max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_data), + GFP_KERNEL); if (!max8998) return -ENOMEM; size = sizeof(struct regulator_dev *) * pdata->num_regulators; - max8998->rdev = kzalloc(size, GFP_KERNEL); - if (!max8998->rdev) { - kfree(max8998); + max8998->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!max8998->rdev) return -ENOMEM; - } rdev = max8998->rdev; max8998->dev = &pdev->dev; @@ -751,14 +750,14 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set1); ret = -EIO; - goto err_free_mem; + goto err_out; } /* Check if SET2 is not equal to 0 */ if (!pdata->buck1_set2) { printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set2); ret = -EIO; - goto err_free_mem; + goto err_out; } gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); @@ -778,7 +777,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); if (ret) - goto err_free_mem; + goto err_out; /* Set predefined value for BUCK1 register 2 */ i = 0; @@ -790,7 +789,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[1] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); if (ret) - goto err_free_mem; + goto err_out; /* Set predefined value for BUCK1 register 3 */ i = 0; @@ -802,7 +801,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[2] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); if (ret) - goto err_free_mem; + goto err_out; /* Set predefined value for BUCK1 register 4 */ i = 0; @@ -814,7 +813,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[3] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); if (ret) - goto err_free_mem; + goto err_out; } @@ -824,7 +823,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck2_set3); ret = -EIO; - goto err_free_mem; + goto err_out; } gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); gpio_direction_output(pdata->buck2_set3, @@ -839,7 +838,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck2_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); if (ret) - goto err_free_mem; + goto err_out; /* BUCK2 register 2 */ i = 0; @@ -850,7 +849,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck2_vol[1] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); if (ret) - goto err_free_mem; + goto err_out; } for (i = 0; i < pdata->num_regulators; i++) { @@ -880,14 +879,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) return 0; err: - for (i = 0; i < max8998->num_regulators; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - -err_free_mem: - kfree(max8998->rdev); - kfree(max8998); - + while (--i >= 0) + regulator_unregister(rdev[i]); +err_out: return ret; } @@ -898,12 +892,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) int i; for (i = 0; i < max8998->num_regulators; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - - kfree(max8998->rdev); - kfree(max8998); - + regulator_unregister(rdev[i]); return 0; } -- cgit v0.10.2 From 9db7f05624ffa845400d2bd2bfe5b9793985ce34 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 21 Apr 2012 11:03:34 +0800 Subject: regulator: tps65912: Convert to get_voltage_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 7312e36..18b2a1d 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -405,7 +405,7 @@ static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector) return voltage; } -static int tps65912_get_voltage(struct regulator_dev *dev) +static int tps65912_get_voltage_sel(struct regulator_dev *dev) { struct tps65912_reg *pmic = rdev_get_drvdata(dev); struct tps65912 *mfd = pmic->mfd; @@ -419,7 +419,7 @@ static int tps65912_get_voltage(struct regulator_dev *dev) vsel = tps65912_reg_read(mfd, reg); vsel &= 0x3F; - return tps65912_list_voltage(dev, vsel); + return vsel; } static int tps65912_set_voltage_sel(struct regulator_dev *dev, @@ -444,7 +444,7 @@ static struct regulator_ops tps65912_ops_dcdc = { .disable = tps65912_reg_disable, .set_mode = tps65912_set_mode, .get_mode = tps65912_get_mode, - .get_voltage = tps65912_get_voltage, + .get_voltage_sel = tps65912_get_voltage_sel, .set_voltage_sel = tps65912_set_voltage_sel, .list_voltage = tps65912_list_voltage, }; @@ -454,7 +454,7 @@ static struct regulator_ops tps65912_ops_ldo = { .is_enabled = tps65912_reg_is_enabled, .enable = tps65912_reg_enable, .disable = tps65912_reg_disable, - .get_voltage = tps65912_get_voltage, + .get_voltage_sel = tps65912_get_voltage_sel, .set_voltage_sel = tps65912_set_voltage_sel, .list_voltage = tps65912_list_voltage, }; -- cgit v0.10.2 From f1aba13fbdcccd36c4ed4b0c1aa910bb05a0fd01 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Mar 2012 21:40:20 +0100 Subject: regulator: wm831x-ldo: Set up supply names Allows hookup via normal consumer mechanisms. Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 5f01040..344beb8 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -25,7 +25,7 @@ #include #include -#define WM831X_LDO_MAX_NAME 6 +#define WM831X_LDO_MAX_NAME 9 #define WM831X_LDO_CONTROL 0 #define WM831X_LDO_ON_CONTROL 1 @@ -36,6 +36,7 @@ struct wm831x_ldo { char name[WM831X_LDO_MAX_NAME]; + char supply_name[WM831X_LDO_MAX_NAME]; struct regulator_desc desc; int base; struct wm831x *wm831x; @@ -345,6 +346,11 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; + + snprintf(ldo->supply_name, sizeof(ldo->supply_name), + "LDO%dVDD", id + 1); + ldo->desc.supply_name = ldo->supply_name; + ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1; @@ -614,6 +620,11 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; + + snprintf(ldo->supply_name, sizeof(ldo->supply_name), + "LDO%dVDD", id + 1); + ldo->desc.supply_name = ldo->supply_name; + ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1; @@ -813,6 +824,11 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; + + snprintf(ldo->supply_name, sizeof(ldo->supply_name), + "LDO%dVDD", id + 1); + ldo->desc.supply_name = ldo->supply_name; + ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1; -- cgit v0.10.2 From 82caa9780a85a97e45e4df6e1f228279707bdcfe Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Mar 2012 21:40:42 +0100 Subject: regulator: wm831x-dcdc: Specify supply names Allows hookup via normal consumer mechanisms. Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index f0da23c..c964863 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -35,7 +35,7 @@ #define WM831X_DCDC_MODE_IDLE 2 #define WM831X_DCDC_MODE_STANDBY 3 -#define WM831X_DCDC_MAX_NAME 6 +#define WM831X_DCDC_MAX_NAME 9 /* Register offsets in control block */ #define WM831X_DCDC_CONTROL_1 0 @@ -50,6 +50,7 @@ struct wm831x_dcdc { char name[WM831X_DCDC_MAX_NAME]; + char supply_name[WM831X_DCDC_MAX_NAME]; struct regulator_desc desc; int base; struct wm831x *wm831x; @@ -534,6 +535,11 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1); dcdc->desc.name = dcdc->name; + + snprintf(dcdc->supply_name, sizeof(dcdc->supply_name), + "DC%dVDD", id + 1); + dcdc->desc.supply_name = dcdc->supply_name; + dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1; @@ -748,6 +754,11 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1); dcdc->desc.name = dcdc->name; + + snprintf(dcdc->supply_name, sizeof(dcdc->supply_name), + "DC%dVDD", id + 1); + dcdc->desc.supply_name = dcdc->supply_name; + dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1; -- cgit v0.10.2 From 1c8fa58f4750e9ad722fbf899866c312ffabab67 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 26 Apr 2012 16:52:20 +0200 Subject: regulator: Add generic DT parsing for regulators Looking up init data for regulators found on chips is a common operation that can be handled in a generic way. The new helper function introduced by this patch looks up the children of a given node by names specified in a match table and fills that match table with information parsed from the DT. This is based on work by Rhyland Klein . Signed-off-by: Thierry Reding Signed-off-by: Mark Brown diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 679734d..56593b7 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -14,6 +14,7 @@ #include #include #include +#include static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) @@ -85,3 +86,49 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, return init_data; } EXPORT_SYMBOL_GPL(of_get_regulator_init_data); + +/** + * of_regulator_match - extract regulator init data + * @dev: device requesting the data + * @node: parent device node of the regulators + * @matches: match table for the regulators + * @num_matches: number of entries in match table + * + * This function uses a match table specified by the regulator driver and + * looks up the corresponding init data in the device tree. Note that the + * match table is modified in place. + * + * Returns the number of matches found or a negative error code on failure. + */ +int of_regulator_match(struct device *dev, struct device_node *node, + struct of_regulator_match *matches, + unsigned int num_matches) +{ + unsigned int count = 0; + unsigned int i; + + if (!dev || !node) + return -EINVAL; + + for (i = 0; i < num_matches; i++) { + struct of_regulator_match *match = &matches[i]; + struct device_node *child; + + child = of_find_node_by_name(node, match->name); + if (!child) + continue; + + match->init_data = of_get_regulator_init_data(dev, child); + if (!match->init_data) { + dev_err(dev, "failed to parse DT for regulator %s\n", + child->name); + return -EINVAL; + } + + match->of_node = child; + count++; + } + + return count; +} +EXPORT_SYMBOL_GPL(of_regulator_match); diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h index 769704f..f921796 100644 --- a/include/linux/regulator/of_regulator.h +++ b/include/linux/regulator/of_regulator.h @@ -6,10 +6,20 @@ #ifndef __LINUX_OF_REG_H #define __LINUX_OF_REG_H +struct of_regulator_match { + const char *name; + void *driver_data; + struct regulator_init_data *init_data; + struct device_node *of_node; +}; + #if defined(CONFIG_OF) extern struct regulator_init_data *of_get_regulator_init_data(struct device *dev, struct device_node *node); +extern int of_regulator_match(struct device *dev, struct device_node *node, + struct of_regulator_match *matches, + unsigned int num_matches); #else static inline struct regulator_init_data *of_get_regulator_init_data(struct device *dev, @@ -17,6 +27,14 @@ static inline struct regulator_init_data { return NULL; } + +static inline int of_regulator_match(struct device *dev, + struct device_node *node, + struct of_regulator_match *matches, + unsigned int num_matches) +{ + return 0; +} #endif /* CONFIG_OF */ #endif /* __LINUX_OF_REG_H */ -- cgit v0.10.2 From 62f6b0879304e2169d6bf6221612e8111e342ee7 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 26 Apr 2012 16:52:21 +0200 Subject: tps6586x: Add device tree support This commit adds device tree support for the TPS6586x regulator. Signed-off-by: Thierry Reding Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt new file mode 100644 index 0000000..0fcabaa --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/tps6586x.txt @@ -0,0 +1,97 @@ +TPS6586x family of regulators + +Required properties: +- compatible: "ti,tps6586x" +- reg: I2C slave address +- interrupts: the interrupt outputs of the controller +- #gpio-cells: number of cells to describe a GPIO +- gpio-controller: mark the device as a GPIO controller +- regulators: list of regulators provided by this controller, must be named + after their hardware counterparts: sm[0-2], ldo[0-9] and ldo_rtc + +Each regulator is defined using the standard binding for regulators. + +Example: + + pmu: tps6586x@34 { + compatible = "ti,tps6586x"; + reg = <0x34>; + interrupts = <0 88 0x4>; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + sm0_reg: sm0 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sm1_reg: sm1 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sm2_reg: sm2 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <4550000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo0_reg: ldo0 { + regulator-name = "PCIE CLK"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo1_reg: ldo1 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + }; + + ldo2_reg: ldo2 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + }; + + ldo3_reg: ldo3 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo4_reg: ldo4 { + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <2475000>; + }; + + ldo5_reg: ldo5 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo6_reg: ldo6 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo7_reg: ldo7 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo8_reg: ldo8 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo9_reg: ldo9 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index a5ddf31..c84b550 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -460,6 +461,7 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, pdev->dev.parent = tps6586x->dev; pdev->dev.platform_data = subdev->platform_data; + pdev->dev.of_node = subdev->of_node; ret = platform_device_add(pdev); if (ret) { @@ -474,6 +476,86 @@ failed: return ret; } +#ifdef CONFIG_OF +static struct of_regulator_match tps6586x_matches[] = { + { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, + { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, + { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, + { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, + { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, + { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, + { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, + { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, + { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, + { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, + { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, + { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, + { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, + { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, +}; + +static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) +{ + const unsigned int num = ARRAY_SIZE(tps6586x_matches); + struct device_node *np = client->dev.of_node; + struct tps6586x_platform_data *pdata; + struct tps6586x_subdev_info *devs; + struct device_node *regs; + unsigned int count; + unsigned int i, j; + int err; + + regs = of_find_node_by_name(np, "regulators"); + if (!regs) + return NULL; + + err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); + if (err < 0) { + of_node_put(regs); + return NULL; + } + + of_node_put(regs); + count = err; + + devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); + if (!devs) + return NULL; + + for (i = 0, j = 0; i < num && j < count; i++) { + if (!tps6586x_matches[i].init_data) + continue; + + devs[j].name = "tps6586x-regulator"; + devs[j].platform_data = tps6586x_matches[i].init_data; + devs[j].id = (int)tps6586x_matches[i].driver_data; + devs[j].of_node = tps6586x_matches[i].of_node; + j++; + } + + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + pdata->num_subdevs = count; + pdata->subdevs = devs; + pdata->gpio_base = -1; + pdata->irq_base = -1; + + return pdata; +} + +static struct of_device_id tps6586x_of_match[] = { + { .compatible = "ti,tps6586x", }, + { }, +}; +#else +static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) +{ + return NULL; +} +#endif + static int __devinit tps6586x_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -481,6 +563,9 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, struct tps6586x *tps6586x; int ret; + if (!pdata && client->dev.of_node) + pdata = tps6586x_parse_dt(client); + if (!pdata) { dev_err(&client->dev, "tps6586x requires platform data\n"); return -ENOTSUPP; @@ -573,6 +658,7 @@ static struct i2c_driver tps6586x_driver = { .driver = { .name = "tps6586x", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tps6586x_of_match), }, .probe = tps6586x_i2c_probe, .remove = __devexit_p(tps6586x_i2c_remove), diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 9a4029a..c0a2145 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -363,6 +363,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) return err; config.dev = &pdev->dev; + config.of_node = pdev->dev.of_node; config.init_data = pdev->dev.platform_data; config.driver_data = ri; diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h index b19176e..f350fd0 100644 --- a/include/linux/mfd/tps6586x.h +++ b/include/linux/mfd/tps6586x.h @@ -68,6 +68,7 @@ struct tps6586x_subdev_info { int id; const char *name; void *platform_data; + struct device_node *of_node; }; struct tps6586x_platform_data { -- cgit v0.10.2 From 9a50dba509251dfce7895a5990cb938f383a6273 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 7 May 2012 15:58:19 +0530 Subject: regulator: fixed: add property for gpio open drain flag Add property for the gpio flag open drain when registering fixed regulator. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt index 9cf57fd..2f5b6b1 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt @@ -8,6 +8,8 @@ Optional properties: - 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. +- gpio-open-drain: GPIO is open drain type. + If this property is missing then default assumption is false. Any property defined as part of the core regulator binding, defined in regulator.txt, can also be used. @@ -25,5 +27,6 @@ Example: gpio = <&gpio1 16 0>; startup-delay-us = <70000>; enable-active-high; - regulator-boot-on + regulator-boot-on; + gpio-open-drain; }; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index bd437c1..f09fe7b 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -90,6 +90,9 @@ of_get_fixed_voltage_config(struct device *dev) if (of_find_property(np, "enable-active-high", NULL)) config->enable_high = true; + if (of_find_property(np, "gpio-open-drain", NULL)) + config->gpio_is_open_drain = true; + return config; } -- cgit v0.10.2 From 8e8a507c2427c960c5d1fe58a250635b35f3acdc Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Mon, 7 May 2012 15:57:23 +0800 Subject: regulator: da9052: fix bug in device tree iteration loop The driver of da9052 is buggy due to the iteration loop of device tree. This patch fix the loop condition to make the driver work with device tree. Signed-off-by: Ying-Chun Liu (PaulLiu) Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index eaa91cc5..f8ad24a 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -444,7 +444,7 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev) if (!nproot) return -ENODEV; - for (np = of_get_next_child(nproot, NULL); !np; + for (np = of_get_next_child(nproot, NULL); np; np = of_get_next_child(nproot, np)) { if (!of_node_cmp(np->name, regulator->info->reg_desc.name)) { -- cgit v0.10.2 From 16ea003bd1c95ea55a0b88187ce7cbeaca760fcf Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 7 May 2012 18:08:25 +0530 Subject: regulator: tps62360: enable register cache Enable cache of device register using regmap cache RBTREE. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index 20fef1d..e893080 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -262,8 +262,10 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, } static const struct regmap_config tps62360_regmap_config = { - .reg_bits = 8, - .val_bits = 8, + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_CHIPID, + .cache_type = REGCACHE_RBTREE, }; static int __devinit tps62360_probe(struct i2c_client *client, -- cgit v0.10.2 From a60cfce051dd5e22329df1018d278bf3e52d82bc Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 7 May 2012 18:08:26 +0530 Subject: regulator: tps62360: Provide settling time for voltage change Settling time is require when there is voltage output change. Implement set_voltage_time_sel() callback which returns delay time for voltage change to settle down to new value. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index e893080..d2f657e 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -71,6 +71,7 @@ struct tps62360_chip { int lru_index[4]; int curr_vset_vsel[4]; int curr_vset_id; + int change_uv_per_us; }; /* @@ -114,7 +115,7 @@ update_lru_index: return found; } -static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) +static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev) { struct tps62360_chip *tps = rdev_get_drvdata(dev); int vsel; @@ -128,7 +129,7 @@ static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) return ret; } vsel = (int)data & tps->voltage_reg_mask; - return (tps->voltage_base + vsel * 10) * 1000; + return vsel; } static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, @@ -193,10 +194,28 @@ static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, return (tps->voltage_base + selector * 10) * 1000; } +static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(rdev); + int old_uV, new_uV; + + old_uV = tps62360_dcdc_list_voltage(rdev, old_selector); + if (old_uV < 0) + return old_uV; + + new_uV = tps62360_dcdc_list_voltage(rdev, new_selector); + if (new_uV < 0) + return new_uV; + + return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); +} + static struct regulator_ops tps62360_dcdc_ops = { - .get_voltage = tps62360_dcdc_get_voltage, - .set_voltage = tps62360_dcdc_set_voltage, - .list_voltage = tps62360_dcdc_list_voltage, + .get_voltage_sel = tps62360_dcdc_get_voltage_sel, + .set_voltage = tps62360_dcdc_set_voltage, + .list_voltage = tps62360_dcdc_list_voltage, + .set_voltage_time_sel = tps62360_set_voltage_time_sel, }; static int tps62360_init_force_pwm(struct tps62360_chip *tps, @@ -228,6 +247,7 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, { int ret; int i; + unsigned int ramp_ctrl; /* Initailize internal pull up/down control */ if (tps->en_internal_pulldn) @@ -255,9 +275,23 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, /* Reset output discharge path to reduce power consumption */ ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); - if (ret < 0) + if (ret < 0) { dev_err(tps->dev, "%s() fails in updating reg %d\n", __func__, REG_RAMPCTRL); + return ret; + } + + /* Get ramp value from ramp control register */ + ret = regmap_read(tps->regmap, REG_RAMPCTRL, &ramp_ctrl); + if (ret < 0) { + dev_err(tps->dev, "%s() fails in reading reg %d\n", + __func__, REG_RAMPCTRL); + return ret; + } + ramp_ctrl = (ramp_ctrl >> 4) & 0x7; + + /* ramp mV/us = 32/(2^ramp_ctrl) */ + tps->change_uv_per_us = DIV_ROUND_UP(32000, BIT(ramp_ctrl)); return ret; } -- cgit v0.10.2 From 09e3fd202df67ec5d6d9a04c05b58c7367580226 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 May 2012 18:18:45 +0100 Subject: regulator: wm8994: Convert to gpio_request_one() Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 0ee81e1..1f7f43c 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -224,19 +224,12 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { ldo->enable = pdata->ldo[id].enable; - ret = gpio_request(ldo->enable, "WM8994 LDO enable"); + ret = gpio_request_one(ldo->enable, 0, "WM8994 LDO enable"); if (ret < 0) { dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); goto err; } - - ret = gpio_direction_output(ldo->enable, ldo->is_enabled); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to set GPIO up: %d\n", - ret); - goto err_gpio; - } } else ldo->is_enabled = true; -- cgit v0.10.2 From 053fa1b75244c4be0d4b4065f80f31deaf2f24a7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 May 2012 18:19:08 +0100 Subject: regulator: wm831x-dcdc: Convert to gpio_request_one() Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index c964863..a2acafd 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -438,23 +438,17 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, if (!pdata || !pdata->dvs_gpio) return; - ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", - dcdc->name, ret); - return; - } - /* gpiolib won't let us read the GPIO status so pick the higher * of the two existing voltages so we take it as platform data. */ dcdc->dvs_gpio_state = pdata->dvs_init_state; - ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state); + ret = gpio_request_one(pdata->dvs_gpio, + dcdc->dvs_gpio_state ? GPIOF_INIT_HIGH : 0, + "DCDC DVS"); if (ret < 0) { - dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n", + dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", dcdc->name, ret); - gpio_free(pdata->dvs_gpio); return; } -- cgit v0.10.2 From 2935fb18aa1e75e6afaab3303cdd1a4ac62be63e Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 8 May 2012 17:05:58 +0530 Subject: regulator: tps62360: fix stylistic issue and optimize code Fix multiple stylistic issue like: - The print message should be not break into multiple line. - line gap after variable declaration and statement. - checkpatch error. - some typo. Some enhancement on error message printing to print error value also along with proper text. Avoid voltage_base conversion to microvolts every time. Put init functions in init section. Using efficient function inplace of calling multiple function to reduce the code size. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index d2f657e..97fd98b 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -47,10 +47,10 @@ enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; -#define TPS62360_BASE_VOLTAGE 770 +#define TPS62360_BASE_VOLTAGE 770000 #define TPS62360_N_VOLTAGES 64 -#define TPS62361_BASE_VOLTAGE 500 +#define TPS62361_BASE_VOLTAGE 500000 #define TPS62361_N_VOLTAGES 128 /* tps 62360 chip information */ @@ -97,6 +97,7 @@ static bool find_voltage_set_register(struct tps62360_chip *tps, bool found = false; int new_vset_reg = tps->lru_index[3]; int found_index = 3; + for (i = 0; i < 4; ++i) { if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { new_vset_reg = tps->lru_index[i]; @@ -124,8 +125,8 @@ static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev) ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); if (ret < 0) { - dev_err(tps->dev, "%s: Error in reading register %d\n", - __func__, REG_VSET0 + tps->curr_vset_id); + dev_err(tps->dev, "%s(): register %d read failed with err %d\n", + __func__, REG_VSET0 + tps->curr_vset_id, ret); return ret; } vsel = (int)data & tps->voltage_reg_mask; @@ -141,17 +142,13 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, bool found = false; int new_vset_id = tps->curr_vset_id; - if (max_uV < min_uV) - return -EINVAL; - - if (min_uV > - ((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000)) + if ((max_uV < min_uV) || (max_uV < tps->voltage_base)) return -EINVAL; - if (max_uV < tps->voltage_base * 1000) + if (min_uV > (tps->voltage_base + (tps->desc.n_voltages - 1) * 10000)) return -EINVAL; - vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000); + vsel = DIV_ROUND_UP(min_uV - tps->voltage_base, 10000); if (selector) *selector = (vsel & tps->voltage_reg_mask); @@ -166,8 +163,9 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, tps->voltage_reg_mask, vsel); if (ret < 0) { - dev_err(tps->dev, "%s: Error in updating register %d\n", - __func__, REG_VSET0 + new_vset_id); + dev_err(tps->dev, + "%s(): register %d update failed with err %d\n", + __func__, REG_VSET0 + new_vset_id, ret); return ret; } tps->curr_vset_id = new_vset_id; @@ -176,8 +174,7 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, /* Select proper VSET register vio gpios */ if (tps->valid_gpios) { - gpio_set_value_cansleep(tps->vsel0_gpio, - new_vset_id & 0x1); + gpio_set_value_cansleep(tps->vsel0_gpio, new_vset_id & 0x1); gpio_set_value_cansleep(tps->vsel1_gpio, (new_vset_id >> 1) & 0x1); } @@ -191,7 +188,8 @@ static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, if (selector >= tps->desc.n_voltages) return -EINVAL; - return (tps->voltage_base + selector * 10) * 1000; + + return tps->voltage_base + selector * 10000; } static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, @@ -218,49 +216,44 @@ static struct regulator_ops tps62360_dcdc_ops = { .set_voltage_time_sel = tps62360_set_voltage_time_sel, }; -static int tps62360_init_force_pwm(struct tps62360_chip *tps, +static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps, struct tps62360_regulator_platform_data *pdata, int vset_id) { - unsigned int data; int ret; - ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); - if (ret < 0) { - dev_err(tps->dev, "%s() fails in writing reg %d\n", - __func__, REG_VSET0 + vset_id); - return ret; - } - tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask; + int bit = 0; + if (pdata->en_force_pwm) - data |= BIT(7); - else - data &= ~BIT(7); - ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data); + bit = BIT(7); + + ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit); if (ret < 0) - dev_err(tps->dev, "%s() fails in writing reg %d\n", - __func__, REG_VSET0 + vset_id); + dev_err(tps->dev, + "%s(): register %d update failed with err %d\n", + __func__, REG_VSET0 + vset_id, ret); return ret; } -static int tps62360_init_dcdc(struct tps62360_chip *tps, +static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, struct tps62360_regulator_platform_data *pdata) { int ret; int i; unsigned int ramp_ctrl; - /* Initailize internal pull up/down control */ + /* Initialize internal pull up/down control */ if (tps->en_internal_pulldn) ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); else ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); if (ret < 0) { - dev_err(tps->dev, "%s() fails in writing reg %d\n", - __func__, REG_CONTROL); + dev_err(tps->dev, + "%s(): register %d write failed with err %d\n", + __func__, REG_CONTROL, ret); return ret; } - /* Initailize force PWM mode */ + /* Initialize force PWM mode */ if (tps->valid_gpios) { for (i = 0; i < 4; ++i) { ret = tps62360_init_force_pwm(tps, pdata, i); @@ -276,16 +269,18 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, /* Reset output discharge path to reduce power consumption */ ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); if (ret < 0) { - dev_err(tps->dev, "%s() fails in updating reg %d\n", - __func__, REG_RAMPCTRL); + dev_err(tps->dev, + "%s(): register %d update failed with err %d\n", + __func__, REG_RAMPCTRL, ret); return ret; } /* Get ramp value from ramp control register */ ret = regmap_read(tps->regmap, REG_RAMPCTRL, &ramp_ctrl); if (ret < 0) { - dev_err(tps->dev, "%s() fails in reading reg %d\n", - __func__, REG_RAMPCTRL); + dev_err(tps->dev, + "%s(): register %d read failed with err %d\n", + __func__, REG_RAMPCTRL, ret); return ret; } ramp_ctrl = (ramp_ctrl >> 4) & 0x7; @@ -314,14 +309,14 @@ static int __devinit tps62360_probe(struct i2c_client *client, pdata = client->dev.platform_data; if (!pdata) { - dev_err(&client->dev, "%s() Err: Platform data not found\n", + dev_err(&client->dev, "%s(): Platform data not found\n", __func__); return -EIO; } tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); if (!tps) { - dev_err(&client->dev, "%s() Err: Memory allocation fails\n", + dev_err(&client->dev, "%s(): Memory allocation failed\n", __func__); return -ENOMEM; } @@ -358,8 +353,9 @@ static int __devinit tps62360_probe(struct i2c_client *client, tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); if (IS_ERR(tps->regmap)) { ret = PTR_ERR(tps->regmap); - dev_err(&client->dev, "%s() Err: Failed to allocate register" - "map: %d\n", __func__, ret); + dev_err(&client->dev, + "%s(): regmap allocation failed with err %d\n", + __func__, ret); return ret; } i2c_set_clientdata(client, tps); @@ -370,35 +366,26 @@ static int __devinit tps62360_probe(struct i2c_client *client, tps->valid_gpios = false; if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { - ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); + int gpio_flags; + gpio_flags = (pdata->vsel0_def_state) ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + ret = gpio_request_one(tps->vsel0_gpio, + gpio_flags, "tps62360-vsel0"); if (ret) { dev_err(&client->dev, - "Err: Could not obtain vsel0 GPIO %d: %d\n", - tps->vsel0_gpio, ret); - goto err_gpio0; - } - ret = gpio_direction_output(tps->vsel0_gpio, - pdata->vsel0_def_state); - if (ret) { - dev_err(&client->dev, "Err: Could not set direction of" - "vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret); - gpio_free(tps->vsel0_gpio); + "%s(): Could not obtain vsel0 GPIO %d: %d\n", + __func__, tps->vsel0_gpio, ret); goto err_gpio0; } - ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); + gpio_flags = (pdata->vsel1_def_state) ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + ret = gpio_request_one(tps->vsel1_gpio, + gpio_flags, "tps62360-vsel1"); if (ret) { dev_err(&client->dev, - "Err: Could not obtain vsel1 GPIO %d: %d\n", - tps->vsel1_gpio, ret); - goto err_gpio1; - } - ret = gpio_direction_output(tps->vsel1_gpio, - pdata->vsel1_def_state); - if (ret) { - dev_err(&client->dev, "Err: Could not set direction of" - "vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret); - gpio_free(tps->vsel1_gpio); + "%s(): Could not obtain vsel1 GPIO %d: %d\n", + __func__, tps->vsel1_gpio, ret); goto err_gpio1; } tps->valid_gpios = true; @@ -415,7 +402,7 @@ static int __devinit tps62360_probe(struct i2c_client *client, ret = tps62360_init_dcdc(tps, pdata); if (ret < 0) { - dev_err(tps->dev, "%s() Err: Init fails with = %d\n", + dev_err(tps->dev, "%s(): Init failed with err = %d\n", __func__, ret); goto err_init; } @@ -427,8 +414,9 @@ static int __devinit tps62360_probe(struct i2c_client *client, /* Register the regulators */ rdev = regulator_register(&tps->desc, &config); if (IS_ERR(rdev)) { - dev_err(tps->dev, "%s() Err: Failed to register %s\n", - __func__, id->name); + dev_err(tps->dev, + "%s(): regulator register failed with err %s\n", + __func__, id->name); ret = PTR_ERR(rdev); goto err_init; } @@ -477,8 +465,9 @@ static void tps62360_shutdown(struct i2c_client *client) /* Configure the output discharge path */ st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); if (st < 0) - dev_err(tps->dev, "%s() fails in updating reg %d\n", - __func__, REG_RAMPCTRL); + dev_err(tps->dev, + "%s(): register %d update failed with err %d\n", + __func__, REG_RAMPCTRL, st); } static const struct i2c_device_id tps62360_id[] = { -- cgit v0.10.2 From 5d0526eade515d29769c46bc522055fa17cc536e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 8 May 2012 17:45:31 +0100 Subject: regulator: wm8994: Use main I2C device as struct device This makes logging a bit clearer as it gives the actual bus location and makes things like board hookup a bit smoother. Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 1f7f43c..f2912f1 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -233,7 +233,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) } else ldo->is_enabled = true; - config.dev = &pdev->dev; + config.dev = wm8994->dev; config.init_data = pdata->ldo[id].init_data; config.driver_data = ldo; -- cgit v0.10.2 From 1f904fd1cdbda0930f667ad6a1b304d3e8f8334f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 9 May 2012 09:22:47 +0800 Subject: regulator: tps65910: Convert to get_voltage_sel Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 3d9c54f..79bb0f3 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -620,10 +620,10 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) return -EINVAL; } -static int tps65910_get_voltage(struct regulator_dev *dev) +static int tps65910_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int reg, value, id = rdev_get_id(dev), voltage = 0; + int reg, value, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) @@ -650,9 +650,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) return -EINVAL; } - voltage = pmic->info[id]->voltage_table[value] * 1000; - - return voltage; + return value; } static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) @@ -660,10 +658,10 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) return 5 * 1000 * 1000; } -static int tps65911_get_voltage(struct regulator_dev *dev) +static int tps65911_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int step_mv, id = rdev_get_id(dev); + int id = rdev_get_id(dev); u8 value, reg; reg = pmic->get_ctrl_reg(id); @@ -676,13 +674,6 @@ static int tps65911_get_voltage(struct regulator_dev *dev) case TPS65911_REG_LDO4: value &= LDO1_SEL_MASK; value >>= LDO_SEL_SHIFT; - /* The first 5 values of the selector correspond to 1V */ - if (value < 5) - value = 0; - else - value -= 4; - - step_mv = 50; break; case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: @@ -691,23 +682,16 @@ static int tps65911_get_voltage(struct regulator_dev *dev) case TPS65911_REG_LDO8: value &= LDO3_SEL_MASK; value >>= LDO_SEL_SHIFT; - /* The first 3 values of the selector correspond to 1V */ - if (value < 3) - value = 0; - else - value -= 2; - - step_mv = 100; break; case TPS65910_REG_VIO: value &= LDO_SEL_MASK; value >>= LDO_SEL_SHIFT; - return pmic->info[id]->voltage_table[value] * 1000; + break; default: return -EINVAL; } - return (LDO_MIN_VOLT + value * step_mv) * 1000; + return value; } static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, @@ -943,7 +927,7 @@ static struct regulator_ops tps65910_ops = { .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, - .get_voltage = tps65910_get_voltage, + .get_voltage_sel = tps65910_get_voltage_sel, .set_voltage_sel = tps65910_set_voltage_sel, .list_voltage = tps65910_list_voltage, }; @@ -955,7 +939,7 @@ static struct regulator_ops tps65911_ops = { .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, - .get_voltage = tps65911_get_voltage, + .get_voltage_sel = tps65911_get_voltage_sel, .set_voltage_sel = tps65911_set_voltage_sel, .list_voltage = tps65911_list_voltage, }; -- cgit v0.10.2 From c30540d78e60068d5638b79f1bcc92b259c3c7e2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 9 May 2012 05:43:59 +1000 Subject: mfd: twl: define all feature flags in one place. twl-regulator has a collection of feature flags, some defined in twl-core.c and one defined in i2c/twl.h. This is confusing for anyone adding a new feature flag. So collect them together and place them in twl.h immediately after the structure in which they are initially set. Signed-off-by: NeilBrown Signed-off-by: Mark Brown diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 7c2267e..6fc90be 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -224,13 +224,6 @@ #define HIGH_PERF_SQ (1 << 3) #define CK32K_LOWPWR_EN (1 << 7) - -/* chip-specific feature flags, for i2c_device_id.driver_data */ -#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */ -#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ -#define TWL5031 BIT(2) /* twl5031 has different registers */ -#define TWL6030_CLASS BIT(3) /* TWL6030 class */ - /*----------------------------------------------------------------------*/ /* is driver active, bound to a chip? */ diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 2463b61..18fc937 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -171,8 +171,6 @@ static inline int twl_class_is_ ##class(void) \ TWL_CLASS_IS(4030, TWL4030_CLASS_ID) TWL_CLASS_IS(6030, TWL6030_CLASS_ID) -#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ - /* * Read and write single 8-bit registers */ @@ -758,6 +756,12 @@ struct twl_regulator_driver_data { void *data; unsigned long features; }; +/* chip-specific feature flags, for twl_regulator_driver_data.features */ +#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */ +#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ +#define TWL5031 BIT(2) /* twl5031 has different registers */ +#define TWL6030_CLASS BIT(3) /* TWL6030 class */ +#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ /*----------------------------------------------------------------------*/ -- cgit v0.10.2 From 411a2df5090ccb88f4c3726e4951ebed579fec11 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 9 May 2012 05:44:00 +1000 Subject: regulator: twl-regulator: make TWL4030_ALLOW_UNSUPPORTED more configurable. The regulators in the twl4030 can provide some voltage settings that are not offically supported. These settings are disabled by default, but can be enabled with CONFIG_TWL4030_ALLOW_UNSUPPORTED=y However - that config variable is not mentioned in any Kconfig so cannot be used, and - a global setting is clumsy - a per regulator setting would be better. So define a new 'feature' flag that a board file can set to enable these unsupported volatages for boards which need them. This flag cannot (yet) be set using device-tree. Signed-off-by: NeilBrown Signed-off-by: Mark Brown diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index fffacb4..c739071 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -395,14 +395,12 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. */ -#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED -#define UNSUP_MASK 0x0000 -#else #define UNSUP_MASK 0x8000 -#endif #define UNSUP(x) (UNSUP_MASK | (x)) -#define IS_UNSUP(x) (UNSUP_MASK & (x)) +#define IS_UNSUP(info, x) \ + ((UNSUP_MASK & (x)) && \ + !((info)->features & TWL4030_ALLOW_UNSUPPORTED)) #define LDO_MV(x) (~UNSUP_MASK & (x)) @@ -476,7 +474,7 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; - return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000); + return IS_UNSUP(info, mV) ? 0 : (LDO_MV(mV) * 1000); } static int diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 18fc937..c1be3db 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -762,6 +762,11 @@ struct twl_regulator_driver_data { #define TWL5031 BIT(2) /* twl5031 has different registers */ #define TWL6030_CLASS BIT(3) /* TWL6030 class */ #define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ +#define TWL4030_ALLOW_UNSUPPORTED BIT(5) /* Some voltages are possible + * but not officially supported. + * This flag is necessary to + * enable them. + */ /*----------------------------------------------------------------------*/ -- cgit v0.10.2