ssp_dev.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. /*
  2. * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/iio/iio.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/io.h>
  18. #include <linux/mfd/core.h>
  19. #include <linux/module.h>
  20. #include <linux/of.h>
  21. #include <linux/of_gpio.h>
  22. #include <linux/of_platform.h>
  23. #include "ssp.h"
  24. #define SSP_WDT_TIME 10000
  25. #define SSP_LIMIT_RESET_CNT 20
  26. #define SSP_LIMIT_TIMEOUT_CNT 3
  27. /* It is possible that it is max clk rate for version 1.0 of bootcode */
  28. #define SSP_BOOT_SPI_HZ 400000
  29. /*
  30. * These fields can look enigmatic but this structure is used mainly to flat
  31. * some values and depends on command type.
  32. */
  33. struct ssp_instruction {
  34. __le32 a;
  35. __le32 b;
  36. u8 c;
  37. } __attribute__((__packed__));
  38. static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
  39. 208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
  40. 243, 13, 45, 250};
  41. static const struct ssp_sensorhub_info ssp_rinato_info = {
  42. .fw_name = "ssp_B2.fw",
  43. .fw_crashed_name = "ssp_crashed.fw",
  44. .fw_rev = 14052300,
  45. .mag_table = ssp_magnitude_table,
  46. .mag_length = ARRAY_SIZE(ssp_magnitude_table),
  47. };
  48. static const struct ssp_sensorhub_info ssp_thermostat_info = {
  49. .fw_name = "thermostat_B2.fw",
  50. .fw_crashed_name = "ssp_crashed.fw",
  51. .fw_rev = 14080600,
  52. .mag_table = ssp_magnitude_table,
  53. .mag_length = ARRAY_SIZE(ssp_magnitude_table),
  54. };
  55. static const struct mfd_cell sensorhub_sensor_devs[] = {
  56. {
  57. .name = "ssp-accelerometer",
  58. },
  59. {
  60. .name = "ssp-gyroscope",
  61. },
  62. };
  63. static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
  64. {
  65. gpio_set_value(data->mcu_reset_gpio, 0);
  66. usleep_range(1000, 1200);
  67. gpio_set_value(data->mcu_reset_gpio, 1);
  68. msleep(50);
  69. }
  70. static void ssp_sync_available_sensors(struct ssp_data *data)
  71. {
  72. int i, ret;
  73. for (i = 0; i < SSP_SENSOR_MAX; ++i) {
  74. if (data->available_sensors & BIT(i)) {
  75. ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
  76. if (ret < 0) {
  77. dev_err(&data->spi->dev,
  78. "Sync sensor nr: %d fail\n", i);
  79. continue;
  80. }
  81. }
  82. }
  83. ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
  84. data->mcu_dump_mode);
  85. if (ret < 0)
  86. dev_err(&data->spi->dev,
  87. "SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
  88. }
  89. static void ssp_enable_mcu(struct ssp_data *data, bool enable)
  90. {
  91. dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
  92. data->shut_down);
  93. if (enable && data->shut_down) {
  94. data->shut_down = false;
  95. enable_irq(data->spi->irq);
  96. enable_irq_wake(data->spi->irq);
  97. } else if (!enable && !data->shut_down) {
  98. data->shut_down = true;
  99. disable_irq(data->spi->irq);
  100. disable_irq_wake(data->spi->irq);
  101. } else {
  102. dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
  103. enable, data->shut_down);
  104. }
  105. }
  106. /*
  107. * This function is the first one which communicates with the mcu so it is
  108. * possible that the first attempt will fail
  109. */
  110. static int ssp_check_fwbl(struct ssp_data *data)
  111. {
  112. int retries = 0;
  113. while (retries++ < 5) {
  114. data->cur_firm_rev = ssp_get_firmware_rev(data);
  115. if (data->cur_firm_rev == SSP_INVALID_REVISION ||
  116. data->cur_firm_rev == SSP_INVALID_REVISION2) {
  117. dev_warn(&data->spi->dev,
  118. "Invalid revision, trying %d time\n", retries);
  119. } else {
  120. break;
  121. }
  122. }
  123. if (data->cur_firm_rev == SSP_INVALID_REVISION ||
  124. data->cur_firm_rev == SSP_INVALID_REVISION2) {
  125. dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
  126. return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
  127. }
  128. dev_info(&data->spi->dev,
  129. "MCU Firm Rev : Old = %8u, New = %8u\n",
  130. data->cur_firm_rev,
  131. data->sensorhub_info->fw_rev);
  132. if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
  133. return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
  134. return SSP_FW_DL_STATE_NONE;
  135. }
  136. static void ssp_reset_mcu(struct ssp_data *data)
  137. {
  138. ssp_enable_mcu(data, false);
  139. ssp_clean_pending_list(data);
  140. ssp_toggle_mcu_reset_gpio(data);
  141. ssp_enable_mcu(data, true);
  142. }
  143. static void ssp_wdt_work_func(struct work_struct *work)
  144. {
  145. struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
  146. dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
  147. __func__, data->available_sensors, data->reset_cnt,
  148. data->com_fail_cnt);
  149. ssp_reset_mcu(data);
  150. data->com_fail_cnt = 0;
  151. data->timeout_cnt = 0;
  152. }
  153. static void ssp_wdt_timer_func(unsigned long ptr)
  154. {
  155. struct ssp_data *data = (struct ssp_data *)ptr;
  156. switch (data->fw_dl_state) {
  157. case SSP_FW_DL_STATE_FAIL:
  158. case SSP_FW_DL_STATE_DOWNLOADING:
  159. case SSP_FW_DL_STATE_SYNC:
  160. goto _mod;
  161. }
  162. if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
  163. data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
  164. queue_work(system_power_efficient_wq, &data->work_wdt);
  165. _mod:
  166. mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
  167. }
  168. static void ssp_enable_wdt_timer(struct ssp_data *data)
  169. {
  170. mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
  171. }
  172. static void ssp_disable_wdt_timer(struct ssp_data *data)
  173. {
  174. del_timer_sync(&data->wdt_timer);
  175. cancel_work_sync(&data->work_wdt);
  176. }
  177. /**
  178. * ssp_get_sensor_delay() - gets sensor data acquisition period
  179. * @data: sensorhub structure
  180. * @type: SSP sensor type
  181. *
  182. * Returns acquisition period in ms
  183. */
  184. u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
  185. {
  186. return data->delay_buf[type];
  187. }
  188. EXPORT_SYMBOL(ssp_get_sensor_delay);
  189. /**
  190. * ssp_enable_sensor() - enables data acquisition for sensor
  191. * @data: sensorhub structure
  192. * @type: SSP sensor type
  193. * @delay: delay in ms
  194. *
  195. * Returns 0 or negative value in case of error
  196. */
  197. int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
  198. u32 delay)
  199. {
  200. int ret;
  201. struct ssp_instruction to_send;
  202. to_send.a = cpu_to_le32(delay);
  203. to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
  204. to_send.c = data->batch_opt_buf[type];
  205. switch (data->check_status[type]) {
  206. case SSP_INITIALIZATION_STATE:
  207. /* do calibration step, now just enable */
  208. case SSP_ADD_SENSOR_STATE:
  209. ret = ssp_send_instruction(data,
  210. SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
  211. type,
  212. (u8 *)&to_send, sizeof(to_send));
  213. if (ret < 0) {
  214. dev_err(&data->spi->dev, "Enabling sensor failed\n");
  215. data->check_status[type] = SSP_NO_SENSOR_STATE;
  216. goto derror;
  217. }
  218. data->sensor_enable |= BIT(type);
  219. data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
  220. break;
  221. case SSP_RUNNING_SENSOR_STATE:
  222. ret = ssp_send_instruction(data,
  223. SSP_MSG2SSP_INST_CHANGE_DELAY, type,
  224. (u8 *)&to_send, sizeof(to_send));
  225. if (ret < 0) {
  226. dev_err(&data->spi->dev,
  227. "Changing sensor delay failed\n");
  228. goto derror;
  229. }
  230. break;
  231. default:
  232. data->check_status[type] = SSP_ADD_SENSOR_STATE;
  233. break;
  234. }
  235. data->delay_buf[type] = delay;
  236. if (atomic_inc_return(&data->enable_refcount) == 1)
  237. ssp_enable_wdt_timer(data);
  238. return 0;
  239. derror:
  240. return ret;
  241. }
  242. EXPORT_SYMBOL(ssp_enable_sensor);
  243. /**
  244. * ssp_change_delay() - changes data acquisition for sensor
  245. * @data: sensorhub structure
  246. * @type: SSP sensor type
  247. * @delay: delay in ms
  248. *
  249. * Returns 0 or negative value in case of error
  250. */
  251. int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
  252. u32 delay)
  253. {
  254. int ret;
  255. struct ssp_instruction to_send;
  256. to_send.a = cpu_to_le32(delay);
  257. to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
  258. to_send.c = data->batch_opt_buf[type];
  259. ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
  260. (u8 *)&to_send, sizeof(to_send));
  261. if (ret < 0) {
  262. dev_err(&data->spi->dev, "Changing sensor delay failed\n");
  263. return ret;
  264. }
  265. data->delay_buf[type] = delay;
  266. return 0;
  267. }
  268. EXPORT_SYMBOL(ssp_change_delay);
  269. /**
  270. * ssp_disable_sensor() - disables sensor
  271. *
  272. * @data: sensorhub structure
  273. * @type: SSP sensor type
  274. *
  275. * Returns 0 or negative value in case of error
  276. */
  277. int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
  278. {
  279. int ret;
  280. __le32 command;
  281. if (data->sensor_enable & BIT(type)) {
  282. command = cpu_to_le32(data->delay_buf[type]);
  283. ret = ssp_send_instruction(data,
  284. SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
  285. type, (u8 *)&command,
  286. sizeof(command));
  287. if (ret < 0) {
  288. dev_err(&data->spi->dev, "Remove sensor fail\n");
  289. return ret;
  290. }
  291. data->sensor_enable &= ~BIT(type);
  292. }
  293. data->check_status[type] = SSP_ADD_SENSOR_STATE;
  294. if (atomic_dec_and_test(&data->enable_refcount))
  295. ssp_disable_wdt_timer(data);
  296. return 0;
  297. }
  298. EXPORT_SYMBOL(ssp_disable_sensor);
  299. static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
  300. {
  301. struct ssp_data *data = dev_id;
  302. /*
  303. * This wrapper is done to preserve error path for ssp_irq_msg, also
  304. * it is defined in different file.
  305. */
  306. ssp_irq_msg(data);
  307. return IRQ_HANDLED;
  308. }
  309. static int ssp_initialize_mcu(struct ssp_data *data)
  310. {
  311. int ret;
  312. ssp_clean_pending_list(data);
  313. ret = ssp_get_chipid(data);
  314. if (ret != SSP_DEVICE_ID) {
  315. dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
  316. ret < 0 ? "is not working" : "identification failed",
  317. ret);
  318. return ret < 0 ? ret : -ENODEV;
  319. }
  320. dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
  321. /*
  322. * needs clarification, for now do not want to export all transfer
  323. * methods to sensors' drivers
  324. */
  325. ret = ssp_set_magnetic_matrix(data);
  326. if (ret < 0) {
  327. dev_err(&data->spi->dev,
  328. "%s - ssp_set_magnetic_matrix failed\n", __func__);
  329. return ret;
  330. }
  331. data->available_sensors = ssp_get_sensor_scanning_info(data);
  332. if (data->available_sensors == 0) {
  333. dev_err(&data->spi->dev,
  334. "%s - ssp_get_sensor_scanning_info failed\n", __func__);
  335. return -EIO;
  336. }
  337. data->cur_firm_rev = ssp_get_firmware_rev(data);
  338. dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
  339. data->cur_firm_rev);
  340. return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
  341. }
  342. /*
  343. * sensorhub can request its reinitialization as some brutal and rare error
  344. * handling. It can be requested from the MCU.
  345. */
  346. static void ssp_refresh_task(struct work_struct *work)
  347. {
  348. struct ssp_data *data = container_of((struct delayed_work *)work,
  349. struct ssp_data, work_refresh);
  350. dev_info(&data->spi->dev, "refreshing\n");
  351. data->reset_cnt++;
  352. if (ssp_initialize_mcu(data) >= 0) {
  353. ssp_sync_available_sensors(data);
  354. if (data->last_ap_state != 0)
  355. ssp_command(data, data->last_ap_state, 0);
  356. if (data->last_resume_state != 0)
  357. ssp_command(data, data->last_resume_state, 0);
  358. data->timeout_cnt = 0;
  359. data->com_fail_cnt = 0;
  360. }
  361. }
  362. int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
  363. {
  364. cancel_delayed_work_sync(&data->work_refresh);
  365. return queue_delayed_work(system_power_efficient_wq,
  366. &data->work_refresh,
  367. msecs_to_jiffies(delay));
  368. }
  369. #ifdef CONFIG_OF
  370. static const struct of_device_id ssp_of_match[] = {
  371. {
  372. .compatible = "samsung,sensorhub-rinato",
  373. .data = &ssp_rinato_info,
  374. }, {
  375. .compatible = "samsung,sensorhub-thermostat",
  376. .data = &ssp_thermostat_info,
  377. },
  378. {},
  379. };
  380. MODULE_DEVICE_TABLE(of, ssp_of_match);
  381. static struct ssp_data *ssp_parse_dt(struct device *dev)
  382. {
  383. int ret;
  384. struct ssp_data *data;
  385. struct device_node *node = dev->of_node;
  386. const struct of_device_id *match;
  387. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  388. if (!data)
  389. return NULL;
  390. data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0);
  391. if (data->mcu_ap_gpio < 0)
  392. goto err_free_pd;
  393. data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0);
  394. if (data->ap_mcu_gpio < 0)
  395. goto err_free_pd;
  396. data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0);
  397. if (data->mcu_reset_gpio < 0)
  398. goto err_free_pd;
  399. ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH,
  400. "ap-mcu-gpios");
  401. if (ret)
  402. goto err_free_pd;
  403. ret = devm_gpio_request_one(dev, data->mcu_reset_gpio,
  404. GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios");
  405. if (ret)
  406. goto err_ap_mcu;
  407. match = of_match_node(ssp_of_match, node);
  408. if (!match)
  409. goto err_mcu_reset_gpio;
  410. data->sensorhub_info = (struct ssp_sensorhub_info *)match->data;
  411. dev_set_drvdata(dev, data);
  412. return data;
  413. err_mcu_reset_gpio:
  414. devm_gpio_free(dev, data->mcu_reset_gpio);
  415. err_ap_mcu:
  416. devm_gpio_free(dev, data->ap_mcu_gpio);
  417. err_free_pd:
  418. devm_kfree(dev, data);
  419. return NULL;
  420. }
  421. #else
  422. static struct ssp_data *ssp_parse_dt(struct device *pdev)
  423. {
  424. return NULL;
  425. }
  426. #endif
  427. /**
  428. * ssp_register_consumer() - registers iio consumer in ssp framework
  429. *
  430. * @indio_dev: consumer iio device
  431. * @type: ssp sensor type
  432. */
  433. void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
  434. {
  435. struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
  436. data->sensor_devs[type] = indio_dev;
  437. }
  438. EXPORT_SYMBOL(ssp_register_consumer);
  439. static int ssp_probe(struct spi_device *spi)
  440. {
  441. int ret, i;
  442. struct ssp_data *data;
  443. data = ssp_parse_dt(&spi->dev);
  444. if (!data) {
  445. dev_err(&spi->dev, "Failed to find platform data\n");
  446. return -ENODEV;
  447. }
  448. ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs,
  449. ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
  450. if (ret < 0) {
  451. dev_err(&spi->dev, "mfd add devices fail\n");
  452. return ret;
  453. }
  454. spi->mode = SPI_MODE_1;
  455. ret = spi_setup(spi);
  456. if (ret < 0) {
  457. dev_err(&spi->dev, "Failed to setup spi\n");
  458. return ret;
  459. }
  460. data->fw_dl_state = SSP_FW_DL_STATE_NONE;
  461. data->spi = spi;
  462. spi_set_drvdata(spi, data);
  463. mutex_init(&data->comm_lock);
  464. for (i = 0; i < SSP_SENSOR_MAX; ++i) {
  465. data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
  466. data->batch_latency_buf[i] = 0;
  467. data->batch_opt_buf[i] = 0;
  468. data->check_status[i] = SSP_INITIALIZATION_STATE;
  469. }
  470. data->delay_buf[SSP_BIO_HRM_LIB] = 100;
  471. data->time_syncing = true;
  472. mutex_init(&data->pending_lock);
  473. INIT_LIST_HEAD(&data->pending_list);
  474. atomic_set(&data->enable_refcount, 0);
  475. INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
  476. INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
  477. setup_timer(&data->wdt_timer, ssp_wdt_timer_func, (unsigned long)data);
  478. ret = request_threaded_irq(data->spi->irq, NULL,
  479. ssp_irq_thread_fn,
  480. IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  481. "SSP_Int", data);
  482. if (ret < 0) {
  483. dev_err(&spi->dev, "Irq request fail\n");
  484. goto err_setup_irq;
  485. }
  486. /* Let's start with enabled one so irq balance could be ok */
  487. data->shut_down = false;
  488. /* just to avoid unbalanced irq set wake up */
  489. enable_irq_wake(data->spi->irq);
  490. data->fw_dl_state = ssp_check_fwbl(data);
  491. if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
  492. ret = ssp_initialize_mcu(data);
  493. if (ret < 0) {
  494. dev_err(&spi->dev, "Initialize_mcu failed\n");
  495. goto err_read_reg;
  496. }
  497. } else {
  498. dev_err(&spi->dev, "Firmware version not supported\n");
  499. ret = -EPERM;
  500. goto err_read_reg;
  501. }
  502. return 0;
  503. err_read_reg:
  504. free_irq(data->spi->irq, data);
  505. err_setup_irq:
  506. mutex_destroy(&data->pending_lock);
  507. mutex_destroy(&data->comm_lock);
  508. dev_err(&spi->dev, "Probe failed!\n");
  509. return ret;
  510. }
  511. static int ssp_remove(struct spi_device *spi)
  512. {
  513. struct ssp_data *data = spi_get_drvdata(spi);
  514. if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
  515. dev_err(&data->spi->dev,
  516. "SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
  517. ssp_enable_mcu(data, false);
  518. ssp_disable_wdt_timer(data);
  519. ssp_clean_pending_list(data);
  520. free_irq(data->spi->irq, data);
  521. del_timer_sync(&data->wdt_timer);
  522. cancel_work_sync(&data->work_wdt);
  523. mutex_destroy(&data->comm_lock);
  524. mutex_destroy(&data->pending_lock);
  525. mfd_remove_devices(&spi->dev);
  526. return 0;
  527. }
  528. #ifdef CONFIG_PM_SLEEP
  529. static int ssp_suspend(struct device *dev)
  530. {
  531. int ret;
  532. struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
  533. data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
  534. if (atomic_read(&data->enable_refcount) > 0)
  535. ssp_disable_wdt_timer(data);
  536. ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
  537. if (ret < 0) {
  538. dev_err(&data->spi->dev,
  539. "%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
  540. ssp_enable_wdt_timer(data);
  541. return ret;
  542. }
  543. data->time_syncing = false;
  544. disable_irq(data->spi->irq);
  545. return 0;
  546. }
  547. static int ssp_resume(struct device *dev)
  548. {
  549. int ret;
  550. struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
  551. enable_irq(data->spi->irq);
  552. if (atomic_read(&data->enable_refcount) > 0)
  553. ssp_enable_wdt_timer(data);
  554. ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
  555. if (ret < 0) {
  556. dev_err(&data->spi->dev,
  557. "%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
  558. ssp_disable_wdt_timer(data);
  559. return ret;
  560. }
  561. /* timesyncing is set by MCU */
  562. data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
  563. return 0;
  564. }
  565. #endif /* CONFIG_PM_SLEEP */
  566. static const struct dev_pm_ops ssp_pm_ops = {
  567. SET_SYSTEM_SLEEP_PM_OPS(ssp_suspend, ssp_resume)
  568. };
  569. static struct spi_driver ssp_driver = {
  570. .probe = ssp_probe,
  571. .remove = ssp_remove,
  572. .driver = {
  573. .pm = &ssp_pm_ops,
  574. .of_match_table = of_match_ptr(ssp_of_match),
  575. .name = "sensorhub"
  576. },
  577. };
  578. module_spi_driver(ssp_driver);
  579. MODULE_DESCRIPTION("ssp sensorhub driver");
  580. MODULE_AUTHOR("Samsung Electronics");
  581. MODULE_LICENSE("GPL");