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