ziirave_wdt.c 19 KB

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