exynos_tmu.c 32 KB

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