/drivers/misc/omap_temp_sensor.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 754 lines · 572 code · 113 blank · 69 comment · 55 complexity · 927280a74bfd363b6c3ad1dad144d60c MD5 · raw file

  1. /*
  2. * OMAP4 Temperature sensor driver file
  3. *
  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>
  7. *
  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.
  11. *
  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.
  16. *
  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
  21. *
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/module.h>
  25. #include <linux/clk.h>
  26. #include <linux/delay.h>
  27. #include <linux/device.h>
  28. #include <linux/err.h>
  29. #include <linux/gpio.h>
  30. #include <linux/init.h>
  31. #include <linux/interrupt.h>
  32. #include <linux/io.h>
  33. #include <linux/mutex.h>
  34. #include <linux/platform_device.h>
  35. #include <linux/pm_runtime.h>
  36. #include <linux/reboot.h>
  37. #include <linux/slab.h>
  38. #include <linux/sysfs.h>
  39. #include <linux/types.h>
  40. #include <plat/common.h>
  41. #include <plat/omap-pm.h>
  42. #include <plat/omap_device.h>
  43. #include <plat/temperature_sensor.h>
  44. #include <plat/omap-pm.h>
  45. /* TO DO: This needs to be fixed */
  46. #include "../../../../arch/arm/mach-omap2/control.h"
  47. /* #include <plat/control.h> */
  48. #include <mach/ctrl_module_core_44xx.h>
  49. extern void omap_thermal_throttle(void);
  50. extern void omap_thermal_unthrottle(void);
  51. static void throttle_delayed_work_fn(struct work_struct *work);
  52. static int throttle_state = 1;
  53. #define THROTTLE_DELAY_MS 1000
  54. #define TSHUT_THRESHOLD_TSHUT_HOT 110000 /* 110 deg C */
  55. #define TSHUT_THRESHOLD_TSHUT_COLD 100000 /* 100 deg C */
  56. #define BGAP_THRESHOLD_T_HOT 72000 /* 72 deg C */
  57. #define BGAP_THRESHOLD_T_COLD 68000 /* 68 deg C */
  58. #define OMAP_ADC_START_VALUE 530
  59. #define OMAP_ADC_END_VALUE 923
  60. /*
  61. * omap_temp_sensor structure
  62. * @pdev - Platform device pointer
  63. * @dev - device pointer
  64. * @clock - Clock pointer
  65. * @sensor_mutex - Mutex for sysfs, irq and PM
  66. * @irq - MPU Irq number for thermal alertemp_sensor
  67. * @tshut_irq - Thermal shutdown IRQ
  68. * @phy_base - Physical base of the temp I/O
  69. * @is_efuse_valid - Flag to determine if eFuse is valid or not
  70. * @clk_on - Manages the current clock state
  71. * @clk_rate - Holds current clock rate
  72. */
  73. struct omap_temp_sensor {
  74. struct platform_device *pdev;
  75. struct device *dev;
  76. struct clk *clock;
  77. struct spinlock lock;
  78. unsigned int irq;
  79. unsigned int tshut_irq;
  80. unsigned long phy_base;
  81. int is_efuse_valid;
  82. u8 clk_on;
  83. unsigned long clk_rate;
  84. u32 current_temp;
  85. struct delayed_work throttle_work;
  86. };
  87. #ifdef CONFIG_PM
  88. struct omap_temp_sensor_regs {
  89. u32 temp_sensor_ctrl;
  90. u32 bg_ctrl;
  91. u32 bg_counter;
  92. u32 bg_threshold;
  93. u32 temp_sensor_tshut_threshold;
  94. };
  95. static struct omap_temp_sensor_regs temp_sensor_context;
  96. static struct omap_temp_sensor *temp_sensor_pm;
  97. #endif
  98. /*
  99. * Temperature values in milli degrees celsius ADC code values from 530 to 923
  100. */
  101. static int adc_to_temp[] = {
  102. -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
  103. -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800,
  104. -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300,
  105. -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800,
  106. -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400,
  107. -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000,
  108. -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600,
  109. -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200,
  110. -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700,
  111. -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800,
  112. -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000,
  113. -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600,
  114. 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400,
  115. 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000,
  116. 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800,
  117. 15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700,
  118. 19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600,
  119. 23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400,
  120. 26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200,
  121. 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000,
  122. 34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800,
  123. 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600,
  124. 42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300,
  125. 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000,
  126. 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800,
  127. 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600,
  128. 57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400,
  129. 60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200,
  130. 64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800,
  131. 68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600,
  132. 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400,
  133. 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000,
  134. 79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800,
  135. 83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400,
  136. 86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200,
  137. 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800,
  138. 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600,
  139. 98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200,
  140. 101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400,
  141. 104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800,
  142. 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
  143. 111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200,
  144. 114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400,
  145. 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600,
  146. 121000, 121400, 121800, 122200, 122600, 123000
  147. };
  148. static unsigned long omap_temp_sensor_readl(struct omap_temp_sensor
  149. *temp_sensor, u32 reg)
  150. {
  151. return omap_ctrl_readl(temp_sensor->phy_base + reg);
  152. }
  153. static void omap_temp_sensor_writel(struct omap_temp_sensor *temp_sensor,
  154. u32 val, u32 reg)
  155. {
  156. omap_ctrl_writel(val, (temp_sensor->phy_base + reg));
  157. }
  158. static int adc_to_temp_conversion(int adc_val)
  159. {
  160. if (adc_val < OMAP_ADC_START_VALUE || adc_val > OMAP_ADC_END_VALUE) {
  161. pr_err("%s:Temp read is invalid %i\n", __func__, adc_val);
  162. return -EINVAL;
  163. }
  164. return adc_to_temp[adc_val - OMAP_ADC_START_VALUE];
  165. }
  166. static int temp_to_adc_conversion(long temp)
  167. {
  168. int i;
  169. for (i = 0; i <= OMAP_ADC_END_VALUE - OMAP_ADC_START_VALUE; i++)
  170. if (temp < adc_to_temp[i])
  171. return OMAP_ADC_START_VALUE + i - 1;
  172. return -EINVAL;
  173. }
  174. static int omap_read_current_temp(struct omap_temp_sensor *temp_sensor)
  175. {
  176. int adc;
  177. adc = omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET);
  178. adc &= (OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK);
  179. if (!temp_sensor->is_efuse_valid)
  180. pr_err_once("%s: Invalid EFUSE, Non-trimmed BGAP,"
  181. "Temp not accurate\n", __func__ );
  182. if (adc < OMAP_ADC_START_VALUE || adc > OMAP_ADC_END_VALUE) {
  183. pr_err("%s:Invalid adc code reported by the sensor %d",
  184. __func__, adc);
  185. return -EINVAL;
  186. }
  187. return adc_to_temp_conversion(adc);
  188. }
  189. static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor
  190. *temp_sensor)
  191. {
  192. u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold;
  193. t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT);
  194. t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD);
  195. if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) {
  196. pr_err("%s:Temp thresholds out of bounds\n", __func__);
  197. return;
  198. }
  199. temp |= ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT));
  200. omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET);
  201. tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT);
  202. tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD);
  203. if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) {
  204. pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__);
  205. return;
  206. }
  207. temp |= ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT)
  208. | (tshut_cold << OMAP4_TSHUT_COLD_SHIFT));
  209. omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET);
  210. }
  211. static void omap_configure_temp_sensor_counter(struct omap_temp_sensor
  212. *temp_sensor, u32 counter)
  213. {
  214. u32 val;
  215. val = omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET);
  216. val = val & ~(OMAP4_COUNTER_MASK);
  217. val = val | (counter << OMAP4_COUNTER_SHIFT);
  218. omap_temp_sensor_writel(temp_sensor, val, BGAP_COUNTER_OFFSET);
  219. }
  220. static void omap_enable_continuous_mode(struct omap_temp_sensor *temp_sensor)
  221. {
  222. u32 val;
  223. val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
  224. val = val | (1 << OMAP4_SINGLE_MODE_SHIFT);
  225. omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET);
  226. }
  227. /*
  228. * sysfs hook functions
  229. */
  230. static ssize_t omap_temp_show_current(struct device *dev,
  231. struct device_attribute *devattr,
  232. char *buf)
  233. {
  234. struct platform_device *pdev = to_platform_device(dev);
  235. struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
  236. return sprintf(buf, "%d\n", omap_read_current_temp(temp_sensor));
  237. }
  238. static ssize_t omap_throttle_store(struct device *dev,
  239. struct device_attribute *devattr, const char *buf, size_t count)
  240. {
  241. if (count && buf[0] == '1') {
  242. throttle_state = 1;
  243. // omap_thermal_throttle();
  244. }
  245. else {
  246. throttle_state = 0;
  247. omap_thermal_unthrottle();
  248. }
  249. return count;
  250. }
  251. static DEVICE_ATTR(temperature, S_IRUGO, omap_temp_show_current, NULL);
  252. static DEVICE_ATTR(throttle, S_IWUSR, NULL, omap_throttle_store);
  253. static struct attribute *omap_temp_sensor_attributes[] = {
  254. &dev_attr_temperature.attr,
  255. &dev_attr_throttle.attr,
  256. NULL
  257. };
  258. static const struct attribute_group omap_temp_sensor_group = {
  259. .attrs = omap_temp_sensor_attributes,
  260. };
  261. static int omap_temp_sensor_enable(struct omap_temp_sensor *temp_sensor)
  262. {
  263. u32 temp;
  264. u32 ret = 0;
  265. unsigned long clk_rate;
  266. unsigned long flags;
  267. spin_lock_irqsave(&temp_sensor->lock, flags);
  268. if (temp_sensor->clk_on) {
  269. pr_debug("%s: clock already on\n", __func__);
  270. goto out;
  271. }
  272. ret = pm_runtime_get_sync(&temp_sensor->pdev->dev);
  273. if (ret) {
  274. pr_err("%s:get sync failed\n", __func__);
  275. ret = -EINVAL;
  276. goto out;
  277. }
  278. clk_set_rate(temp_sensor->clock, 1000000);
  279. clk_rate = clk_get_rate(temp_sensor->clock);
  280. temp_sensor->clk_rate = clk_rate;
  281. temp = omap_temp_sensor_readl(temp_sensor,
  282. TEMP_SENSOR_CTRL_OFFSET);
  283. temp &= ~(OMAP4_BGAP_TEMPSOFF_MASK);
  284. /* write BGAP_TEMPSOFF should be reset to 0 */
  285. omap_temp_sensor_writel(temp_sensor, temp,
  286. TEMP_SENSOR_CTRL_OFFSET);
  287. temp_sensor->clk_on = 1;
  288. out:
  289. spin_unlock_irqrestore(&temp_sensor->lock, flags);
  290. return ret;
  291. }
  292. static int omap_temp_sensor_disable(struct omap_temp_sensor *temp_sensor)
  293. {
  294. u32 temp;
  295. u32 ret = 0;
  296. u32 counter = 1000;
  297. unsigned long flags;
  298. spin_lock_irqsave(&temp_sensor->lock, flags);
  299. if (!temp_sensor->clk_on) {
  300. pr_debug("%s: clock already off\n", __func__);
  301. goto out;
  302. }
  303. temp = omap_temp_sensor_readl(temp_sensor,
  304. TEMP_SENSOR_CTRL_OFFSET);
  305. temp |= OMAP4_BGAP_TEMPSOFF_MASK;
  306. /* write BGAP_TEMPSOFF should be set to 1 before gating clock */
  307. omap_temp_sensor_writel(temp_sensor, temp,
  308. TEMP_SENSOR_CTRL_OFFSET);
  309. temp = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET);
  310. /* wait till the clean stop bit is set */
  311. while ((temp & OMAP4_CLEAN_STOP_MASK) && --counter)
  312. temp = omap_temp_sensor_readl(temp_sensor,
  313. BGAP_STATUS_OFFSET);
  314. /* Gate the clock */
  315. ret = pm_runtime_put_sync_suspend(&temp_sensor->pdev->dev);
  316. if (ret) {
  317. pr_err("%s:put sync failed\n", __func__);
  318. ret = -EINVAL;
  319. goto out;
  320. }
  321. temp_sensor->clk_on = 0;
  322. out:
  323. spin_unlock_irqrestore(&temp_sensor->lock, flags);
  324. return ret;
  325. }
  326. /*
  327. * Check if the die sensor is cooling down. If it's higher than
  328. * t_hot since the last throttle then throttle it again.
  329. * OMAP junction temperature could stay for a long time in an
  330. * unacceptable temperature range. The idea here is to check after
  331. * t_hot->throttle the system really came below t_hot else re-throttle
  332. * and keep doing till it's under t_hot temp range.
  333. */
  334. static void throttle_delayed_work_fn(struct work_struct *work)
  335. {
  336. int curr;
  337. struct omap_temp_sensor *temp_sensor =
  338. container_of(work, struct omap_temp_sensor,
  339. throttle_work.work);
  340. curr = omap_read_current_temp(temp_sensor);
  341. if ((curr >= BGAP_THRESHOLD_T_HOT || curr < 0)) {
  342. pr_warn("%s: OMAP temp read %d exceeds the threshold\n",
  343. __func__, curr);
  344. if (throttle_state == 1)
  345. omap_thermal_throttle();
  346. schedule_delayed_work(&temp_sensor->throttle_work,
  347. msecs_to_jiffies(THROTTLE_DELAY_MS));
  348. } else {
  349. schedule_delayed_work(&temp_sensor->throttle_work,
  350. msecs_to_jiffies(THROTTLE_DELAY_MS));
  351. }
  352. }
  353. static irqreturn_t omap_tshut_irq_handler(int irq, void *data)
  354. {
  355. struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;
  356. /* Need to handle thermal mgmt in bootloader
  357. * to avoid restart again at kernel level
  358. */
  359. if (temp_sensor->is_efuse_valid) {
  360. pr_emerg("%s: Thermal shutdown reached rebooting device\n",
  361. __func__);
  362. kernel_restart(NULL);
  363. } else {
  364. pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__);
  365. }
  366. return IRQ_HANDLED;
  367. }
  368. static irqreturn_t omap_talert_irq_handler(int irq, void *data)
  369. {
  370. struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;
  371. int t_hot, t_cold, temp_offset;
  372. t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
  373. & OMAP4_HOT_FLAG_MASK;
  374. t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
  375. & OMAP4_COLD_FLAG_MASK;
  376. temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
  377. if (t_hot) {
  378. if (throttle_state == 1)
  379. omap_thermal_throttle();
  380. schedule_delayed_work(&temp_sensor->throttle_work,
  381. msecs_to_jiffies(THROTTLE_DELAY_MS));
  382. temp_offset &= ~(OMAP4_MASK_HOT_MASK);
  383. temp_offset |= OMAP4_MASK_COLD_MASK;
  384. } else if (t_cold) {
  385. cancel_delayed_work_sync(&temp_sensor->throttle_work);
  386. omap_thermal_unthrottle();
  387. temp_offset &= ~(OMAP4_MASK_COLD_MASK);
  388. temp_offset |= OMAP4_MASK_HOT_MASK;
  389. }
  390. omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET);
  391. return IRQ_HANDLED;
  392. }
  393. static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
  394. {
  395. struct device *dev = &pdev->dev;
  396. struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data;
  397. struct omap_temp_sensor *temp_sensor;
  398. struct resource *mem;
  399. int ret = 0, val;
  400. if (!pdata) {
  401. dev_err(dev, "%s: platform data missing\n", __func__);
  402. return -EINVAL;
  403. }
  404. temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL);
  405. if (!temp_sensor)
  406. return -ENOMEM;
  407. spin_lock_init(&temp_sensor->lock);
  408. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  409. if (!mem) {
  410. dev_err(dev, "%s:no mem resource\n", __func__);
  411. ret = -EINVAL;
  412. goto plat_res_err;
  413. }
  414. temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert");
  415. if (temp_sensor->irq < 0) {
  416. dev_err(dev, "%s:Cannot get thermal alert irq\n",
  417. __func__);
  418. ret = -EINVAL;
  419. goto get_irq_err;
  420. }
  421. ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN,
  422. "thermal_shutdown");
  423. if (ret) {
  424. dev_err(dev, "%s: Could not get tshut_gpio\n",
  425. __func__);
  426. goto tshut_gpio_req_err;
  427. }
  428. temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO);
  429. if (temp_sensor->tshut_irq < 0) {
  430. dev_err(dev, "%s:Cannot get thermal shutdown irq\n",
  431. __func__);
  432. ret = -EINVAL;
  433. goto get_tshut_irq_err;
  434. }
  435. temp_sensor->phy_base = pdata->offset;
  436. temp_sensor->pdev = pdev;
  437. temp_sensor->dev = dev;
  438. pm_runtime_enable(dev);
  439. pm_runtime_irq_safe(dev);
  440. /*
  441. * check if the efuse has a non-zero value if not
  442. * it is an untrimmed sample and the temperatures
  443. * may not be accurate */
  444. if (omap_readl(OMAP4_CTRL_MODULE_CORE +
  445. OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP))
  446. temp_sensor->is_efuse_valid = 1;
  447. temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck");
  448. if (IS_ERR(temp_sensor->clock)) {
  449. ret = PTR_ERR(temp_sensor->clock);
  450. pr_err("%s:Unable to get fclk: %d\n", __func__, ret);
  451. ret = -EINVAL;
  452. goto clk_get_err;
  453. }
  454. /* Init delayed work for throttle decision */
  455. INIT_DELAYED_WORK(&temp_sensor->throttle_work,
  456. throttle_delayed_work_fn);
  457. platform_set_drvdata(pdev, temp_sensor);
  458. ret = omap_temp_sensor_enable(temp_sensor);
  459. if (ret) {
  460. dev_err(dev, "%s:Cannot enable temp sensor\n", __func__);
  461. goto sensor_enable_err;
  462. }
  463. omap_enable_continuous_mode(temp_sensor);
  464. omap_configure_temp_sensor_thresholds(temp_sensor);
  465. /* 1 ms */
  466. omap_configure_temp_sensor_counter(temp_sensor, 1);
  467. /* Wait till the first conversion is done wait for at least 1ms */
  468. mdelay(2);
  469. /* Read the temperature once due to hw issue*/
  470. omap_read_current_temp(temp_sensor);
  471. /* Set 2 seconds time as default counter */
  472. omap_configure_temp_sensor_counter(temp_sensor,
  473. temp_sensor->clk_rate * 2);
  474. ret = request_threaded_irq(temp_sensor->irq, NULL,
  475. omap_talert_irq_handler,
  476. IRQF_TRIGGER_RISING | IRQF_ONESHOT,
  477. "temp_sensor", (void *)temp_sensor);
  478. if (ret) {
  479. dev_err(dev, "Request threaded irq failed.\n");
  480. goto req_irq_err;
  481. }
  482. ret = request_threaded_irq(temp_sensor->tshut_irq, NULL,
  483. omap_tshut_irq_handler,
  484. IRQF_TRIGGER_RISING | IRQF_ONESHOT,
  485. "tshut", (void *)temp_sensor);
  486. if (ret) {
  487. dev_err(dev, "Request threaded irq failed for TSHUT.\n");
  488. goto tshut_irq_req_err;
  489. }
  490. ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group);
  491. if (ret) {
  492. dev_err(&pdev->dev, "could not create sysfs files\n");
  493. goto sysfs_create_err;
  494. }
  495. /* unmask the T_COLD and unmask T_HOT at init */
  496. val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
  497. val |= OMAP4_MASK_COLD_MASK;
  498. val |= OMAP4_MASK_HOT_MASK;
  499. omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET);
  500. dev_info(dev, "%s probed", pdata->name);
  501. temp_sensor_pm = temp_sensor;
  502. return 0;
  503. sysfs_create_err:
  504. free_irq(temp_sensor->tshut_irq, temp_sensor);
  505. cancel_delayed_work_sync(&temp_sensor->throttle_work);
  506. tshut_irq_req_err:
  507. free_irq(temp_sensor->irq, temp_sensor);
  508. req_irq_err:
  509. platform_set_drvdata(pdev, NULL);
  510. omap_temp_sensor_disable(temp_sensor);
  511. sensor_enable_err:
  512. clk_put(temp_sensor->clock);
  513. clk_get_err:
  514. pm_runtime_disable(dev);
  515. get_tshut_irq_err:
  516. gpio_free(OMAP_TSHUT_GPIO);
  517. tshut_gpio_req_err:
  518. get_irq_err:
  519. plat_res_err:
  520. kfree(temp_sensor);
  521. return ret;
  522. }
  523. static int __devexit omap_temp_sensor_remove(struct platform_device *pdev)
  524. {
  525. struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
  526. sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group);
  527. cancel_delayed_work_sync(&temp_sensor->throttle_work);
  528. omap_temp_sensor_disable(temp_sensor);
  529. clk_put(temp_sensor->clock);
  530. platform_set_drvdata(pdev, NULL);
  531. if (temp_sensor->irq)
  532. free_irq(temp_sensor->irq, temp_sensor);
  533. if (temp_sensor->tshut_irq)
  534. free_irq(temp_sensor->tshut_irq, temp_sensor);
  535. kfree(temp_sensor);
  536. return 0;
  537. }
  538. #ifdef CONFIG_PM
  539. static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor)
  540. {
  541. temp_sensor_context.temp_sensor_ctrl =
  542. omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET);
  543. temp_sensor_context.bg_ctrl =
  544. omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
  545. temp_sensor_context.bg_counter =
  546. omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET);
  547. temp_sensor_context.bg_threshold =
  548. omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET);
  549. temp_sensor_context.temp_sensor_tshut_threshold =
  550. omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET);
  551. }
  552. static void omap_temp_sensor_restore_ctxt(struct omap_temp_sensor *temp_sensor)
  553. {
  554. omap_temp_sensor_writel(temp_sensor,
  555. temp_sensor_context.temp_sensor_ctrl,
  556. TEMP_SENSOR_CTRL_OFFSET);
  557. omap_temp_sensor_writel(temp_sensor,
  558. temp_sensor_context.bg_ctrl,
  559. BGAP_CTRL_OFFSET);
  560. omap_temp_sensor_writel(temp_sensor,
  561. temp_sensor_context.bg_counter,
  562. BGAP_COUNTER_OFFSET);
  563. omap_temp_sensor_writel(temp_sensor,
  564. temp_sensor_context.bg_threshold,
  565. BGAP_THRESHOLD_OFFSET);
  566. omap_temp_sensor_writel(temp_sensor,
  567. temp_sensor_context.temp_sensor_tshut_threshold,
  568. BGAP_TSHUT_OFFSET);
  569. }
  570. static int omap_temp_sensor_suspend(struct platform_device *pdev,
  571. pm_message_t state)
  572. {
  573. struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
  574. omap_temp_sensor_disable(temp_sensor);
  575. return 0;
  576. }
  577. static int omap_temp_sensor_resume(struct platform_device *pdev)
  578. {
  579. struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
  580. omap_temp_sensor_enable(temp_sensor);
  581. return 0;
  582. }
  583. void omap_temp_sensor_idle(int idle_state)
  584. {
  585. if (!temp_sensor_pm)
  586. return;
  587. if (idle_state)
  588. omap_temp_sensor_disable(temp_sensor_pm);
  589. else
  590. omap_temp_sensor_enable(temp_sensor_pm);
  591. }
  592. #else
  593. omap_temp_sensor_suspend NULL
  594. omap_temp_sensor_resume NULL
  595. #endif /* CONFIG_PM */
  596. static int omap_temp_sensor_runtime_suspend(struct device *dev)
  597. {
  598. struct omap_temp_sensor *temp_sensor =
  599. platform_get_drvdata(to_platform_device(dev));
  600. omap_temp_sensor_save_ctxt(temp_sensor);
  601. return 0;
  602. }
  603. static int omap_temp_sensor_runtime_resume(struct device *dev)
  604. {
  605. struct omap_temp_sensor *temp_sensor =
  606. platform_get_drvdata(to_platform_device(dev));
  607. if (omap_pm_was_context_lost(dev)) {
  608. omap_temp_sensor_restore_ctxt(temp_sensor);
  609. }
  610. return 0;
  611. }
  612. static const struct dev_pm_ops omap_temp_sensor_dev_pm_ops = {
  613. .runtime_suspend = omap_temp_sensor_runtime_suspend,
  614. .runtime_resume = omap_temp_sensor_runtime_resume,
  615. };
  616. static struct platform_driver omap_temp_sensor_driver = {
  617. .probe = omap_temp_sensor_probe,
  618. .remove = omap_temp_sensor_remove,
  619. .suspend = omap_temp_sensor_suspend,
  620. .resume = omap_temp_sensor_resume,
  621. .driver = {
  622. .name = "omap_temp_sensor",
  623. .pm = &omap_temp_sensor_dev_pm_ops,
  624. },
  625. };
  626. int __init omap_temp_sensor_init(void)
  627. {
  628. if (!cpu_is_omap446x())
  629. return 0;
  630. return platform_driver_register(&omap_temp_sensor_driver);
  631. }
  632. static void __exit omap_temp_sensor_exit(void)
  633. {
  634. platform_driver_unregister(&omap_temp_sensor_driver);
  635. }
  636. module_init(omap_temp_sensor_init);
  637. module_exit(omap_temp_sensor_exit);
  638. MODULE_DESCRIPTION("OMAP446X Temperature Sensor Driver");
  639. MODULE_LICENSE("GPL");
  640. MODULE_ALIAS("platform:" DRIVER_NAME);
  641. MODULE_AUTHOR("Texas Instruments Inc");