ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / drivers / misc / omap_temp_sensor.c
blob946d721471e7be7387d901c171a5006d986d8039
1 /*
2 * OMAP4 Temperature sensor driver file
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 * Author: J Keerthy <j-keerthy@ti.com>
6 * Author: Moiz Sonasath <m-sonasath@ti.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/clk.h>
27 #include <linux/delay.h>
28 #include <linux/device.h>
29 #include <linux/err.h>
30 #include <linux/gpio.h>
31 #include <linux/init.h>
32 #include <linux/interrupt.h>
33 #include <linux/io.h>
34 #include <linux/mutex.h>
35 #include <linux/platform_device.h>
36 #include <linux/pm_runtime.h>
37 #include <linux/reboot.h>
38 #include <linux/slab.h>
39 #include <linux/sysfs.h>
40 #include <linux/types.h>
42 #include <plat/common.h>
43 #include <plat/omap-pm.h>
44 #include <plat/omap_device.h>
45 #include <plat/temperature_sensor.h>
46 #include <plat/omap-pm.h>
48 /* TO DO: This needs to be fixed */
49 #include "../../../../arch/arm/mach-omap2/control.h"
50 /* #include <plat/control.h> */
52 #include <mach/ctrl_module_core_44xx.h>
54 extern void omap_thermal_throttle(void);
55 extern void omap_thermal_unthrottle(void);
57 static void throttle_delayed_work_fn(struct work_struct *work);
59 #define THROTTLE_DELAY_MS 1000
61 #define TSHUT_THRESHOLD_TSHUT_HOT 110000 /* 110 deg C */
62 #define TSHUT_THRESHOLD_TSHUT_COLD 100000 /* 100 deg C */
63 #define BGAP_THRESHOLD_T_HOT 83000 /* 83 deg C */
64 #define BGAP_THRESHOLD_T_COLD 76000 /* 76 deg C */
65 #define OMAP_ADC_START_VALUE 530
66 #define OMAP_ADC_END_VALUE 923
69 * omap_temp_sensor structure
70 * @pdev - Platform device pointer
71 * @dev - device pointer
72 * @clock - Clock pointer
73 * @sensor_mutex - Mutex for sysfs, irq and PM
74 * @irq - MPU Irq number for thermal alertemp_sensor
75 * @tshut_irq - Thermal shutdown IRQ
76 * @phy_base - Physical base of the temp I/O
77 * @is_efuse_valid - Flag to determine if eFuse is valid or not
78 * @clk_on - Manages the current clock state
79 * @clk_rate - Holds current clock rate
81 struct omap_temp_sensor {
82 struct platform_device *pdev;
83 struct device *dev;
84 struct clk *clock;
85 struct spinlock lock;
86 unsigned int irq;
87 unsigned int tshut_irq;
88 unsigned long phy_base;
89 int is_efuse_valid;
90 u8 clk_on;
91 unsigned long clk_rate;
92 u32 current_temp;
93 struct delayed_work throttle_work;
96 #ifdef CONFIG_PM
97 struct omap_temp_sensor_regs {
98 u32 temp_sensor_ctrl;
99 u32 bg_ctrl;
100 u32 bg_counter;
101 u32 bg_threshold;
102 u32 temp_sensor_tshut_threshold;
105 static struct omap_temp_sensor_regs temp_sensor_context;
106 static struct omap_temp_sensor *temp_sensor_pm;
107 #endif
110 * Temperature values in milli degrees celsius ADC code values from 530 to 923
112 static int adc_to_temp[] = {
113 -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
114 -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800,
115 -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300,
116 -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800,
117 -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400,
118 -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000,
119 -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600,
120 -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200,
121 -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700,
122 -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800,
123 -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000,
124 -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600,
125 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400,
126 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000,
127 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800,
128 15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700,
129 19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600,
130 23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400,
131 26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200,
132 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000,
133 34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800,
134 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600,
135 42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300,
136 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000,
137 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800,
138 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600,
139 57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400,
140 60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200,
141 64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800,
142 68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600,
143 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400,
144 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000,
145 79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800,
146 83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400,
147 86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200,
148 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800,
149 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600,
150 98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200,
151 101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400,
152 104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800,
153 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
154 111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200,
155 114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400,
156 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600,
157 121000, 121400, 121800, 122200, 122600, 123000
160 static unsigned long omap_temp_sensor_readl(struct omap_temp_sensor
161 *temp_sensor, u32 reg)
163 return omap_ctrl_readl(temp_sensor->phy_base + reg);
166 static void omap_temp_sensor_writel(struct omap_temp_sensor *temp_sensor,
167 u32 val, u32 reg)
169 omap_ctrl_writel(val, (temp_sensor->phy_base + reg));
172 static int adc_to_temp_conversion(int adc_val)
174 if (adc_val < OMAP_ADC_START_VALUE || adc_val > OMAP_ADC_END_VALUE) {
175 pr_err("%s:Temp read is invalid %i\n", __func__, adc_val);
176 return -EINVAL;
179 return adc_to_temp[adc_val - OMAP_ADC_START_VALUE];
182 static int temp_to_adc_conversion(long temp)
184 int i;
186 for (i = 0; i <= OMAP_ADC_END_VALUE - OMAP_ADC_START_VALUE; i++)
187 if (temp < adc_to_temp[i])
188 return OMAP_ADC_START_VALUE + i - 1;
189 return -EINVAL;
192 static int omap_read_current_temp(struct omap_temp_sensor *temp_sensor)
194 int adc;
196 adc = omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET);
197 adc &= (OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK);
199 if (!temp_sensor->is_efuse_valid)
200 pr_err_once("%s: Invalid EFUSE, Non-trimmed BGAP,"
201 "Temp not accurate\n", __func__ );
203 if (adc < OMAP_ADC_START_VALUE || adc > OMAP_ADC_END_VALUE) {
204 pr_err("%s:Invalid adc code reported by the sensor %d",
205 __func__, adc);
206 return -EINVAL;
209 return adc_to_temp_conversion(adc);
212 static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor
213 *temp_sensor)
215 u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold;
217 t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT);
218 t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD);
220 if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) {
221 pr_err("%s:Temp thresholds out of bounds\n", __func__);
222 return;
224 temp |= ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT));
225 omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET);
227 tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT);
228 tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD);
229 if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) {
230 pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__);
231 return;
233 temp |= ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT)
234 | (tshut_cold << OMAP4_TSHUT_COLD_SHIFT));
235 omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET);
238 static void omap_configure_temp_sensor_counter(struct omap_temp_sensor
239 *temp_sensor, u32 counter)
241 u32 val;
243 val = omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET);
244 val = val & ~(OMAP4_COUNTER_MASK);
245 val = val | (counter << OMAP4_COUNTER_SHIFT);
246 omap_temp_sensor_writel(temp_sensor, val, BGAP_COUNTER_OFFSET);
249 static void omap_enable_continuous_mode(struct omap_temp_sensor *temp_sensor)
251 u32 val;
253 val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
255 val = val | (1 << OMAP4_SINGLE_MODE_SHIFT);
257 omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET);
261 * sysfs hook functions
263 static ssize_t omap_temp_show_current(struct device *dev,
264 struct device_attribute *devattr,
265 char *buf)
267 struct platform_device *pdev = to_platform_device(dev);
268 struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
270 return sprintf(buf, "%d\n", omap_read_current_temp(temp_sensor));
273 static ssize_t omap_throttle_store(struct device *dev,
274 struct device_attribute *devattr, const char *buf, size_t count)
276 if (count && buf[0] == '1')
277 omap_thermal_throttle();
278 else
279 omap_thermal_unthrottle();
281 return count;
284 static DEVICE_ATTR(temperature, S_IRUGO, omap_temp_show_current, NULL);
285 static DEVICE_ATTR(throttle, S_IWUSR, NULL, omap_throttle_store);
286 static struct attribute *omap_temp_sensor_attributes[] = {
287 &dev_attr_temperature.attr,
288 &dev_attr_throttle.attr,
289 NULL
292 static const struct attribute_group omap_temp_sensor_group = {
293 .attrs = omap_temp_sensor_attributes,
296 static int omap_temp_sensor_enable(struct omap_temp_sensor *temp_sensor)
298 u32 temp;
299 u32 ret = 0;
300 unsigned long clk_rate;
302 unsigned long flags;
304 spin_lock_irqsave(&temp_sensor->lock, flags);
306 if (temp_sensor->clk_on) {
307 pr_debug("%s: clock already on\n", __func__);
308 goto out;
311 ret = pm_runtime_get_sync(&temp_sensor->pdev->dev);
312 if (ret) {
313 pr_err("%s:get sync failed\n", __func__);
314 ret = -EINVAL;
315 goto out;
318 clk_set_rate(temp_sensor->clock, 1000000);
319 clk_rate = clk_get_rate(temp_sensor->clock);
320 temp_sensor->clk_rate = clk_rate;
322 temp = omap_temp_sensor_readl(temp_sensor,
323 TEMP_SENSOR_CTRL_OFFSET);
324 temp &= ~(OMAP4_BGAP_TEMPSOFF_MASK);
326 /* write BGAP_TEMPSOFF should be reset to 0 */
327 omap_temp_sensor_writel(temp_sensor, temp,
328 TEMP_SENSOR_CTRL_OFFSET);
329 temp_sensor->clk_on = 1;
331 out:
332 spin_unlock_irqrestore(&temp_sensor->lock, flags);
333 return ret;
337 static int omap_temp_sensor_disable(struct omap_temp_sensor *temp_sensor)
339 u32 temp;
340 u32 ret = 0;
341 u32 counter = 1000;
342 unsigned long flags;
344 spin_lock_irqsave(&temp_sensor->lock, flags);
346 if (!temp_sensor->clk_on) {
347 pr_debug("%s: clock already off\n", __func__);
348 goto out;
350 temp = omap_temp_sensor_readl(temp_sensor,
351 TEMP_SENSOR_CTRL_OFFSET);
352 temp |= OMAP4_BGAP_TEMPSOFF_MASK;
354 /* write BGAP_TEMPSOFF should be set to 1 before gating clock */
355 omap_temp_sensor_writel(temp_sensor, temp,
356 TEMP_SENSOR_CTRL_OFFSET);
357 temp = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET);
359 /* wait till the clean stop bit is set */
360 while ((temp & OMAP4_CLEAN_STOP_MASK) && --counter)
361 temp = omap_temp_sensor_readl(temp_sensor,
362 BGAP_STATUS_OFFSET);
363 /* Gate the clock */
364 ret = pm_runtime_put_sync_suspend(&temp_sensor->pdev->dev);
365 if (ret) {
366 pr_err("%s:put sync failed\n", __func__);
367 ret = -EINVAL;
368 goto out;
370 temp_sensor->clk_on = 0;
372 out:
373 spin_unlock_irqrestore(&temp_sensor->lock, flags);
374 return ret;
378 * Check if the die sensor is cooling down. If it's higher than
379 * t_hot since the last throttle then throttle it again.
380 * OMAP junction temperature could stay for a long time in an
381 * unacceptable temperature range. The idea here is to check after
382 * t_hot->throttle the system really came below t_hot else re-throttle
383 * and keep doing till it's under t_hot temp range.
385 static void throttle_delayed_work_fn(struct work_struct *work)
387 int curr;
388 struct omap_temp_sensor *temp_sensor =
389 container_of(work, struct omap_temp_sensor,
390 throttle_work.work);
391 curr = omap_read_current_temp(temp_sensor);
393 if (curr >= BGAP_THRESHOLD_T_HOT || curr < 0) {
394 pr_warn("%s: OMAP temp read %d exceeds the threshold\n",
395 __func__, curr);
396 omap_thermal_throttle();
397 schedule_delayed_work(&temp_sensor->throttle_work,
398 msecs_to_jiffies(THROTTLE_DELAY_MS));
399 } else {
400 schedule_delayed_work(&temp_sensor->throttle_work,
401 msecs_to_jiffies(THROTTLE_DELAY_MS));
405 static irqreturn_t omap_tshut_irq_handler(int irq, void *data)
407 struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;
409 /* Need to handle thermal mgmt in bootloader
410 * to avoid restart again at kernel level
412 if (temp_sensor->is_efuse_valid) {
413 pr_emerg("%s: Thermal shutdown reached rebooting device\n",
414 __func__);
415 kernel_restart(NULL);
416 } else {
417 pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__);
420 return IRQ_HANDLED;
423 static irqreturn_t omap_talert_irq_handler(int irq, void *data)
425 struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;
426 int t_hot, t_cold, temp_offset;
428 t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
429 & OMAP4_HOT_FLAG_MASK;
430 t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
431 & OMAP4_COLD_FLAG_MASK;
432 temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
433 if (t_hot) {
434 omap_thermal_throttle();
435 schedule_delayed_work(&temp_sensor->throttle_work,
436 msecs_to_jiffies(THROTTLE_DELAY_MS));
437 temp_offset &= ~(OMAP4_MASK_HOT_MASK);
438 temp_offset |= OMAP4_MASK_COLD_MASK;
439 } else if (t_cold) {
440 cancel_delayed_work_sync(&temp_sensor->throttle_work);
441 omap_thermal_unthrottle();
442 temp_offset &= ~(OMAP4_MASK_COLD_MASK);
443 temp_offset |= OMAP4_MASK_HOT_MASK;
446 omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET);
448 return IRQ_HANDLED;
451 static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
453 struct device *dev = &pdev->dev;
454 struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data;
455 struct omap_temp_sensor *temp_sensor;
456 struct resource *mem;
457 int ret = 0, val;
459 if (!pdata) {
460 dev_err(dev, "%s: platform data missing\n", __func__);
461 return -EINVAL;
464 temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL);
465 if (!temp_sensor)
466 return -ENOMEM;
468 spin_lock_init(&temp_sensor->lock);
470 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
471 if (!mem) {
472 dev_err(dev, "%s:no mem resource\n", __func__);
473 ret = -EINVAL;
474 goto plat_res_err;
477 temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert");
478 if (temp_sensor->irq < 0) {
479 dev_err(dev, "%s:Cannot get thermal alert irq\n",
480 __func__);
481 ret = -EINVAL;
482 goto get_irq_err;
485 ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN,
486 "thermal_shutdown");
487 if (ret) {
488 dev_err(dev, "%s: Could not get tshut_gpio\n",
489 __func__);
490 goto tshut_gpio_req_err;
493 temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO);
494 if (temp_sensor->tshut_irq < 0) {
495 dev_err(dev, "%s:Cannot get thermal shutdown irq\n",
496 __func__);
497 ret = -EINVAL;
498 goto get_tshut_irq_err;
501 temp_sensor->phy_base = pdata->offset;
502 temp_sensor->pdev = pdev;
503 temp_sensor->dev = dev;
505 pm_runtime_enable(dev);
506 pm_runtime_irq_safe(dev);
509 * check if the efuse has a non-zero value if not
510 * it is an untrimmed sample and the temperatures
511 * may not be accurate */
512 if (omap_readl(OMAP4_CTRL_MODULE_CORE +
513 OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP))
514 temp_sensor->is_efuse_valid = 1;
516 temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck");
517 if (IS_ERR(temp_sensor->clock)) {
518 ret = PTR_ERR(temp_sensor->clock);
519 pr_err("%s:Unable to get fclk: %d\n", __func__, ret);
520 ret = -EINVAL;
521 goto clk_get_err;
524 /* Init delayed work for throttle decision */
525 INIT_DELAYED_WORK(&temp_sensor->throttle_work,
526 throttle_delayed_work_fn);
528 platform_set_drvdata(pdev, temp_sensor);
530 ret = omap_temp_sensor_enable(temp_sensor);
531 if (ret) {
532 dev_err(dev, "%s:Cannot enable temp sensor\n", __func__);
533 goto sensor_enable_err;
536 omap_enable_continuous_mode(temp_sensor);
537 omap_configure_temp_sensor_thresholds(temp_sensor);
538 /* 1 ms */
539 omap_configure_temp_sensor_counter(temp_sensor, 1);
541 /* Wait till the first conversion is done wait for at least 1ms */
542 mdelay(2);
544 /* Read the temperature once due to hw issue*/
545 omap_read_current_temp(temp_sensor);
547 /* Set 2 seconds time as default counter */
548 omap_configure_temp_sensor_counter(temp_sensor,
549 temp_sensor->clk_rate * 2);
550 ret = request_threaded_irq(temp_sensor->irq, NULL,
551 omap_talert_irq_handler,
552 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
553 "temp_sensor", (void *)temp_sensor);
554 if (ret) {
555 dev_err(dev, "Request threaded irq failed.\n");
556 goto req_irq_err;
559 ret = request_threaded_irq(temp_sensor->tshut_irq, NULL,
560 omap_tshut_irq_handler,
561 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
562 "tshut", (void *)temp_sensor);
563 if (ret) {
564 dev_err(dev, "Request threaded irq failed for TSHUT.\n");
565 goto tshut_irq_req_err;
568 ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group);
569 if (ret) {
570 dev_err(&pdev->dev, "could not create sysfs files\n");
571 goto sysfs_create_err;
574 /* unmask the T_COLD and unmask T_HOT at init */
575 val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
576 val |= OMAP4_MASK_COLD_MASK;
577 val |= OMAP4_MASK_HOT_MASK;
578 omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET);
580 dev_info(dev, "%s probed", pdata->name);
582 temp_sensor_pm = temp_sensor;
584 return 0;
586 sysfs_create_err:
587 free_irq(temp_sensor->tshut_irq, temp_sensor);
588 cancel_delayed_work_sync(&temp_sensor->throttle_work);
589 tshut_irq_req_err:
590 free_irq(temp_sensor->irq, temp_sensor);
591 req_irq_err:
592 platform_set_drvdata(pdev, NULL);
593 omap_temp_sensor_disable(temp_sensor);
594 sensor_enable_err:
595 clk_put(temp_sensor->clock);
596 clk_get_err:
597 pm_runtime_disable(dev);
598 get_tshut_irq_err:
599 gpio_free(OMAP_TSHUT_GPIO);
600 tshut_gpio_req_err:
601 get_irq_err:
602 plat_res_err:
603 kfree(temp_sensor);
604 return ret;
607 static int __devexit omap_temp_sensor_remove(struct platform_device *pdev)
609 struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
611 sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group);
612 cancel_delayed_work_sync(&temp_sensor->throttle_work);
613 omap_temp_sensor_disable(temp_sensor);
614 clk_put(temp_sensor->clock);
615 platform_set_drvdata(pdev, NULL);
616 if (temp_sensor->irq)
617 free_irq(temp_sensor->irq, temp_sensor);
618 if (temp_sensor->tshut_irq)
619 free_irq(temp_sensor->tshut_irq, temp_sensor);
620 kfree(temp_sensor);
622 return 0;
625 #ifdef CONFIG_PM
626 static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor)
628 temp_sensor_context.temp_sensor_ctrl =
629 omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET);
630 temp_sensor_context.bg_ctrl =
631 omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
632 temp_sensor_context.bg_counter =
633 omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET);
634 temp_sensor_context.bg_threshold =
635 omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET);
636 temp_sensor_context.temp_sensor_tshut_threshold =
637 omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET);
640 static void omap_temp_sensor_restore_ctxt(struct omap_temp_sensor *temp_sensor)
642 omap_temp_sensor_writel(temp_sensor,
643 temp_sensor_context.temp_sensor_ctrl,
644 TEMP_SENSOR_CTRL_OFFSET);
645 omap_temp_sensor_writel(temp_sensor,
646 temp_sensor_context.bg_ctrl,
647 BGAP_CTRL_OFFSET);
648 omap_temp_sensor_writel(temp_sensor,
649 temp_sensor_context.bg_counter,
650 BGAP_COUNTER_OFFSET);
651 omap_temp_sensor_writel(temp_sensor,
652 temp_sensor_context.bg_threshold,
653 BGAP_THRESHOLD_OFFSET);
654 omap_temp_sensor_writel(temp_sensor,
655 temp_sensor_context.temp_sensor_tshut_threshold,
656 BGAP_TSHUT_OFFSET);
659 static int omap_temp_sensor_suspend(struct platform_device *pdev,
660 pm_message_t state)
662 struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
664 omap_temp_sensor_disable(temp_sensor);
666 return 0;
669 static int omap_temp_sensor_resume(struct platform_device *pdev)
671 struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
673 omap_temp_sensor_enable(temp_sensor);
675 return 0;
678 void omap_temp_sensor_idle(int idle_state)
680 if (!temp_sensor_pm)
681 return;
683 if (idle_state)
684 omap_temp_sensor_disable(temp_sensor_pm);
685 else
686 omap_temp_sensor_enable(temp_sensor_pm);
689 #else
690 omap_temp_sensor_suspend NULL
691 omap_temp_sensor_resume NULL
693 #endif /* CONFIG_PM */
694 static int omap_temp_sensor_runtime_suspend(struct device *dev)
696 struct omap_temp_sensor *temp_sensor =
697 platform_get_drvdata(to_platform_device(dev));
699 omap_temp_sensor_save_ctxt(temp_sensor);
700 return 0;
703 static int omap_temp_sensor_runtime_resume(struct device *dev)
705 struct omap_temp_sensor *temp_sensor =
706 platform_get_drvdata(to_platform_device(dev));
707 if (omap_pm_was_context_lost(dev)) {
708 omap_temp_sensor_restore_ctxt(temp_sensor);
710 return 0;
713 static const struct dev_pm_ops omap_temp_sensor_dev_pm_ops = {
714 .runtime_suspend = omap_temp_sensor_runtime_suspend,
715 .runtime_resume = omap_temp_sensor_runtime_resume,
718 static struct platform_driver omap_temp_sensor_driver = {
719 .probe = omap_temp_sensor_probe,
720 .remove = omap_temp_sensor_remove,
721 .suspend = omap_temp_sensor_suspend,
722 .resume = omap_temp_sensor_resume,
723 .driver = {
724 .name = "omap_temp_sensor",
725 .pm = &omap_temp_sensor_dev_pm_ops,
729 int __init omap_temp_sensor_init(void)
731 if (!cpu_is_omap446x())
732 return 0;
734 return platform_driver_register(&omap_temp_sensor_driver);
737 static void __exit omap_temp_sensor_exit(void)
739 platform_driver_unregister(&omap_temp_sensor_driver);
742 module_init(omap_temp_sensor_init);
743 module_exit(omap_temp_sensor_exit);
745 MODULE_DESCRIPTION("OMAP446X Temperature Sensor Driver");
746 MODULE_LICENSE("GPL");
747 MODULE_ALIAS("platform:" DRIVER_NAME);
748 MODULE_AUTHOR("Texas Instruments Inc");