From: Todd Poynor <toddpoynor@google.com>
To: Keerthy <j-keerthy@ti.com>
Cc: linux-omap@vger.kernel.org, Jean Delvare <khali@linux-fr.org>,
Guenter Roeck <guenter.roeck@ericsson.com>,
lm-sensors@lm-sensors.org
Subject: Re: [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver
Date: Thu, 18 Aug 2011 22:34:38 -0700 [thread overview]
Message-ID: <20110819053438.GA2901@google.com> (raw)
In-Reply-To: <1313664735-8917-7-git-send-email-j-keerthy@ti.com>
On Thu, Aug 18, 2011 at 04:22:15PM +0530, Keerthy wrote:
...
> +static int omap_temp_sensor_clk_enable(struct omap_temp_sensor *temp_sensor)
> +{
> + u32 ret = 0;
> +
> + if (temp_sensor->clk_on) {
> + dev_err(temp_sensor->hwmon_dev, "clock already on\n");
> + goto out;
> + }
> +
> + ret = pm_runtime_get_sync(temp_sensor->hwmon_dev);
> + if (ret < 0) {
> + dev_err(temp_sensor->hwmon_dev, "get sync failed\n");
> + goto out;
> + }
> +
> + temp_sensor->clk_on = 1;
Probably should hold the mutex around this to keep clk_on consistent
with runtime PM state (and in disable method).
...
> +static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
> +{
> + struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data;
> + struct omap_temp_sensor *temp_sensor;
> + struct resource *mem;
> + int ret = 0;
> + int val, clk_rate;
> +
> + if (!pdata) {
> + dev_err(&pdev->dev, "platform data missing\n");
> + return -EINVAL;
> + }
> +
> + temp_sensor = kzalloc(sizeof(*temp_sensor), GFP_KERNEL);
> + if (!temp_sensor)
> + return -ENOMEM;
> +
> + mutex_init(&temp_sensor->sensor_mutex);
> +
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!mem) {
> + dev_err(&pdev->dev, "no mem resource\n");
> + ret = -ENOMEM;
> + goto plat_res_err;
> + }
> +
> + temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert");
> + if (temp_sensor->irq < 0) {
> + dev_err(&pdev->dev, "get_irq_byname failed\n");
> + ret = temp_sensor->irq;
> + goto plat_res_err;
> + }
> +
> + temp_sensor->phy_base = ioremap(mem->start, resource_size(mem));
> + temp_sensor->clock = NULL;
> + temp_sensor->registers = pdata->registers;
> + temp_sensor->hwmon_dev = &pdev->dev;
> +
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_irq_safe(&pdev->dev);
> +
> + /*
> + * check if the efuse has a non-zero value if not
> + * it is an untrimmed sample and the temperatures
> + * may not be accurate
> + */
> +
> + if (omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->bgap_efuse))
> + temp_sensor->is_efuse_valid = 1;
> +
> + platform_set_drvdata(pdev, temp_sensor);
> + dev_set_drvdata(&pdev->dev, temp_sensor);
> + temp_sensor->clock = clk_get(temp_sensor->hwmon_dev, "fck");
> + if (IS_ERR(temp_sensor->clock)) {
> + ret = PTR_ERR(temp_sensor->clock);
> + dev_err(temp_sensor->hwmon_dev,
> + "unable to get fclk: %d\n", ret);
> + ret = -EINVAL;
> + goto plat_res_err;
> + }
> +
> + ret = omap_temp_sensor_clk_enable(temp_sensor);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot enable temp sensor\n");
> + goto clken_err;
> + }
> +
> + clk_rate = clk_round_rate(temp_sensor->clock, 2000000);
> + if (clk_rate < 1000000 || clk_rate == 0xffffffff) {
> + dev_err(&pdev->dev, "Error round rate\n");
> + ret = -EINVAL;
> + goto clken_err;
> + }
> +
> + ret = clk_set_rate(temp_sensor->clock, clk_rate);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot set clock rate\n");
> + goto clken_err;
> + }
> +
> + temp_sensor->clk_rate = clk_rate;
> + omap_enable_continuous_mode(temp_sensor, 1);
> + omap_configure_temp_sensor_thresholds(temp_sensor);
> + /* 1 ms */
> + omap_configure_temp_sensor_counter(temp_sensor, 1);
> +
> + /* Wait till the first conversion is done wait for at least 1ms */
> + usleep_range(1000, 2000);
> +
> + /* Read the temperature once due to hw issue*/
> + omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->temp_sensor_ctrl);
> +
> + /* Set 2 seconds time as default counter */
> + omap_configure_temp_sensor_counter(temp_sensor,
> + temp_sensor->clk_rate * 2);
> +
> + temp_sensor->hwmon_dev = hwmon_device_register(&pdev->dev);
> + if (IS_ERR(temp_sensor->hwmon_dev)) {
> + dev_err(&pdev->dev, "hwmon_device_register failed.\n");
> + ret = PTR_ERR(temp_sensor->hwmon_dev);
> + goto hwmon_reg_err;
> + }
> +
> + ret = sysfs_create_group(&pdev->dev.kobj,
> + &omap_temp_sensor_group);
> + if (ret) {
> + dev_err(&pdev->dev, "could not create sysfs files\n");
> + goto sysfs_create_err;
> + }
> +
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_ADD);
> +
> + ret = request_threaded_irq(temp_sensor->irq, NULL,
> + omap_talert_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> + "temp_sensor", temp_sensor);
> + if (ret) {
> + dev_err(&pdev->dev, "Request threaded irq failed.\n");
> + goto req_irq_err;
> + }
> +
> + /* unmask the T_COLD and unmask T_HOT at init */
> + val = omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->bgap_mask_ctrl);
> + val |= temp_sensor->registers->mask_cold_mask
> + | temp_sensor->registers->mask_hot_mask;
> +
> + omap_temp_sensor_writel(temp_sensor, val,
> + temp_sensor->registers->bgap_mask_ctrl);
> +
> + return 0;
> +
> +req_irq_err:
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_REMOVE);
> + sysfs_remove_group(&temp_sensor->hwmon_dev->kobj,
> + &omap_temp_sensor_group);
> +sysfs_create_err:
> + hwmon_device_unregister(&pdev->dev);
> +hwmon_reg_err:
> + omap_temp_sensor_clk_disable(temp_sensor);
> +clken_err:
> + clk_put(temp_sensor->clock);
> +plat_res_err:
> + mutex_destroy(&temp_sensor->sensor_mutex);
> + kfree(temp_sensor);
Should also:
platform_set_drvdata(pdev, NULL);
dev_set_drvdata(&pdev->dev, NULL);
> + return ret;
> +}
> +
> +static int __devexit omap_temp_sensor_remove(struct platform_device *pdev)
> +{
> + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
> +
> + hwmon_device_unregister(&pdev->dev);
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_REMOVE);
> + sysfs_remove_group(&temp_sensor->hwmon_dev->kobj,
> + &omap_temp_sensor_group);
> + omap_temp_sensor_clk_disable(temp_sensor);
> + clk_put(temp_sensor->clock);
> + platform_set_drvdata(pdev, NULL);
And:
dev_set_drvdata(&pdev->dev, NULL);
> + free_irq(temp_sensor->irq, temp_sensor);
Need to free IRQ before clock is disabled (else ISR may access while
clock stopped, possible L3 interconnect error and ARM imprecise
external abort)?
> + mutex_destroy(&temp_sensor->sensor_mutex);
> + kfree(temp_sensor);
> +
> + return 0;
> +}
Todd
WARNING: multiple messages have this Message-ID (diff)
From: Todd Poynor <toddpoynor@google.com>
To: Keerthy <j-keerthy@ti.com>
Cc: linux-omap@vger.kernel.org, Jean Delvare <khali@linux-fr.org>,
Guenter Roeck <guenter.roeck@ericsson.com>,
lm-sensors@lm-sensors.org
Subject: Re: [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die
Date: Fri, 19 Aug 2011 05:34:38 +0000 [thread overview]
Message-ID: <20110819053438.GA2901@google.com> (raw)
In-Reply-To: <1313664735-8917-7-git-send-email-j-keerthy@ti.com>
On Thu, Aug 18, 2011 at 04:22:15PM +0530, Keerthy wrote:
...
> +static int omap_temp_sensor_clk_enable(struct omap_temp_sensor *temp_sensor)
> +{
> + u32 ret = 0;
> +
> + if (temp_sensor->clk_on) {
> + dev_err(temp_sensor->hwmon_dev, "clock already on\n");
> + goto out;
> + }
> +
> + ret = pm_runtime_get_sync(temp_sensor->hwmon_dev);
> + if (ret < 0) {
> + dev_err(temp_sensor->hwmon_dev, "get sync failed\n");
> + goto out;
> + }
> +
> + temp_sensor->clk_on = 1;
Probably should hold the mutex around this to keep clk_on consistent
with runtime PM state (and in disable method).
...
> +static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
> +{
> + struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data;
> + struct omap_temp_sensor *temp_sensor;
> + struct resource *mem;
> + int ret = 0;
> + int val, clk_rate;
> +
> + if (!pdata) {
> + dev_err(&pdev->dev, "platform data missing\n");
> + return -EINVAL;
> + }
> +
> + temp_sensor = kzalloc(sizeof(*temp_sensor), GFP_KERNEL);
> + if (!temp_sensor)
> + return -ENOMEM;
> +
> + mutex_init(&temp_sensor->sensor_mutex);
> +
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!mem) {
> + dev_err(&pdev->dev, "no mem resource\n");
> + ret = -ENOMEM;
> + goto plat_res_err;
> + }
> +
> + temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert");
> + if (temp_sensor->irq < 0) {
> + dev_err(&pdev->dev, "get_irq_byname failed\n");
> + ret = temp_sensor->irq;
> + goto plat_res_err;
> + }
> +
> + temp_sensor->phy_base = ioremap(mem->start, resource_size(mem));
> + temp_sensor->clock = NULL;
> + temp_sensor->registers = pdata->registers;
> + temp_sensor->hwmon_dev = &pdev->dev;
> +
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_irq_safe(&pdev->dev);
> +
> + /*
> + * check if the efuse has a non-zero value if not
> + * it is an untrimmed sample and the temperatures
> + * may not be accurate
> + */
> +
> + if (omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->bgap_efuse))
> + temp_sensor->is_efuse_valid = 1;
> +
> + platform_set_drvdata(pdev, temp_sensor);
> + dev_set_drvdata(&pdev->dev, temp_sensor);
> + temp_sensor->clock = clk_get(temp_sensor->hwmon_dev, "fck");
> + if (IS_ERR(temp_sensor->clock)) {
> + ret = PTR_ERR(temp_sensor->clock);
> + dev_err(temp_sensor->hwmon_dev,
> + "unable to get fclk: %d\n", ret);
> + ret = -EINVAL;
> + goto plat_res_err;
> + }
> +
> + ret = omap_temp_sensor_clk_enable(temp_sensor);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot enable temp sensor\n");
> + goto clken_err;
> + }
> +
> + clk_rate = clk_round_rate(temp_sensor->clock, 2000000);
> + if (clk_rate < 1000000 || clk_rate = 0xffffffff) {
> + dev_err(&pdev->dev, "Error round rate\n");
> + ret = -EINVAL;
> + goto clken_err;
> + }
> +
> + ret = clk_set_rate(temp_sensor->clock, clk_rate);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot set clock rate\n");
> + goto clken_err;
> + }
> +
> + temp_sensor->clk_rate = clk_rate;
> + omap_enable_continuous_mode(temp_sensor, 1);
> + omap_configure_temp_sensor_thresholds(temp_sensor);
> + /* 1 ms */
> + omap_configure_temp_sensor_counter(temp_sensor, 1);
> +
> + /* Wait till the first conversion is done wait for at least 1ms */
> + usleep_range(1000, 2000);
> +
> + /* Read the temperature once due to hw issue*/
> + omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->temp_sensor_ctrl);
> +
> + /* Set 2 seconds time as default counter */
> + omap_configure_temp_sensor_counter(temp_sensor,
> + temp_sensor->clk_rate * 2);
> +
> + temp_sensor->hwmon_dev = hwmon_device_register(&pdev->dev);
> + if (IS_ERR(temp_sensor->hwmon_dev)) {
> + dev_err(&pdev->dev, "hwmon_device_register failed.\n");
> + ret = PTR_ERR(temp_sensor->hwmon_dev);
> + goto hwmon_reg_err;
> + }
> +
> + ret = sysfs_create_group(&pdev->dev.kobj,
> + &omap_temp_sensor_group);
> + if (ret) {
> + dev_err(&pdev->dev, "could not create sysfs files\n");
> + goto sysfs_create_err;
> + }
> +
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_ADD);
> +
> + ret = request_threaded_irq(temp_sensor->irq, NULL,
> + omap_talert_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> + "temp_sensor", temp_sensor);
> + if (ret) {
> + dev_err(&pdev->dev, "Request threaded irq failed.\n");
> + goto req_irq_err;
> + }
> +
> + /* unmask the T_COLD and unmask T_HOT at init */
> + val = omap_temp_sensor_readl(temp_sensor,
> + temp_sensor->registers->bgap_mask_ctrl);
> + val |= temp_sensor->registers->mask_cold_mask
> + | temp_sensor->registers->mask_hot_mask;
> +
> + omap_temp_sensor_writel(temp_sensor, val,
> + temp_sensor->registers->bgap_mask_ctrl);
> +
> + return 0;
> +
> +req_irq_err:
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_REMOVE);
> + sysfs_remove_group(&temp_sensor->hwmon_dev->kobj,
> + &omap_temp_sensor_group);
> +sysfs_create_err:
> + hwmon_device_unregister(&pdev->dev);
> +hwmon_reg_err:
> + omap_temp_sensor_clk_disable(temp_sensor);
> +clken_err:
> + clk_put(temp_sensor->clock);
> +plat_res_err:
> + mutex_destroy(&temp_sensor->sensor_mutex);
> + kfree(temp_sensor);
Should also:
platform_set_drvdata(pdev, NULL);
dev_set_drvdata(&pdev->dev, NULL);
> + return ret;
> +}
> +
> +static int __devexit omap_temp_sensor_remove(struct platform_device *pdev)
> +{
> + struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
> +
> + hwmon_device_unregister(&pdev->dev);
> + kobject_uevent(&temp_sensor->hwmon_dev->kobj, KOBJ_REMOVE);
> + sysfs_remove_group(&temp_sensor->hwmon_dev->kobj,
> + &omap_temp_sensor_group);
> + omap_temp_sensor_clk_disable(temp_sensor);
> + clk_put(temp_sensor->clock);
> + platform_set_drvdata(pdev, NULL);
And:
dev_set_drvdata(&pdev->dev, NULL);
> + free_irq(temp_sensor->irq, temp_sensor);
Need to free IRQ before clock is disabled (else ISR may access while
clock stopped, possible L3 interconnect error and ARM imprecise
external abort)?
> + mutex_destroy(&temp_sensor->sensor_mutex);
> + kfree(temp_sensor);
> +
> + return 0;
> +}
Todd
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
next prev parent reply other threads:[~2011-08-19 5:35 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-18 10:52 [RFC PATCH 0/6 V2] OMAP4: Temperature sensor driver Keerthy
2011-08-18 10:52 ` [RFC PATCH 1/6 V2] OMAP4: Clock: Associate clocks for OMAP temperature sensor Keerthy
2011-08-29 21:47 ` Kevin Hilman
2011-08-18 10:52 ` [RFC PATCH 2/6 V2] OMAP4: Adding the temperature sensor register set bit fields Keerthy
2011-08-29 21:52 ` Kevin Hilman
2011-08-18 10:52 ` [RFC PATCH 3/6 V2] OMAP4460: Temperature sensor data Keerthy
2011-08-18 11:32 ` Felipe Balbi
2011-08-18 10:52 ` [RFC PATCH 4/6 V2] OMAP4: Hwmod: OMAP temperature sensor Keerthy
2011-08-18 10:52 ` [RFC PATCH 5/6 V2] OMAP4: Temperature sensor device support Keerthy
2011-08-19 5:47 ` Todd Poynor
2011-08-18 10:52 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver Keerthy
2011-08-18 11:37 ` Felipe Balbi
2011-08-18 11:37 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die Felipe Balbi
2011-08-22 4:29 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-22 4:41 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
2011-08-22 9:24 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver Felipe Balbi
2011-08-22 9:24 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die Felipe Balbi
2011-08-19 2:13 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver Guenter Roeck
2011-08-19 2:13 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die Guenter Roeck
2011-08-19 6:04 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-19 6:16 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
2011-08-19 6:17 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver Guenter Roeck
2011-08-19 6:17 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die Guenter Roeck
2011-08-19 13:01 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-19 13:13 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
2011-08-19 13:48 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver Guenter Roeck
2011-08-19 13:48 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die Guenter Roeck
2011-08-19 9:04 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-19 9:16 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
2011-08-19 12:53 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-19 12:55 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
2011-08-19 5:34 ` Todd Poynor [this message]
2011-08-19 5:34 ` Todd Poynor
2011-08-22 4:40 ` [RFC PATCH 6/6 V2] hwmon: OMAP4: On die temperature sensor driver J, KEERTHY
2011-08-22 4:52 ` [lm-sensors] [RFC PATCH 6/6 V2] hwmon: OMAP4: On die J, KEERTHY
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=20110819053438.GA2901@google.com \
--to=toddpoynor@google.com \
--cc=guenter.roeck@ericsson.com \
--cc=j-keerthy@ti.com \
--cc=khali@linux-fr.org \
--cc=linux-omap@vger.kernel.org \
--cc=lm-sensors@lm-sensors.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.