rcar_thermal.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * R-Car THS/TSC thermal sensor driver
  3. *
  4. * Copyright (C) 2012 Renesas Solutions Corp.
  5. * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  19. */
  20. #include <linux/delay.h>
  21. #include <linux/err.h>
  22. #include <linux/irq.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/io.h>
  25. #include <linux/module.h>
  26. #include <linux/of_device.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/pm_runtime.h>
  29. #include <linux/reboot.h>
  30. #include <linux/slab.h>
  31. #include <linux/spinlock.h>
  32. #include <linux/thermal.h>
  33. #include "thermal_hwmon.h"
  34. #define IDLE_INTERVAL 5000
  35. #define COMMON_STR 0x00
  36. #define COMMON_ENR 0x04
  37. #define COMMON_INTMSK 0x0c
  38. #define REG_POSNEG 0x20
  39. #define REG_FILONOFF 0x28
  40. #define REG_THSCR 0x2c
  41. #define REG_THSSR 0x30
  42. #define REG_INTCTRL 0x34
  43. /* THSCR */
  44. #define CPCTL (1 << 12)
  45. /* THSSR */
  46. #define CTEMP 0x3f
  47. struct rcar_thermal_common {
  48. void __iomem *base;
  49. struct device *dev;
  50. struct list_head head;
  51. spinlock_t lock;
  52. };
  53. struct rcar_thermal_chip {
  54. unsigned int use_of_thermal : 1;
  55. unsigned int has_filonoff : 1;
  56. unsigned int irq_per_ch : 1;
  57. unsigned int needs_suspend_resume : 1;
  58. unsigned int nirqs;
  59. };
  60. static const struct rcar_thermal_chip rcar_thermal = {
  61. .use_of_thermal = 0,
  62. .has_filonoff = 1,
  63. .irq_per_ch = 0,
  64. .needs_suspend_resume = 0,
  65. .nirqs = 1,
  66. };
  67. static const struct rcar_thermal_chip rcar_gen2_thermal = {
  68. .use_of_thermal = 1,
  69. .has_filonoff = 1,
  70. .irq_per_ch = 0,
  71. .needs_suspend_resume = 0,
  72. .nirqs = 1,
  73. };
  74. static const struct rcar_thermal_chip rcar_gen3_thermal = {
  75. .use_of_thermal = 1,
  76. .has_filonoff = 0,
  77. .irq_per_ch = 1,
  78. .needs_suspend_resume = 1,
  79. /*
  80. * The Gen3 chip has 3 interrupts, but this driver uses only 2
  81. * interrupts to detect a temperature change, rise or fall.
  82. */
  83. .nirqs = 2,
  84. };
  85. struct rcar_thermal_priv {
  86. void __iomem *base;
  87. struct rcar_thermal_common *common;
  88. struct thermal_zone_device *zone;
  89. const struct rcar_thermal_chip *chip;
  90. struct delayed_work work;
  91. struct mutex lock;
  92. struct list_head list;
  93. int id;
  94. u32 ctemp;
  95. };
  96. #define rcar_thermal_for_each_priv(pos, common) \
  97. list_for_each_entry(pos, &common->head, list)
  98. #define MCELSIUS(temp) ((temp) * 1000)
  99. #define rcar_zone_to_priv(zone) ((zone)->devdata)
  100. #define rcar_priv_to_dev(priv) ((priv)->common->dev)
  101. #define rcar_has_irq_support(priv) ((priv)->common->base)
  102. #define rcar_id_to_shift(priv) ((priv)->id * 8)
  103. static const struct of_device_id rcar_thermal_dt_ids[] = {
  104. {
  105. .compatible = "renesas,rcar-thermal",
  106. .data = &rcar_thermal,
  107. },
  108. {
  109. .compatible = "renesas,rcar-gen2-thermal",
  110. .data = &rcar_gen2_thermal,
  111. },
  112. {
  113. .compatible = "renesas,thermal-r8a77970",
  114. .data = &rcar_gen3_thermal,
  115. },
  116. {
  117. .compatible = "renesas,thermal-r8a77995",
  118. .data = &rcar_gen3_thermal,
  119. },
  120. {},
  121. };
  122. MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
  123. /*
  124. * basic functions
  125. */
  126. #define rcar_thermal_common_read(c, r) \
  127. _rcar_thermal_common_read(c, COMMON_ ##r)
  128. static u32 _rcar_thermal_common_read(struct rcar_thermal_common *common,
  129. u32 reg)
  130. {
  131. return ioread32(common->base + reg);
  132. }
  133. #define rcar_thermal_common_write(c, r, d) \
  134. _rcar_thermal_common_write(c, COMMON_ ##r, d)
  135. static void _rcar_thermal_common_write(struct rcar_thermal_common *common,
  136. u32 reg, u32 data)
  137. {
  138. iowrite32(data, common->base + reg);
  139. }
  140. #define rcar_thermal_common_bset(c, r, m, d) \
  141. _rcar_thermal_common_bset(c, COMMON_ ##r, m, d)
  142. static void _rcar_thermal_common_bset(struct rcar_thermal_common *common,
  143. u32 reg, u32 mask, u32 data)
  144. {
  145. u32 val;
  146. val = ioread32(common->base + reg);
  147. val &= ~mask;
  148. val |= (data & mask);
  149. iowrite32(val, common->base + reg);
  150. }
  151. #define rcar_thermal_read(p, r) _rcar_thermal_read(p, REG_ ##r)
  152. static u32 _rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg)
  153. {
  154. return ioread32(priv->base + reg);
  155. }
  156. #define rcar_thermal_write(p, r, d) _rcar_thermal_write(p, REG_ ##r, d)
  157. static void _rcar_thermal_write(struct rcar_thermal_priv *priv,
  158. u32 reg, u32 data)
  159. {
  160. iowrite32(data, priv->base + reg);
  161. }
  162. #define rcar_thermal_bset(p, r, m, d) _rcar_thermal_bset(p, REG_ ##r, m, d)
  163. static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
  164. u32 mask, u32 data)
  165. {
  166. u32 val;
  167. val = ioread32(priv->base + reg);
  168. val &= ~mask;
  169. val |= (data & mask);
  170. iowrite32(val, priv->base + reg);
  171. }
  172. /*
  173. * zone device functions
  174. */
  175. static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
  176. {
  177. struct device *dev = rcar_priv_to_dev(priv);
  178. int i;
  179. u32 ctemp, old, new;
  180. int ret = -EINVAL;
  181. mutex_lock(&priv->lock);
  182. /*
  183. * TSC decides a value of CPTAP automatically,
  184. * and this is the conditions which validate interrupt.
  185. */
  186. rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);
  187. ctemp = 0;
  188. old = ~0;
  189. for (i = 0; i < 128; i++) {
  190. /*
  191. * we need to wait 300us after changing comparator offset
  192. * to get stable temperature.
  193. * see "Usage Notes" on datasheet
  194. */
  195. udelay(300);
  196. new = rcar_thermal_read(priv, THSSR) & CTEMP;
  197. if (new == old) {
  198. ctemp = new;
  199. break;
  200. }
  201. old = new;
  202. }
  203. if (!ctemp) {
  204. dev_err(dev, "thermal sensor was broken\n");
  205. goto err_out_unlock;
  206. }
  207. /*
  208. * enable IRQ
  209. */
  210. if (rcar_has_irq_support(priv)) {
  211. if (priv->chip->has_filonoff)
  212. rcar_thermal_write(priv, FILONOFF, 0);
  213. /* enable Rising/Falling edge interrupt */
  214. rcar_thermal_write(priv, POSNEG, 0x1);
  215. rcar_thermal_write(priv, INTCTRL, (((ctemp - 0) << 8) |
  216. ((ctemp - 1) << 0)));
  217. }
  218. dev_dbg(dev, "thermal%d %d -> %d\n", priv->id, priv->ctemp, ctemp);
  219. priv->ctemp = ctemp;
  220. ret = 0;
  221. err_out_unlock:
  222. mutex_unlock(&priv->lock);
  223. return ret;
  224. }
  225. static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
  226. int *temp)
  227. {
  228. int tmp;
  229. int ret;
  230. ret = rcar_thermal_update_temp(priv);
  231. if (ret < 0)
  232. return ret;
  233. mutex_lock(&priv->lock);
  234. tmp = MCELSIUS((priv->ctemp * 5) - 65);
  235. mutex_unlock(&priv->lock);
  236. if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) {
  237. struct device *dev = rcar_priv_to_dev(priv);
  238. dev_err(dev, "it couldn't measure temperature correctly\n");
  239. return -EIO;
  240. }
  241. *temp = tmp;
  242. return 0;
  243. }
  244. static int rcar_thermal_of_get_temp(void *data, int *temp)
  245. {
  246. struct rcar_thermal_priv *priv = data;
  247. return rcar_thermal_get_current_temp(priv, temp);
  248. }
  249. static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
  250. {
  251. struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
  252. return rcar_thermal_get_current_temp(priv, temp);
  253. }
  254. static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
  255. int trip, enum thermal_trip_type *type)
  256. {
  257. struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
  258. struct device *dev = rcar_priv_to_dev(priv);
  259. /* see rcar_thermal_get_temp() */
  260. switch (trip) {
  261. case 0: /* +90 <= temp */
  262. *type = THERMAL_TRIP_CRITICAL;
  263. break;
  264. default:
  265. dev_err(dev, "rcar driver trip error\n");
  266. return -EINVAL;
  267. }
  268. return 0;
  269. }
  270. static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone,
  271. int trip, int *temp)
  272. {
  273. struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
  274. struct device *dev = rcar_priv_to_dev(priv);
  275. /* see rcar_thermal_get_temp() */
  276. switch (trip) {
  277. case 0: /* +90 <= temp */
  278. *temp = MCELSIUS(90);
  279. break;
  280. default:
  281. dev_err(dev, "rcar driver trip error\n");
  282. return -EINVAL;
  283. }
  284. return 0;
  285. }
  286. static int rcar_thermal_notify(struct thermal_zone_device *zone,
  287. int trip, enum thermal_trip_type type)
  288. {
  289. struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
  290. struct device *dev = rcar_priv_to_dev(priv);
  291. switch (type) {
  292. case THERMAL_TRIP_CRITICAL:
  293. /* FIXME */
  294. dev_warn(dev, "Thermal reached to critical temperature\n");
  295. break;
  296. default:
  297. break;
  298. }
  299. return 0;
  300. }
  301. static const struct thermal_zone_of_device_ops rcar_thermal_zone_of_ops = {
  302. .get_temp = rcar_thermal_of_get_temp,
  303. };
  304. static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
  305. .get_temp = rcar_thermal_get_temp,
  306. .get_trip_type = rcar_thermal_get_trip_type,
  307. .get_trip_temp = rcar_thermal_get_trip_temp,
  308. .notify = rcar_thermal_notify,
  309. };
  310. /*
  311. * interrupt
  312. */
  313. #define rcar_thermal_irq_enable(p) _rcar_thermal_irq_ctrl(p, 1)
  314. #define rcar_thermal_irq_disable(p) _rcar_thermal_irq_ctrl(p, 0)
  315. static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
  316. {
  317. struct rcar_thermal_common *common = priv->common;
  318. unsigned long flags;
  319. u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */
  320. if (!rcar_has_irq_support(priv))
  321. return;
  322. spin_lock_irqsave(&common->lock, flags);
  323. rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask);
  324. spin_unlock_irqrestore(&common->lock, flags);
  325. }
  326. static void rcar_thermal_work(struct work_struct *work)
  327. {
  328. struct rcar_thermal_priv *priv;
  329. int cctemp, nctemp;
  330. int ret;
  331. priv = container_of(work, struct rcar_thermal_priv, work.work);
  332. ret = rcar_thermal_get_current_temp(priv, &cctemp);
  333. if (ret < 0)
  334. return;
  335. ret = rcar_thermal_update_temp(priv);
  336. if (ret < 0)
  337. return;
  338. rcar_thermal_irq_enable(priv);
  339. ret = rcar_thermal_get_current_temp(priv, &nctemp);
  340. if (ret < 0)
  341. return;
  342. if (nctemp != cctemp)
  343. thermal_zone_device_update(priv->zone,
  344. THERMAL_EVENT_UNSPECIFIED);
  345. }
  346. static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
  347. {
  348. struct device *dev = rcar_priv_to_dev(priv);
  349. status = (status >> rcar_id_to_shift(priv)) & 0x3;
  350. if (status) {
  351. dev_dbg(dev, "thermal%d %s%s\n",
  352. priv->id,
  353. (status & 0x2) ? "Rising " : "",
  354. (status & 0x1) ? "Falling" : "");
  355. }
  356. return status;
  357. }
  358. static irqreturn_t rcar_thermal_irq(int irq, void *data)
  359. {
  360. struct rcar_thermal_common *common = data;
  361. struct rcar_thermal_priv *priv;
  362. unsigned long flags;
  363. u32 status, mask;
  364. spin_lock_irqsave(&common->lock, flags);
  365. mask = rcar_thermal_common_read(common, INTMSK);
  366. status = rcar_thermal_common_read(common, STR);
  367. rcar_thermal_common_write(common, STR, 0x000F0F0F & mask);
  368. spin_unlock_irqrestore(&common->lock, flags);
  369. status = status & ~mask;
  370. /*
  371. * check the status
  372. */
  373. rcar_thermal_for_each_priv(priv, common) {
  374. if (rcar_thermal_had_changed(priv, status)) {
  375. rcar_thermal_irq_disable(priv);
  376. queue_delayed_work(system_freezable_wq, &priv->work,
  377. msecs_to_jiffies(300));
  378. }
  379. }
  380. return IRQ_HANDLED;
  381. }
  382. /*
  383. * platform functions
  384. */
  385. static int rcar_thermal_remove(struct platform_device *pdev)
  386. {
  387. struct rcar_thermal_common *common = platform_get_drvdata(pdev);
  388. struct device *dev = &pdev->dev;
  389. struct rcar_thermal_priv *priv;
  390. rcar_thermal_for_each_priv(priv, common) {
  391. rcar_thermal_irq_disable(priv);
  392. cancel_delayed_work_sync(&priv->work);
  393. if (priv->chip->use_of_thermal)
  394. thermal_remove_hwmon_sysfs(priv->zone);
  395. else
  396. thermal_zone_device_unregister(priv->zone);
  397. }
  398. pm_runtime_put(dev);
  399. pm_runtime_disable(dev);
  400. return 0;
  401. }
  402. static int rcar_thermal_probe(struct platform_device *pdev)
  403. {
  404. struct rcar_thermal_common *common;
  405. struct rcar_thermal_priv *priv;
  406. struct device *dev = &pdev->dev;
  407. struct resource *res, *irq;
  408. const struct rcar_thermal_chip *chip = of_device_get_match_data(dev);
  409. int mres = 0;
  410. int i;
  411. int ret = -ENODEV;
  412. int idle = IDLE_INTERVAL;
  413. u32 enr_bits = 0;
  414. common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
  415. if (!common)
  416. return -ENOMEM;
  417. platform_set_drvdata(pdev, common);
  418. INIT_LIST_HEAD(&common->head);
  419. spin_lock_init(&common->lock);
  420. common->dev = dev;
  421. pm_runtime_enable(dev);
  422. pm_runtime_get_sync(dev);
  423. for (i = 0; i < chip->nirqs; i++) {
  424. irq = platform_get_resource(pdev, IORESOURCE_IRQ, i);
  425. if (!irq)
  426. continue;
  427. if (!common->base) {
  428. /*
  429. * platform has IRQ support.
  430. * Then, driver uses common registers
  431. * rcar_has_irq_support() will be enabled
  432. */
  433. res = platform_get_resource(pdev, IORESOURCE_MEM,
  434. mres++);
  435. common->base = devm_ioremap_resource(dev, res);
  436. if (IS_ERR(common->base))
  437. return PTR_ERR(common->base);
  438. idle = 0; /* polling delay is not needed */
  439. }
  440. ret = devm_request_irq(dev, irq->start, rcar_thermal_irq,
  441. IRQF_SHARED, dev_name(dev), common);
  442. if (ret) {
  443. dev_err(dev, "irq request failed\n ");
  444. goto error_unregister;
  445. }
  446. /* update ENR bits */
  447. if (chip->irq_per_ch)
  448. enr_bits |= 1 << i;
  449. }
  450. for (i = 0;; i++) {
  451. res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
  452. if (!res)
  453. break;
  454. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  455. if (!priv) {
  456. ret = -ENOMEM;
  457. goto error_unregister;
  458. }
  459. priv->base = devm_ioremap_resource(dev, res);
  460. if (IS_ERR(priv->base)) {
  461. ret = PTR_ERR(priv->base);
  462. goto error_unregister;
  463. }
  464. priv->common = common;
  465. priv->id = i;
  466. priv->chip = chip;
  467. mutex_init(&priv->lock);
  468. INIT_LIST_HEAD(&priv->list);
  469. INIT_DELAYED_WORK(&priv->work, rcar_thermal_work);
  470. ret = rcar_thermal_update_temp(priv);
  471. if (ret < 0)
  472. goto error_unregister;
  473. if (chip->use_of_thermal)
  474. priv->zone = devm_thermal_zone_of_sensor_register(
  475. dev, i, priv,
  476. &rcar_thermal_zone_of_ops);
  477. else
  478. priv->zone = thermal_zone_device_register(
  479. "rcar_thermal",
  480. 1, 0, priv,
  481. &rcar_thermal_zone_ops, NULL, 0,
  482. idle);
  483. if (IS_ERR(priv->zone)) {
  484. dev_err(dev, "can't register thermal zone\n");
  485. ret = PTR_ERR(priv->zone);
  486. priv->zone = NULL;
  487. goto error_unregister;
  488. }
  489. if (chip->use_of_thermal) {
  490. /*
  491. * thermal_zone doesn't enable hwmon as default,
  492. * but, enable it here to keep compatible
  493. */
  494. priv->zone->tzp->no_hwmon = false;
  495. ret = thermal_add_hwmon_sysfs(priv->zone);
  496. if (ret)
  497. goto error_unregister;
  498. }
  499. rcar_thermal_irq_enable(priv);
  500. list_move_tail(&priv->list, &common->head);
  501. /* update ENR bits */
  502. if (!chip->irq_per_ch)
  503. enr_bits |= 3 << (i * 8);
  504. }
  505. if (common->base && enr_bits)
  506. rcar_thermal_common_write(common, ENR, enr_bits);
  507. dev_info(dev, "%d sensor probed\n", i);
  508. return 0;
  509. error_unregister:
  510. rcar_thermal_remove(pdev);
  511. return ret;
  512. }
  513. #ifdef CONFIG_PM_SLEEP
  514. static int rcar_thermal_suspend(struct device *dev)
  515. {
  516. struct rcar_thermal_common *common = dev_get_drvdata(dev);
  517. struct rcar_thermal_priv *priv = list_first_entry(&common->head,
  518. typeof(*priv), list);
  519. if (priv->chip->needs_suspend_resume) {
  520. rcar_thermal_common_write(common, ENR, 0);
  521. rcar_thermal_irq_disable(priv);
  522. rcar_thermal_bset(priv, THSCR, CPCTL, 0);
  523. }
  524. return 0;
  525. }
  526. static int rcar_thermal_resume(struct device *dev)
  527. {
  528. struct rcar_thermal_common *common = dev_get_drvdata(dev);
  529. struct rcar_thermal_priv *priv = list_first_entry(&common->head,
  530. typeof(*priv), list);
  531. int ret;
  532. if (priv->chip->needs_suspend_resume) {
  533. ret = rcar_thermal_update_temp(priv);
  534. if (ret < 0)
  535. return ret;
  536. rcar_thermal_irq_enable(priv);
  537. rcar_thermal_common_write(common, ENR, 0x03);
  538. }
  539. return 0;
  540. }
  541. #endif
  542. static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend,
  543. rcar_thermal_resume);
  544. static struct platform_driver rcar_thermal_driver = {
  545. .driver = {
  546. .name = "rcar_thermal",
  547. .pm = &rcar_thermal_pm_ops,
  548. .of_match_table = rcar_thermal_dt_ids,
  549. },
  550. .probe = rcar_thermal_probe,
  551. .remove = rcar_thermal_remove,
  552. };
  553. module_platform_driver(rcar_thermal_driver);
  554. MODULE_LICENSE("GPL");
  555. MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
  556. MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");