From: francescolavra.fl@gmail.com (Francesco Lavra)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] mfd: ab8500: add devicetree support for fuelgauge
Date: Sat, 20 Oct 2012 17:52:40 +0200 [thread overview]
Message-ID: <5082C8C8.80902@gmail.com> (raw)
In-Reply-To: <1350358619-1160-1-git-send-email-rajanikanth.hv@stericsson.com>
Hi Rajanikanth,
On 10/16/2012 05:36 AM, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>
> - This patch adds device tree support for fuelgauge driver
> - optimize bm devices platform_data usage and of_probe(...)
> Note: of_probe() routine for battery managed devices is made
> common across all bm drivers.
> - test status:
> - interrupt numbers assigned differs between legacy and FDT mode.
>
> Legacy platform_data Mode:
> root at ME:/ cat /proc/interrupts
> CPU0 CPU1
> 483: 0 0 ab8500 ab8500-ponkey-dbf
> 484: 0 0 ab8500 ab8500-ponkey-dbr
> 485: 0 0 ab8500 BATT_OVV
> 494: 0 1 ab8500
> 495: 0 0 ab8500 ab8500-rtc
> 501: 0 13 ab8500 NCONV_ACCU
> 503: 7 22 ab8500 CCEOC
> 504: 0 1 ab8500 CC_INT_CALIB
> 505: 0 0 ab8500 LOW_BAT_F
> 516: 0 34 ab8500 ab8500-gpadc
> 556: 0 0 ab8500 usb-link-status
>
> FDT Mode:
> root at ME:/ cat /proc/interrupts
> CPU0 CPU1
> 6: 0 0 ab8500 ab8500-ponkey-dbf
> 7: 0 0 ab8500 ab8500-ponkey-dbr
> 8: 0 0 ab8500 BATT_OVV
> 162: 0 7 ab8500 ab8500-gpadc
> 163: 0 1 ab8500
> 164: 0 0 ab8500 ab8500-rtc
> 484: 0 0 ab8500 usb-link-status
> 499: 0 4 ab8500 NCONV_ACCU
> 500: 0 0 ab8500 LOW_BAT_F
> 502: 0 1 ab8500 CC_INT_CALIB
> 503: 0 6 ab8500 CCEOC
>
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
[...]
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> + struct device_node *np,
> + struct abx500_bm_data **battery)
> +{
> + struct abx500_battery_type *btype;
> + struct device_node *np_bat_supply;
> + struct abx500_bm_data *bat;
> + int i, thermistor;
> + char *bat_tech = "UNKNOWN";
This initialization is useless.
> +
> + *battery = devm_kzalloc(dev, sizeof(*bat), GFP_KERNEL);
> + if (!*battery) {
> + dev_err(dev, "%s no mem for plat_data\n", __func__);
> + return -ENOMEM;
> + }
> + *battery = &ab8500_bm_data;
Looks like dynamic allocation here is not what you need, since you are
overwriting the pointer to the allocated data.
> +
> + /* get phandle to 'battery-info' node */
> + np_bat_supply = of_parse_phandle(np, "battery", 0);
> + if (!np_bat_supply) {
> + dev_err(dev, "missing property battery\n");
> + return -EINVAL;
> + }
> + if (of_property_read_bool(np_bat_supply,
> + "thermistor-on-batctrl"))
> + thermistor = NTC_INTERNAL;
> + else
> + thermistor = NTC_EXTERNAL;
> +
> + bat = *battery;
> + if (thermistor == NTC_EXTERNAL) {
> + bat->n_btypes = 4;
> + bat->bat_type = bat_type_ext_thermistor;
> + bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
> + }
> + bat_tech = (char *)of_get_property(
> + np_bat_supply, "stericsson,battery-type", NULL);
No need to cast a void * to a char *.
> + if (!bat_tech) {
> + dev_warn(dev, "missing property battery-name/type\n");
> + strncpy(bat_tech, "UNKNOWN", 7);
You are writing at a NULL pointer here...
> + }
> + of_node_put(np_bat_supply);
You can't call of_node_put here, because you are going to use bat_tech
later on. You have to call it at the end of this function, after you are
done with bat_tech.
> +
> + if (strncmp(bat_tech, "LION", 4) == 0) {
> + bat->no_maintenance = true;
> + bat->chg_unknown_bat = true;
> + bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
> + bat->bat_type[BATTERY_UNKNOWN].termination_vol = 4150;
> + bat->bat_type[BATTERY_UNKNOWN].recharge_vol = 4130;
> + bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520;
> + bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200;
> + }
> + /* select the battery resolution table */
> + for (i = 0; i < bat->n_btypes; ++i) {
> + btype = (bat->bat_type + i);
> + if (thermistor == NTC_EXTERNAL) {
> + btype->batres_tbl =
> + temp_to_batres_tbl_ext_thermistor;
> + } else if (strncmp(bat_tech, "LION", 4) == 0) {
> + btype->batres_tbl =
> + temp_to_batres_tbl_9100;
> + } else {
> + btype->batres_tbl =
> + temp_to_batres_tbl_thermistor;
> + }
> + }
> + return 0;
> +}
[...]
> diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
> index bf02225..ff64dd4 100644
> --- a/drivers/power/ab8500_fg.c
> +++ b/drivers/power/ab8500_fg.c
> @@ -22,15 +22,16 @@
> #include <linux/platform_device.h>
> #include <linux/power_supply.h>
> #include <linux/kobject.h>
> -#include <linux/mfd/abx500/ab8500.h>
> -#include <linux/mfd/abx500.h>
> #include <linux/slab.h>
> -#include <linux/mfd/abx500/ab8500-bm.h>
> #include <linux/delay.h>
> -#include <linux/mfd/abx500/ab8500-gpadc.h>
> -#include <linux/mfd/abx500.h>
> #include <linux/time.h>
> +#include <linux/of.h>
> #include <linux/completion.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/abx500.h>
> +#include <linux/mfd/abx500/ab8500.h>
> +#include <linux/mfd/abx500/ab8500-bm.h>
> +#include <linux/mfd/abx500/ab8500-gpadc.h>
>
> #define MILLI_TO_MICRO 1000
> #define FG_LSB_IN_MA 1627
> @@ -212,7 +213,6 @@ struct ab8500_fg {
> struct ab8500_fg_avg_cap avg_cap;
> struct ab8500 *parent;
> struct ab8500_gpadc *gpadc;
> - struct abx500_fg_platform_data *pdata;
> struct abx500_bm_data *bat;
> struct power_supply fg_psy;
> struct workqueue_struct *fg_wq;
> @@ -2416,6 +2416,8 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
> int ret = 0;
> struct ab8500_fg *di = platform_get_drvdata(pdev);
>
> + of_node_put(pdev->dev.of_node);
This is wrong, the probe function doesn't increment the refcount of this
node, so you don't have to decrement it here.
> +
> list_del(&di->node);
>
> /* Disable coulomb counter */
> @@ -2429,7 +2431,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
> flush_scheduled_work();
> power_supply_unregister(&di->fg_psy);
> platform_set_drvdata(pdev, NULL);
> - kfree(di);
> return ret;
> }
>
> @@ -2442,21 +2443,44 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
> {"CCEOC", ab8500_fg_cc_data_end_handler},
> };
>
> +char *supply_interface[] = {
> + "ab8500_chargalg",
> + "ab8500_usb",
> +};
> +
> static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> {
> + struct device_node *np = pdev->dev.of_node;
> + struct ab8500_fg *di;
> int i, irq;
> int ret = 0;
> - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
> - struct ab8500_fg *di;
>
> - if (!plat_data) {
> - dev_err(&pdev->dev, "No platform data\n");
> - return -EINVAL;
> + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
> + if (!di) {
> + dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
> + if (np) {
> + ret = -ENOMEM;
> + goto release_node;
Here and below, release_node is wrong for the same reason as I wrote for
the remove function, you don't have to call of_node_put().
> + }
> + }
> + di->bat = (struct abx500_bm_data *)
> + pdev->mfd_cell->platform_data;
No need to cast a void *.
> + if (!di->bat) {
> + if (np) {
> + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
> + if (ret) {
> + dev_err(&pdev->dev,
> + "failed to get battery information\n");
> + goto release_node;
> + }
> + } else {
> + dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
> + ret = -EINVAL;
> + goto release_node;
> + }
> + } else {
> + dev_info(&pdev->dev, "falling back to legacy platform data\n");
> }
> -
> - di = kzalloc(sizeof(*di), GFP_KERNEL);
> - if (!di)
> - return -ENOMEM;
>
> mutex_init(&di->cc_lock);
>
> @@ -2465,29 +2489,13 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> di->parent = dev_get_drvdata(pdev->dev.parent);
> di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>
> - /* get fg specific platform data */
> - di->pdata = plat_data->fg;
> - if (!di->pdata) {
> - dev_err(di->dev, "no fg platform data supplied\n");
> - ret = -EINVAL;
> - goto free_device_info;
> - }
> -
> - /* get battery specific platform data */
> - di->bat = plat_data->battery;
> - if (!di->bat) {
> - dev_err(di->dev, "no battery platform data supplied\n");
> - ret = -EINVAL;
> - goto free_device_info;
> - }
> -
> di->fg_psy.name = "ab8500_fg";
> di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
> di->fg_psy.properties = ab8500_fg_props;
> di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
> di->fg_psy.get_property = ab8500_fg_get_property;
> - di->fg_psy.supplied_to = di->pdata->supplied_to;
> - di->fg_psy.num_supplicants = di->pdata->num_supplicants;
> + di->fg_psy.supplied_to = supply_interface;
> + di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
> di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
>
> di->bat_cap.max_mah_design = MILLI_TO_MICRO *
> @@ -2506,7 +2514,8 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
> if (di->fg_wq == NULL) {
> dev_err(di->dev, "failed to create work queue\n");
> - goto free_device_info;
> + ret = -ENOMEM;
> + goto release_node;
> }
>
> /* Init work for running the fg algorithm instantly */
> @@ -2605,12 +2614,17 @@ free_irq:
> }
> free_inst_curr_wq:
> destroy_workqueue(di->fg_wq);
> -free_device_info:
> - kfree(di);
>
> +release_node:
> + of_node_put(np);
> return ret;
> }
--
Francesco
WARNING: multiple messages have this Message-ID (diff)
From: Francesco Lavra <francescolavra.fl@gmail.com>
To: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
Cc: lee.jones@linaro.org, arnd@arndb.de, anton.vorontsov@linaro.org,
linus.walleij@stericsson.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linaro-dev@lists.linaro.org,
patches@linaro.org, STEricsson_nomadik_linux@list.st.com
Subject: Re: [PATCH] mfd: ab8500: add devicetree support for fuelgauge
Date: Sat, 20 Oct 2012 17:52:40 +0200 [thread overview]
Message-ID: <5082C8C8.80902@gmail.com> (raw)
In-Reply-To: <1350358619-1160-1-git-send-email-rajanikanth.hv@stericsson.com>
Hi Rajanikanth,
On 10/16/2012 05:36 AM, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>
> - This patch adds device tree support for fuelgauge driver
> - optimize bm devices platform_data usage and of_probe(...)
> Note: of_probe() routine for battery managed devices is made
> common across all bm drivers.
> - test status:
> - interrupt numbers assigned differs between legacy and FDT mode.
>
> Legacy platform_data Mode:
> root@ME:/ cat /proc/interrupts
> CPU0 CPU1
> 483: 0 0 ab8500 ab8500-ponkey-dbf
> 484: 0 0 ab8500 ab8500-ponkey-dbr
> 485: 0 0 ab8500 BATT_OVV
> 494: 0 1 ab8500
> 495: 0 0 ab8500 ab8500-rtc
> 501: 0 13 ab8500 NCONV_ACCU
> 503: 7 22 ab8500 CCEOC
> 504: 0 1 ab8500 CC_INT_CALIB
> 505: 0 0 ab8500 LOW_BAT_F
> 516: 0 34 ab8500 ab8500-gpadc
> 556: 0 0 ab8500 usb-link-status
>
> FDT Mode:
> root@ME:/ cat /proc/interrupts
> CPU0 CPU1
> 6: 0 0 ab8500 ab8500-ponkey-dbf
> 7: 0 0 ab8500 ab8500-ponkey-dbr
> 8: 0 0 ab8500 BATT_OVV
> 162: 0 7 ab8500 ab8500-gpadc
> 163: 0 1 ab8500
> 164: 0 0 ab8500 ab8500-rtc
> 484: 0 0 ab8500 usb-link-status
> 499: 0 4 ab8500 NCONV_ACCU
> 500: 0 0 ab8500 LOW_BAT_F
> 502: 0 1 ab8500 CC_INT_CALIB
> 503: 0 6 ab8500 CCEOC
>
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
[...]
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> + struct device_node *np,
> + struct abx500_bm_data **battery)
> +{
> + struct abx500_battery_type *btype;
> + struct device_node *np_bat_supply;
> + struct abx500_bm_data *bat;
> + int i, thermistor;
> + char *bat_tech = "UNKNOWN";
This initialization is useless.
> +
> + *battery = devm_kzalloc(dev, sizeof(*bat), GFP_KERNEL);
> + if (!*battery) {
> + dev_err(dev, "%s no mem for plat_data\n", __func__);
> + return -ENOMEM;
> + }
> + *battery = &ab8500_bm_data;
Looks like dynamic allocation here is not what you need, since you are
overwriting the pointer to the allocated data.
> +
> + /* get phandle to 'battery-info' node */
> + np_bat_supply = of_parse_phandle(np, "battery", 0);
> + if (!np_bat_supply) {
> + dev_err(dev, "missing property battery\n");
> + return -EINVAL;
> + }
> + if (of_property_read_bool(np_bat_supply,
> + "thermistor-on-batctrl"))
> + thermistor = NTC_INTERNAL;
> + else
> + thermistor = NTC_EXTERNAL;
> +
> + bat = *battery;
> + if (thermistor == NTC_EXTERNAL) {
> + bat->n_btypes = 4;
> + bat->bat_type = bat_type_ext_thermistor;
> + bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
> + }
> + bat_tech = (char *)of_get_property(
> + np_bat_supply, "stericsson,battery-type", NULL);
No need to cast a void * to a char *.
> + if (!bat_tech) {
> + dev_warn(dev, "missing property battery-name/type\n");
> + strncpy(bat_tech, "UNKNOWN", 7);
You are writing at a NULL pointer here...
> + }
> + of_node_put(np_bat_supply);
You can't call of_node_put here, because you are going to use bat_tech
later on. You have to call it at the end of this function, after you are
done with bat_tech.
> +
> + if (strncmp(bat_tech, "LION", 4) == 0) {
> + bat->no_maintenance = true;
> + bat->chg_unknown_bat = true;
> + bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
> + bat->bat_type[BATTERY_UNKNOWN].termination_vol = 4150;
> + bat->bat_type[BATTERY_UNKNOWN].recharge_vol = 4130;
> + bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520;
> + bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200;
> + }
> + /* select the battery resolution table */
> + for (i = 0; i < bat->n_btypes; ++i) {
> + btype = (bat->bat_type + i);
> + if (thermistor == NTC_EXTERNAL) {
> + btype->batres_tbl =
> + temp_to_batres_tbl_ext_thermistor;
> + } else if (strncmp(bat_tech, "LION", 4) == 0) {
> + btype->batres_tbl =
> + temp_to_batres_tbl_9100;
> + } else {
> + btype->batres_tbl =
> + temp_to_batres_tbl_thermistor;
> + }
> + }
> + return 0;
> +}
[...]
> diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
> index bf02225..ff64dd4 100644
> --- a/drivers/power/ab8500_fg.c
> +++ b/drivers/power/ab8500_fg.c
> @@ -22,15 +22,16 @@
> #include <linux/platform_device.h>
> #include <linux/power_supply.h>
> #include <linux/kobject.h>
> -#include <linux/mfd/abx500/ab8500.h>
> -#include <linux/mfd/abx500.h>
> #include <linux/slab.h>
> -#include <linux/mfd/abx500/ab8500-bm.h>
> #include <linux/delay.h>
> -#include <linux/mfd/abx500/ab8500-gpadc.h>
> -#include <linux/mfd/abx500.h>
> #include <linux/time.h>
> +#include <linux/of.h>
> #include <linux/completion.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/abx500.h>
> +#include <linux/mfd/abx500/ab8500.h>
> +#include <linux/mfd/abx500/ab8500-bm.h>
> +#include <linux/mfd/abx500/ab8500-gpadc.h>
>
> #define MILLI_TO_MICRO 1000
> #define FG_LSB_IN_MA 1627
> @@ -212,7 +213,6 @@ struct ab8500_fg {
> struct ab8500_fg_avg_cap avg_cap;
> struct ab8500 *parent;
> struct ab8500_gpadc *gpadc;
> - struct abx500_fg_platform_data *pdata;
> struct abx500_bm_data *bat;
> struct power_supply fg_psy;
> struct workqueue_struct *fg_wq;
> @@ -2416,6 +2416,8 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
> int ret = 0;
> struct ab8500_fg *di = platform_get_drvdata(pdev);
>
> + of_node_put(pdev->dev.of_node);
This is wrong, the probe function doesn't increment the refcount of this
node, so you don't have to decrement it here.
> +
> list_del(&di->node);
>
> /* Disable coulomb counter */
> @@ -2429,7 +2431,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
> flush_scheduled_work();
> power_supply_unregister(&di->fg_psy);
> platform_set_drvdata(pdev, NULL);
> - kfree(di);
> return ret;
> }
>
> @@ -2442,21 +2443,44 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
> {"CCEOC", ab8500_fg_cc_data_end_handler},
> };
>
> +char *supply_interface[] = {
> + "ab8500_chargalg",
> + "ab8500_usb",
> +};
> +
> static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> {
> + struct device_node *np = pdev->dev.of_node;
> + struct ab8500_fg *di;
> int i, irq;
> int ret = 0;
> - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
> - struct ab8500_fg *di;
>
> - if (!plat_data) {
> - dev_err(&pdev->dev, "No platform data\n");
> - return -EINVAL;
> + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
> + if (!di) {
> + dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
> + if (np) {
> + ret = -ENOMEM;
> + goto release_node;
Here and below, release_node is wrong for the same reason as I wrote for
the remove function, you don't have to call of_node_put().
> + }
> + }
> + di->bat = (struct abx500_bm_data *)
> + pdev->mfd_cell->platform_data;
No need to cast a void *.
> + if (!di->bat) {
> + if (np) {
> + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
> + if (ret) {
> + dev_err(&pdev->dev,
> + "failed to get battery information\n");
> + goto release_node;
> + }
> + } else {
> + dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
> + ret = -EINVAL;
> + goto release_node;
> + }
> + } else {
> + dev_info(&pdev->dev, "falling back to legacy platform data\n");
> }
> -
> - di = kzalloc(sizeof(*di), GFP_KERNEL);
> - if (!di)
> - return -ENOMEM;
>
> mutex_init(&di->cc_lock);
>
> @@ -2465,29 +2489,13 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> di->parent = dev_get_drvdata(pdev->dev.parent);
> di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>
> - /* get fg specific platform data */
> - di->pdata = plat_data->fg;
> - if (!di->pdata) {
> - dev_err(di->dev, "no fg platform data supplied\n");
> - ret = -EINVAL;
> - goto free_device_info;
> - }
> -
> - /* get battery specific platform data */
> - di->bat = plat_data->battery;
> - if (!di->bat) {
> - dev_err(di->dev, "no battery platform data supplied\n");
> - ret = -EINVAL;
> - goto free_device_info;
> - }
> -
> di->fg_psy.name = "ab8500_fg";
> di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
> di->fg_psy.properties = ab8500_fg_props;
> di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
> di->fg_psy.get_property = ab8500_fg_get_property;
> - di->fg_psy.supplied_to = di->pdata->supplied_to;
> - di->fg_psy.num_supplicants = di->pdata->num_supplicants;
> + di->fg_psy.supplied_to = supply_interface;
> + di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
> di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
>
> di->bat_cap.max_mah_design = MILLI_TO_MICRO *
> @@ -2506,7 +2514,8 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
> di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
> if (di->fg_wq == NULL) {
> dev_err(di->dev, "failed to create work queue\n");
> - goto free_device_info;
> + ret = -ENOMEM;
> + goto release_node;
> }
>
> /* Init work for running the fg algorithm instantly */
> @@ -2605,12 +2614,17 @@ free_irq:
> }
> free_inst_curr_wq:
> destroy_workqueue(di->fg_wq);
> -free_device_info:
> - kfree(di);
>
> +release_node:
> + of_node_put(np);
> return ret;
> }
--
Francesco
next prev parent reply other threads:[~2012-10-20 15:52 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-16 3:36 [PATCH] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
2012-10-20 15:52 ` Francesco Lavra [this message]
2012-10-20 15:52 ` Francesco Lavra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5082C8C8.80902@gmail.com \
--to=francescolavra.fl@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.