exynos_tmu.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. /*
  2. * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
  3. *
  4. * Copyright (C) 2014 Samsung Electronics
  5. * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  6. * Lukasz Majewski <l.majewski@samsung.com>
  7. *
  8. * Copyright (C) 2011 Samsung Electronics
  9. * Donggeun Kim <dg77.kim@samsung.com>
  10. * Amit Daniel Kachhap <amit.kachhap@linaro.org>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. *
  26. */
  27. #include <linux/clk.h>
  28. #include <linux/io.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/module.h>
  31. #include <linux/of_device.h>
  32. #include <linux/of_address.h>
  33. #include <linux/of_irq.h>
  34. #include <linux/platform_device.h>
  35. #include <linux/regulator/consumer.h>
  36. #include <dt-bindings/thermal/thermal_exynos.h>
  37. #include "../thermal_core.h"
  38. /* Exynos generic registers */
  39. #define EXYNOS_TMU_REG_TRIMINFO 0x0
  40. #define EXYNOS_TMU_REG_CONTROL 0x20
  41. #define EXYNOS_TMU_REG_STATUS 0x28
  42. #define EXYNOS_TMU_REG_CURRENT_TEMP 0x40
  43. #define EXYNOS_TMU_REG_INTEN 0x70
  44. #define EXYNOS_TMU_REG_INTSTAT 0x74
  45. #define EXYNOS_TMU_REG_INTCLEAR 0x78
  46. #define EXYNOS_TMU_TEMP_MASK 0xff
  47. #define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
  48. #define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f
  49. #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
  50. #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8
  51. #define EXYNOS_TMU_CORE_EN_SHIFT 0
  52. /* Exynos3250 specific registers */
  53. #define EXYNOS_TMU_TRIMINFO_CON1 0x10
  54. /* Exynos4210 specific registers */
  55. #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
  56. #define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
  57. /* Exynos5250, Exynos4412, Exynos3250 specific registers */
  58. #define EXYNOS_TMU_TRIMINFO_CON2 0x14
  59. #define EXYNOS_THD_TEMP_RISE 0x50
  60. #define EXYNOS_THD_TEMP_FALL 0x54
  61. #define EXYNOS_EMUL_CON 0x80
  62. #define EXYNOS_TRIMINFO_RELOAD_ENABLE 1
  63. #define EXYNOS_TRIMINFO_25_SHIFT 0
  64. #define EXYNOS_TRIMINFO_85_SHIFT 8
  65. #define EXYNOS_TMU_TRIP_MODE_SHIFT 13
  66. #define EXYNOS_TMU_TRIP_MODE_MASK 0x7
  67. #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12
  68. #define EXYNOS_TMU_INTEN_RISE0_SHIFT 0
  69. #define EXYNOS_TMU_INTEN_FALL0_SHIFT 16
  70. #define EXYNOS_EMUL_TIME 0x57F0
  71. #define EXYNOS_EMUL_TIME_MASK 0xffff
  72. #define EXYNOS_EMUL_TIME_SHIFT 16
  73. #define EXYNOS_EMUL_DATA_SHIFT 8
  74. #define EXYNOS_EMUL_DATA_MASK 0xFF
  75. #define EXYNOS_EMUL_ENABLE 0x1
  76. /* Exynos5260 specific */
  77. #define EXYNOS5260_TMU_REG_INTEN 0xC0
  78. #define EXYNOS5260_TMU_REG_INTSTAT 0xC4
  79. #define EXYNOS5260_TMU_REG_INTCLEAR 0xC8
  80. #define EXYNOS5260_EMUL_CON 0x100
  81. /* Exynos4412 specific */
  82. #define EXYNOS4412_MUX_ADDR_VALUE 6
  83. #define EXYNOS4412_MUX_ADDR_SHIFT 20
  84. /* Exynos5433 specific registers */
  85. #define EXYNOS5433_THD_TEMP_RISE3_0 0x050
  86. #define EXYNOS5433_THD_TEMP_RISE7_4 0x054
  87. #define EXYNOS5433_THD_TEMP_FALL3_0 0x060
  88. #define EXYNOS5433_THD_TEMP_FALL7_4 0x064
  89. #define EXYNOS5433_TMU_REG_INTEN 0x0c0
  90. #define EXYNOS5433_TMU_REG_INTPEND 0x0c8
  91. #define EXYNOS5433_TMU_EMUL_CON 0x110
  92. #define EXYNOS5433_TMU_PD_DET_EN 0x130
  93. #define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16
  94. #define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23
  95. #define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \
  96. (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
  97. #define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23)
  98. #define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0
  99. #define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1
  100. #define EXYNOS5433_PD_DET_EN 1
  101. #define EXYNOS5433_G3D_BASE 0x10070000
  102. /* Exynos7 specific registers */
  103. #define EXYNOS7_THD_TEMP_RISE7_6 0x50
  104. #define EXYNOS7_THD_TEMP_FALL7_6 0x60
  105. #define EXYNOS7_TMU_REG_INTEN 0x110
  106. #define EXYNOS7_TMU_REG_INTPEND 0x118
  107. #define EXYNOS7_TMU_REG_EMUL_CON 0x160
  108. #define EXYNOS7_TMU_TEMP_MASK 0x1ff
  109. #define EXYNOS7_PD_DET_EN_SHIFT 23
  110. #define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0
  111. #define EXYNOS7_EMUL_DATA_SHIFT 7
  112. #define EXYNOS7_EMUL_DATA_MASK 0x1ff
  113. #define EXYNOS_FIRST_POINT_TRIM 25
  114. #define EXYNOS_SECOND_POINT_TRIM 85
  115. #define EXYNOS_NOISE_CANCEL_MODE 4
  116. #define MCELSIUS 1000
  117. enum soc_type {
  118. SOC_ARCH_EXYNOS3250 = 1,
  119. SOC_ARCH_EXYNOS4210,
  120. SOC_ARCH_EXYNOS4412,
  121. SOC_ARCH_EXYNOS5250,
  122. SOC_ARCH_EXYNOS5260,
  123. SOC_ARCH_EXYNOS5420,
  124. SOC_ARCH_EXYNOS5420_TRIMINFO,
  125. SOC_ARCH_EXYNOS5433,
  126. SOC_ARCH_EXYNOS7,
  127. };
  128. /**
  129. * struct exynos_tmu_data : A structure to hold the private data of the TMU
  130. driver
  131. * @id: identifier of the one instance of the TMU controller.
  132. * @base: base address of the single instance of the TMU controller.
  133. * @base_second: base address of the common registers of the TMU controller.
  134. * @irq: irq number of the TMU controller.
  135. * @soc: id of the SOC type.
  136. * @irq_work: pointer to the irq work structure.
  137. * @lock: lock to implement synchronization.
  138. * @clk: pointer to the clock structure.
  139. * @clk_sec: pointer to the clock structure for accessing the base_second.
  140. * @sclk: pointer to the clock structure for accessing the tmu special clk.
  141. * @cal_type: calibration type for temperature
  142. * @efuse_value: SoC defined fuse value
  143. * @min_efuse_value: minimum valid trimming data
  144. * @max_efuse_value: maximum valid trimming data
  145. * @temp_error1: fused value of the first point trim.
  146. * @temp_error2: fused value of the second point trim.
  147. * @gain: gain of amplifier in the positive-TC generator block
  148. * 0 < gain <= 15
  149. * @reference_voltage: reference voltage of amplifier
  150. * in the positive-TC generator block
  151. * 0 < reference_voltage <= 31
  152. * @regulator: pointer to the TMU regulator structure.
  153. * @reg_conf: pointer to structure to register with core thermal.
  154. * @ntrip: number of supported trip points.
  155. * @enabled: current status of TMU device
  156. * @tmu_initialize: SoC specific TMU initialization method
  157. * @tmu_control: SoC specific TMU control method
  158. * @tmu_read: SoC specific TMU temperature read method
  159. * @tmu_set_emulation: SoC specific TMU emulation setting method
  160. * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
  161. */
  162. struct exynos_tmu_data {
  163. int id;
  164. void __iomem *base;
  165. void __iomem *base_second;
  166. int irq;
  167. enum soc_type soc;
  168. struct work_struct irq_work;
  169. struct mutex lock;
  170. struct clk *clk, *clk_sec, *sclk;
  171. u32 cal_type;
  172. u32 efuse_value;
  173. u32 min_efuse_value;
  174. u32 max_efuse_value;
  175. u16 temp_error1, temp_error2;
  176. u8 gain;
  177. u8 reference_voltage;
  178. struct regulator *regulator;
  179. struct thermal_zone_device *tzd;
  180. unsigned int ntrip;
  181. bool enabled;
  182. void (*tmu_set_trip_temp)(struct exynos_tmu_data *data, int trip,
  183. u8 temp);
  184. void (*tmu_set_trip_hyst)(struct exynos_tmu_data *data, int trip,
  185. u8 temp, u8 hyst);
  186. void (*tmu_initialize)(struct platform_device *pdev);
  187. void (*tmu_control)(struct platform_device *pdev, bool on);
  188. int (*tmu_read)(struct exynos_tmu_data *data);
  189. void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp);
  190. void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
  191. };
  192. /*
  193. * TMU treats temperature as a mapped temperature code.
  194. * The temperature is converted differently depending on the calibration type.
  195. */
  196. static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
  197. {
  198. if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
  199. return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM;
  200. return (temp - EXYNOS_FIRST_POINT_TRIM) *
  201. (data->temp_error2 - data->temp_error1) /
  202. (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) +
  203. data->temp_error1;
  204. }
  205. /*
  206. * Calculate a temperature value from a temperature code.
  207. * The unit of the temperature is degree Celsius.
  208. */
  209. static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
  210. {
  211. if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
  212. return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM;
  213. return (temp_code - data->temp_error1) *
  214. (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) /
  215. (data->temp_error2 - data->temp_error1) +
  216. EXYNOS_FIRST_POINT_TRIM;
  217. }
  218. static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
  219. {
  220. u16 tmu_temp_mask =
  221. (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
  222. : EXYNOS_TMU_TEMP_MASK;
  223. data->temp_error1 = trim_info & tmu_temp_mask;
  224. data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
  225. EXYNOS_TMU_TEMP_MASK);
  226. if (!data->temp_error1 ||
  227. (data->min_efuse_value > data->temp_error1) ||
  228. (data->temp_error1 > data->max_efuse_value))
  229. data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK;
  230. if (!data->temp_error2)
  231. data->temp_error2 =
  232. (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
  233. EXYNOS_TMU_TEMP_MASK;
  234. }
  235. static int exynos_tmu_initialize(struct platform_device *pdev)
  236. {
  237. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  238. struct thermal_zone_device *tzd = data->tzd;
  239. const struct thermal_trip * const trips =
  240. of_thermal_get_trip_points(tzd);
  241. unsigned int status;
  242. int ret = 0, temp, hyst;
  243. if (!trips) {
  244. dev_err(&pdev->dev,
  245. "Cannot get trip points from device tree!\n");
  246. return -ENODEV;
  247. }
  248. if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */
  249. ret = tzd->ops->get_crit_temp(tzd, &temp);
  250. if (ret) {
  251. dev_err(&pdev->dev,
  252. "No CRITICAL trip point defined in device tree!\n");
  253. goto out;
  254. }
  255. if (of_thermal_get_ntrips(tzd) > data->ntrip) {
  256. dev_info(&pdev->dev,
  257. "More trip points than supported by this TMU.\n");
  258. dev_info(&pdev->dev,
  259. "%d trip points should be configured in polling mode.\n",
  260. (of_thermal_get_ntrips(tzd) - data->ntrip));
  261. }
  262. mutex_lock(&data->lock);
  263. clk_enable(data->clk);
  264. if (!IS_ERR(data->clk_sec))
  265. clk_enable(data->clk_sec);
  266. status = readb(data->base + EXYNOS_TMU_REG_STATUS);
  267. if (!status) {
  268. ret = -EBUSY;
  269. } else {
  270. int i, ntrips =
  271. min_t(int, of_thermal_get_ntrips(tzd), data->ntrip);
  272. data->tmu_initialize(pdev);
  273. /* Write temperature code for rising and falling threshold */
  274. for (i = 0; i < ntrips; i++) {
  275. /* Write temperature code for rising threshold */
  276. ret = tzd->ops->get_trip_temp(tzd, i, &temp);
  277. if (ret)
  278. goto err;
  279. temp /= MCELSIUS;
  280. data->tmu_set_trip_temp(data, i, temp);
  281. /* Write temperature code for falling threshold */
  282. ret = tzd->ops->get_trip_hyst(tzd, i, &hyst);
  283. if (ret)
  284. goto err;
  285. hyst /= MCELSIUS;
  286. data->tmu_set_trip_hyst(data, i, temp, hyst);
  287. }
  288. data->tmu_clear_irqs(data);
  289. }
  290. err:
  291. clk_disable(data->clk);
  292. mutex_unlock(&data->lock);
  293. if (!IS_ERR(data->clk_sec))
  294. clk_disable(data->clk_sec);
  295. out:
  296. return ret;
  297. }
  298. static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
  299. {
  300. if (data->soc == SOC_ARCH_EXYNOS4412 ||
  301. data->soc == SOC_ARCH_EXYNOS3250)
  302. con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
  303. con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
  304. con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
  305. con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
  306. con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
  307. con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
  308. con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
  309. return con;
  310. }
  311. static void exynos_tmu_control(struct platform_device *pdev, bool on)
  312. {
  313. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  314. mutex_lock(&data->lock);
  315. clk_enable(data->clk);
  316. data->tmu_control(pdev, on);
  317. data->enabled = on;
  318. clk_disable(data->clk);
  319. mutex_unlock(&data->lock);
  320. }
  321. static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
  322. int trip, u8 temp)
  323. {
  324. const struct thermal_trip * const trips =
  325. of_thermal_get_trip_points(data->tzd);
  326. u8 ref, th_code;
  327. ref = trips[0].temperature / MCELSIUS;
  328. if (trip == 0) {
  329. th_code = temp_to_code(data, ref);
  330. writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
  331. }
  332. temp -= ref;
  333. writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4);
  334. }
  335. /* failing thresholds are not supported on Exynos4210 */
  336. static void exynos4210_tmu_set_trip_hyst(struct exynos_tmu_data *data,
  337. int trip, u8 temp, u8 hyst)
  338. {
  339. }
  340. static void exynos4210_tmu_initialize(struct platform_device *pdev)
  341. {
  342. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  343. sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
  344. }
  345. static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data,
  346. int trip, u8 temp)
  347. {
  348. u32 th, con;
  349. th = readl(data->base + EXYNOS_THD_TEMP_RISE);
  350. th &= ~(0xff << 8 * trip);
  351. th |= temp_to_code(data, temp) << 8 * trip;
  352. writel(th, data->base + EXYNOS_THD_TEMP_RISE);
  353. if (trip == 3) {
  354. con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
  355. con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
  356. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  357. }
  358. }
  359. static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data,
  360. int trip, u8 temp, u8 hyst)
  361. {
  362. u32 th;
  363. th = readl(data->base + EXYNOS_THD_TEMP_FALL);
  364. th &= ~(0xff << 8 * trip);
  365. if (hyst)
  366. th |= temp_to_code(data, temp - hyst) << 8 * trip;
  367. writel(th, data->base + EXYNOS_THD_TEMP_FALL);
  368. }
  369. static void exynos4412_tmu_initialize(struct platform_device *pdev)
  370. {
  371. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  372. unsigned int trim_info, ctrl;
  373. if (data->soc == SOC_ARCH_EXYNOS3250 ||
  374. data->soc == SOC_ARCH_EXYNOS4412 ||
  375. data->soc == SOC_ARCH_EXYNOS5250) {
  376. if (data->soc == SOC_ARCH_EXYNOS3250) {
  377. ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
  378. ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
  379. writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
  380. }
  381. ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
  382. ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
  383. writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
  384. }
  385. /* On exynos5420 the triminfo register is in the shared space */
  386. if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
  387. trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
  388. else
  389. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  390. sanitize_temp_error(data, trim_info);
  391. }
  392. static void exynos5433_tmu_set_trip_temp(struct exynos_tmu_data *data,
  393. int trip, u8 temp)
  394. {
  395. unsigned int reg_off, j;
  396. u32 th;
  397. if (trip > 3) {
  398. reg_off = EXYNOS5433_THD_TEMP_RISE7_4;
  399. j = trip - 4;
  400. } else {
  401. reg_off = EXYNOS5433_THD_TEMP_RISE3_0;
  402. j = trip;
  403. }
  404. th = readl(data->base + reg_off);
  405. th &= ~(0xff << j * 8);
  406. th |= (temp_to_code(data, temp) << j * 8);
  407. writel(th, data->base + reg_off);
  408. }
  409. static void exynos5433_tmu_set_trip_hyst(struct exynos_tmu_data *data,
  410. int trip, u8 temp, u8 hyst)
  411. {
  412. unsigned int reg_off, j;
  413. u32 th;
  414. if (trip > 3) {
  415. reg_off = EXYNOS5433_THD_TEMP_FALL7_4;
  416. j = trip - 4;
  417. } else {
  418. reg_off = EXYNOS5433_THD_TEMP_FALL3_0;
  419. j = trip;
  420. }
  421. th = readl(data->base + reg_off);
  422. th &= ~(0xff << j * 8);
  423. th |= (temp_to_code(data, temp - hyst) << j * 8);
  424. writel(th, data->base + reg_off);
  425. }
  426. static void exynos5433_tmu_initialize(struct platform_device *pdev)
  427. {
  428. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  429. unsigned int trim_info;
  430. int sensor_id, cal_type;
  431. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  432. sanitize_temp_error(data, trim_info);
  433. /* Read the temperature sensor id */
  434. sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
  435. >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
  436. dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id);
  437. /* Read the calibration mode */
  438. writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
  439. cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
  440. >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT;
  441. switch (cal_type) {
  442. case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
  443. data->cal_type = TYPE_TWO_POINT_TRIMMING;
  444. break;
  445. case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
  446. default:
  447. data->cal_type = TYPE_ONE_POINT_TRIMMING;
  448. break;
  449. }
  450. dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
  451. cal_type ? 2 : 1);
  452. }
  453. static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data,
  454. int trip, u8 temp)
  455. {
  456. unsigned int reg_off, bit_off;
  457. u32 th;
  458. reg_off = ((7 - trip) / 2) * 4;
  459. bit_off = ((8 - trip) % 2);
  460. th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
  461. th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
  462. th |= temp_to_code(data, temp) << (16 * bit_off);
  463. writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
  464. }
  465. static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data,
  466. int trip, u8 temp, u8 hyst)
  467. {
  468. unsigned int reg_off, bit_off;
  469. u32 th;
  470. reg_off = ((7 - trip) / 2) * 4;
  471. bit_off = ((8 - trip) % 2);
  472. th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
  473. th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
  474. th |= temp_to_code(data, temp - hyst) << (16 * bit_off);
  475. writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
  476. }
  477. static void exynos7_tmu_initialize(struct platform_device *pdev)
  478. {
  479. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  480. unsigned int trim_info;
  481. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  482. sanitize_temp_error(data, trim_info);
  483. }
  484. static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
  485. {
  486. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  487. struct thermal_zone_device *tz = data->tzd;
  488. unsigned int con, interrupt_en = 0, i;
  489. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  490. if (on) {
  491. for (i = 0; i < data->ntrip; i++) {
  492. if (!of_thermal_is_trip_valid(tz, i))
  493. continue;
  494. interrupt_en |=
  495. (1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4));
  496. }
  497. if (data->soc != SOC_ARCH_EXYNOS4210)
  498. interrupt_en |=
  499. interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
  500. con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
  501. } else {
  502. con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
  503. }
  504. writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
  505. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  506. }
  507. static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
  508. {
  509. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  510. struct thermal_zone_device *tz = data->tzd;
  511. unsigned int con, interrupt_en = 0, pd_det_en, i;
  512. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  513. if (on) {
  514. for (i = 0; i < data->ntrip; i++) {
  515. if (!of_thermal_is_trip_valid(tz, i))
  516. continue;
  517. interrupt_en |=
  518. (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
  519. }
  520. interrupt_en |=
  521. interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
  522. con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
  523. } else
  524. con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
  525. pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
  526. writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
  527. writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN);
  528. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  529. }
  530. static void exynos7_tmu_control(struct platform_device *pdev, bool on)
  531. {
  532. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  533. struct thermal_zone_device *tz = data->tzd;
  534. unsigned int con, interrupt_en = 0, i;
  535. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  536. if (on) {
  537. for (i = 0; i < data->ntrip; i++) {
  538. if (!of_thermal_is_trip_valid(tz, i))
  539. continue;
  540. interrupt_en |=
  541. (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
  542. }
  543. interrupt_en |=
  544. interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
  545. con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
  546. con |= (1 << EXYNOS7_PD_DET_EN_SHIFT);
  547. } else {
  548. con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
  549. con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT);
  550. }
  551. writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN);
  552. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  553. }
  554. static int exynos_get_temp(void *p, int *temp)
  555. {
  556. struct exynos_tmu_data *data = p;
  557. int value, ret = 0;
  558. if (!data || !data->tmu_read || !data->enabled)
  559. return -EINVAL;
  560. else if (!data->enabled)
  561. /*
  562. * Called too early, probably
  563. * from thermal_zone_of_sensor_register().
  564. */
  565. return -EAGAIN;
  566. mutex_lock(&data->lock);
  567. clk_enable(data->clk);
  568. value = data->tmu_read(data);
  569. if (value < 0)
  570. ret = value;
  571. else
  572. *temp = code_to_temp(data, value) * MCELSIUS;
  573. clk_disable(data->clk);
  574. mutex_unlock(&data->lock);
  575. return ret;
  576. }
  577. #ifdef CONFIG_THERMAL_EMULATION
  578. static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
  579. int temp)
  580. {
  581. if (temp) {
  582. temp /= MCELSIUS;
  583. val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
  584. val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
  585. if (data->soc == SOC_ARCH_EXYNOS7) {
  586. val &= ~(EXYNOS7_EMUL_DATA_MASK <<
  587. EXYNOS7_EMUL_DATA_SHIFT);
  588. val |= (temp_to_code(data, temp) <<
  589. EXYNOS7_EMUL_DATA_SHIFT) |
  590. EXYNOS_EMUL_ENABLE;
  591. } else {
  592. val &= ~(EXYNOS_EMUL_DATA_MASK <<
  593. EXYNOS_EMUL_DATA_SHIFT);
  594. val |= (temp_to_code(data, temp) <<
  595. EXYNOS_EMUL_DATA_SHIFT) |
  596. EXYNOS_EMUL_ENABLE;
  597. }
  598. } else {
  599. val &= ~EXYNOS_EMUL_ENABLE;
  600. }
  601. return val;
  602. }
  603. static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
  604. int temp)
  605. {
  606. unsigned int val;
  607. u32 emul_con;
  608. if (data->soc == SOC_ARCH_EXYNOS5260)
  609. emul_con = EXYNOS5260_EMUL_CON;
  610. else if (data->soc == SOC_ARCH_EXYNOS5433)
  611. emul_con = EXYNOS5433_TMU_EMUL_CON;
  612. else if (data->soc == SOC_ARCH_EXYNOS7)
  613. emul_con = EXYNOS7_TMU_REG_EMUL_CON;
  614. else
  615. emul_con = EXYNOS_EMUL_CON;
  616. val = readl(data->base + emul_con);
  617. val = get_emul_con_reg(data, val, temp);
  618. writel(val, data->base + emul_con);
  619. }
  620. static int exynos_tmu_set_emulation(void *drv_data, int temp)
  621. {
  622. struct exynos_tmu_data *data = drv_data;
  623. int ret = -EINVAL;
  624. if (data->soc == SOC_ARCH_EXYNOS4210)
  625. goto out;
  626. if (temp && temp < MCELSIUS)
  627. goto out;
  628. mutex_lock(&data->lock);
  629. clk_enable(data->clk);
  630. data->tmu_set_emulation(data, temp);
  631. clk_disable(data->clk);
  632. mutex_unlock(&data->lock);
  633. return 0;
  634. out:
  635. return ret;
  636. }
  637. #else
  638. #define exynos4412_tmu_set_emulation NULL
  639. static int exynos_tmu_set_emulation(void *drv_data, int temp)
  640. { return -EINVAL; }
  641. #endif /* CONFIG_THERMAL_EMULATION */
  642. static int exynos4210_tmu_read(struct exynos_tmu_data *data)
  643. {
  644. int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
  645. /* "temp_code" should range between 75 and 175 */
  646. return (ret < 75 || ret > 175) ? -ENODATA : ret;
  647. }
  648. static int exynos4412_tmu_read(struct exynos_tmu_data *data)
  649. {
  650. return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
  651. }
  652. static int exynos7_tmu_read(struct exynos_tmu_data *data)
  653. {
  654. return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) &
  655. EXYNOS7_TMU_TEMP_MASK;
  656. }
  657. static void exynos_tmu_work(struct work_struct *work)
  658. {
  659. struct exynos_tmu_data *data = container_of(work,
  660. struct exynos_tmu_data, irq_work);
  661. thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
  662. mutex_lock(&data->lock);
  663. clk_enable(data->clk);
  664. /* TODO: take action based on particular interrupt */
  665. data->tmu_clear_irqs(data);
  666. clk_disable(data->clk);
  667. mutex_unlock(&data->lock);
  668. enable_irq(data->irq);
  669. }
  670. static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
  671. {
  672. unsigned int val_irq;
  673. u32 tmu_intstat, tmu_intclear;
  674. if (data->soc == SOC_ARCH_EXYNOS5260) {
  675. tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
  676. tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
  677. } else if (data->soc == SOC_ARCH_EXYNOS7) {
  678. tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
  679. tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
  680. } else if (data->soc == SOC_ARCH_EXYNOS5433) {
  681. tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
  682. tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
  683. } else {
  684. tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
  685. tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
  686. }
  687. val_irq = readl(data->base + tmu_intstat);
  688. /*
  689. * Clear the interrupts. Please note that the documentation for
  690. * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
  691. * states that INTCLEAR register has a different placing of bits
  692. * responsible for FALL IRQs than INTSTAT register. Exynos5420
  693. * and Exynos5440 documentation is correct (Exynos4210 doesn't
  694. * support FALL IRQs at all).
  695. */
  696. writel(val_irq, data->base + tmu_intclear);
  697. }
  698. static irqreturn_t exynos_tmu_irq(int irq, void *id)
  699. {
  700. struct exynos_tmu_data *data = id;
  701. disable_irq_nosync(irq);
  702. schedule_work(&data->irq_work);
  703. return IRQ_HANDLED;
  704. }
  705. static const struct of_device_id exynos_tmu_match[] = {
  706. {
  707. .compatible = "samsung,exynos3250-tmu",
  708. .data = (const void *)SOC_ARCH_EXYNOS3250,
  709. }, {
  710. .compatible = "samsung,exynos4210-tmu",
  711. .data = (const void *)SOC_ARCH_EXYNOS4210,
  712. }, {
  713. .compatible = "samsung,exynos4412-tmu",
  714. .data = (const void *)SOC_ARCH_EXYNOS4412,
  715. }, {
  716. .compatible = "samsung,exynos5250-tmu",
  717. .data = (const void *)SOC_ARCH_EXYNOS5250,
  718. }, {
  719. .compatible = "samsung,exynos5260-tmu",
  720. .data = (const void *)SOC_ARCH_EXYNOS5260,
  721. }, {
  722. .compatible = "samsung,exynos5420-tmu",
  723. .data = (const void *)SOC_ARCH_EXYNOS5420,
  724. }, {
  725. .compatible = "samsung,exynos5420-tmu-ext-triminfo",
  726. .data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO,
  727. }, {
  728. .compatible = "samsung,exynos5433-tmu",
  729. .data = (const void *)SOC_ARCH_EXYNOS5433,
  730. }, {
  731. .compatible = "samsung,exynos7-tmu",
  732. .data = (const void *)SOC_ARCH_EXYNOS7,
  733. },
  734. { },
  735. };
  736. MODULE_DEVICE_TABLE(of, exynos_tmu_match);
  737. static int exynos_map_dt_data(struct platform_device *pdev)
  738. {
  739. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  740. struct resource res;
  741. if (!data || !pdev->dev.of_node)
  742. return -ENODEV;
  743. data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
  744. if (data->id < 0)
  745. data->id = 0;
  746. data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
  747. if (data->irq <= 0) {
  748. dev_err(&pdev->dev, "failed to get IRQ\n");
  749. return -ENODEV;
  750. }
  751. if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
  752. dev_err(&pdev->dev, "failed to get Resource 0\n");
  753. return -ENODEV;
  754. }
  755. data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
  756. if (!data->base) {
  757. dev_err(&pdev->dev, "Failed to ioremap memory\n");
  758. return -EADDRNOTAVAIL;
  759. }
  760. data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev);
  761. switch (data->soc) {
  762. case SOC_ARCH_EXYNOS4210:
  763. data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp;
  764. data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst;
  765. data->tmu_initialize = exynos4210_tmu_initialize;
  766. data->tmu_control = exynos4210_tmu_control;
  767. data->tmu_read = exynos4210_tmu_read;
  768. data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
  769. data->ntrip = 4;
  770. data->gain = 15;
  771. data->reference_voltage = 7;
  772. data->efuse_value = 55;
  773. data->min_efuse_value = 40;
  774. data->max_efuse_value = 100;
  775. break;
  776. case SOC_ARCH_EXYNOS3250:
  777. case SOC_ARCH_EXYNOS4412:
  778. case SOC_ARCH_EXYNOS5250:
  779. case SOC_ARCH_EXYNOS5260:
  780. case SOC_ARCH_EXYNOS5420:
  781. case SOC_ARCH_EXYNOS5420_TRIMINFO:
  782. data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp;
  783. data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst;
  784. data->tmu_initialize = exynos4412_tmu_initialize;
  785. data->tmu_control = exynos4210_tmu_control;
  786. data->tmu_read = exynos4412_tmu_read;
  787. data->tmu_set_emulation = exynos4412_tmu_set_emulation;
  788. data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
  789. data->ntrip = 4;
  790. data->gain = 8;
  791. data->reference_voltage = 16;
  792. data->efuse_value = 55;
  793. if (data->soc != SOC_ARCH_EXYNOS5420 &&
  794. data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
  795. data->min_efuse_value = 40;
  796. else
  797. data->min_efuse_value = 0;
  798. data->max_efuse_value = 100;
  799. break;
  800. case SOC_ARCH_EXYNOS5433:
  801. data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp;
  802. data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst;
  803. data->tmu_initialize = exynos5433_tmu_initialize;
  804. data->tmu_control = exynos5433_tmu_control;
  805. data->tmu_read = exynos4412_tmu_read;
  806. data->tmu_set_emulation = exynos4412_tmu_set_emulation;
  807. data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
  808. data->ntrip = 8;
  809. data->gain = 8;
  810. if (res.start == EXYNOS5433_G3D_BASE)
  811. data->reference_voltage = 23;
  812. else
  813. data->reference_voltage = 16;
  814. data->efuse_value = 75;
  815. data->min_efuse_value = 40;
  816. data->max_efuse_value = 150;
  817. break;
  818. case SOC_ARCH_EXYNOS7:
  819. data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp;
  820. data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst;
  821. data->tmu_initialize = exynos7_tmu_initialize;
  822. data->tmu_control = exynos7_tmu_control;
  823. data->tmu_read = exynos7_tmu_read;
  824. data->tmu_set_emulation = exynos4412_tmu_set_emulation;
  825. data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
  826. data->ntrip = 8;
  827. data->gain = 9;
  828. data->reference_voltage = 17;
  829. data->efuse_value = 75;
  830. data->min_efuse_value = 15;
  831. data->max_efuse_value = 100;
  832. break;
  833. default:
  834. dev_err(&pdev->dev, "Platform not supported\n");
  835. return -EINVAL;
  836. }
  837. data->cal_type = TYPE_ONE_POINT_TRIMMING;
  838. /*
  839. * Check if the TMU shares some registers and then try to map the
  840. * memory of common registers.
  841. */
  842. if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
  843. return 0;
  844. if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
  845. dev_err(&pdev->dev, "failed to get Resource 1\n");
  846. return -ENODEV;
  847. }
  848. data->base_second = devm_ioremap(&pdev->dev, res.start,
  849. resource_size(&res));
  850. if (!data->base_second) {
  851. dev_err(&pdev->dev, "Failed to ioremap memory\n");
  852. return -ENOMEM;
  853. }
  854. return 0;
  855. }
  856. static const struct thermal_zone_of_device_ops exynos_sensor_ops = {
  857. .get_temp = exynos_get_temp,
  858. .set_emul_temp = exynos_tmu_set_emulation,
  859. };
  860. static int exynos_tmu_probe(struct platform_device *pdev)
  861. {
  862. struct exynos_tmu_data *data;
  863. int ret;
  864. data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
  865. GFP_KERNEL);
  866. if (!data)
  867. return -ENOMEM;
  868. platform_set_drvdata(pdev, data);
  869. mutex_init(&data->lock);
  870. /*
  871. * Try enabling the regulator if found
  872. * TODO: Add regulator as an SOC feature, so that regulator enable
  873. * is a compulsory call.
  874. */
  875. data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu");
  876. if (!IS_ERR(data->regulator)) {
  877. ret = regulator_enable(data->regulator);
  878. if (ret) {
  879. dev_err(&pdev->dev, "failed to enable vtmu\n");
  880. return ret;
  881. }
  882. } else {
  883. if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
  884. return -EPROBE_DEFER;
  885. dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
  886. }
  887. ret = exynos_map_dt_data(pdev);
  888. if (ret)
  889. goto err_sensor;
  890. INIT_WORK(&data->irq_work, exynos_tmu_work);
  891. data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
  892. if (IS_ERR(data->clk)) {
  893. dev_err(&pdev->dev, "Failed to get clock\n");
  894. ret = PTR_ERR(data->clk);
  895. goto err_sensor;
  896. }
  897. data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
  898. if (IS_ERR(data->clk_sec)) {
  899. if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
  900. dev_err(&pdev->dev, "Failed to get triminfo clock\n");
  901. ret = PTR_ERR(data->clk_sec);
  902. goto err_sensor;
  903. }
  904. } else {
  905. ret = clk_prepare(data->clk_sec);
  906. if (ret) {
  907. dev_err(&pdev->dev, "Failed to get clock\n");
  908. goto err_sensor;
  909. }
  910. }
  911. ret = clk_prepare(data->clk);
  912. if (ret) {
  913. dev_err(&pdev->dev, "Failed to get clock\n");
  914. goto err_clk_sec;
  915. }
  916. switch (data->soc) {
  917. case SOC_ARCH_EXYNOS5433:
  918. case SOC_ARCH_EXYNOS7:
  919. data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk");
  920. if (IS_ERR(data->sclk)) {
  921. dev_err(&pdev->dev, "Failed to get sclk\n");
  922. goto err_clk;
  923. } else {
  924. ret = clk_prepare_enable(data->sclk);
  925. if (ret) {
  926. dev_err(&pdev->dev, "Failed to enable sclk\n");
  927. goto err_clk;
  928. }
  929. }
  930. break;
  931. default:
  932. break;
  933. }
  934. /*
  935. * data->tzd must be registered before calling exynos_tmu_initialize(),
  936. * requesting irq and calling exynos_tmu_control().
  937. */
  938. data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
  939. &exynos_sensor_ops);
  940. if (IS_ERR(data->tzd)) {
  941. ret = PTR_ERR(data->tzd);
  942. dev_err(&pdev->dev, "Failed to register sensor: %d\n", ret);
  943. goto err_sclk;
  944. }
  945. ret = exynos_tmu_initialize(pdev);
  946. if (ret) {
  947. dev_err(&pdev->dev, "Failed to initialize TMU\n");
  948. goto err_thermal;
  949. }
  950. ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
  951. IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
  952. if (ret) {
  953. dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
  954. goto err_thermal;
  955. }
  956. exynos_tmu_control(pdev, true);
  957. return 0;
  958. err_thermal:
  959. thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
  960. err_sclk:
  961. clk_disable_unprepare(data->sclk);
  962. err_clk:
  963. clk_unprepare(data->clk);
  964. err_clk_sec:
  965. if (!IS_ERR(data->clk_sec))
  966. clk_unprepare(data->clk_sec);
  967. err_sensor:
  968. if (!IS_ERR(data->regulator))
  969. regulator_disable(data->regulator);
  970. return ret;
  971. }
  972. static int exynos_tmu_remove(struct platform_device *pdev)
  973. {
  974. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  975. struct thermal_zone_device *tzd = data->tzd;
  976. thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
  977. exynos_tmu_control(pdev, false);
  978. clk_disable_unprepare(data->sclk);
  979. clk_unprepare(data->clk);
  980. if (!IS_ERR(data->clk_sec))
  981. clk_unprepare(data->clk_sec);
  982. if (!IS_ERR(data->regulator))
  983. regulator_disable(data->regulator);
  984. return 0;
  985. }
  986. #ifdef CONFIG_PM_SLEEP
  987. static int exynos_tmu_suspend(struct device *dev)
  988. {
  989. exynos_tmu_control(to_platform_device(dev), false);
  990. return 0;
  991. }
  992. static int exynos_tmu_resume(struct device *dev)
  993. {
  994. struct platform_device *pdev = to_platform_device(dev);
  995. exynos_tmu_initialize(pdev);
  996. exynos_tmu_control(pdev, true);
  997. return 0;
  998. }
  999. static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
  1000. exynos_tmu_suspend, exynos_tmu_resume);
  1001. #define EXYNOS_TMU_PM (&exynos_tmu_pm)
  1002. #else
  1003. #define EXYNOS_TMU_PM NULL
  1004. #endif
  1005. static struct platform_driver exynos_tmu_driver = {
  1006. .driver = {
  1007. .name = "exynos-tmu",
  1008. .pm = EXYNOS_TMU_PM,
  1009. .of_match_table = exynos_tmu_match,
  1010. },
  1011. .probe = exynos_tmu_probe,
  1012. .remove = exynos_tmu_remove,
  1013. };
  1014. module_platform_driver(exynos_tmu_driver);
  1015. MODULE_DESCRIPTION("EXYNOS TMU Driver");
  1016. MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
  1017. MODULE_LICENSE("GPL");
  1018. MODULE_ALIAS("platform:exynos-tmu");