ziirave_wdt.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2015 Zodiac Inflight Innovations
  4. *
  5. * Author: Martyn Welch <martyn.welch@collabora.co.uk>
  6. *
  7. * Based on twl4030_wdt.c by Timo Kokkonen <timo.t.kokkonen at nokia.com>:
  8. *
  9. * Copyright (C) Nokia Corporation
  10. */
  11. #include <linux/delay.h>
  12. #include <linux/i2c.h>
  13. #include <linux/ihex.h>
  14. #include <linux/firmware.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <linux/sysfs.h>
  19. #include <linux/types.h>
  20. #include <linux/version.h>
  21. #include <linux/watchdog.h>
  22. #include <asm/unaligned.h>
  23. #define ZIIRAVE_TIMEOUT_MIN 3
  24. #define ZIIRAVE_TIMEOUT_MAX 255
  25. #define ZIIRAVE_TIMEOUT_DEFAULT 30
  26. #define ZIIRAVE_PING_VALUE 0x0
  27. #define ZIIRAVE_STATE_INITIAL 0x0
  28. #define ZIIRAVE_STATE_OFF 0x1
  29. #define ZIIRAVE_STATE_ON 0x2
  30. #define ZIIRAVE_FW_NAME "ziirave_wdt.fw"
  31. static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL,
  32. "host request", NULL, "illegal configuration",
  33. "illegal instruction", "illegal trap",
  34. "unknown"};
  35. #define ZIIRAVE_WDT_FIRM_VER_MAJOR 0x1
  36. #define ZIIRAVE_WDT_BOOT_VER_MAJOR 0x3
  37. #define ZIIRAVE_WDT_RESET_REASON 0x5
  38. #define ZIIRAVE_WDT_STATE 0x6
  39. #define ZIIRAVE_WDT_TIMEOUT 0x7
  40. #define ZIIRAVE_WDT_TIME_LEFT 0x8
  41. #define ZIIRAVE_WDT_PING 0x9
  42. #define ZIIRAVE_WDT_RESET_DURATION 0xa
  43. #define ZIIRAVE_FIRM_PKT_TOTAL_SIZE 20
  44. #define ZIIRAVE_FIRM_PKT_DATA_SIZE 16
  45. #define ZIIRAVE_FIRM_FLASH_MEMORY_START (2 * 0x1600)
  46. #define ZIIRAVE_FIRM_FLASH_MEMORY_END (2 * 0x2bbf)
  47. #define ZIIRAVE_FIRM_PAGE_SIZE 128
  48. /* Received and ready for next Download packet. */
  49. #define ZIIRAVE_FIRM_DOWNLOAD_ACK 1
  50. /* Firmware commands */
  51. #define ZIIRAVE_CMD_DOWNLOAD_START 0x10
  52. #define ZIIRAVE_CMD_DOWNLOAD_END 0x11
  53. #define ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR 0x12
  54. #define ZIIRAVE_CMD_DOWNLOAD_READ_BYTE 0x13
  55. #define ZIIRAVE_CMD_RESET_PROCESSOR 0x0b
  56. #define ZIIRAVE_CMD_JUMP_TO_BOOTLOADER 0x0c
  57. #define ZIIRAVE_CMD_DOWNLOAD_PACKET 0x0e
  58. #define ZIIRAVE_CMD_JUMP_TO_BOOTLOADER_MAGIC 1
  59. #define ZIIRAVE_CMD_RESET_PROCESSOR_MAGIC 1
  60. #define ZIIRAVE_FW_VERSION_FMT "02.%02u.%02u"
  61. #define ZIIRAVE_BL_VERSION_FMT "01.%02u.%02u"
  62. struct ziirave_wdt_rev {
  63. unsigned char major;
  64. unsigned char minor;
  65. };
  66. struct ziirave_wdt_data {
  67. struct mutex sysfs_mutex;
  68. struct watchdog_device wdd;
  69. struct ziirave_wdt_rev bootloader_rev;
  70. struct ziirave_wdt_rev firmware_rev;
  71. int reset_reason;
  72. };
  73. static int wdt_timeout;
  74. module_param(wdt_timeout, int, 0);
  75. MODULE_PARM_DESC(wdt_timeout, "Watchdog timeout in seconds");
  76. static int reset_duration;
  77. module_param(reset_duration, int, 0);
  78. MODULE_PARM_DESC(reset_duration,
  79. "Watchdog reset pulse duration in milliseconds");
  80. static bool nowayout = WATCHDOG_NOWAYOUT;
  81. module_param(nowayout, bool, 0);
  82. MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default="
  83. __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  84. static int ziirave_wdt_revision(struct i2c_client *client,
  85. struct ziirave_wdt_rev *rev, u8 command)
  86. {
  87. int ret;
  88. ret = i2c_smbus_read_byte_data(client, command);
  89. if (ret < 0)
  90. return ret;
  91. rev->major = ret;
  92. ret = i2c_smbus_read_byte_data(client, command + 1);
  93. if (ret < 0)
  94. return ret;
  95. rev->minor = ret;
  96. return 0;
  97. }
  98. static int ziirave_wdt_set_state(struct watchdog_device *wdd, int state)
  99. {
  100. struct i2c_client *client = to_i2c_client(wdd->parent);
  101. return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_STATE, state);
  102. }
  103. static int ziirave_wdt_start(struct watchdog_device *wdd)
  104. {
  105. return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_ON);
  106. }
  107. static int ziirave_wdt_stop(struct watchdog_device *wdd)
  108. {
  109. return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_OFF);
  110. }
  111. static int ziirave_wdt_ping(struct watchdog_device *wdd)
  112. {
  113. struct i2c_client *client = to_i2c_client(wdd->parent);
  114. return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_PING,
  115. ZIIRAVE_PING_VALUE);
  116. }
  117. static int ziirave_wdt_set_timeout(struct watchdog_device *wdd,
  118. unsigned int timeout)
  119. {
  120. struct i2c_client *client = to_i2c_client(wdd->parent);
  121. int ret;
  122. ret = i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_TIMEOUT, timeout);
  123. if (!ret)
  124. wdd->timeout = timeout;
  125. return ret;
  126. }
  127. static unsigned int ziirave_wdt_get_timeleft(struct watchdog_device *wdd)
  128. {
  129. struct i2c_client *client = to_i2c_client(wdd->parent);
  130. int ret;
  131. ret = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIME_LEFT);
  132. if (ret < 0)
  133. ret = 0;
  134. return ret;
  135. }
  136. static int ziirave_firm_read_ack(struct watchdog_device *wdd)
  137. {
  138. struct i2c_client *client = to_i2c_client(wdd->parent);
  139. int ret;
  140. ret = i2c_smbus_read_byte(client);
  141. if (ret < 0) {
  142. dev_err(&client->dev, "Failed to read status byte\n");
  143. return ret;
  144. }
  145. return ret == ZIIRAVE_FIRM_DOWNLOAD_ACK ? 0 : -EIO;
  146. }
  147. static int ziirave_firm_set_read_addr(struct watchdog_device *wdd, u32 addr)
  148. {
  149. struct i2c_client *client = to_i2c_client(wdd->parent);
  150. const u16 addr16 = (u16)addr / 2;
  151. u8 address[2];
  152. put_unaligned_le16(addr16, address);
  153. return i2c_smbus_write_block_data(client,
  154. ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR,
  155. sizeof(address), address);
  156. }
  157. static bool ziirave_firm_addr_readonly(u32 addr)
  158. {
  159. return addr < ZIIRAVE_FIRM_FLASH_MEMORY_START ||
  160. addr > ZIIRAVE_FIRM_FLASH_MEMORY_END;
  161. }
  162. /*
  163. * ziirave_firm_write_pkt() - Build and write a firmware packet
  164. *
  165. * A packet to send to the firmware is composed by following bytes:
  166. * Length | Addr0 | Addr1 | Data0 .. Data15 | Checksum |
  167. * Where,
  168. * Length: A data byte containing the length of the data.
  169. * Addr0: Low byte of the address.
  170. * Addr1: High byte of the address.
  171. * Data0 .. Data15: Array of 16 bytes of data.
  172. * Checksum: Checksum byte to verify data integrity.
  173. */
  174. static int __ziirave_firm_write_pkt(struct watchdog_device *wdd,
  175. u32 addr, const u8 *data, u8 len)
  176. {
  177. const u16 addr16 = (u16)addr / 2;
  178. struct i2c_client *client = to_i2c_client(wdd->parent);
  179. u8 i, checksum = 0, packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE];
  180. int ret;
  181. /* Check max data size */
  182. if (len > ZIIRAVE_FIRM_PKT_DATA_SIZE) {
  183. dev_err(&client->dev, "Firmware packet too long (%d)\n",
  184. len);
  185. return -EMSGSIZE;
  186. }
  187. /*
  188. * Ignore packets that are targeting program memory outisde of
  189. * app partition, since they will be ignored by the
  190. * bootloader. At the same time, we need to make sure we'll
  191. * allow zero length packet that will be sent as the last step
  192. * of firmware update
  193. */
  194. if (len && ziirave_firm_addr_readonly(addr))
  195. return 0;
  196. /* Packet length */
  197. packet[0] = len;
  198. /* Packet address */
  199. put_unaligned_le16(addr16, packet + 1);
  200. memcpy(packet + 3, data, len);
  201. memset(packet + 3 + len, 0, ZIIRAVE_FIRM_PKT_DATA_SIZE - len);
  202. /* Packet checksum */
  203. for (i = 0; i < len + 3; i++)
  204. checksum += packet[i];
  205. packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1] = checksum;
  206. ret = i2c_smbus_write_block_data(client, ZIIRAVE_CMD_DOWNLOAD_PACKET,
  207. sizeof(packet), packet);
  208. if (ret) {
  209. dev_err(&client->dev,
  210. "Failed to send DOWNLOAD_PACKET: %d\n", ret);
  211. return ret;
  212. }
  213. ret = ziirave_firm_read_ack(wdd);
  214. if (ret)
  215. dev_err(&client->dev,
  216. "Failed to write firmware packet at address 0x%04x: %d\n",
  217. addr, ret);
  218. return ret;
  219. }
  220. static int ziirave_firm_write_pkt(struct watchdog_device *wdd,
  221. u32 addr, const u8 *data, u8 len)
  222. {
  223. const u8 max_write_len = ZIIRAVE_FIRM_PAGE_SIZE -
  224. (addr - ALIGN_DOWN(addr, ZIIRAVE_FIRM_PAGE_SIZE));
  225. int ret;
  226. if (len > max_write_len) {
  227. /*
  228. * If data crossed page boundary we need to split this
  229. * write in two
  230. */
  231. ret = __ziirave_firm_write_pkt(wdd, addr, data, max_write_len);
  232. if (ret)
  233. return ret;
  234. addr += max_write_len;
  235. data += max_write_len;
  236. len -= max_write_len;
  237. }
  238. return __ziirave_firm_write_pkt(wdd, addr, data, len);
  239. }
  240. static int ziirave_firm_verify(struct watchdog_device *wdd,
  241. const struct firmware *fw)
  242. {
  243. struct i2c_client *client = to_i2c_client(wdd->parent);
  244. const struct ihex_binrec *rec;
  245. int i, ret;
  246. u8 data[ZIIRAVE_FIRM_PKT_DATA_SIZE];
  247. for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
  248. const u16 len = be16_to_cpu(rec->len);
  249. const u32 addr = be32_to_cpu(rec->addr);
  250. if (ziirave_firm_addr_readonly(addr))
  251. continue;
  252. ret = ziirave_firm_set_read_addr(wdd, addr);
  253. if (ret) {
  254. dev_err(&client->dev,
  255. "Failed to send SET_READ_ADDR command: %d\n",
  256. ret);
  257. return ret;
  258. }
  259. for (i = 0; i < len; i++) {
  260. ret = i2c_smbus_read_byte_data(client,
  261. ZIIRAVE_CMD_DOWNLOAD_READ_BYTE);
  262. if (ret < 0) {
  263. dev_err(&client->dev,
  264. "Failed to READ DATA: %d\n", ret);
  265. return ret;
  266. }
  267. data[i] = ret;
  268. }
  269. if (memcmp(data, rec->data, len)) {
  270. dev_err(&client->dev,
  271. "Firmware mismatch at address 0x%04x\n", addr);
  272. return -EINVAL;
  273. }
  274. }
  275. return 0;
  276. }
  277. static int ziirave_firm_upload(struct watchdog_device *wdd,
  278. const struct firmware *fw)
  279. {
  280. struct i2c_client *client = to_i2c_client(wdd->parent);
  281. const struct ihex_binrec *rec;
  282. int ret;
  283. ret = i2c_smbus_write_byte_data(client,
  284. ZIIRAVE_CMD_JUMP_TO_BOOTLOADER,
  285. ZIIRAVE_CMD_JUMP_TO_BOOTLOADER_MAGIC);
  286. if (ret) {
  287. dev_err(&client->dev, "Failed to jump to bootloader\n");
  288. return ret;
  289. }
  290. msleep(500);
  291. ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_START);
  292. if (ret) {
  293. dev_err(&client->dev, "Failed to start download\n");
  294. return ret;
  295. }
  296. ret = ziirave_firm_read_ack(wdd);
  297. if (ret) {
  298. dev_err(&client->dev, "No ACK for start download\n");
  299. return ret;
  300. }
  301. msleep(500);
  302. for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
  303. ret = ziirave_firm_write_pkt(wdd, be32_to_cpu(rec->addr),
  304. rec->data, be16_to_cpu(rec->len));
  305. if (ret)
  306. return ret;
  307. }
  308. /*
  309. * Finish firmware download process by sending a zero length
  310. * payload
  311. */
  312. ret = ziirave_firm_write_pkt(wdd, 0, NULL, 0);
  313. if (ret) {
  314. dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret);
  315. return ret;
  316. }
  317. /* This sleep seems to be required */
  318. msleep(20);
  319. /* Start firmware verification */
  320. ret = ziirave_firm_verify(wdd, fw);
  321. if (ret) {
  322. dev_err(&client->dev,
  323. "Failed to verify firmware: %d\n", ret);
  324. return ret;
  325. }
  326. /* End download operation */
  327. ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_END);
  328. if (ret) {
  329. dev_err(&client->dev,
  330. "Failed to end firmware download: %d\n", ret);
  331. return ret;
  332. }
  333. /* Reset the processor */
  334. ret = i2c_smbus_write_byte_data(client,
  335. ZIIRAVE_CMD_RESET_PROCESSOR,
  336. ZIIRAVE_CMD_RESET_PROCESSOR_MAGIC);
  337. if (ret) {
  338. dev_err(&client->dev,
  339. "Failed to reset the watchdog: %d\n", ret);
  340. return ret;
  341. }
  342. msleep(500);
  343. return 0;
  344. }
  345. static const struct watchdog_info ziirave_wdt_info = {
  346. .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
  347. .identity = "Zodiac RAVE Watchdog",
  348. };
  349. static const struct watchdog_ops ziirave_wdt_ops = {
  350. .owner = THIS_MODULE,
  351. .start = ziirave_wdt_start,
  352. .stop = ziirave_wdt_stop,
  353. .ping = ziirave_wdt_ping,
  354. .set_timeout = ziirave_wdt_set_timeout,
  355. .get_timeleft = ziirave_wdt_get_timeleft,
  356. };
  357. static ssize_t ziirave_wdt_sysfs_show_firm(struct device *dev,
  358. struct device_attribute *attr,
  359. char *buf)
  360. {
  361. struct i2c_client *client = to_i2c_client(dev->parent);
  362. struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
  363. int ret;
  364. ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
  365. if (ret)
  366. return ret;
  367. ret = sprintf(buf, ZIIRAVE_FW_VERSION_FMT, w_priv->firmware_rev.major,
  368. w_priv->firmware_rev.minor);
  369. mutex_unlock(&w_priv->sysfs_mutex);
  370. return ret;
  371. }
  372. static DEVICE_ATTR(firmware_version, S_IRUGO, ziirave_wdt_sysfs_show_firm,
  373. NULL);
  374. static ssize_t ziirave_wdt_sysfs_show_boot(struct device *dev,
  375. struct device_attribute *attr,
  376. char *buf)
  377. {
  378. struct i2c_client *client = to_i2c_client(dev->parent);
  379. struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
  380. int ret;
  381. ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
  382. if (ret)
  383. return ret;
  384. ret = sprintf(buf, ZIIRAVE_BL_VERSION_FMT, w_priv->bootloader_rev.major,
  385. w_priv->bootloader_rev.minor);
  386. mutex_unlock(&w_priv->sysfs_mutex);
  387. return ret;
  388. }
  389. static DEVICE_ATTR(bootloader_version, S_IRUGO, ziirave_wdt_sysfs_show_boot,
  390. NULL);
  391. static ssize_t ziirave_wdt_sysfs_show_reason(struct device *dev,
  392. struct device_attribute *attr,
  393. char *buf)
  394. {
  395. struct i2c_client *client = to_i2c_client(dev->parent);
  396. struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
  397. int ret;
  398. ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
  399. if (ret)
  400. return ret;
  401. ret = sprintf(buf, "%s", ziirave_reasons[w_priv->reset_reason]);
  402. mutex_unlock(&w_priv->sysfs_mutex);
  403. return ret;
  404. }
  405. static DEVICE_ATTR(reset_reason, S_IRUGO, ziirave_wdt_sysfs_show_reason,
  406. NULL);
  407. static ssize_t ziirave_wdt_sysfs_store_firm(struct device *dev,
  408. struct device_attribute *attr,
  409. const char *buf, size_t count)
  410. {
  411. struct i2c_client *client = to_i2c_client(dev->parent);
  412. struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
  413. const struct firmware *fw;
  414. int err;
  415. err = request_ihex_firmware(&fw, ZIIRAVE_FW_NAME, dev);
  416. if (err) {
  417. dev_err(&client->dev, "Failed to request ihex firmware\n");
  418. return err;
  419. }
  420. err = mutex_lock_interruptible(&w_priv->sysfs_mutex);
  421. if (err)
  422. goto release_firmware;
  423. err = ziirave_firm_upload(&w_priv->wdd, fw);
  424. if (err) {
  425. dev_err(&client->dev, "The firmware update failed: %d\n", err);
  426. goto unlock_mutex;
  427. }
  428. /* Update firmware version */
  429. err = ziirave_wdt_revision(client, &w_priv->firmware_rev,
  430. ZIIRAVE_WDT_FIRM_VER_MAJOR);
  431. if (err) {
  432. dev_err(&client->dev, "Failed to read firmware version: %d\n",
  433. err);
  434. goto unlock_mutex;
  435. }
  436. dev_info(&client->dev,
  437. "Firmware updated to version " ZIIRAVE_FW_VERSION_FMT "\n",
  438. w_priv->firmware_rev.major, w_priv->firmware_rev.minor);
  439. /* Restore the watchdog timeout */
  440. err = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout);
  441. if (err)
  442. dev_err(&client->dev, "Failed to set timeout: %d\n", err);
  443. unlock_mutex:
  444. mutex_unlock(&w_priv->sysfs_mutex);
  445. release_firmware:
  446. release_firmware(fw);
  447. return err ? err : count;
  448. }
  449. static DEVICE_ATTR(update_firmware, S_IWUSR, NULL,
  450. ziirave_wdt_sysfs_store_firm);
  451. static struct attribute *ziirave_wdt_attrs[] = {
  452. &dev_attr_firmware_version.attr,
  453. &dev_attr_bootloader_version.attr,
  454. &dev_attr_reset_reason.attr,
  455. &dev_attr_update_firmware.attr,
  456. NULL
  457. };
  458. ATTRIBUTE_GROUPS(ziirave_wdt);
  459. static int ziirave_wdt_init_duration(struct i2c_client *client)
  460. {
  461. int ret;
  462. if (!reset_duration) {
  463. /* See if the reset pulse duration is provided in an of_node */
  464. if (!client->dev.of_node)
  465. ret = -ENODEV;
  466. else
  467. ret = of_property_read_u32(client->dev.of_node,
  468. "reset-duration-ms",
  469. &reset_duration);
  470. if (ret) {
  471. dev_info(&client->dev,
  472. "No reset pulse duration specified, using default\n");
  473. return 0;
  474. }
  475. }
  476. if (reset_duration < 1 || reset_duration > 255)
  477. return -EINVAL;
  478. dev_info(&client->dev, "Setting reset duration to %dms",
  479. reset_duration);
  480. return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_RESET_DURATION,
  481. reset_duration);
  482. }
  483. static int ziirave_wdt_probe(struct i2c_client *client,
  484. const struct i2c_device_id *id)
  485. {
  486. int ret;
  487. struct ziirave_wdt_data *w_priv;
  488. int val;
  489. if (!i2c_check_functionality(client->adapter,
  490. I2C_FUNC_SMBUS_BYTE |
  491. I2C_FUNC_SMBUS_BYTE_DATA |
  492. I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
  493. return -ENODEV;
  494. w_priv = devm_kzalloc(&client->dev, sizeof(*w_priv), GFP_KERNEL);
  495. if (!w_priv)
  496. return -ENOMEM;
  497. mutex_init(&w_priv->sysfs_mutex);
  498. w_priv->wdd.info = &ziirave_wdt_info;
  499. w_priv->wdd.ops = &ziirave_wdt_ops;
  500. w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN;
  501. w_priv->wdd.max_timeout = ZIIRAVE_TIMEOUT_MAX;
  502. w_priv->wdd.parent = &client->dev;
  503. w_priv->wdd.groups = ziirave_wdt_groups;
  504. watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
  505. /*
  506. * The default value set in the watchdog should be perfectly valid, so
  507. * pass that in if we haven't provided one via the module parameter or
  508. * of property.
  509. */
  510. if (w_priv->wdd.timeout == 0) {
  511. val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIMEOUT);
  512. if (val < 0) {
  513. dev_err(&client->dev, "Failed to read timeout\n");
  514. return val;
  515. }
  516. if (val > ZIIRAVE_TIMEOUT_MAX ||
  517. val < ZIIRAVE_TIMEOUT_MIN)
  518. val = ZIIRAVE_TIMEOUT_DEFAULT;
  519. w_priv->wdd.timeout = val;
  520. }
  521. ret = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout);
  522. if (ret) {
  523. dev_err(&client->dev, "Failed to set timeout\n");
  524. return ret;
  525. }
  526. dev_info(&client->dev, "Timeout set to %ds\n", w_priv->wdd.timeout);
  527. watchdog_set_nowayout(&w_priv->wdd, nowayout);
  528. i2c_set_clientdata(client, w_priv);
  529. /* If in unconfigured state, set to stopped */
  530. val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_STATE);
  531. if (val < 0) {
  532. dev_err(&client->dev, "Failed to read state\n");
  533. return val;
  534. }
  535. if (val == ZIIRAVE_STATE_INITIAL)
  536. ziirave_wdt_stop(&w_priv->wdd);
  537. ret = ziirave_wdt_init_duration(client);
  538. if (ret) {
  539. dev_err(&client->dev, "Failed to init duration\n");
  540. return ret;
  541. }
  542. ret = ziirave_wdt_revision(client, &w_priv->firmware_rev,
  543. ZIIRAVE_WDT_FIRM_VER_MAJOR);
  544. if (ret) {
  545. dev_err(&client->dev, "Failed to read firmware version\n");
  546. return ret;
  547. }
  548. dev_info(&client->dev,
  549. "Firmware version: " ZIIRAVE_FW_VERSION_FMT "\n",
  550. w_priv->firmware_rev.major, w_priv->firmware_rev.minor);
  551. ret = ziirave_wdt_revision(client, &w_priv->bootloader_rev,
  552. ZIIRAVE_WDT_BOOT_VER_MAJOR);
  553. if (ret) {
  554. dev_err(&client->dev, "Failed to read bootloader version\n");
  555. return ret;
  556. }
  557. dev_info(&client->dev,
  558. "Bootloader version: " ZIIRAVE_BL_VERSION_FMT "\n",
  559. w_priv->bootloader_rev.major, w_priv->bootloader_rev.minor);
  560. w_priv->reset_reason = i2c_smbus_read_byte_data(client,
  561. ZIIRAVE_WDT_RESET_REASON);
  562. if (w_priv->reset_reason < 0) {
  563. dev_err(&client->dev, "Failed to read reset reason\n");
  564. return w_priv->reset_reason;
  565. }
  566. if (w_priv->reset_reason >= ARRAY_SIZE(ziirave_reasons) ||
  567. !ziirave_reasons[w_priv->reset_reason]) {
  568. dev_err(&client->dev, "Invalid reset reason\n");
  569. return -ENODEV;
  570. }
  571. ret = watchdog_register_device(&w_priv->wdd);
  572. return ret;
  573. }
  574. static int ziirave_wdt_remove(struct i2c_client *client)
  575. {
  576. struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
  577. watchdog_unregister_device(&w_priv->wdd);
  578. return 0;
  579. }
  580. static const struct i2c_device_id ziirave_wdt_id[] = {
  581. { "rave-wdt", 0 },
  582. { }
  583. };
  584. MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id);
  585. static const struct of_device_id zrv_wdt_of_match[] = {
  586. { .compatible = "zii,rave-wdt", },
  587. { },
  588. };
  589. MODULE_DEVICE_TABLE(of, zrv_wdt_of_match);
  590. static struct i2c_driver ziirave_wdt_driver = {
  591. .driver = {
  592. .name = "ziirave_wdt",
  593. .of_match_table = zrv_wdt_of_match,
  594. },
  595. .probe = ziirave_wdt_probe,
  596. .remove = ziirave_wdt_remove,
  597. .id_table = ziirave_wdt_id,
  598. };
  599. module_i2c_driver(ziirave_wdt_driver);
  600. MODULE_AUTHOR("Martyn Welch <martyn.welch@collabora.co.uk");
  601. MODULE_DESCRIPTION("Zodiac Aerospace RAVE Switch Watchdog Processor Driver");
  602. MODULE_LICENSE("GPL");