* [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver @ 2013-03-11 2:09 Naveen Krishna Chatradhi [not found] ` <1362967787-22557-1-git-send-email-ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> 2013-03-11 12:21 ` [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver Guenter Roeck 0 siblings, 2 replies; 6+ messages in thread From: Naveen Krishna Chatradhi @ 2013-03-11 2:09 UTC (permalink / raw) To: linux-kernel, lm-sensors Cc: devicetree-discuss, khali, linux, dianders, naveenkrishna.ch, dg77.kim This patch adds the DT support to NTC driver to parse the platform data. Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> --- drivers/hwmon/ntc_thermistor.c | 93 ++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index d92b237..cfedbd3 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -26,6 +26,7 @@ #include <linux/math64.h> #include <linux/platform_device.h> #include <linux/err.h> +#include <linux/of.h> #include <linux/platform_data/ntc_thermistor.h> @@ -37,6 +38,41 @@ struct ntc_compensation { unsigned int ohm; }; +static const struct platform_device_id ntc_thermistor_id[] = { + { "ncp15wb473", TYPE_NCPXXWB473 }, + { "ncp18wb473", TYPE_NCPXXWB473 }, + { "ncp21wb473", TYPE_NCPXXWB473 }, + { "ncp03wb473", TYPE_NCPXXWB473 }, + { "ncp15wl333", TYPE_NCPXXWL333 }, + { }, +}; + +#ifdef CONFIG_OF +static const struct of_device_id ntc_match[] = { + { .compatible = "ntc,ncp15wb473", .data = (void *)TYPE_NCPXXWB473 }, + { .compatible = "ntc,ncp18wb473", .data = (void *)TYPE_NCPXXWB473 }, + { .compatible = "ntc,ncp21wb473", .data = (void *)TYPE_NCPXXWB473 }, + { .compatible = "ntc,ncp03wb473", .data = (void *)TYPE_NCPXXWB473 }, + { .compatible = "ntc,ncp15wl333", .data = (void *)TYPE_NCPXXWL333 }, + { }, +}; +MODULE_DEVICE_TABLE(of, ntc_match); +#endif + +/* Get NTC type either from device tree or platform data. */ +static enum ntc_thermistor_type thermistor_get_type + (struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(of_match_ptr(ntc_match), + pdev->dev.of_node); + return (unsigned int)match->data; + } + + return platform_get_device_id(pdev)->driver_data; +} + /* * A compensation table should be sorted by the values of .ohm * in descending order. @@ -126,6 +162,27 @@ struct ntc_data { char name[PLATFORM_NAME_SIZE]; }; +#ifdef CONFIG_OF +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, + struct device_node *np) +{ + of_property_read_u32(np, "pullup-uV", &pdata->pullup_uV); + of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm); + of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm); + if (of_find_property(np, "connected-positive", NULL)) + pdata->connect = NTC_CONNECTED_POSITIVE; + else /* status change should be possible if not always on. */ + pdata->connect = NTC_CONNECTED_GROUND; +} +#else +static void +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, + struct device_node *np) +{ + return; +} +#endif + static inline u64 div64_u64_safe(u64 dividend, u64 divisor) { if (divisor == 0 && dividend == 0) @@ -313,9 +370,19 @@ static const struct attribute_group ntc_attr_group = { static int ntc_thermistor_probe(struct platform_device *pdev) { struct ntc_data *data; - struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; + struct ntc_thermistor_platform_data *pdata = NULL; int ret = 0; + if (np) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ntc_thermistor_parse_dt(pdata, np); + } else + pdata = pdev->dev.platform_data; + if (!pdata) { dev_err(&pdev->dev, "No platform init data supplied.\n"); return -ENODEV; @@ -353,9 +420,9 @@ static int ntc_thermistor_probe(struct platform_device *pdev) data->dev = &pdev->dev; data->pdev = pdev; data->pdata = pdata; - strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); + strncpy(data->name, dev_name(&pdev->dev), PLATFORM_NAME_SIZE); - switch (pdev->id_entry->driver_data) { + switch (thermistor_get_type(pdev)) { case TYPE_NCPXXWB473: data->comp = ncpXXwb473; data->n_comp = ARRAY_SIZE(ncpXXwb473); @@ -365,9 +432,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) data->n_comp = ARRAY_SIZE(ncpXXwl333); break; default: - dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", - pdev->id_entry->driver_data, - pdev->id_entry->name); + dev_err(&pdev->dev, "Unknown device type: %u\n", + thermistor_get_type(pdev)); return -EINVAL; } @@ -386,9 +452,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) goto err_after_sysfs; } - dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", - pdev->name, pdev->id, pdev->id_entry->name, - pdev->id_entry->driver_data); + dev_info(&pdev->dev, "Thermistor successfully probed.\n"); + return 0; err_after_sysfs: sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); @@ -406,19 +471,11 @@ static int ntc_thermistor_remove(struct platform_device *pdev) return 0; } -static const struct platform_device_id ntc_thermistor_id[] = { - { "ncp15wb473", TYPE_NCPXXWB473 }, - { "ncp18wb473", TYPE_NCPXXWB473 }, - { "ncp21wb473", TYPE_NCPXXWB473 }, - { "ncp03wb473", TYPE_NCPXXWB473 }, - { "ncp15wl333", TYPE_NCPXXWL333 }, - { }, -}; - static struct platform_driver ntc_thermistor_driver = { .driver = { .name = "ntc-thermistor", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ntc_match), }, .probe = ntc_thermistor_probe, .remove = ntc_thermistor_remove, -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
[parent not found: <1362967787-22557-1-git-send-email-ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>]
* [PATCH 2/2] hwmon: NTC: add IIO get channel and read support [not found] ` <1362967787-22557-1-git-send-email-ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> @ 2013-03-11 2:09 ` Naveen Krishna Chatradhi 2013-03-11 12:46 ` Guenter Roeck 2013-03-11 21:36 ` Doug Anderson 0 siblings, 2 replies; 6+ messages in thread From: Naveen Krishna Chatradhi @ 2013-03-11 2:09 UTC (permalink / raw) To: linux-kernel-u79uwXL29TY76Z2rM5mHXA, lm-sensors-GZX6beZjE8VD60Wz+7aTrA Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, dg77.kim-Sze3O3UU22JBDgjK7y7TUQ, khali-PUYAD+kWke1g9hUCZPvPmw, naveenkrishna.ch-Re5JQEeQqe8AvxtiuMwx3w, linux-0h96xk9xTtrk1uMJSBkQmQ This patch adds the support to work as a iio device. iio_get_channel and iio_raw_read works. During the probe ntc driver gets the respective channels of ADC and uses iio_raw_read calls to get the ADC converted value. Signed-off-by: Naveen Krishna Chatradhi <ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> --- Still not sure about the read_uV function parameter change and placement. There were a few CamelCase warnings during checkpatch run. I can clean them if anyone insists. drivers/hwmon/ntc_thermistor.c | 36 +++++++++++++++++++++++++- include/linux/platform_data/ntc_thermistor.h | 7 ++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index cfedbd3..1d31260 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -30,6 +30,11 @@ #include <linux/platform_data/ntc_thermistor.h> +#include <linux/iio/iio.h> +#include <linux/iio/machine.h> +#include <linux/iio/driver.h> +#include <linux/iio/consumer.h> + #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> @@ -162,6 +167,28 @@ struct ntc_data { char name[PLATFORM_NAME_SIZE]; }; +static int ntc_adc_read(struct ntc_thermistor_platform_data *pdata) +{ + struct iio_channel *channel = pdata->chan; + unsigned int result; + int val, ret; + + if (!channel) + return -EINVAL; + + ret = iio_read_channel_raw(channel, &val); + if (ret < 0) { + pr_err("read channel() error: %d\n", ret); + return ret; + } + + /* unit: mV */ + result = pdata->pullup_uV * (s64) val; + result >>= 12; + + return result; +} + #ifdef CONFIG_OF static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, struct device_node *np) @@ -173,6 +200,8 @@ static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, pdata->connect = NTC_CONNECTED_POSITIVE; else /* status change should be possible if not always on. */ pdata->connect = NTC_CONNECTED_GROUND; + + pdata->read_uV = ntc_adc_read; } #else static void @@ -317,7 +346,7 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) return data->pdata->read_ohm(data->pdev); if (data->pdata->read_uV) { - read_uV = data->pdata->read_uV(data->pdev); + read_uV = data->pdata->read_uV(data->pdata); if (read_uV < 0) return read_uV; return get_ohm_of_thermistor(data, read_uV); @@ -417,6 +446,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + pdata->chan = iio_channel_get(&pdev->dev, NULL); + data->dev = &pdev->dev; data->pdev = pdev; data->pdata = pdata; @@ -457,15 +488,18 @@ static int ntc_thermistor_probe(struct platform_device *pdev) return 0; err_after_sysfs: sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); + iio_channel_release(pdata->chan); return ret; } static int ntc_thermistor_remove(struct platform_device *pdev) { struct ntc_data *data = platform_get_drvdata(pdev); + struct ntc_thermistor_platform_data *pdata = data->pdata; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); + iio_channel_release(pdata->chan); platform_set_drvdata(pdev, NULL); return 0; diff --git a/include/linux/platform_data/ntc_thermistor.h b/include/linux/platform_data/ntc_thermistor.h index 18f3c3a..671d056 100644 --- a/include/linux/platform_data/ntc_thermistor.h +++ b/include/linux/platform_data/ntc_thermistor.h @@ -34,19 +34,24 @@ struct ntc_thermistor_platform_data { * * pullup_uV, pullup_ohm, pulldown_ohm, and connect are required to use * read_uV() + * takes the platform data structure as the parameter * * How to setup pullup_ohm, pulldown_ohm, and connect is * described at Documentation/hwmon/ntc_thermistor * * pullup/down_ohm: 0 for infinite / not-connected + * + * iio_channel to communicate with the ADC which the + * thermistor is using for conversion of the analog values. */ - int (*read_uV)(struct platform_device *); + int (*read_uV)(struct ntc_thermistor_platform_data *); int (*read_ohm)(struct platform_device *); unsigned int pullup_uV; unsigned int pullup_ohm; unsigned int pulldown_ohm; enum { NTC_CONNECTED_POSITIVE, NTC_CONNECTED_GROUND } connect; + struct iio_channel *chan; }; #endif /* _LINUX_NTC_H */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] hwmon: NTC: add IIO get channel and read support 2013-03-11 2:09 ` [PATCH 2/2] hwmon: NTC: add IIO get channel and read support Naveen Krishna Chatradhi @ 2013-03-11 12:46 ` Guenter Roeck 2013-03-11 21:36 ` Doug Anderson 1 sibling, 0 replies; 6+ messages in thread From: Guenter Roeck @ 2013-03-11 12:46 UTC (permalink / raw) To: Naveen Krishna Chatradhi Cc: linux-kernel, lm-sensors, devicetree-discuss, khali, dianders, naveenkrishna.ch, dg77.kim On Mon, Mar 11, 2013 at 07:39:47AM +0530, Naveen Krishna Chatradhi wrote: > This patch adds the support to work as a iio device. > iio_get_channel and iio_raw_read works. > > During the probe ntc driver gets the respective channels of ADC > and uses iio_raw_read calls to get the ADC converted value. > > Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> > --- > > Still not sure about the read_uV function parameter change and placement. > Me not either. Is the parameter change really necessary ? There was a good reason to pass pdev, as it lets the called function deal with the device, eg for error messages. > There were a few CamelCase warnings during checkpatch run. > I can clean them if anyone insists. > I actually have a patch sitting somewhere doing just that. Might make sense if I send it out for review and you rebase your patches on top of it. > drivers/hwmon/ntc_thermistor.c | 36 +++++++++++++++++++++++++- > include/linux/platform_data/ntc_thermistor.h | 7 ++++- > 2 files changed, 41 insertions(+), 2 deletions(-) > > diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c > index cfedbd3..1d31260 100644 > --- a/drivers/hwmon/ntc_thermistor.c > +++ b/drivers/hwmon/ntc_thermistor.c > @@ -30,6 +30,11 @@ > > #include <linux/platform_data/ntc_thermistor.h> > > +#include <linux/iio/iio.h> > +#include <linux/iio/machine.h> > +#include <linux/iio/driver.h> > +#include <linux/iio/consumer.h> > + One problem with this change is that the driver now mandates the existence of the IIO subsystem, even if not needed (ie if CONFIG_OF is not defined. We'll have to limit that impact. I would suggest to keep all the ioo code in the #ifdef CONFIG_OF block. also, you'll have to add a conditional dependency to Kconfig. > #include <linux/hwmon.h> > #include <linux/hwmon-sysfs.h> > > @@ -162,6 +167,28 @@ struct ntc_data { > char name[PLATFORM_NAME_SIZE]; > }; > > +static int ntc_adc_read(struct ntc_thermistor_platform_data *pdata) > +{ Better name it ntc_adc_iio_read. > + struct iio_channel *channel = pdata->chan; > + unsigned int result; > + int val, ret; > + > + if (!channel) > + return -EINVAL; > + You should check this earlier (see below). > + ret = iio_read_channel_raw(channel, &val); > + if (ret < 0) { > + pr_err("read channel() error: %d\n", ret); > + return ret; > + } > + > + /* unit: mV */ > + result = pdata->pullup_uV * (s64) val; > + result >>= 12; > + > + return result; > +} > + > #ifdef CONFIG_OF > static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > struct device_node *np) > @@ -173,6 +200,8 @@ static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > pdata->connect = NTC_CONNECTED_POSITIVE; > else /* status change should be possible if not always on. */ > pdata->connect = NTC_CONNECTED_GROUND; > + > + pdata->read_uV = ntc_adc_read; > } > #else > static void > @@ -317,7 +346,7 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) > return data->pdata->read_ohm(data->pdev); > > if (data->pdata->read_uV) { > - read_uV = data->pdata->read_uV(data->pdev); > + read_uV = data->pdata->read_uV(data->pdata); I am really not happy with this parameter change. you should be able to get the pointer to pdata with data = platform_get_drvdata(pdev); pdata = data->pdata; > if (read_uV < 0) > return read_uV; > return get_ohm_of_thermistor(data, read_uV); > @@ -417,6 +446,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > if (!data) > return -ENOMEM; > > + pdata->chan = iio_channel_get(&pdev->dev, NULL); > + I think this should be assigned together with read_uV in ntc_thermistor_parse_dt, and bail out if it returns an error. It does not make sense to instantiate the driver otherwise if OF is used to construct pdata. Also, iio_channel_get can return an error, so you have to check the returned value for an error return with IS_ERR. This error can be EDEFER, so make sure it is returned to the caller to cause the probe t be called again later. > data->dev = &pdev->dev; > data->pdev = pdev; > data->pdata = pdata; > @@ -457,15 +488,18 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > return 0; > err_after_sysfs: > sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); > + iio_channel_release(pdata->chan); That will crash nicely if pdata->chan is not set or has an error. > return ret; > } > > static int ntc_thermistor_remove(struct platform_device *pdev) > { > struct ntc_data *data = platform_get_drvdata(pdev); > + struct ntc_thermistor_platform_data *pdata = data->pdata; > > hwmon_device_unregister(data->hwmon_dev); > sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); > + iio_channel_release(pdata->chan); Same here - you'll have to make sure pdata->chan is valid. > platform_set_drvdata(pdev, NULL); > > return 0; > diff --git a/include/linux/platform_data/ntc_thermistor.h b/include/linux/platform_data/ntc_thermistor.h > index 18f3c3a..671d056 100644 > --- a/include/linux/platform_data/ntc_thermistor.h > +++ b/include/linux/platform_data/ntc_thermistor.h > @@ -34,19 +34,24 @@ struct ntc_thermistor_platform_data { > * > * pullup_uV, pullup_ohm, pulldown_ohm, and connect are required to use > * read_uV() > + * takes the platform data structure as the parameter Please undo this change. > * > * How to setup pullup_ohm, pulldown_ohm, and connect is > * described at Documentation/hwmon/ntc_thermistor > * > * pullup/down_ohm: 0 for infinite / not-connected > + * > + * iio_channel to communicate with the ADC which the > + * thermistor is using for conversion of the analog values. > */ > - int (*read_uV)(struct platform_device *); > + int (*read_uV)(struct ntc_thermistor_platform_data *); Please undo this change. > int (*read_ohm)(struct platform_device *); > unsigned int pullup_uV; > > unsigned int pullup_ohm; > unsigned int pulldown_ohm; > enum { NTC_CONNECTED_POSITIVE, NTC_CONNECTED_GROUND } connect; > + struct iio_channel *chan; > }; > > #endif /* _LINUX_NTC_H */ > -- > 1.7.9.5 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] hwmon: NTC: add IIO get channel and read support 2013-03-11 2:09 ` [PATCH 2/2] hwmon: NTC: add IIO get channel and read support Naveen Krishna Chatradhi 2013-03-11 12:46 ` Guenter Roeck @ 2013-03-11 21:36 ` Doug Anderson 1 sibling, 0 replies; 6+ messages in thread From: Doug Anderson @ 2013-03-11 21:36 UTC (permalink / raw) To: Naveen Krishna Chatradhi Cc: linux-kernel@vger.kernel.org, lm-sensors, devicetree-discuss, Jean Delvare, Guenter Roeck, Naveen Krishna, dg77.kim Naveen, On Sun, Mar 10, 2013 at 7:09 PM, Naveen Krishna Chatradhi <ch.naveen@samsung.com> wrote: > @@ -317,7 +346,7 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) > return data->pdata->read_ohm(data->pdev); > > if (data->pdata->read_uV) { > - read_uV = data->pdata->read_uV(data->pdev); > + read_uV = data->pdata->read_uV(data->pdata); This doesn't apply for me. Did you perhaps accidentally send up a patch against the version of the driver that's in the Chrome OS tree? You should be sending patches against some tree that's upstream (linux, linux-next, iio, ...). Thanks! -Doug ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver 2013-03-11 2:09 [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver Naveen Krishna Chatradhi [not found] ` <1362967787-22557-1-git-send-email-ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> @ 2013-03-11 12:21 ` Guenter Roeck [not found] ` <20130311122144.GA30159-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org> 1 sibling, 1 reply; 6+ messages in thread From: Guenter Roeck @ 2013-03-11 12:21 UTC (permalink / raw) To: Naveen Krishna Chatradhi Cc: linux-kernel, lm-sensors, devicetree-discuss, khali, dianders, naveenkrishna.ch, dg77.kim On Mon, Mar 11, 2013 at 07:39:46AM +0530, Naveen Krishna Chatradhi wrote: > This patch adds the DT support to NTC driver to parse the > platform data. > > Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> > --- > drivers/hwmon/ntc_thermistor.c | 93 ++++++++++++++++++++++++++++++++-------- > 1 file changed, 75 insertions(+), 18 deletions(-) > > diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c > index d92b237..cfedbd3 100644 > --- a/drivers/hwmon/ntc_thermistor.c > +++ b/drivers/hwmon/ntc_thermistor.c > @@ -26,6 +26,7 @@ > #include <linux/math64.h> > #include <linux/platform_device.h> > #include <linux/err.h> > +#include <linux/of.h> > > #include <linux/platform_data/ntc_thermistor.h> > > @@ -37,6 +38,41 @@ struct ntc_compensation { > unsigned int ohm; > }; > > +static const struct platform_device_id ntc_thermistor_id[] = { > + { "ncp15wb473", TYPE_NCPXXWB473 }, > + { "ncp18wb473", TYPE_NCPXXWB473 }, > + { "ncp21wb473", TYPE_NCPXXWB473 }, > + { "ncp03wb473", TYPE_NCPXXWB473 }, > + { "ncp15wl333", TYPE_NCPXXWL333 }, > + { }, > +}; > + > +#ifdef CONFIG_OF > +static const struct of_device_id ntc_match[] = { > + { .compatible = "ntc,ncp15wb473", .data = (void *)TYPE_NCPXXWB473 }, > + { .compatible = "ntc,ncp18wb473", .data = (void *)TYPE_NCPXXWB473 }, > + { .compatible = "ntc,ncp21wb473", .data = (void *)TYPE_NCPXXWB473 }, > + { .compatible = "ntc,ncp03wb473", .data = (void *)TYPE_NCPXXWB473 }, > + { .compatible = "ntc,ncp15wl333", .data = (void *)TYPE_NCPXXWL333 }, Better point to ntc_thermistor_id[TYPE_xxx]. See below. > + { }, > +}; > +MODULE_DEVICE_TABLE(of, ntc_match); > +#endif > + > +/* Get NTC type either from device tree or platform data. */ > +static enum ntc_thermistor_type thermistor_get_type > + (struct platform_device *pdev) > +{ > + if (pdev->dev.of_node) { > + const struct of_device_id *match; > + match = of_match_node(of_match_ptr(ntc_match), > + pdev->dev.of_node); > + return (unsigned int)match->data; > + } > + > + return platform_get_device_id(pdev)->driver_data; > +} > + > /* > * A compensation table should be sorted by the values of .ohm > * in descending order. > @@ -126,6 +162,27 @@ struct ntc_data { > char name[PLATFORM_NAME_SIZE]; > }; > > +#ifdef CONFIG_OF Please merge the two CONFIG_OF blocks into one. > +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > + struct device_node *np) > +{ > + of_property_read_u32(np, "pullup-uV", &pdata->pullup_uV); > + of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm); > + of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm); > + if (of_find_property(np, "connected-positive", NULL)) > + pdata->connect = NTC_CONNECTED_POSITIVE; > + else /* status change should be possible if not always on. */ > + pdata->connect = NTC_CONNECTED_GROUND; > +} > +#else > +static void > +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > + struct device_node *np) > +{ > + return; Unnecessary return statement. > +} > +#endif > + > static inline u64 div64_u64_safe(u64 dividend, u64 divisor) > { > if (divisor == 0 && dividend == 0) > @@ -313,9 +370,19 @@ static const struct attribute_group ntc_attr_group = { > static int ntc_thermistor_probe(struct platform_device *pdev) > { > struct ntc_data *data; > - struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data; > + struct device_node *np = pdev->dev.of_node; > + struct ntc_thermistor_platform_data *pdata = NULL; Unnecessary change. It doesn't hurt if pdata is initialized to non-NULL, and initializing it to NULL is unnecessary anyway since it is always assigned below. > int ret = 0; > > + if (np) { > + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); > + if (!pdata) > + return -ENOMEM; > + > + ntc_thermistor_parse_dt(pdata, np); This compiles, but the resulting code would not work as the necessary fields in pdata are not all filled out. So I think it would be better to merge the code with the next patch, as both don't really work independently. > + } else > + pdata = pdev->dev.platform_data; Not necessary if you keep above pre-initialization. A better idea would be to move the devm_kzalloc into ntc_thermistor_parse_dt and return a pointer to pdata from it. Then you would have pdata = ntc_thermistor_parse_dt(np); if (!pdata) pdata = pdev->dev.platform_data; The check for np == NULL could then also be in ntc_thermistor_parse_dt and only be executed if CONFIG_OF is defined. This would make the code flow look much nicer. > + > if (!pdata) { > dev_err(&pdev->dev, "No platform init data supplied.\n"); > return -ENODEV; > @@ -353,9 +420,9 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > data->dev = &pdev->dev; > data->pdev = pdev; > data->pdata = pdata; > - strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); > + strncpy(data->name, dev_name(&pdev->dev), PLATFORM_NAME_SIZE); > strlcpy is used to ensure 0 termination. sizeof(data->name) is used to ensure object size. You should introduce a variable such as pdev_id and either assign pdev->id_entry or the result of the of function call to it. Other code does that for example with const struct of_device_id *of_id = of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev); const struct platform_device_id *pdev_id; ... pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); and then just use pdev_id. Then you can use strncpy(data->name, pdev_id->name, sizeof(data->name)); That requires to change .data in the of_device_id table to point to the platform_device_id. > - switch (pdev->id_entry->driver_data) { > + switch (thermistor_get_type(pdev)) { And then: switch (pdev_id) { > case TYPE_NCPXXWB473: > data->comp = ncpXXwb473; > data->n_comp = ARRAY_SIZE(ncpXXwb473); > @@ -365,9 +432,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > data->n_comp = ARRAY_SIZE(ncpXXwl333); > break; > default: > - dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", > - pdev->id_entry->driver_data, > - pdev->id_entry->name); > + dev_err(&pdev->dev, "Unknown device type: %u\n", > + thermistor_get_type(pdev)); dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", pdev_id->driver_data, pdev_id->name); > return -EINVAL; > } > > @@ -386,9 +452,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > goto err_after_sysfs; > } > > - dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", > - pdev->name, pdev->id, pdev->id_entry->name, > - pdev->id_entry->driver_data); > + dev_info(&pdev->dev, "Thermistor successfully probed.\n"); Same here again. dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", pdev->name, pdev->id, pdev_id->name, pdev_id->driver_data); Though I would change that to dev_info(&pdev->dev, "Thermistor type %s successfully probed.\n", pdev_id->name); since the rest of the output is either redundant (name/id) or internal (pdev_id->driver_data). > + > return 0; > err_after_sysfs: > sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); > @@ -406,19 +471,11 @@ static int ntc_thermistor_remove(struct platform_device *pdev) > return 0; > } > > -static const struct platform_device_id ntc_thermistor_id[] = { > - { "ncp15wb473", TYPE_NCPXXWB473 }, > - { "ncp18wb473", TYPE_NCPXXWB473 }, > - { "ncp21wb473", TYPE_NCPXXWB473 }, > - { "ncp03wb473", TYPE_NCPXXWB473 }, > - { "ncp15wl333", TYPE_NCPXXWL333 }, > - { }, > -}; > - > static struct platform_driver ntc_thermistor_driver = { > .driver = { > .name = "ntc-thermistor", > .owner = THIS_MODULE, > + .of_match_table = of_match_ptr(ntc_match), > }, > .probe = ntc_thermistor_probe, > .remove = ntc_thermistor_remove, > -- > 1.7.9.5 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <20130311122144.GA30159-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>]
* Re: [lm-sensors] [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver [not found] ` <20130311122144.GA30159-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org> @ 2013-03-11 12:48 ` Guenter Roeck 0 siblings, 0 replies; 6+ messages in thread From: Guenter Roeck @ 2013-03-11 12:48 UTC (permalink / raw) To: Naveen Krishna Chatradhi Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA, lm-sensors-GZX6beZjE8VD60Wz+7aTrA, naveenkrishna.ch-Re5JQEeQqe8AvxtiuMwx3w, dg77.kim-Sze3O3UU22JBDgjK7y7TUQ On Mon, Mar 11, 2013 at 05:21:44AM -0700, Guenter Roeck wrote: > On Mon, Mar 11, 2013 at 07:39:46AM +0530, Naveen Krishna Chatradhi wrote: > > This patch adds the DT support to NTC driver to parse the > > platform data. > > > > Signed-off-by: Naveen Krishna Chatradhi <ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> > > --- > > drivers/hwmon/ntc_thermistor.c | 93 ++++++++++++++++++++++++++++++++-------- > > 1 file changed, 75 insertions(+), 18 deletions(-) > > > > diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c > > index d92b237..cfedbd3 100644 > > --- a/drivers/hwmon/ntc_thermistor.c > > +++ b/drivers/hwmon/ntc_thermistor.c > > @@ -26,6 +26,7 @@ > > #include <linux/math64.h> > > #include <linux/platform_device.h> > > #include <linux/err.h> > > +#include <linux/of.h> > > > > #include <linux/platform_data/ntc_thermistor.h> > > > > @@ -37,6 +38,41 @@ struct ntc_compensation { > > unsigned int ohm; > > }; > > > > +static const struct platform_device_id ntc_thermistor_id[] = { > > + { "ncp15wb473", TYPE_NCPXXWB473 }, > > + { "ncp18wb473", TYPE_NCPXXWB473 }, > > + { "ncp21wb473", TYPE_NCPXXWB473 }, > > + { "ncp03wb473", TYPE_NCPXXWB473 }, > > + { "ncp15wl333", TYPE_NCPXXWL333 }, > > + { }, > > +}; > > + > > +#ifdef CONFIG_OF > > +static const struct of_device_id ntc_match[] = { > > + { .compatible = "ntc,ncp15wb473", .data = (void *)TYPE_NCPXXWB473 }, > > + { .compatible = "ntc,ncp18wb473", .data = (void *)TYPE_NCPXXWB473 }, > > + { .compatible = "ntc,ncp21wb473", .data = (void *)TYPE_NCPXXWB473 }, > > + { .compatible = "ntc,ncp03wb473", .data = (void *)TYPE_NCPXXWB473 }, > > + { .compatible = "ntc,ncp15wl333", .data = (void *)TYPE_NCPXXWL333 }, > > Better point to ntc_thermistor_id[TYPE_xxx]. See below. > > > + { }, > > +}; > > +MODULE_DEVICE_TABLE(of, ntc_match); > > +#endif > > + > > +/* Get NTC type either from device tree or platform data. */ > > +static enum ntc_thermistor_type thermistor_get_type > > + (struct platform_device *pdev) > > +{ > > + if (pdev->dev.of_node) { > > + const struct of_device_id *match; > > + match = of_match_node(of_match_ptr(ntc_match), > > + pdev->dev.of_node); > > + return (unsigned int)match->data; > > + } > > + > > + return platform_get_device_id(pdev)->driver_data; > > +} > > + > > /* > > * A compensation table should be sorted by the values of .ohm > > * in descending order. > > @@ -126,6 +162,27 @@ struct ntc_data { > > char name[PLATFORM_NAME_SIZE]; > > }; > > > > +#ifdef CONFIG_OF > > Please merge the two CONFIG_OF blocks into one. > > > +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > > + struct device_node *np) > > +{ > > + of_property_read_u32(np, "pullup-uV", &pdata->pullup_uV); > > + of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm); > > + of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm); > > + if (of_find_property(np, "connected-positive", NULL)) > > + pdata->connect = NTC_CONNECTED_POSITIVE; > > + else /* status change should be possible if not always on. */ > > + pdata->connect = NTC_CONNECTED_GROUND; > > +} Forgot to mention: You'll have to add a devicetree bindings file describing the bindings. > > +#else > > +static void > > +static void ntc_thermistor_parse_dt(struct ntc_thermistor_platform_data *pdata, > > + struct device_node *np) > > +{ > > + return; > > Unnecessary return statement. > > > +} > > +#endif > > + > > static inline u64 div64_u64_safe(u64 dividend, u64 divisor) > > { > > if (divisor == 0 && dividend == 0) > > @@ -313,9 +370,19 @@ static const struct attribute_group ntc_attr_group = { > > static int ntc_thermistor_probe(struct platform_device *pdev) > > { > > struct ntc_data *data; > > - struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data; > > + struct device_node *np = pdev->dev.of_node; > > + struct ntc_thermistor_platform_data *pdata = NULL; > > Unnecessary change. It doesn't hurt if pdata is initialized to non-NULL, and > initializing it to NULL is unnecessary anyway since it is always assigned below. > > > int ret = 0; > > > > + if (np) { > > + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); > > + if (!pdata) > > + return -ENOMEM; > > + > > + ntc_thermistor_parse_dt(pdata, np); > > This compiles, but the resulting code would not work as the necessary fields > in pdata are not all filled out. So I think it would be better to merge the code > with the next patch, as both don't really work independently. > > > + } else > > + pdata = pdev->dev.platform_data; > > Not necessary if you keep above pre-initialization. > > A better idea would be to move the devm_kzalloc into ntc_thermistor_parse_dt > and return a pointer to pdata from it. Then you would have > > pdata = ntc_thermistor_parse_dt(np); > if (!pdata) > pdata = pdev->dev.platform_data; > > The check for np == NULL could then also be in ntc_thermistor_parse_dt and only > be executed if CONFIG_OF is defined. This would make the code flow look much nicer. > > > + > > if (!pdata) { > > dev_err(&pdev->dev, "No platform init data supplied.\n"); > > return -ENODEV; > > @@ -353,9 +420,9 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > > data->dev = &pdev->dev; > > data->pdev = pdev; > > data->pdata = pdata; > > - strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); > > + strncpy(data->name, dev_name(&pdev->dev), PLATFORM_NAME_SIZE); > > > strlcpy is used to ensure 0 termination. > sizeof(data->name) is used to ensure object size. > > You should introduce a variable such as pdev_id and either assign pdev->id_entry > or the result of the of function call to it. Other code does that for example > with > const struct of_device_id *of_id = > of_match_device(of_match_ptr(coda_dt_ids), > &pdev->dev); > const struct platform_device_id *pdev_id; > ... > pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); > > and then just use pdev_id. Then you can use > strncpy(data->name, pdev_id->name, sizeof(data->name)); > > That requires to change .data in the of_device_id table to point to the > platform_device_id. > > > - switch (pdev->id_entry->driver_data) { > > + switch (thermistor_get_type(pdev)) { > > And then: > switch (pdev_id) { > > > case TYPE_NCPXXWB473: > > data->comp = ncpXXwb473; > > data->n_comp = ARRAY_SIZE(ncpXXwb473); > > @@ -365,9 +432,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > > data->n_comp = ARRAY_SIZE(ncpXXwl333); > > break; > > default: > > - dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", > > - pdev->id_entry->driver_data, > > - pdev->id_entry->name); > > + dev_err(&pdev->dev, "Unknown device type: %u\n", > > + thermistor_get_type(pdev)); > > dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", > pdev_id->driver_data, > pdev_id->name); > > > return -EINVAL; > > } > > > > @@ -386,9 +452,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) > > goto err_after_sysfs; > > } > > > > - dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", > > - pdev->name, pdev->id, pdev->id_entry->name, > > - pdev->id_entry->driver_data); > > + dev_info(&pdev->dev, "Thermistor successfully probed.\n"); > > Same here again. > dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", > pdev->name, pdev->id, pdev_id->name, > pdev_id->driver_data); > > Though I would change that to > dev_info(&pdev->dev, "Thermistor type %s successfully probed.\n", > pdev_id->name); > > since the rest of the output is either redundant (name/id) or internal > (pdev_id->driver_data). > > > + > > return 0; > > err_after_sysfs: > > sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); > > @@ -406,19 +471,11 @@ static int ntc_thermistor_remove(struct platform_device *pdev) > > return 0; > > } > > > > -static const struct platform_device_id ntc_thermistor_id[] = { > > - { "ncp15wb473", TYPE_NCPXXWB473 }, > > - { "ncp18wb473", TYPE_NCPXXWB473 }, > > - { "ncp21wb473", TYPE_NCPXXWB473 }, > > - { "ncp03wb473", TYPE_NCPXXWB473 }, > > - { "ncp15wl333", TYPE_NCPXXWL333 }, > > - { }, > > -}; > > - > > static struct platform_driver ntc_thermistor_driver = { > > .driver = { > > .name = "ntc-thermistor", > > .owner = THIS_MODULE, > > + .of_match_table = of_match_ptr(ntc_match), > > }, > > .probe = ntc_thermistor_probe, > > .remove = ntc_thermistor_remove, > > -- > > 1.7.9.5 > > > > > > _______________________________________________ > lm-sensors mailing list > lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org > http://lists.lm-sensors.org/mailman/listinfo/lm-sensors > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-03-11 21:36 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-03-11 2:09 [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver Naveen Krishna Chatradhi [not found] ` <1362967787-22557-1-git-send-email-ch.naveen-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> 2013-03-11 2:09 ` [PATCH 2/2] hwmon: NTC: add IIO get channel and read support Naveen Krishna Chatradhi 2013-03-11 12:46 ` Guenter Roeck 2013-03-11 21:36 ` Doug Anderson 2013-03-11 12:21 ` [PATCH 1/2] hwmon: ntc: Add DT support to NTC thermistor driver Guenter Roeck [not found] ` <20130311122144.GA30159-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org> 2013-03-11 12:48 ` [lm-sensors] " Guenter Roeck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).