Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2015 Zodiac Inflight Innovations
0004  *
0005  * Author: Martyn Welch <martyn.welch@collabora.co.uk>
0006  *
0007  * Based on twl4030_wdt.c by Timo Kokkonen <timo.t.kokkonen at nokia.com>:
0008  *
0009  * Copyright (C) Nokia Corporation
0010  */
0011 
0012 #include <linux/delay.h>
0013 #include <linux/i2c.h>
0014 #include <linux/ihex.h>
0015 #include <linux/firmware.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/slab.h>
0019 #include <linux/sysfs.h>
0020 #include <linux/types.h>
0021 #include <linux/watchdog.h>
0022 
0023 #include <asm/unaligned.h>
0024 
0025 #define ZIIRAVE_TIMEOUT_MIN 3
0026 #define ZIIRAVE_TIMEOUT_MAX 255
0027 #define ZIIRAVE_TIMEOUT_DEFAULT 30
0028 
0029 #define ZIIRAVE_PING_VALUE  0x0
0030 
0031 #define ZIIRAVE_STATE_INITIAL   0x0
0032 #define ZIIRAVE_STATE_OFF   0x1
0033 #define ZIIRAVE_STATE_ON    0x2
0034 
0035 #define ZIIRAVE_FW_NAME     "ziirave_wdt.fw"
0036 
0037 static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL,
0038                   "host request", NULL, "illegal configuration",
0039                   "illegal instruction", "illegal trap",
0040                   "unknown"};
0041 
0042 #define ZIIRAVE_WDT_FIRM_VER_MAJOR  0x1
0043 #define ZIIRAVE_WDT_BOOT_VER_MAJOR  0x3
0044 #define ZIIRAVE_WDT_RESET_REASON    0x5
0045 #define ZIIRAVE_WDT_STATE       0x6
0046 #define ZIIRAVE_WDT_TIMEOUT     0x7
0047 #define ZIIRAVE_WDT_TIME_LEFT       0x8
0048 #define ZIIRAVE_WDT_PING        0x9
0049 #define ZIIRAVE_WDT_RESET_DURATION  0xa
0050 
0051 #define ZIIRAVE_FIRM_PKT_TOTAL_SIZE 20
0052 #define ZIIRAVE_FIRM_PKT_DATA_SIZE  16
0053 #define ZIIRAVE_FIRM_FLASH_MEMORY_START (2 * 0x1600)
0054 #define ZIIRAVE_FIRM_FLASH_MEMORY_END   (2 * 0x2bbf)
0055 #define ZIIRAVE_FIRM_PAGE_SIZE      128
0056 
0057 /* Received and ready for next Download packet. */
0058 #define ZIIRAVE_FIRM_DOWNLOAD_ACK   1
0059 
0060 /* Firmware commands */
0061 #define ZIIRAVE_CMD_DOWNLOAD_START      0x10
0062 #define ZIIRAVE_CMD_DOWNLOAD_END        0x11
0063 #define ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR  0x12
0064 #define ZIIRAVE_CMD_DOWNLOAD_READ_BYTE      0x13
0065 #define ZIIRAVE_CMD_RESET_PROCESSOR     0x0b
0066 #define ZIIRAVE_CMD_JUMP_TO_BOOTLOADER      0x0c
0067 #define ZIIRAVE_CMD_DOWNLOAD_PACKET     0x0e
0068 
0069 #define ZIIRAVE_CMD_JUMP_TO_BOOTLOADER_MAGIC    1
0070 #define ZIIRAVE_CMD_RESET_PROCESSOR_MAGIC   1
0071 
0072 struct ziirave_wdt_rev {
0073     unsigned char major;
0074     unsigned char minor;
0075 };
0076 
0077 struct ziirave_wdt_data {
0078     struct mutex sysfs_mutex;
0079     struct watchdog_device wdd;
0080     struct ziirave_wdt_rev bootloader_rev;
0081     struct ziirave_wdt_rev firmware_rev;
0082     int reset_reason;
0083 };
0084 
0085 static int wdt_timeout;
0086 module_param(wdt_timeout, int, 0);
0087 MODULE_PARM_DESC(wdt_timeout, "Watchdog timeout in seconds");
0088 
0089 static int reset_duration;
0090 module_param(reset_duration, int, 0);
0091 MODULE_PARM_DESC(reset_duration,
0092          "Watchdog reset pulse duration in milliseconds");
0093 
0094 static bool nowayout = WATCHDOG_NOWAYOUT;
0095 module_param(nowayout, bool, 0);
0096 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default="
0097          __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0098 
0099 static int ziirave_wdt_revision(struct i2c_client *client,
0100                 struct ziirave_wdt_rev *rev, u8 command)
0101 {
0102     int ret;
0103 
0104     ret = i2c_smbus_read_byte_data(client, command);
0105     if (ret < 0)
0106         return ret;
0107 
0108     rev->major = ret;
0109 
0110     ret = i2c_smbus_read_byte_data(client, command + 1);
0111     if (ret < 0)
0112         return ret;
0113 
0114     rev->minor = ret;
0115 
0116     return 0;
0117 }
0118 
0119 static int ziirave_wdt_set_state(struct watchdog_device *wdd, int state)
0120 {
0121     struct i2c_client *client = to_i2c_client(wdd->parent);
0122 
0123     return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_STATE, state);
0124 }
0125 
0126 static int ziirave_wdt_start(struct watchdog_device *wdd)
0127 {
0128     return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_ON);
0129 }
0130 
0131 static int ziirave_wdt_stop(struct watchdog_device *wdd)
0132 {
0133     return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_OFF);
0134 }
0135 
0136 static int ziirave_wdt_ping(struct watchdog_device *wdd)
0137 {
0138     struct i2c_client *client = to_i2c_client(wdd->parent);
0139 
0140     return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_PING,
0141                      ZIIRAVE_PING_VALUE);
0142 }
0143 
0144 static int ziirave_wdt_set_timeout(struct watchdog_device *wdd,
0145                    unsigned int timeout)
0146 {
0147     struct i2c_client *client = to_i2c_client(wdd->parent);
0148     int ret;
0149 
0150     ret = i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_TIMEOUT, timeout);
0151     if (!ret)
0152         wdd->timeout = timeout;
0153 
0154     return ret;
0155 }
0156 
0157 static unsigned int ziirave_wdt_get_timeleft(struct watchdog_device *wdd)
0158 {
0159     struct i2c_client *client = to_i2c_client(wdd->parent);
0160     int ret;
0161 
0162     ret = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIME_LEFT);
0163     if (ret < 0)
0164         ret = 0;
0165 
0166     return ret;
0167 }
0168 
0169 static int ziirave_firm_read_ack(struct watchdog_device *wdd)
0170 {
0171     struct i2c_client *client = to_i2c_client(wdd->parent);
0172     int ret;
0173 
0174     ret = i2c_smbus_read_byte(client);
0175     if (ret < 0) {
0176         dev_err(&client->dev, "Failed to read status byte\n");
0177         return ret;
0178     }
0179 
0180     return ret == ZIIRAVE_FIRM_DOWNLOAD_ACK ? 0 : -EIO;
0181 }
0182 
0183 static int ziirave_firm_set_read_addr(struct watchdog_device *wdd, u32 addr)
0184 {
0185     struct i2c_client *client = to_i2c_client(wdd->parent);
0186     const u16 addr16 = (u16)addr / 2;
0187     u8 address[2];
0188 
0189     put_unaligned_le16(addr16, address);
0190 
0191     return i2c_smbus_write_block_data(client,
0192                       ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR,
0193                       sizeof(address), address);
0194 }
0195 
0196 static bool ziirave_firm_addr_readonly(u32 addr)
0197 {
0198     return addr < ZIIRAVE_FIRM_FLASH_MEMORY_START ||
0199            addr > ZIIRAVE_FIRM_FLASH_MEMORY_END;
0200 }
0201 
0202 /*
0203  * ziirave_firm_write_pkt() - Build and write a firmware packet
0204  *
0205  * A packet to send to the firmware is composed by following bytes:
0206  *     Length | Addr0 | Addr1 | Data0 .. Data15 | Checksum |
0207  * Where,
0208  *     Length: A data byte containing the length of the data.
0209  *     Addr0: Low byte of the address.
0210  *     Addr1: High byte of the address.
0211  *     Data0 .. Data15: Array of 16 bytes of data.
0212  *     Checksum: Checksum byte to verify data integrity.
0213  */
0214 static int __ziirave_firm_write_pkt(struct watchdog_device *wdd,
0215                     u32 addr, const u8 *data, u8 len)
0216 {
0217     const u16 addr16 = (u16)addr / 2;
0218     struct i2c_client *client = to_i2c_client(wdd->parent);
0219     u8 i, checksum = 0, packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE];
0220     int ret;
0221 
0222     /* Check max data size */
0223     if (len > ZIIRAVE_FIRM_PKT_DATA_SIZE) {
0224         dev_err(&client->dev, "Firmware packet too long (%d)\n",
0225             len);
0226         return -EMSGSIZE;
0227     }
0228 
0229     /*
0230      * Ignore packets that are targeting program memory outisde of
0231      * app partition, since they will be ignored by the
0232      * bootloader. At the same time, we need to make sure we'll
0233      * allow zero length packet that will be sent as the last step
0234      * of firmware update
0235      */
0236     if (len && ziirave_firm_addr_readonly(addr))
0237         return 0;
0238 
0239     /* Packet length */
0240     packet[0] = len;
0241     /* Packet address */
0242     put_unaligned_le16(addr16, packet + 1);
0243 
0244     memcpy(packet + 3, data, len);
0245     memset(packet + 3 + len, 0, ZIIRAVE_FIRM_PKT_DATA_SIZE - len);
0246 
0247     /* Packet checksum */
0248     for (i = 0; i < len + 3; i++)
0249         checksum += packet[i];
0250     packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1] = checksum;
0251 
0252     ret = i2c_smbus_write_block_data(client, ZIIRAVE_CMD_DOWNLOAD_PACKET,
0253                      sizeof(packet), packet);
0254     if (ret) {
0255         dev_err(&client->dev,
0256             "Failed to send DOWNLOAD_PACKET: %d\n", ret);
0257         return ret;
0258     }
0259 
0260     ret = ziirave_firm_read_ack(wdd);
0261     if (ret)
0262         dev_err(&client->dev,
0263               "Failed to write firmware packet at address 0x%04x: %d\n",
0264               addr, ret);
0265 
0266     return ret;
0267 }
0268 
0269 static int ziirave_firm_write_pkt(struct watchdog_device *wdd,
0270                   u32 addr, const u8 *data, u8 len)
0271 {
0272     const u8 max_write_len = ZIIRAVE_FIRM_PAGE_SIZE -
0273         (addr - ALIGN_DOWN(addr, ZIIRAVE_FIRM_PAGE_SIZE));
0274     int ret;
0275 
0276     if (len > max_write_len) {
0277         /*
0278          * If data crossed page boundary we need to split this
0279          * write in two
0280          */
0281         ret = __ziirave_firm_write_pkt(wdd, addr, data, max_write_len);
0282         if (ret)
0283             return ret;
0284 
0285         addr += max_write_len;
0286         data += max_write_len;
0287         len  -= max_write_len;
0288     }
0289 
0290     return __ziirave_firm_write_pkt(wdd, addr, data, len);
0291 }
0292 
0293 static int ziirave_firm_verify(struct watchdog_device *wdd,
0294                    const struct firmware *fw)
0295 {
0296     struct i2c_client *client = to_i2c_client(wdd->parent);
0297     const struct ihex_binrec *rec;
0298     int i, ret;
0299     u8 data[ZIIRAVE_FIRM_PKT_DATA_SIZE];
0300 
0301     for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
0302         const u16 len = be16_to_cpu(rec->len);
0303         const u32 addr = be32_to_cpu(rec->addr);
0304 
0305         if (ziirave_firm_addr_readonly(addr))
0306             continue;
0307 
0308         ret = ziirave_firm_set_read_addr(wdd, addr);
0309         if (ret) {
0310             dev_err(&client->dev,
0311                 "Failed to send SET_READ_ADDR command: %d\n",
0312                 ret);
0313             return ret;
0314         }
0315 
0316         for (i = 0; i < len; i++) {
0317             ret = i2c_smbus_read_byte_data(client,
0318                         ZIIRAVE_CMD_DOWNLOAD_READ_BYTE);
0319             if (ret < 0) {
0320                 dev_err(&client->dev,
0321                     "Failed to READ DATA: %d\n", ret);
0322                 return ret;
0323             }
0324             data[i] = ret;
0325         }
0326 
0327         if (memcmp(data, rec->data, len)) {
0328             dev_err(&client->dev,
0329                 "Firmware mismatch at address 0x%04x\n", addr);
0330             return -EINVAL;
0331         }
0332     }
0333 
0334     return 0;
0335 }
0336 
0337 static int ziirave_firm_upload(struct watchdog_device *wdd,
0338                    const struct firmware *fw)
0339 {
0340     struct i2c_client *client = to_i2c_client(wdd->parent);
0341     const struct ihex_binrec *rec;
0342     int ret;
0343 
0344     ret = i2c_smbus_write_byte_data(client,
0345                     ZIIRAVE_CMD_JUMP_TO_BOOTLOADER,
0346                     ZIIRAVE_CMD_JUMP_TO_BOOTLOADER_MAGIC);
0347     if (ret) {
0348         dev_err(&client->dev, "Failed to jump to bootloader\n");
0349         return ret;
0350     }
0351 
0352     msleep(500);
0353 
0354     ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_START);
0355     if (ret) {
0356         dev_err(&client->dev, "Failed to start download\n");
0357         return ret;
0358     }
0359 
0360     ret = ziirave_firm_read_ack(wdd);
0361     if (ret) {
0362         dev_err(&client->dev, "No ACK for start download\n");
0363         return ret;
0364     }
0365 
0366     msleep(500);
0367 
0368     for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
0369         ret = ziirave_firm_write_pkt(wdd, be32_to_cpu(rec->addr),
0370                          rec->data, be16_to_cpu(rec->len));
0371         if (ret)
0372             return ret;
0373     }
0374 
0375     /*
0376      * Finish firmware download process by sending a zero length
0377      * payload
0378      */
0379     ret = ziirave_firm_write_pkt(wdd, 0, NULL, 0);
0380     if (ret) {
0381         dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret);
0382         return ret;
0383     }
0384 
0385     /* This sleep seems to be required */
0386     msleep(20);
0387 
0388     /* Start firmware verification */
0389     ret = ziirave_firm_verify(wdd, fw);
0390     if (ret) {
0391         dev_err(&client->dev,
0392             "Failed to verify firmware: %d\n", ret);
0393         return ret;
0394     }
0395 
0396     /* End download operation */
0397     ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_END);
0398     if (ret) {
0399         dev_err(&client->dev,
0400             "Failed to end firmware download: %d\n", ret);
0401         return ret;
0402     }
0403 
0404     /* Reset the processor */
0405     ret = i2c_smbus_write_byte_data(client,
0406                     ZIIRAVE_CMD_RESET_PROCESSOR,
0407                     ZIIRAVE_CMD_RESET_PROCESSOR_MAGIC);
0408     if (ret) {
0409         dev_err(&client->dev,
0410             "Failed to reset the watchdog: %d\n", ret);
0411         return ret;
0412     }
0413 
0414     msleep(500);
0415 
0416     return 0;
0417 }
0418 
0419 static const struct watchdog_info ziirave_wdt_info = {
0420     .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
0421     .identity = "RAVE Switch Watchdog",
0422 };
0423 
0424 static const struct watchdog_ops ziirave_wdt_ops = {
0425     .owner      = THIS_MODULE,
0426     .start      = ziirave_wdt_start,
0427     .stop       = ziirave_wdt_stop,
0428     .ping       = ziirave_wdt_ping,
0429     .set_timeout    = ziirave_wdt_set_timeout,
0430     .get_timeleft   = ziirave_wdt_get_timeleft,
0431 };
0432 
0433 static ssize_t ziirave_wdt_sysfs_show_firm(struct device *dev,
0434                        struct device_attribute *attr,
0435                        char *buf)
0436 {
0437     struct i2c_client *client = to_i2c_client(dev->parent);
0438     struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
0439     int ret;
0440 
0441     ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
0442     if (ret)
0443         return ret;
0444 
0445     ret = sysfs_emit(buf, "02.%02u.%02u\n",
0446              w_priv->firmware_rev.major,
0447              w_priv->firmware_rev.minor);
0448 
0449     mutex_unlock(&w_priv->sysfs_mutex);
0450 
0451     return ret;
0452 }
0453 
0454 static DEVICE_ATTR(firmware_version, S_IRUGO, ziirave_wdt_sysfs_show_firm,
0455            NULL);
0456 
0457 static ssize_t ziirave_wdt_sysfs_show_boot(struct device *dev,
0458                        struct device_attribute *attr,
0459                        char *buf)
0460 {
0461     struct i2c_client *client = to_i2c_client(dev->parent);
0462     struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
0463     int ret;
0464 
0465     ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
0466     if (ret)
0467         return ret;
0468 
0469     ret = sysfs_emit(buf, "01.%02u.%02u\n",
0470              w_priv->bootloader_rev.major,
0471              w_priv->bootloader_rev.minor);
0472 
0473     mutex_unlock(&w_priv->sysfs_mutex);
0474 
0475     return ret;
0476 }
0477 
0478 static DEVICE_ATTR(bootloader_version, S_IRUGO, ziirave_wdt_sysfs_show_boot,
0479            NULL);
0480 
0481 static ssize_t ziirave_wdt_sysfs_show_reason(struct device *dev,
0482                          struct device_attribute *attr,
0483                          char *buf)
0484 {
0485     struct i2c_client *client = to_i2c_client(dev->parent);
0486     struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
0487     int ret;
0488 
0489     ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
0490     if (ret)
0491         return ret;
0492 
0493     ret = sysfs_emit(buf, "%s\n", ziirave_reasons[w_priv->reset_reason]);
0494 
0495     mutex_unlock(&w_priv->sysfs_mutex);
0496 
0497     return ret;
0498 }
0499 
0500 static DEVICE_ATTR(reset_reason, S_IRUGO, ziirave_wdt_sysfs_show_reason,
0501            NULL);
0502 
0503 static ssize_t ziirave_wdt_sysfs_store_firm(struct device *dev,
0504                         struct device_attribute *attr,
0505                         const char *buf, size_t count)
0506 {
0507     struct i2c_client *client = to_i2c_client(dev->parent);
0508     struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
0509     const struct firmware *fw;
0510     int err;
0511 
0512     err = request_ihex_firmware(&fw, ZIIRAVE_FW_NAME, dev);
0513     if (err) {
0514         dev_err(&client->dev, "Failed to request ihex firmware\n");
0515         return err;
0516     }
0517 
0518     err = mutex_lock_interruptible(&w_priv->sysfs_mutex);
0519     if (err)
0520         goto release_firmware;
0521 
0522     err = ziirave_firm_upload(&w_priv->wdd, fw);
0523     if (err) {
0524         dev_err(&client->dev, "The firmware update failed: %d\n", err);
0525         goto unlock_mutex;
0526     }
0527 
0528     /* Update firmware version */
0529     err = ziirave_wdt_revision(client, &w_priv->firmware_rev,
0530                    ZIIRAVE_WDT_FIRM_VER_MAJOR);
0531     if (err) {
0532         dev_err(&client->dev, "Failed to read firmware version: %d\n",
0533             err);
0534         goto unlock_mutex;
0535     }
0536 
0537     dev_info(&client->dev,
0538          "Firmware updated to version 02.%02u.%02u\n",
0539          w_priv->firmware_rev.major, w_priv->firmware_rev.minor);
0540 
0541     /* Restore the watchdog timeout */
0542     err = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout);
0543     if (err)
0544         dev_err(&client->dev, "Failed to set timeout: %d\n", err);
0545 
0546 unlock_mutex:
0547     mutex_unlock(&w_priv->sysfs_mutex);
0548 
0549 release_firmware:
0550     release_firmware(fw);
0551 
0552     return err ? err : count;
0553 }
0554 
0555 static DEVICE_ATTR(update_firmware, S_IWUSR, NULL,
0556            ziirave_wdt_sysfs_store_firm);
0557 
0558 static struct attribute *ziirave_wdt_attrs[] = {
0559     &dev_attr_firmware_version.attr,
0560     &dev_attr_bootloader_version.attr,
0561     &dev_attr_reset_reason.attr,
0562     &dev_attr_update_firmware.attr,
0563     NULL
0564 };
0565 ATTRIBUTE_GROUPS(ziirave_wdt);
0566 
0567 static int ziirave_wdt_init_duration(struct i2c_client *client)
0568 {
0569     int ret;
0570 
0571     if (!reset_duration) {
0572         /* See if the reset pulse duration is provided in an of_node */
0573         if (!client->dev.of_node)
0574             ret = -ENODEV;
0575         else
0576             ret = of_property_read_u32(client->dev.of_node,
0577                            "reset-duration-ms",
0578                            &reset_duration);
0579         if (ret) {
0580             dev_info(&client->dev,
0581              "No reset pulse duration specified, using default\n");
0582             return 0;
0583         }
0584     }
0585 
0586     if (reset_duration < 1 || reset_duration > 255)
0587         return -EINVAL;
0588 
0589     dev_info(&client->dev, "Setting reset duration to %dms",
0590          reset_duration);
0591 
0592     return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_RESET_DURATION,
0593                      reset_duration);
0594 }
0595 
0596 static int ziirave_wdt_probe(struct i2c_client *client,
0597                  const struct i2c_device_id *id)
0598 {
0599     int ret;
0600     struct ziirave_wdt_data *w_priv;
0601     int val;
0602 
0603     if (!i2c_check_functionality(client->adapter,
0604                      I2C_FUNC_SMBUS_BYTE |
0605                      I2C_FUNC_SMBUS_BYTE_DATA |
0606                      I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
0607         return -ENODEV;
0608 
0609     w_priv = devm_kzalloc(&client->dev, sizeof(*w_priv), GFP_KERNEL);
0610     if (!w_priv)
0611         return -ENOMEM;
0612 
0613     mutex_init(&w_priv->sysfs_mutex);
0614 
0615     w_priv->wdd.info = &ziirave_wdt_info;
0616     w_priv->wdd.ops = &ziirave_wdt_ops;
0617     w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN;
0618     w_priv->wdd.max_timeout = ZIIRAVE_TIMEOUT_MAX;
0619     w_priv->wdd.parent = &client->dev;
0620     w_priv->wdd.groups = ziirave_wdt_groups;
0621 
0622     watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
0623 
0624     /*
0625      * The default value set in the watchdog should be perfectly valid, so
0626      * pass that in if we haven't provided one via the module parameter or
0627      * of property.
0628      */
0629     if (w_priv->wdd.timeout == 0) {
0630         val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIMEOUT);
0631         if (val < 0) {
0632             dev_err(&client->dev, "Failed to read timeout\n");
0633             return val;
0634         }
0635 
0636         if (val > ZIIRAVE_TIMEOUT_MAX ||
0637             val < ZIIRAVE_TIMEOUT_MIN)
0638             val = ZIIRAVE_TIMEOUT_DEFAULT;
0639 
0640         w_priv->wdd.timeout = val;
0641     }
0642 
0643     ret = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout);
0644     if (ret) {
0645         dev_err(&client->dev, "Failed to set timeout\n");
0646         return ret;
0647     }
0648 
0649     dev_info(&client->dev, "Timeout set to %ds\n", w_priv->wdd.timeout);
0650 
0651     watchdog_set_nowayout(&w_priv->wdd, nowayout);
0652 
0653     i2c_set_clientdata(client, w_priv);
0654 
0655     /* If in unconfigured state, set to stopped */
0656     val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_STATE);
0657     if (val < 0) {
0658         dev_err(&client->dev, "Failed to read state\n");
0659         return val;
0660     }
0661 
0662     if (val == ZIIRAVE_STATE_INITIAL)
0663         ziirave_wdt_stop(&w_priv->wdd);
0664 
0665     ret = ziirave_wdt_init_duration(client);
0666     if (ret) {
0667         dev_err(&client->dev, "Failed to init duration\n");
0668         return ret;
0669     }
0670 
0671     ret = ziirave_wdt_revision(client, &w_priv->firmware_rev,
0672                    ZIIRAVE_WDT_FIRM_VER_MAJOR);
0673     if (ret) {
0674         dev_err(&client->dev, "Failed to read firmware version\n");
0675         return ret;
0676     }
0677 
0678     dev_info(&client->dev,
0679          "Firmware version: 02.%02u.%02u\n",
0680          w_priv->firmware_rev.major, w_priv->firmware_rev.minor);
0681 
0682     ret = ziirave_wdt_revision(client, &w_priv->bootloader_rev,
0683                    ZIIRAVE_WDT_BOOT_VER_MAJOR);
0684     if (ret) {
0685         dev_err(&client->dev, "Failed to read bootloader version\n");
0686         return ret;
0687     }
0688 
0689     dev_info(&client->dev,
0690          "Bootloader version: 01.%02u.%02u\n",
0691          w_priv->bootloader_rev.major, w_priv->bootloader_rev.minor);
0692 
0693     w_priv->reset_reason = i2c_smbus_read_byte_data(client,
0694                         ZIIRAVE_WDT_RESET_REASON);
0695     if (w_priv->reset_reason < 0) {
0696         dev_err(&client->dev, "Failed to read reset reason\n");
0697         return w_priv->reset_reason;
0698     }
0699 
0700     if (w_priv->reset_reason >= ARRAY_SIZE(ziirave_reasons) ||
0701         !ziirave_reasons[w_priv->reset_reason]) {
0702         dev_err(&client->dev, "Invalid reset reason\n");
0703         return -ENODEV;
0704     }
0705 
0706     ret = watchdog_register_device(&w_priv->wdd);
0707 
0708     return ret;
0709 }
0710 
0711 static int ziirave_wdt_remove(struct i2c_client *client)
0712 {
0713     struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
0714 
0715     watchdog_unregister_device(&w_priv->wdd);
0716 
0717     return 0;
0718 }
0719 
0720 static const struct i2c_device_id ziirave_wdt_id[] = {
0721     { "rave-wdt", 0 },
0722     { }
0723 };
0724 MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id);
0725 
0726 static const struct of_device_id zrv_wdt_of_match[] = {
0727     { .compatible = "zii,rave-wdt", },
0728     { },
0729 };
0730 MODULE_DEVICE_TABLE(of, zrv_wdt_of_match);
0731 
0732 static struct i2c_driver ziirave_wdt_driver = {
0733     .driver = {
0734         .name = "ziirave_wdt",
0735         .of_match_table = zrv_wdt_of_match,
0736     },
0737     .probe = ziirave_wdt_probe,
0738     .remove = ziirave_wdt_remove,
0739     .id_table = ziirave_wdt_id,
0740 };
0741 
0742 module_i2c_driver(ziirave_wdt_driver);
0743 
0744 MODULE_AUTHOR("Martyn Welch <martyn.welch@collabora.co.uk");
0745 MODULE_DESCRIPTION("Zodiac Aerospace RAVE Switch Watchdog Processor Driver");
0746 MODULE_LICENSE("GPL");