Advertisement
Guest User

Untitled

a guest
Jan 21st, 2018
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.67 KB | None | 0 0
  1. commit 14910f9f2fc0b6f703693cf772da366e1615accb
  2. Author: Dmitry Smirnov <divis1969@gmail.com>
  3. Date: Sun Jan 7 21:50:51 2018 +0300
  4.  
  5. Thermal sensor
  6.  
  7. diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
  8. index a384b766f..dca724527 100644
  9. --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
  10. +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
  11. @@ -48,6 +48,7 @@
  12. #include <dt-bindings/clock/sun8i-r-ccu.h>
  13. #include <dt-bindings/reset/sun8i-a83t-ccu.h>
  14. #include <dt-bindings/reset/sun8i-r-ccu.h>
  15. +#include <dt-bindings/thermal/thermal.h>
  16.  
  17. / {
  18. interrupt-parent = <&gic>;
  19. @@ -55,55 +56,224 @@
  20. #size-cells = <1>;
  21.  
  22. cpus {
  23. + enable-method = "allwinner,sun8i-a23";
  24. #address-cells = <1>;
  25. #size-cells = <0>;
  26.  
  27. - cpu@0 {
  28. + cpu0: cpu@0 {
  29. compatible = "arm,cortex-a7";
  30. device_type = "cpu";
  31. reg = <0>;
  32. + clocks = <&ccu CLK_C0CPUX>;
  33. + clock-names = "c0cpux";
  34. + operating-points-v2 = <&cluster0_opp_table>;
  35. + #cooling-cells = <2>;
  36. };
  37.  
  38. cpu@1 {
  39. compatible = "arm,cortex-a7";
  40. device_type = "cpu";
  41. reg = <1>;
  42. + operating-points-v2 = <&cluster0_opp_table>;
  43. };
  44.  
  45. cpu@2 {
  46. compatible = "arm,cortex-a7";
  47. device_type = "cpu";
  48. reg = <2>;
  49. + operating-points-v2 = <&cluster0_opp_table>;
  50. };
  51.  
  52. cpu@3 {
  53. compatible = "arm,cortex-a7";
  54. device_type = "cpu";
  55. reg = <3>;
  56. + operating-points-v2 = <&cluster0_opp_table>;
  57. };
  58.  
  59. - cpu@100 {
  60. + cpu100: cpu@100 {
  61. compatible = "arm,cortex-a7";
  62. device_type = "cpu";
  63. reg = <0x100>;
  64. + clocks = <&ccu CLK_C1CPUX>;
  65. + clock-names = "c1cpux";
  66. + operating-points-v2 = <&cluster1_opp_table>;
  67. + #cooling-cells = <2>;
  68. };
  69.  
  70. cpu@101 {
  71. compatible = "arm,cortex-a7";
  72. device_type = "cpu";
  73. reg = <0x101>;
  74. + operating-points-v2 = <&cluster1_opp_table>;
  75. };
  76.  
  77. cpu@102 {
  78. compatible = "arm,cortex-a7";
  79. device_type = "cpu";
  80. reg = <0x102>;
  81. + operating-points-v2 = <&cluster1_opp_table>;
  82. };
  83.  
  84. cpu@103 {
  85. compatible = "arm,cortex-a7";
  86. device_type = "cpu";
  87. reg = <0x103>;
  88. + operating-points-v2 = <&cluster1_opp_table>;
  89. + };
  90. + };
  91. +
  92. + cluster0_opp_table: opp_table0 {
  93. + compatible = "operating-points-v2";
  94. + opp-shared;
  95. +
  96. + opp-120000000 {
  97. + opp-hz = /bits/ 64 <120000000>;
  98. + opp-microvolt = <1040000>;
  99. + clock-latency-ns = <244144>; /* 8 32k periods */
  100. + };
  101. +
  102. + opp-240000000 {
  103. + opp-hz = /bits/ 64 <240000000>;
  104. + opp-microvolt = <1040000>;
  105. + clock-latency-ns = <244144>; /* 8 32k periods */
  106. + };
  107. +
  108. + opp-312000000 {
  109. + opp-hz = /bits/ 64 <312000000>;
  110. + opp-microvolt = <1040000>;
  111. + clock-latency-ns = <244144>; /* 8 32k periods */
  112. + };
  113. +
  114. + opp-408000000 {
  115. + opp-hz = /bits/ 64 <408000000>;
  116. + opp-microvolt = <1040000>;
  117. + clock-latency-ns = <244144>; /* 8 32k periods */
  118. + };
  119. +
  120. + opp-480000000 {
  121. + opp-hz = /bits/ 64 <480000000>;
  122. + opp-microvolt = <1040000>;
  123. + clock-latency-ns = <244144>; /* 8 32k periods */
  124. + };
  125. +
  126. + opp-504000000 {
  127. + opp-hz = /bits/ 64 <504000000>;
  128. + opp-microvolt = <1040000>;
  129. + clock-latency-ns = <244144>; /* 8 32k periods */
  130. + };
  131. +
  132. + opp-600000000 {
  133. + opp-hz = /bits/ 64 <600000000>;
  134. + opp-microvolt = <1040000>;
  135. + clock-latency-ns = <244144>; /* 8 32k periods */
  136. + };
  137. +
  138. + opp-648000000 {
  139. + opp-hz = /bits/ 64 <648000000>;
  140. + opp-microvolt = <1040000>;
  141. + clock-latency-ns = <244144>; /* 8 32k periods */
  142. + };
  143. +
  144. + opp-720000000 {
  145. + opp-hz = /bits/ 64 <720000000>;
  146. + opp-microvolt = <1100000>;
  147. + clock-latency-ns = <244144>; /* 8 32k periods */
  148. + };
  149. +
  150. + opp-816000000 {
  151. + opp-hz = /bits/ 64 <816000000>;
  152. + opp-microvolt = <1100000>;
  153. + clock-latency-ns = <244144>; /* 8 32k periods */
  154. + };
  155. +
  156. + opp-912000000 {
  157. + opp-hz = /bits/ 64 <912000000>;
  158. + opp-microvolt = <1200000>;
  159. + clock-latency-ns = <244144>; /* 8 32k periods */
  160. + };
  161. +
  162. + opp-1008000000 {
  163. + opp-hz = /bits/ 64 <1008000000>;
  164. + opp-microvolt = <1200000>;
  165. + clock-latency-ns = <244144>; /* 8 32k periods */
  166. + };
  167. + };
  168. +
  169. + cluster1_opp_table: opp_table1 {
  170. + compatible = "operating-points-v2";
  171. + opp-shared;
  172. +
  173. + opp-120000000 {
  174. + opp-hz = /bits/ 64 <120000000>;
  175. + opp-microvolt = <1040000>;
  176. + clock-latency-ns = <244144>; /* 8 32k periods */
  177. + };
  178. +
  179. + opp-240000000 {
  180. + opp-hz = /bits/ 64 <240000000>;
  181. + opp-microvolt = <1040000>;
  182. + clock-latency-ns = <244144>; /* 8 32k periods */
  183. + };
  184. +
  185. + opp-312000000 {
  186. + opp-hz = /bits/ 64 <312000000>;
  187. + opp-microvolt = <1040000>;
  188. + clock-latency-ns = <244144>; /* 8 32k periods */
  189. + };
  190. +
  191. + opp-408000000 {
  192. + opp-hz = /bits/ 64 <408000000>;
  193. + opp-microvolt = <1040000>;
  194. + clock-latency-ns = <244144>; /* 8 32k periods */
  195. + };
  196. +
  197. + opp-480000000 {
  198. + opp-hz = /bits/ 64 <480000000>;
  199. + opp-microvolt = <1040000>;
  200. + clock-latency-ns = <244144>; /* 8 32k periods */
  201. + };
  202. +
  203. + opp-504000000 {
  204. + opp-hz = /bits/ 64 <504000000>;
  205. + opp-microvolt = <1040000>;
  206. + clock-latency-ns = <244144>; /* 8 32k periods */
  207. + };
  208. +
  209. + opp-600000000 {
  210. + opp-hz = /bits/ 64 <600000000>;
  211. + opp-microvolt = <1040000>;
  212. + clock-latency-ns = <244144>; /* 8 32k periods */
  213. + };
  214. +
  215. + opp-648000000 {
  216. + opp-hz = /bits/ 64 <648000000>;
  217. + opp-microvolt = <1040000>;
  218. + clock-latency-ns = <244144>; /* 8 32k periods */
  219. + };
  220. +
  221. + opp-720000000 {
  222. + opp-hz = /bits/ 64 <720000000>;
  223. + opp-microvolt = <1100000>;
  224. + clock-latency-ns = <244144>; /* 8 32k periods */
  225. + };
  226. +
  227. + opp-816000000 {
  228. + opp-hz = /bits/ 64 <816000000>;
  229. + opp-microvolt = <1100000>;
  230. + clock-latency-ns = <244144>; /* 8 32k periods */
  231. + };
  232. +
  233. + opp-912000000 {
  234. + opp-hz = /bits/ 64 <912000000>;
  235. + opp-microvolt = <1200000>;
  236. + clock-latency-ns = <244144>; /* 8 32k periods */
  237. + };
  238. +
  239. + opp-1008000000 {
  240. + opp-hz = /bits/ 64 <1008000000>;
  241. + opp-microvolt = <1200000>;
  242. + clock-latency-ns = <244144>; /* 8 32k periods */
  243. };
  244. };
  245.  
  246. @@ -537,5 +707,135 @@
  247. #address-cells = <1>;
  248. #size-cells = <0>;
  249. };
  250. +
  251. + ths: ths@1f04000 {
  252. + compatible = "allwinner,sun8i-a83t-ths";
  253. + reg = <0x1f04000 0x100>;
  254. + #thermal-sensor-cells = <1>;
  255. + #io-channel-cells = <1>;
  256. + };
  257. +
  258. };
  259. +
  260. + thermal-zones {
  261. + cpu0x_thermal {
  262. + /* milliseconds */
  263. + polling-delay-passive = <250>;
  264. + polling-delay = <1000>;
  265. + thermal-sensors = <&ths 0>;
  266. +
  267. + trips {
  268. + cpu_alert0: cpu_alert0 {
  269. + /* milliCelsius */
  270. + temperature = <75000>;
  271. + hysteresis = <2000>;
  272. + type = "passive";
  273. + };
  274. +
  275. + cpu_alert1: cpu_alert1 {
  276. + /* milliCelsius */
  277. + temperature = <90000>;
  278. + hysteresis = <2000>;
  279. + type = "hot";
  280. + };
  281. +
  282. + cpu_crit0: cpu_crit0 {
  283. + /* milliCelsius */
  284. + temperature = <110000>;
  285. + hysteresis = <2000>;
  286. + type = "critical";
  287. + };
  288. + };
  289. +
  290. + cooling-maps {
  291. + map0 {
  292. + trip = <&cpu_alert0>;
  293. + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
  294. + };
  295. + map1 {
  296. + trip = <&cpu_alert1>;
  297. + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
  298. + };
  299. + };
  300. + };
  301. +
  302. + cpu1x_thermal {
  303. + /* milliseconds */
  304. + polling-delay-passive = <250>;
  305. + polling-delay = <1000>;
  306. + thermal-sensors = <&ths 1>;
  307. +
  308. + trips {
  309. + cpu_alert100: cpu_alert100 {
  310. + /* milliCelsius */
  311. + temperature = <75000>;
  312. + hysteresis = <2000>;
  313. + type = "passive";
  314. + };
  315. +
  316. + cpu_alert101: cpu_alert101 {
  317. + /* milliCelsius */
  318. + temperature = <90000>;
  319. + hysteresis = <2000>;
  320. + type = "hot";
  321. + };
  322. +
  323. + cpu_crit1: cpu_crit1 {
  324. + /* milliCelsius */
  325. + temperature = <110000>;
  326. + hysteresis = <2000>;
  327. + type = "critical";
  328. + };
  329. + };
  330. +
  331. + cooling-maps {
  332. + map0 {
  333. + trip = <&cpu_alert100>;
  334. + cooling-device = <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
  335. + };
  336. + map1 {
  337. + trip = <&cpu_alert101>;
  338. + cooling-device = <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
  339. + };
  340. + };
  341. +
  342. + };
  343. +
  344. + gpu_thermal {
  345. + /* milliseconds */
  346. + polling-delay-passive = <250>;
  347. + polling-delay = <1000>;
  348. + thermal-sensors = <&ths 2>;
  349. +
  350. + trips {
  351. + gpu_alert0: gpu_alert0 {
  352. + /* milliCelsius */
  353. + temperature = <85000>;
  354. + hysteresis = <2000>;
  355. + type = "passive";
  356. + };
  357. +
  358. + gpu_alert1: gpu_alert1 {
  359. + /* milliCelsius */
  360. + temperature = <95000>;
  361. + hysteresis = <2000>;
  362. + type = "hot";
  363. + };
  364. +
  365. + };
  366. +
  367. +/* cooling-maps {
  368. + map0 {
  369. + trip = <&gpu_alert0>;
  370. + cooling-device = <&mali 1 THERMAL_NO_LIMIT>;
  371. + };
  372. +
  373. + map1 {
  374. + trip = <&gpu_alert1>;
  375. + cooling-device = <&mali 2 THERMAL_NO_LIMIT>;
  376. + };
  377. + };*/
  378. +
  379. + };
  380. + };
  381. };
  382. diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
  383. index 315ae2926..0ed8ed0b0 100644
  384. --- a/drivers/thermal/Kconfig
  385. +++ b/drivers/thermal/Kconfig
  386. @@ -482,4 +482,17 @@ config UNIPHIER_THERMAL
  387. Enable this to plug in UniPhier on-chip PVT thermal driver into the
  388. thermal framework. The driver supports CPU thermal zone temperature
  389. reporting and a couple of trip points.
  390. +
  391. +config SUN8I_A83T_THERMAL
  392. + tristate "Allwinner A83T SoC Thermal Sensor"
  393. + depends on MACH_SUN8I
  394. + depends on THERMAL || !THERMAL_OF
  395. + help
  396. + Say yes here to build support for Allwinner (A83T) SoC
  397. + Thermal Controller. This controller provides 3 thermal sensors
  398. + (2 for CPU clusters and 1 for GPU).
  399. +
  400. + To compile this driver as a module, choose M here: the module will be
  401. + called sun8i-thermal-iio.
  402. +
  403. endif
  404. diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
  405. index 610344eb3..6bdae87d4 100644
  406. --- a/drivers/thermal/Makefile
  407. +++ b/drivers/thermal/Makefile
  408. @@ -61,3 +61,5 @@ obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
  409. obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
  410. obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
  411. obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
  412. +obj-$(CONFIG_SUN8I_A83T_THERMAL) += sun8i-soc-thermal.o
  413. +
  414. diff --git a/drivers/thermal/sun8i-soc-thermal.c b/drivers/thermal/sun8i-soc-thermal.c
  415. new file mode 100644
  416. index 000000000..e56e19371
  417. --- /dev/null
  418. +++ b/drivers/thermal/sun8i-soc-thermal.c
  419. @@ -0,0 +1,870 @@
  420. +/* Thermal sensor driver for sunxi platforms' (A83T)
  421. + *
  422. + * Copyright (c) 2017 Dmitry Smirnov <divis1969@gmail.com>
  423. + *
  424. + * This program is free software; you can redistribute it and/or modify it under
  425. + * the terms of the GNU General Public License version 2 as published by the
  426. + * Free Software Foundation.
  427. + *
  428. + * The Allwinner SoCs all have an ADC that can also act as a touchscreen
  429. + * controller and a thermal sensor.
  430. + * The thermal sensor works only when the ADC acts as a touchscreen controller
  431. + * and is configured to throw an interrupt every fixed periods of time (let say
  432. + * every X seconds).
  433. + * One would be tempted to disable the IP on the hardware side rather than
  434. + * disabling interrupts to save some power but that resets the internal clock of
  435. + * the IP, resulting in having to wait X seconds every time we want to read the
  436. + * value of the thermal sensor.
  437. + * This is also the reason of using autosuspend in pm_runtime. If there was no
  438. + * autosuspend, the thermal sensor would need X seconds after every
  439. + * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
  440. + * thermal sensor to be requested again in a certain time span before it gets
  441. + * shutdown for not being used.
  442. + */
  443. +
  444. +#include <linux/completion.h>
  445. +#include <linux/interrupt.h>
  446. +#include <linux/io.h>
  447. +#include <linux/module.h>
  448. +#include <linux/of.h>
  449. +#include <linux/of_device.h>
  450. +#include <linux/platform_device.h>
  451. +#include <linux/pm_runtime.h>
  452. +#include <linux/regmap.h>
  453. +#include <linux/thermal.h>
  454. +#include <linux/delay.h>
  455. +
  456. +#include <linux/iio/iio.h>
  457. +#include <linux/iio/driver.h>
  458. +#include <linux/iio/machine.h>
  459. +#include <linux/soc/sunxi/sun8i-soc-thermal.h>
  460. +
  461. +//static unsigned int sun8i_gpadc_chan_select(unsigned int chan)
  462. +//{
  463. +// return SUN8I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
  464. +//}
  465. +//
  466. +//static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
  467. +//{
  468. +// return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
  469. +//}
  470. +
  471. +struct ths_data {
  472. + int temp_offset;
  473. + int temp_scale;
  474. + unsigned int tp_mode_en;
  475. + unsigned int tp_adc_select;
  476. + unsigned int (*adc_chan_select)(unsigned int chan);
  477. + unsigned int adc_chan_mask;
  478. +};
  479. +
  480. +//static const struct gpadc_data sun8i_gpadc_data = {
  481. +// .temp_offset = -1932,
  482. +// .temp_scale = 133,
  483. +// .tp_mode_en = SUN8I_GPADC_CTRL1_TP_MODE_EN,
  484. +// .tp_adc_select = SUN8I_GPADC_CTRL1_TP_ADC_SELECT,
  485. +// .adc_chan_select = &sun8i_gpadc_chan_select,
  486. +// .adc_chan_mask = SUN8I_GPADC_CTRL1_ADC_CHAN_MASK,
  487. +//};
  488. +//
  489. +//static const struct gpadc_data sun5i_gpadc_data = {
  490. +// .temp_offset = -1447,
  491. +// .temp_scale = 100,
  492. +// .tp_mode_en = SUN8I_GPADC_CTRL1_TP_MODE_EN,
  493. +// .tp_adc_select = SUN8I_GPADC_CTRL1_TP_ADC_SELECT,
  494. +// .adc_chan_select = &sun8i_gpadc_chan_select,
  495. +// .adc_chan_mask = SUN8I_GPADC_CTRL1_ADC_CHAN_MASK,
  496. +//};
  497. +//
  498. +//static const struct gpadc_data sun6i_gpadc_data = {
  499. +// .temp_offset = -1623,
  500. +// .temp_scale = 167,
  501. +// .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
  502. +// .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
  503. +// .adc_chan_select = &sun6i_gpadc_chan_select,
  504. +// .adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
  505. +//};
  506. +
  507. +
  508. +/*
  509. + * T = (2719-Tem)/14.186
  510. + */
  511. +static const struct ths_data sun8i_a83t_ths_data = {
  512. + .temp_offset = -2719,
  513. + .temp_scale = -70,
  514. +// .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
  515. +};
  516. +
  517. +struct sun8i_soc_thermal_dev;
  518. +
  519. +struct sun8i_soc_thermal_sensor {
  520. + struct sun8i_soc_thermal_dev *device;
  521. + struct iio_dev *indio_dev;
  522. + struct thermal_zone_device *tzd;
  523. + const struct ths_data *ths_data;
  524. +};
  525. +
  526. +struct sun8i_soc_thermal_dev {
  527. + struct platform_device *pdev;
  528. + struct sun8i_soc_thermal_sensor sensors[3];
  529. + struct regmap *regmap;
  530. +};
  531. +
  532. +//struct sun8i_ths_iio {
  533. +// struct iio_dev *indio_dev;
  534. +// struct completion completion;
  535. +// int temp_data;
  536. +// u32 adc_data;
  537. +// struct regmap *regmap;
  538. +// unsigned int fifo_data_irq;
  539. +// atomic_t ignore_fifo_data_irq;
  540. +// unsigned int temp_data_irq;
  541. +// atomic_t ignore_temp_data_irq;
  542. +// const struct ths_data *data;
  543. +// bool no_irq;
  544. +// /* prevents concurrent reads of temperature and ADC */
  545. +// struct mutex mutex;
  546. +// struct sun8i_thermal_sensor sensors[3];
  547. +// struct device *sensor_device;
  548. +//};
  549. +
  550. +//#define SUN8I_GPADC_ADC_CHANNEL(_channel, _name) { \
  551. +// .type = IIO_VOLTAGE, \
  552. +// .indexed = 1, \
  553. +// .channel = _channel, \
  554. +// .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  555. +// .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
  556. +// .datasheet_name = _name, \
  557. +//}
  558. +
  559. +//static struct iio_map sun8i_gpadc_hwmon_maps[] = {
  560. +// {
  561. +// .adc_channel_label = "temp_adc",
  562. +// .consumer_dev_name = "iio_hwmon.0",
  563. +// },
  564. +// { /* sentinel */ },
  565. +//};
  566. +
  567. +//static const struct iio_chan_spec sun8i_gpadc_channels[] = {
  568. +// SUN8I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
  569. +// SUN8I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
  570. +// SUN8I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
  571. +// SUN8I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
  572. +// {
  573. +// .type = IIO_TEMP,
  574. +// .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  575. +// BIT(IIO_CHAN_INFO_SCALE) |
  576. +// BIT(IIO_CHAN_INFO_OFFSET),
  577. +// .datasheet_name = "temp_adc",
  578. +// },
  579. +//};
  580. +
  581. +//static const struct iio_chan_spec sun8i_gpadc_channels_no_temp[] = {
  582. +// SUN8I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
  583. +// SUN8I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
  584. +// SUN8I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
  585. +// SUN8I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
  586. +//};
  587. +
  588. +static const struct iio_chan_spec sun8i_a83t_ths_channels[] = {
  589. + {
  590. + .type = IIO_TEMP,
  591. + .channel = 0,
  592. + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  593. + BIT(IIO_CHAN_INFO_SCALE) |
  594. + BIT(IIO_CHAN_INFO_OFFSET),
  595. + .datasheet_name = "temp_cluster0",
  596. + },
  597. + {
  598. + .type = IIO_TEMP,
  599. + .channel = 1,
  600. + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  601. + BIT(IIO_CHAN_INFO_SCALE) |
  602. + BIT(IIO_CHAN_INFO_OFFSET),
  603. + .datasheet_name = "temp_cluster1",
  604. + },
  605. + {
  606. + .type = IIO_TEMP,
  607. + .channel = 2,
  608. + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  609. + BIT(IIO_CHAN_INFO_SCALE) |
  610. + BIT(IIO_CHAN_INFO_OFFSET),
  611. + .datasheet_name = "temp_gpu",
  612. + },
  613. +};
  614. +
  615. +static const struct regmap_config sun8i_ths_regmap_config = {
  616. + .reg_bits = 32,
  617. + .val_bits = 32,
  618. + .reg_stride = 4,
  619. + .fast_io = true,
  620. +};
  621. +
  622. +//static int sun8i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
  623. +// unsigned int irq)
  624. +//{
  625. +// struct sun8i_gpadc_iio *info = iio_priv(indio_dev);
  626. +// int ret;
  627. +// u32 reg;
  628. +//
  629. +// pm_runtime_get_sync(indio_dev->dev.parent);
  630. +//
  631. +// reinit_completion(&info->completion);
  632. +//
  633. +// ret = regmap_write(info->regmap, SUN8I_GPADC_INT_FIFOC,
  634. +// SUN8I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
  635. +// SUN8I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
  636. +// if (ret)
  637. +// return ret;
  638. +//
  639. +// ret = regmap_read(info->regmap, SUN8I_GPADC_CTRL1, &reg);
  640. +// if (ret)
  641. +// return ret;
  642. +//
  643. +// if (irq == info->fifo_data_irq) {
  644. +// ret = regmap_write(info->regmap, SUN8I_GPADC_CTRL1,
  645. +// info->data->tp_mode_en |
  646. +// info->data->tp_adc_select |
  647. +// info->data->adc_chan_select(channel));
  648. +// /*
  649. +// * When the IP changes channel, it needs a bit of time to get
  650. +// * correct values.
  651. +// */
  652. +// if ((reg & info->data->adc_chan_mask) !=
  653. +// info->data->adc_chan_select(channel))
  654. +// mdelay(10);
  655. +//
  656. +// } else {
  657. +// /*
  658. +// * The temperature sensor returns valid data only when the ADC
  659. +// * operates in touchscreen mode.
  660. +// */
  661. +// ret = regmap_write(info->regmap, SUN8I_GPADC_CTRL1,
  662. +// info->data->tp_mode_en);
  663. +// }
  664. +//
  665. +// if (ret)
  666. +// return ret;
  667. +//
  668. +// /*
  669. +// * When the IP changes mode between ADC or touchscreen, it
  670. +// * needs a bit of time to get correct values.
  671. +// */
  672. +// if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
  673. +// mdelay(100);
  674. +//
  675. +// return 0;
  676. +//}
  677. +
  678. +//static int sun8i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
  679. +// unsigned int irq)
  680. +//{
  681. +// struct sun8i_gpadc_iio *info = iio_priv(indio_dev);
  682. +// int ret;
  683. +//
  684. +// mutex_lock(&info->mutex);
  685. +//
  686. +// ret = sun8i_prepare_for_irq(indio_dev, channel, irq);
  687. +// if (ret)
  688. +// goto err;
  689. +//
  690. +// enable_irq(irq);
  691. +//
  692. +// /*
  693. +// * The temperature sensor throws an interruption periodically (currently
  694. +// * set at periods of ~0.6s in sun8i_gpadc_runtime_resume). A 1s delay
  695. +// * makes sure an interruption occurs in normal conditions. If it doesn't
  696. +// * occur, then there is a timeout.
  697. +// */
  698. +// if (!wait_for_completion_timeout(&info->completion,
  699. +// msecs_to_jiffies(1000))) {
  700. +// ret = -ETIMEDOUT;
  701. +// goto err;
  702. +// }
  703. +//
  704. +// if (irq == info->fifo_data_irq)
  705. +// *val = info->adc_data;
  706. +// else
  707. +// *val = info->temp_data;
  708. +//
  709. +// ret = 0;
  710. +// pm_runtime_mark_last_busy(indio_dev->dev.parent);
  711. +//
  712. +//err:
  713. +// pm_runtime_put_autosuspend(indio_dev->dev.parent);
  714. +// disable_irq(irq);
  715. +// mutex_unlock(&info->mutex);
  716. +//
  717. +// return ret;
  718. +//}
  719. +
  720. +//static int sun8i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
  721. +// int *val)
  722. +//{
  723. +// struct sun8i_gpadc_iio *info = iio_priv(indio_dev);
  724. +//
  725. +// return sun8i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
  726. +//}
  727. +
  728. +static int sun8i_ths_temp_read(struct sun8i_soc_thermal_dev *sensor_dev, int sensor, int *val)
  729. +{
  730. +// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  731. + static const int reg[] = { SUN8I_THS_DATA0, SUN8I_THS_DATA1, SUN8I_THS_DATA2 };
  732. +
  733. +// if (sensor >= indio_dev->num_channels) {
  734. +// return -1;
  735. +// }
  736. +
  737. +// if (info->no_irq) {
  738. +
  739. + pm_runtime_get_sync(&(sensor_dev->pdev->dev));
  740. +
  741. + regmap_read(sensor_dev->regmap, reg[sensor], val);
  742. +
  743. + pm_runtime_mark_last_busy(&(sensor_dev->pdev->dev));
  744. + pm_runtime_put_autosuspend(&(sensor_dev->pdev->dev));
  745. +
  746. + return 0;
  747. +// }
  748. +
  749. + //return sun8i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
  750. +// return -1;
  751. +}
  752. +
  753. +static int sun8i_ths_temp_offset(struct sun8i_soc_thermal_sensor *sensor, int *val)
  754. +{
  755. +// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  756. +
  757. + *val = sensor->ths_data->temp_offset;
  758. +
  759. + return 0;
  760. +}
  761. +
  762. +static int sun8i_ths_temp_scale(struct sun8i_soc_thermal_sensor *sensor, int *val)
  763. +{
  764. +// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  765. +
  766. + *val = sensor->ths_data->temp_scale;
  767. +
  768. + return 0;
  769. +}
  770. +
  771. +//static int sun8i_ths_read_raw(struct iio_dev *indio_dev,
  772. +// struct iio_chan_spec const *chan, int *val,
  773. +// int *val2, long mask)
  774. +//{
  775. +// int ret;
  776. +//// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  777. +// if (chan->channel > indio_dev->num_channels) {
  778. +// return -EINVAL;
  779. +// }
  780. +//
  781. +// switch (mask) {
  782. +// case IIO_CHAN_INFO_OFFSET:
  783. +// ret = sun8i_ths_temp_offset(indio_dev, val);
  784. +// if (ret)
  785. +// return ret;
  786. +//
  787. +// return IIO_VAL_INT;
  788. +// case IIO_CHAN_INFO_RAW:
  789. +// if (chan->type == IIO_VOLTAGE)
  790. +// ret = sun8i_gpadc_adc_read(indio_dev, chan->channel,
  791. +// val);
  792. +// else
  793. +// ret = sun8i_ths_temp_read(indio_dev, chan->channel, val);
  794. +//
  795. +// if (ret)
  796. +// return ret;
  797. +//
  798. +// return IIO_VAL_INT;
  799. +// case IIO_CHAN_INFO_SCALE:
  800. +// if (chan->type == IIO_VOLTAGE) {
  801. +// /* 3000mV / 4096 * raw */
  802. +// *val = 0;
  803. +// *val2 = 732421875;
  804. +// return IIO_VAL_INT_PLUS_NANO;
  805. +// }
  806. +//
  807. +// ret = sun8i_ths_temp_scale(indio_dev, val);
  808. +// if (ret)
  809. +// return ret;
  810. +//
  811. +// return IIO_VAL_INT;
  812. +// default:
  813. +// return -EINVAL;
  814. +// }
  815. +//
  816. +// return -EINVAL;
  817. +//}
  818. +
  819. +//static const struct iio_info sun8i_ths_iio_info = {
  820. +// .read_raw = sun8i_ths_read_raw,
  821. +//// .driver_module = THIS_MODULE,
  822. +//};
  823. +
  824. +//static irqreturn_t sun8i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
  825. +//{
  826. +// struct sun8i_gpadc_iio *info = dev_id;
  827. +//
  828. +// if (atomic_read(&info->ignore_temp_data_irq))
  829. +// goto out;
  830. +//
  831. +// if (!regmap_read(info->regmap, SUN8I_GPADC_TEMP_DATA, &info->temp_data))
  832. +// complete(&info->completion);
  833. +//
  834. +//out:
  835. +// return IRQ_HANDLED;
  836. +//}
  837. +
  838. +//static irqreturn_t sun8i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
  839. +//{
  840. +// struct sun8i_gpadc_iio *info = dev_id;
  841. +//
  842. +// if (atomic_read(&info->ignore_fifo_data_irq))
  843. +// goto out;
  844. +//
  845. +// if (!regmap_read(info->regmap, SUN8I_GPADC_DATA, &info->adc_data))
  846. +// complete(&info->completion);
  847. +//
  848. +//out:
  849. +// return IRQ_HANDLED;
  850. +//}
  851. +
  852. +static int sun8i_ths_runtime_suspend(struct device *dev)
  853. +{
  854. +// struct sun8i_ths_iio *info = iio_priv(dev_get_drvdata(dev));
  855. + struct sun8i_soc_thermal_dev *sensor_dev = (struct sun8i_soc_thermal_dev *)dev_get_drvdata(dev);
  856. +
  857. + /* Disable temperature sensors */
  858. + regmap_write(sensor_dev->regmap, SUN8I_THS_CTRL2, 0);
  859. +
  860. + return 0;
  861. +}
  862. +
  863. +static int sun8i_ths_runtime_resume(struct device *dev)
  864. +{
  865. +// struct sun8i_ths_iio *info = iio_priv(dev_get_drvdata(dev));
  866. + struct sun8i_soc_thermal_dev *sensor_dev = (struct sun8i_soc_thermal_dev *)dev_get_drvdata(dev);
  867. +#ifdef SUN8IW6_SID_CALIBRATION
  868. + int reg_value = 0;
  869. +#endif
  870. +
  871. + regmap_write(sensor_dev->regmap, SUN8I_THS_CTRL1, SUN8I_THS_CTRL1_ADC_CALI_EN);
  872. +
  873. +#ifdef SUN8IW6_SID_CALIBRATION
  874. + reg_value = readl(SID_THERMAL_CDATA1_SRAM);
  875. + if (0 != reg_value)
  876. + writel(reg_value, thermal_data->base_addr + THS_0_1_CDATA_REG);
  877. + reg_value = readl(SID_THERMAL_CDATA2_SRAM);
  878. + if (0 != reg_value)
  879. + writel(reg_value, thermal_data->base_addr + THS_2_CDATA_REG);
  880. +#endif
  881. +
  882. + regmap_write(sensor_dev->regmap, SUN8I_THS_CTRL0, SUN8I_THS_CTRL0_ACQ0_VALUE);
  883. + regmap_write(sensor_dev->regmap, SUN8I_THS_CTRL2,
  884. + SUN8I_THS_CTRL2_ACQ1_VALUE | SUN8I_THS_CTRL2_SENSE2_EN |
  885. + SUN8I_THS_CTRL2_SENSE1_EN | SUN8I_THS_CTRL2_SENSE0_EN);
  886. + regmap_write(sensor_dev->regmap, SUN8I_THS_INT_CTRL,
  887. + SUN8I_THS_INT_CTRL_THERMAL_PER_VALUE | SUN8I_THS_INT_CTRL_SHUT_INT2_EN |
  888. + SUN8I_THS_INT_CTRL_SHUT_INT1_EN | SUN8I_THS_INT_CTRL_SHUT_INT1_EN);
  889. + regmap_write(sensor_dev->regmap, SUN8I_THS_INT_STA, SUN8I_THS_INT_CTRL_RESET_ALL);
  890. + regmap_write(sensor_dev->regmap, SUN8I_THS_FILT_CTRL,
  891. + SUN8I_THS_FILT_CTRL_FILTER_EN | SUN8I_THS_FILT_CTRL_FILTER_TYPE_4);
  892. +
  893. +// reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14186, 2794);
  894. +// reg_value = (reg_value<<16);
  895. +//
  896. +// writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG0);
  897. +// writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG1);
  898. +// writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG2);
  899. +
  900. + return 0;
  901. +}
  902. +
  903. +static int sun8i_ths_get_temp(void *data, int *temp)
  904. +{
  905. + struct sun8i_soc_thermal_sensor *sensor = (struct sun8i_soc_thermal_sensor *)data;
  906. + //struct iio_dev *iio_dev = sensor->indio_dev;
  907. + //struct sun8i_ths_iio *info = iio_priv(iio_dev);
  908. + struct sun8i_soc_thermal_dev *sensor_dev = sensor->device;
  909. + int val, scale, offset, i;
  910. +
  911. + for (i = 0; i < 3; i++) {
  912. + if (&(sensor_dev->sensors[i]) == sensor) {
  913. + break;
  914. + }
  915. + }
  916. +
  917. + if (i == 3) {
  918. + return -1;
  919. + }
  920. +
  921. + if (sun8i_ths_temp_read(sensor_dev, i, &val))
  922. + return -ETIMEDOUT;
  923. +
  924. + sun8i_ths_temp_scale(sensor, &scale);
  925. + sun8i_ths_temp_offset(sensor, &offset);
  926. +
  927. + *temp = (val + offset) * scale;
  928. + pr_debug("sun8i_ths_get_temp: %d = (%d + %d) * %d\n", *temp, val, offset, scale);
  929. +
  930. + return 0;
  931. +}
  932. +
  933. +static const struct thermal_zone_of_device_ops sun8i_ts_tz_ops = {
  934. + .get_temp = &sun8i_ths_get_temp,
  935. +};
  936. +
  937. +static const struct dev_pm_ops sun8i_ths_pm_ops = {
  938. + .runtime_suspend = &sun8i_ths_runtime_suspend,
  939. + .runtime_resume = &sun8i_ths_runtime_resume,
  940. +};
  941. +
  942. +//static int sun8i_irq_init(struct platform_device *pdev, const char *name,
  943. +// irq_handler_t handler, const char *devname,
  944. +// unsigned int *irq, atomic_t *atomic)
  945. +//{
  946. +// int ret;
  947. +// struct sun8i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
  948. +// struct sun8i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
  949. +//
  950. +// /*
  951. +// * Once the interrupt is activated, the IP continuously performs
  952. +// * conversions thus throws interrupts. The interrupt is activated right
  953. +// * after being requested but we want to control when these interrupts
  954. +// * occur thus we disable it right after being requested. However, an
  955. +// * interrupt might occur between these two instructions and we have to
  956. +// * make sure that does not happen, by using atomic flags. We set the
  957. +// * flag before requesting the interrupt and unset it right after
  958. +// * disabling the interrupt. When an interrupt occurs between these two
  959. +// * instructions, reading the atomic flag will tell us to ignore the
  960. +// * interrupt.
  961. +// */
  962. +// atomic_set(atomic, 1);
  963. +//
  964. +// ret = platform_get_irq_byname(pdev, name);
  965. +// if (ret < 0) {
  966. +// dev_err(&pdev->dev, "no %s interrupt registered\n", name);
  967. +// return ret;
  968. +// }
  969. +//
  970. +// ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret);
  971. +// if (ret < 0) {
  972. +// dev_err(&pdev->dev, "failed to get virq for irq %s\n", name);
  973. +// return ret;
  974. +// }
  975. +//
  976. +// *irq = ret;
  977. +// ret = devm_request_any_context_irq(&pdev->dev, *irq, handler, 0,
  978. +// devname, info);
  979. +// if (ret < 0) {
  980. +// dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
  981. +// name, ret);
  982. +// return ret;
  983. +// }
  984. +//
  985. +// disable_irq(*irq);
  986. +// atomic_set(atomic, 0);
  987. +//
  988. +// return 0;
  989. +//}
  990. +
  991. +static const struct of_device_id sun8i_ths_of_id[] = {
  992. + {
  993. + .compatible = "allwinner,sun8i-a83t-ths",
  994. + .data = &sun8i_a83t_ths_data,
  995. + },
  996. + { /* sentinel */ }
  997. +};
  998. +
  999. +//static int sun8i_ths_probe_dt(struct platform_device *pdev,
  1000. +// struct iio_dev *indio_dev)
  1001. +//{
  1002. +// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  1003. +// const struct of_device_id *of_dev;
  1004. +// struct resource *mem;
  1005. +// void __iomem *base;
  1006. +// int ret, i;
  1007. +//
  1008. +// of_dev = of_match_device(sun8i_ths_of_id, &pdev->dev);
  1009. +// if (!of_dev)
  1010. +// return -ENODEV;
  1011. +//
  1012. +// info->no_irq = true;
  1013. +// info->data = (struct ths_data *)of_dev->data;
  1014. +// indio_dev->num_channels = ARRAY_SIZE(sun8i_a83t_ths_channels);
  1015. +// indio_dev->channels = sun8i_a83t_ths_channels;
  1016. +//
  1017. +// mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1018. +// base = devm_ioremap_resource(&pdev->dev, mem);
  1019. +// if (IS_ERR(base))
  1020. +// return PTR_ERR(base);
  1021. +//
  1022. +// info->regmap = devm_regmap_init_mmio(&pdev->dev, base,
  1023. +// &sun8i_ths_regmap_config);
  1024. +// if (IS_ERR(info->regmap)) {
  1025. +// ret = PTR_ERR(info->regmap);
  1026. +// dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
  1027. +// return ret;
  1028. +// }
  1029. +//
  1030. +// if (!IS_ENABLED(CONFIG_THERMAL_OF))
  1031. +// return 0;
  1032. +//
  1033. +// info->sensor_device = &pdev->dev;
  1034. +// for (i = 0; i < indio_dev->num_channels; i++) {
  1035. +// info->sensors[i].indio_dev = indio_dev;
  1036. +// info->sensors[i].cell = i;
  1037. +// info->sensors[i].tzd = thermal_zone_of_sensor_register(info->sensor_device, i,
  1038. +// &(info->sensors[i]), &sun8i_ts_tz_ops);
  1039. +// if (IS_ERR(info->sensors[i].tzd)) {
  1040. +// dev_err(&pdev->dev, "could not register thermal sensor: %ld\n",
  1041. +// PTR_ERR(info->sensors[i].tzd));
  1042. +// return PTR_ERR_OR_ZERO(info->sensors[i].tzd);
  1043. +// }
  1044. +// }
  1045. +//
  1046. +// return 0;
  1047. +//}
  1048. +
  1049. +//static int sun8i_gpadc_probe_mfd(struct platform_device *pdev,
  1050. +// struct iio_dev *indio_dev)
  1051. +//{
  1052. +// struct sun8i_gpadc_iio *info = iio_priv(indio_dev);
  1053. +// struct sun8i_gpadc_dev *sun8i_gpadc_dev =
  1054. +// dev_get_drvdata(pdev->dev.parent);
  1055. +// int ret;
  1056. +//
  1057. +// info->no_irq = false;
  1058. +// info->regmap = sun8i_gpadc_dev->regmap;
  1059. +//
  1060. +// indio_dev->num_channels = ARRAY_SIZE(sun8i_gpadc_channels);
  1061. +// indio_dev->channels = sun8i_gpadc_channels;
  1062. +//
  1063. +// info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
  1064. +//
  1065. +// /*
  1066. +// * Since the controller needs to be in touchscreen mode for its thermal
  1067. +// * sensor to operate properly, and that switching between the two modes
  1068. +// * needs a delay, always registering in the thermal framework will
  1069. +// * significantly slow down the conversion rate of the ADCs.
  1070. +// *
  1071. +// * Therefore, instead of depending on THERMAL_OF in Kconfig, we only
  1072. +// * register the sensor if that option is enabled, eventually leaving
  1073. +// * that choice to the user.
  1074. +// */
  1075. +//
  1076. +// if (IS_ENABLED(CONFIG_THERMAL_OF)) {
  1077. +// /*
  1078. +// * This driver is a child of an MFD which has a node in the DT
  1079. +// * but not its children, because of DT backward compatibility
  1080. +// * for A10, A13 and A31 SoCs. Therefore, the resulting devices
  1081. +// * of this driver do not have an of_node variable.
  1082. +// * However, its parent (the MFD driver) has an of_node variable
  1083. +// * and since devm_thermal_zone_of_sensor_register uses its first
  1084. +// * argument to match the phandle defined in the node of the
  1085. +// * thermal driver with the of_node of the device passed as first
  1086. +// * argument and the third argument to call ops from
  1087. +// * thermal_zone_of_device_ops, the solution is to use the parent
  1088. +// * device as first argument to match the phandle with its
  1089. +// * of_node, and the device from this driver as third argument to
  1090. +// * return the temperature.
  1091. +// */
  1092. +// info->sensor_device = pdev->dev.parent;
  1093. +// info->tzd = thermal_zone_of_sensor_register(info->sensor_device,
  1094. +// 0, info,
  1095. +// &sun8i_ts_tz_ops);
  1096. +// if (IS_ERR(info->tzd)) {
  1097. +// dev_err(&pdev->dev,
  1098. +// "could not register thermal sensor: %ld\n",
  1099. +// PTR_ERR(info->tzd));
  1100. +// return PTR_ERR(info->tzd);
  1101. +// }
  1102. +// } else {
  1103. +// indio_dev->num_channels =
  1104. +// ARRAY_SIZE(sun8i_gpadc_channels_no_temp);
  1105. +// indio_dev->channels = sun8i_gpadc_channels_no_temp;
  1106. +// }
  1107. +//
  1108. +// if (IS_ENABLED(CONFIG_THERMAL_OF)) {
  1109. +// ret = sun8i_irq_init(pdev, "TEMP_DATA_PENDING",
  1110. +// sun8i_gpadc_temp_data_irq_handler,
  1111. +// "temp_data", &info->temp_data_irq,
  1112. +// &info->ignore_temp_data_irq);
  1113. +// if (ret < 0)
  1114. +// return ret;
  1115. +// }
  1116. +//
  1117. +// ret = sun8i_irq_init(pdev, "FIFO_DATA_PENDING",
  1118. +// sun8i_gpadc_fifo_data_irq_handler, "fifo_data",
  1119. +// &info->fifo_data_irq, &info->ignore_fifo_data_irq);
  1120. +// if (ret < 0)
  1121. +// return ret;
  1122. +//
  1123. +// if (IS_ENABLED(CONFIG_THERMAL_OF)) {
  1124. +// ret = iio_map_array_register(indio_dev, sun8i_gpadc_hwmon_maps);
  1125. +// if (ret < 0) {
  1126. +// dev_err(&pdev->dev,
  1127. +// "failed to register iio map array\n");
  1128. +// return ret;
  1129. +// }
  1130. +// }
  1131. +//
  1132. +// return 0;
  1133. +//}
  1134. +
  1135. +static int sun8i_ths_probe(struct platform_device *pdev)
  1136. +{
  1137. + //struct sun8i_ths_iio *info;
  1138. + //struct iio_dev *indio_dev;
  1139. + struct sun8i_soc_thermal_dev *sensor_dev;
  1140. + int ret, i;
  1141. + struct resource *mem;
  1142. + void __iomem *base;
  1143. + const struct of_device_id *of_dev;
  1144. +
  1145. + pr_err("sun8i_ths_probe ++\n");
  1146. + of_dev = of_match_device(sun8i_ths_of_id, &pdev->dev);
  1147. + if (!of_dev) {
  1148. + dev_err(&pdev->dev, "cannot find a matching device in device tree\n");
  1149. + return -ENODEV;
  1150. + }
  1151. +
  1152. + sensor_dev = (struct sun8i_soc_thermal_dev *) devm_kzalloc(&(pdev->dev), sizeof(struct sun8i_soc_thermal_dev), GFP_KERNEL);
  1153. + if (!sensor_dev) {
  1154. + dev_err(&pdev->dev, "cannot allocate memory\n");
  1155. + ret = -ENOMEM;
  1156. + goto alloc_fail;
  1157. + }
  1158. +
  1159. + platform_set_drvdata(pdev, sensor_dev);
  1160. + sensor_dev->pdev = pdev;
  1161. +
  1162. + //mutex_init(&info->mutex);
  1163. + //info->indio_dev = indio_dev;
  1164. + //init_completion(&info->completion);
  1165. + //indio_dev->name = dev_name(&pdev->dev);
  1166. + //indio_dev->dev.parent = &pdev->dev;
  1167. + //indio_dev->dev.of_node = pdev->dev.of_node;
  1168. + //indio_dev->info = &sun8i_ths_iio_info;
  1169. + //indio_dev->modes = INDIO_DIRECT_MODE;
  1170. +
  1171. +// if (pdev->dev.of_node)
  1172. +// ret = sun8i_ths_probe_dt(pdev, indio_dev);
  1173. +// else
  1174. +// ret = sun8i_gpadc_probe_mfd(pdev, indio_dev);
  1175. +// ret = -1;
  1176. +//
  1177. +// if (ret) {
  1178. +// pr_err("sun8i_ths_probe failed 2 --\n");
  1179. +// return ret;
  1180. +// }
  1181. +
  1182. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1183. + base = devm_ioremap_resource(&pdev->dev, mem);
  1184. + if (IS_ERR(base)) {
  1185. + dev_err(&pdev->dev, "failed to allocate io map\n");
  1186. + ret = PTR_ERR(base);
  1187. + goto resource_fail;
  1188. + }
  1189. +
  1190. + sensor_dev->regmap = devm_regmap_init_mmio(&pdev->dev, base,
  1191. + &sun8i_ths_regmap_config);
  1192. + if (IS_ERR(sensor_dev->regmap)) {
  1193. + ret = PTR_ERR(sensor_dev->regmap);
  1194. + dev_err(&pdev->dev, "failed to init io map: %d\n", ret);
  1195. + goto regmap_init_fail;
  1196. + }
  1197. +
  1198. + //if (!IS_ENABLED(CONFIG_THERMAL_OF))
  1199. + // return 0;
  1200. +
  1201. + for (i = 0; i < 3; i++) {
  1202. + sensor_dev->sensors[i].device = sensor_dev;
  1203. + sensor_dev->sensors[i].ths_data = of_dev->data;
  1204. + sensor_dev->sensors[i].tzd = thermal_zone_of_sensor_register(&pdev->dev, i,
  1205. + &(sensor_dev->sensors[i]), &sun8i_ts_tz_ops);
  1206. + if (IS_ERR(sensor_dev->sensors[i].tzd)) {
  1207. + dev_err(&pdev->dev, "could not register thermal sensor: %ld\n",
  1208. + PTR_ERR(sensor_dev->sensors[i].tzd));
  1209. + ret = PTR_ERR_OR_ZERO(sensor_dev->sensors[i].tzd);
  1210. + sensor_dev->sensors[i].tzd = NULL;
  1211. + goto tzd_fail;
  1212. + }
  1213. + }
  1214. +
  1215. + pm_runtime_set_autosuspend_delay(&pdev->dev,
  1216. + SUN8I_THS_AUTOSUSPEND_DELAY);
  1217. + pm_runtime_use_autosuspend(&pdev->dev);
  1218. + pm_runtime_set_suspended(&pdev->dev);
  1219. + pm_runtime_enable(&pdev->dev);
  1220. +
  1221. + //ret = devm_iio_device_register(&pdev->dev, indio_dev);
  1222. + //if (ret < 0) {
  1223. + // pr_err("sun8i_ths_probe failed 3 --\n");
  1224. + // goto err_map;
  1225. + //}
  1226. + pr_err("sun8i_ths_probe succeded");
  1227. + return 0;
  1228. +
  1229. +tzd_fail:
  1230. + for (i = 0; i < 3; i++) {
  1231. + if (sensor_dev->sensors[i].tzd)
  1232. + thermal_zone_of_sensor_unregister(&pdev->dev, sensor_dev->sensors[i].tzd);
  1233. + }
  1234. +regmap_init_fail:
  1235. +resource_fail:
  1236. + devm_kfree(&(pdev->dev), sensor_dev);
  1237. +alloc_fail:
  1238. + pr_err("sun8i_ths_probe failed: %d --\n", ret);
  1239. + return ret;
  1240. +
  1241. +//err_map:
  1242. +// if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF))
  1243. +// iio_map_array_unregister(indio_dev);
  1244. +//
  1245. +// pm_runtime_put(&pdev->dev);
  1246. +// pm_runtime_disable(&pdev->dev);
  1247. +//
  1248. +// return ret;
  1249. +}
  1250. +
  1251. +static int sun8i_ths_remove(struct platform_device *pdev)
  1252. +{
  1253. + struct sun8i_soc_thermal_dev *sensor_dev = platform_get_drvdata(pdev);
  1254. +// struct sun8i_ths_iio *info = iio_priv(indio_dev);
  1255. + int i;
  1256. +
  1257. + pm_runtime_put(&pdev->dev);
  1258. + pm_runtime_disable(&pdev->dev);
  1259. +
  1260. +// if (!IS_ENABLED(CONFIG_THERMAL_OF))
  1261. +// return 0;
  1262. +
  1263. + for (i = 0; i < 3; i++) {
  1264. + thermal_zone_of_sensor_unregister(&pdev->dev, sensor_dev->sensors[i].tzd);
  1265. + }
  1266. +
  1267. + devm_kfree(&(pdev->dev), sensor_dev);
  1268. +// if (!info->no_irq)
  1269. +// iio_map_array_unregister(indio_dev);
  1270. +
  1271. + return 0;
  1272. +}
  1273. +
  1274. +static struct platform_driver sun8i_ths_driver = {
  1275. + .driver = {
  1276. + .name = "sun8i-soc-ths",
  1277. + .of_match_table = sun8i_ths_of_id,
  1278. + .pm = &sun8i_ths_pm_ops,
  1279. + },
  1280. + .probe = sun8i_ths_probe,
  1281. + .remove = sun8i_ths_remove,
  1282. +};
  1283. +MODULE_DEVICE_TABLE(of, sun8i_ths_of_id);
  1284. +
  1285. +module_platform_driver(sun8i_ths_driver);
  1286. +
  1287. +MODULE_DESCRIPTION("Thermal sensor controller driver for sunxi platforms");
  1288. +MODULE_AUTHOR("Dmitry Smirnov <divis1969@gmail.com>");
  1289. +MODULE_LICENSE("GPL v2");
  1290. diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
  1291. index 2b1b0ba39..9f88645d0 100644
  1292. --- a/drivers/thermal/thermal_core.c
  1293. +++ b/drivers/thermal/thermal_core.c
  1294. @@ -1186,20 +1186,30 @@ thermal_zone_device_register(const char *type, int trips, int mask,
  1295. int count;
  1296. struct thermal_governor *governor;
  1297.  
  1298. - if (!type || strlen(type) == 0)
  1299. + if (!type || strlen(type) == 0) {
  1300. + pr_err("thermal_zone_device_register EINVAL type\n");
  1301. return ERR_PTR(-EINVAL);
  1302. + }
  1303.  
  1304. - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
  1305. + if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
  1306. + pr_err("thermal_zone_device_register EINVAL type2\n");
  1307. return ERR_PTR(-EINVAL);
  1308. + }
  1309.  
  1310. - if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
  1311. + if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
  1312. + pr_err("thermal_zone_device_register EINVAL trips\n");
  1313. return ERR_PTR(-EINVAL);
  1314. + }
  1315.  
  1316. - if (!ops)
  1317. + if (!ops) {
  1318. + pr_err("thermal_zone_device_register EINVAL ops\n");
  1319. return ERR_PTR(-EINVAL);
  1320. + }
  1321.  
  1322. - if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
  1323. + if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp)) {
  1324. + pr_err("thermal_zone_device_register EINVAL trips&ops\n");
  1325. return ERR_PTR(-EINVAL);
  1326. + }
  1327.  
  1328. tz = kzalloc(sizeof(*tz), GFP_KERNEL);
  1329. if (!tz)
  1330. diff --git a/include/linux/soc/sunxi/sun8i-soc-thermal.h b/include/linux/soc/sunxi/sun8i-soc-thermal.h
  1331. new file mode 100644
  1332. index 000000000..91ceed01f
  1333. --- /dev/null
  1334. +++ b/include/linux/soc/sunxi/sun8i-soc-thermal.h
  1335. @@ -0,0 +1,158 @@
  1336. +/* Header of thermal sensor controller core driver for sunxi platforms
  1337. + *
  1338. + * Copyright (c) 2017 Dmitry Smirnov <divis1969@gmail.com>
  1339. + *
  1340. + * This program is free software; you can redistribute it and/or modify it under
  1341. + * the terms of the GNU General Public License version 2 as published by the
  1342. + * Free Software Foundation.
  1343. + */
  1344. +
  1345. +#ifndef __SUN8I_THS__H__
  1346. +#define __SUN8I_THS__H__
  1347. +
  1348. +#define SUN8I_THS_CTRL0 0x00
  1349. +#define SUN8I_THS_CTRL0_ACQ0_VALUE 0x17 // default value
  1350. +
  1351. +#define SUN8I_THS_CTRL1 0x04
  1352. +#define SUN8I_THS_CTRL1_ADC_CALI_EN BIT(17)
  1353. +
  1354. +//#define SUN8I_THS_CTRL1_STYLUS_UP_DEBOUNCE(x) ((GENMASK(7, 0) & (x)) << 12)
  1355. +//#define SUN8I_THS_CTRL1_STYLUS_UP_DEBOUNCE_EN BIT(9)
  1356. +//#define SUN8I_THS_CTRL1_TOUCH_PAN_CALI_EN BIT(6)
  1357. +//#define SUN8I_THS_CTRL1_TP_DUAL_EN BIT(5)
  1358. +//#define SUN8I_THS_CTRL1_TP_MODE_EN BIT(4)
  1359. +//#define SUN8I_THS_CTRL1_TP_ADC_SELECT BIT(3)
  1360. +//#define SUN8I_THS_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(2, 0) & (x))
  1361. +//#define SUN8I_THS_CTRL1_ADC_CHAN_MASK GENMASK(2, 0)
  1362. +//
  1363. +///* TP_CTRL1 bits for sun6i SOCs */
  1364. +//#define SUN6I_THS_CTRL1_TOUCH_PAN_CALI_EN BIT(7)
  1365. +//#define SUN6I_THS_CTRL1_TP_DUAL_EN BIT(6)
  1366. +//#define SUN6I_THS_CTRL1_TP_MODE_EN BIT(5)
  1367. +//#define SUN6I_THS_CTRL1_TP_ADC_SELECT BIT(4)
  1368. +//#define SUN6I_THS_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x))
  1369. +//#define SUN6I_THS_CTRL1_ADC_CHAN_MASK GENMASK(3, 0)
  1370. +//
  1371. +///* TP_CTRL1 bits for sun8i SoCs */
  1372. +//#define SUN8I_THS_CTRL1_CHOP_TEMP_EN BIT(8)
  1373. +//#define SUN8I_THS_CTRL1_THS_CALI_EN BIT(7)
  1374. +//
  1375. +//#define SUN8I_THS_CTRL2 0x08
  1376. +//
  1377. +//#define SUN8I_THS_CTRL2_TP_SENSITIVE_ADJUST(x) ((GENMASK(3, 0) & (x)) << 28)
  1378. +//#define SUN8I_THS_CTRL2_TP_MODE_SELECT(x) ((GENMASK(1, 0) & (x)) << 26)
  1379. +//#define SUN8I_THS_CTRL2_PRE_MEA_EN BIT(24)
  1380. +//#define SUN8I_THS_CTRL2_PRE_MEA_THRE_CNT(x) (GENMASK(23, 0) & (x))
  1381. +//
  1382. +//#define SUN8I_THS_CTRL3 0x0c
  1383. +//
  1384. +//#define SUN8I_THS_CTRL3_FILTER_EN BIT(2)
  1385. +//#define SUN8I_THS_CTRL3_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
  1386. +
  1387. +#define SUN8I_THS_ADC_CDAT 0x14
  1388. +
  1389. +#define SUN8I_THS_CTRL2 0x40
  1390. +#define SUN8I_THS_CTRL2_ACQ1_VALUE (0x17 << 16) /* default value */
  1391. +#define SUN8I_THS_CTRL2_SENSE2_EN BIT(2)
  1392. +#define SUN8I_THS_CTRL2_SENSE1_EN BIT(1)
  1393. +#define SUN8I_THS_CTRL2_SENSE0_EN BIT(0)
  1394. +
  1395. +#define SUN8I_THS_INT_CTRL 0x44
  1396. +#define SUN8I_THS_INT_CTRL_THERMAL_PER_VALUE (1 << 12) /* default value */
  1397. +#define SUN8I_THS_INT_CTRL_THS2_DATA_IRQ_EN BIT(10)
  1398. +#define SUN8I_THS_INT_CTRL_THS1_DATA_IRQ_EN BIT(9)
  1399. +#define SUN8I_THS_INT_CTRL_THS0_DATA_IRQ_EN BIT(8)
  1400. +#define SUN8I_THS_INT_CTRL_SHUT_INT2_EN BIT(6)
  1401. +#define SUN8I_THS_INT_CTRL_SHUT_INT1_EN BIT(5)
  1402. +#define SUN8I_THS_INT_CTRL_SHUT_INT0_EN BIT(4)
  1403. +#define SUN8I_THS_INT_CTRL_ALARM_INT2_EN BIT(2)
  1404. +#define SUN8I_THS_INT_CTRL_ALARM_INT1_EN BIT(1)
  1405. +#define SUN8I_THS_INT_CTRL_ALARM_INT0_EN BIT(0)
  1406. +
  1407. +#define SUN8I_THS_INT_STA 0x48
  1408. +#define SUN8I_THS_INT_CTRL_THS2_DATA_IRQ_STS BIT(10)
  1409. +#define SUN8I_THS_INT_CTRL_THS1_DATA_IRQ_STS BIT(9)
  1410. +#define SUN8I_THS_INT_CTRL_THS0_DATA_IRQ_STS BIT(8)
  1411. +#define SUN8I_THS_INT_CTRL_SHUT_INT2_STS BIT(6)
  1412. +#define SUN8I_THS_INT_CTRL_SHUT_INT1_STS BIT(5)
  1413. +#define SUN8I_THS_INT_CTRL_SHUT_INT0_STS BIT(4)
  1414. +#define SUN8I_THS_INT_CTRL_ALARM_INT2_STS BIT(2)
  1415. +#define SUN8I_THS_INT_CTRL_ALARM_INT1_STS BIT(1)
  1416. +#define SUN8I_THS_INT_CTRL_ALARM_INT0_STS BIT(0)
  1417. +#define SUN8I_THS_INT_CTRL_RESET_ALL ( \
  1418. + SUN8I_THS_INT_CTRL_THS2_DATA_IRQ_STS | \
  1419. + SUN8I_THS_INT_CTRL_THS1_DATA_IRQ_STS | \
  1420. + SUN8I_THS_INT_CTRL_THS0_DATA_IRQ_STS | \
  1421. + SUN8I_THS_INT_CTRL_SHUT_INT2_STS | \
  1422. + SUN8I_THS_INT_CTRL_SHUT_INT1_STS | \
  1423. + SUN8I_THS_INT_CTRL_SHUT_INT0_STS | \
  1424. + SUN8I_THS_INT_CTRL_ALARM_INT2_STS | \
  1425. + SUN8I_THS_INT_CTRL_ALARM_INT1_STS | \
  1426. + SUN8I_THS_INT_CTRL_ALARM_INT0_STS \
  1427. + )
  1428. +
  1429. +#define SUN8I_THS_INT_ALM_TH0 0x50
  1430. +#define SUN8I_THS_INT_ALM_TH1 0x54
  1431. +#define SUN8I_THS_INT_ALM_TH2 0x58
  1432. +#define SUN8I_THS_INT_SHUT_TH0 0x60
  1433. +#define SUN8I_THS_INT_SHUT_TH1 0x64
  1434. +#define SUN8I_THS_INT_SHUT_TH2 0x68
  1435. +
  1436. +#define SUN8I_THS_FILT_CTRL 0x70
  1437. +#define SUN8I_THS_FILT_CTRL_FILTER_EN BIT(2)
  1438. +#define SUN8I_THS_FILT_CTRL_FILTER_TYPE_2 0
  1439. +#define SUN8I_THS_FILT_CTRL_FILTER_TYPE_4 1
  1440. +#define SUN8I_THS_FILT_CTRL_FILTER_TYPE_8 2
  1441. +#define SUN8I_THS_FILT_CTRL_FILTER_TYPE_16 3
  1442. +
  1443. +
  1444. +#define SUN8I_THS_0_1_CDATA 0x74
  1445. +#define SUN8I_THS_2_CDATA 0x78
  1446. +#define SUN8I_THS_DATA0 0x80
  1447. +#define SUN8I_THS_DATA1 0x84
  1448. +#define SUN8I_THS_DATA2 0x88
  1449. +
  1450. +//#define SUN8I_THS_TPR 0x18
  1451. +//
  1452. +//#define SUN8I_THS_TPR_TEMP_ENABLE BIT(16)
  1453. +//#define SUN8I_THS_TPR_TEMP_PERIOD(x) (GENMASK(15, 0) & (x))
  1454. +//
  1455. +//#define SUN8I_THS_INT_FIFOC 0x10
  1456. +//
  1457. +//#define SUN8I_THS_INT_FIFOC_TEMP_IRQ_EN BIT(18)
  1458. +//#define SUN8I_THS_INT_FIFOC_TP_OVERRUN_IRQ_EN BIT(17)
  1459. +//#define SUN8I_THS_INT_FIFOC_TP_DATA_IRQ_EN BIT(16)
  1460. +//#define SUN8I_THS_INT_FIFOC_TP_DATA_XY_CHANGE BIT(13)
  1461. +//#define SUN8I_THS_INT_FIFOC_TP_FIFO_TRIG_LEVEL(x) ((GENMASK(4, 0) & (x)) << 8)
  1462. +//#define SUN8I_THS_INT_FIFOC_TP_DATA_DRQ_EN BIT(7)
  1463. +//#define SUN8I_THS_INT_FIFOC_TP_FIFO_FLUSH BIT(4)
  1464. +//#define SUN8I_THS_INT_FIFOC_TP_UP_IRQ_EN BIT(1)
  1465. +//#define SUN8I_THS_INT_FIFOC_TP_DOWN_IRQ_EN BIT(0)
  1466. +//
  1467. +//#define SUN8I_THS_INT_FIFOS 0x14
  1468. +//
  1469. +//#define SUN8I_THS_INT_FIFOS_TEMP_DATA_PENDING BIT(18)
  1470. +//#define SUN8I_THS_INT_FIFOS_FIFO_OVERRUN_PENDING BIT(17)
  1471. +//#define SUN8I_THS_INT_FIFOS_FIFO_DATA_PENDING BIT(16)
  1472. +//#define SUN8I_THS_INT_FIFOS_TP_IDLE_FLG BIT(2)
  1473. +//#define SUN8I_THS_INT_FIFOS_TP_UP_PENDING BIT(1)
  1474. +//#define SUN8I_THS_INT_FIFOS_TP_DOWN_PENDING BIT(0)
  1475. +//
  1476. +//#define SUN8I_THS_CDAT 0x1c
  1477. +//#define SUN8I_THS_TEMP_DATA 0x20
  1478. +//#define SUN8I_THS_DATA 0x24
  1479. +//
  1480. +//#define SUN8I_THS_IRQ_FIFO_DATA 0
  1481. +//#define SUN8I_THS_IRQ_TEMP_DATA 1
  1482. +
  1483. +/* 10s delay before suspending the IP */
  1484. +#define SUN8I_THS_AUTOSUSPEND_DELAY 10000
  1485. +
  1486. +struct sun8i_gpadc_dev {
  1487. + struct device *dev;
  1488. + struct regmap *regmap;
  1489. + struct regmap_irq_chip_data *regmap_irqc;
  1490. + void __iomem *base;
  1491. +};
  1492. +
  1493. +#endif
  1494. diff --git a/kernel/cpu.c b/kernel/cpu.c
  1495. index 41376c3ac..006544d88 100644
  1496. --- a/kernel/cpu.c
  1497. +++ b/kernel/cpu.c
  1498. @@ -170,6 +170,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
  1499. if (!(bringup ? step->startup.single : step->teardown.single))
  1500. return 0;
  1501.  
  1502. + pr_err("cpuhp_invoke_callback %d: state == fail\n", cpu);
  1503. return -EAGAIN;
  1504. }
  1505.  
  1506. @@ -181,6 +182,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
  1507. trace_cpuhp_enter(cpu, st->target, state, cb);
  1508. ret = cb(cpu);
  1509. trace_cpuhp_exit(cpu, st->state, state, ret);
  1510. + pr_err("cpuhp_invoke_callback %d: single (target %d, state %d) %d\n", cpu, st->target, state, ret);
  1511. return ret;
  1512. }
  1513. cbm = bringup ? step->startup.multi : step->teardown.multi;
  1514. @@ -193,6 +195,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
  1515. trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node);
  1516. ret = cbm(cpu, node);
  1517. trace_cpuhp_exit(cpu, st->state, state, ret);
  1518. + pr_err("cpuhp_invoke_callback %d: multi %d\n", cpu, ret);
  1519. return ret;
  1520. }
  1521.  
  1522. @@ -206,6 +209,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
  1523. ret = cbm(cpu, node);
  1524. trace_cpuhp_exit(cpu, st->state, state, ret);
  1525. if (ret) {
  1526. + pr_err("cpuhp_invoke_callback %d: multi %d\n", cpu, ret);
  1527. if (!lastp)
  1528. goto err;
  1529.  
  1530. @@ -990,6 +994,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
  1531. cpus_write_lock();
  1532.  
  1533. if (!cpu_present(cpu)) {
  1534. + pr_err("_cpu_up %d: !cpu_present\n", cpu);
  1535. ret = -EINVAL;
  1536. goto out;
  1537. }
  1538. @@ -998,14 +1003,17 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
  1539. * The caller of do_cpu_up might have raced with another
  1540. * caller. Ignore it for now.
  1541. */
  1542. - if (st->state >= target)
  1543. + if (st->state >= target) {
  1544. + pr_err("_cpu_up %d: race? %d <> %d\n", cpu, st->state, target);
  1545. goto out;
  1546. + }
  1547.  
  1548. if (st->state == CPUHP_OFFLINE) {
  1549. /* Let it fail before we try to bring the cpu up */
  1550. idle = idle_thread_get(cpu);
  1551. if (IS_ERR(idle)) {
  1552. ret = PTR_ERR(idle);
  1553. + pr_err("_cpu_up %d: idle_thread_get %d\n", cpu, ret);
  1554. goto out;
  1555. }
  1556. }
  1557. @@ -1023,8 +1031,10 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
  1558. * The AP side has done the error rollback already. Just
  1559. * return the error code..
  1560. */
  1561. - if (ret)
  1562. + if (ret) {
  1563. + pr_err("_cpu_up %d: cpuhp_kick_ap_work %d\n", cpu, ret);
  1564. goto out;
  1565. + }
  1566. }
  1567.  
  1568. /*
  1569. @@ -1034,6 +1044,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
  1570. */
  1571. target = min((int)target, CPUHP_BRINGUP_CPU);
  1572. ret = cpuhp_up_callbacks(cpu, st, target);
  1573. + pr_err("_cpu_up %d: cpuhp_up_callbacks %d\n", cpu, ret);
  1574. out:
  1575. cpus_write_unlock();
  1576. return ret;
  1577. @@ -1053,17 +1064,21 @@ static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
  1578. }
  1579.  
  1580. err = try_online_node(cpu_to_node(cpu));
  1581. - if (err)
  1582. + if (err) {
  1583. + pr_err("do_cpu_up %d: try_online_node %d\n", cpu, err);
  1584. return err;
  1585. + }
  1586.  
  1587. cpu_maps_update_begin();
  1588.  
  1589. if (cpu_hotplug_disabled) {
  1590. + pr_err("do_cpu_up %d: cpu_hotplug_disabled %d\n", cpu, cpu_hotplug_disabled);
  1591. err = -EBUSY;
  1592. goto out;
  1593. }
  1594.  
  1595. err = _cpu_up(cpu, 0, target);
  1596. + pr_err("do_cpu_up %d: _cpu_up %d\n", cpu, err);
  1597. out:
  1598. cpu_maps_update_done();
  1599. return err;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement