Lines Matching +full:firmware +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-or-later
15 #include <linux/firmware.h>
61 /* Firmware commands */
96 "Watchdog reset pulse duration in milliseconds");
112 rev->major = ret; in ziirave_wdt_revision()
118 rev->minor = ret; in ziirave_wdt_revision()
125 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_set_state()
142 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_ping()
151 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_set_timeout()
156 wdd->timeout = timeout; in ziirave_wdt_set_timeout()
163 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_get_timeleft()
175 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_read_ack()
180 dev_err(&client->dev, "Failed to read status byte\n"); in ziirave_firm_read_ack()
184 return ret == ZIIRAVE_FIRM_DOWNLOAD_ACK ? 0 : -EIO; in ziirave_firm_read_ack()
189 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_set_read_addr()
207 * ziirave_firm_write_pkt() - Build and write a firmware packet
209 * A packet to send to the firmware is composed by following bytes:
222 struct i2c_client *client = to_i2c_client(wdd->parent); in __ziirave_firm_write_pkt()
228 dev_err(&client->dev, "Firmware packet too long (%d)\n", in __ziirave_firm_write_pkt()
230 return -EMSGSIZE; in __ziirave_firm_write_pkt()
238 * of firmware update in __ziirave_firm_write_pkt()
249 memset(packet + 3 + len, 0, ZIIRAVE_FIRM_PKT_DATA_SIZE - len); in __ziirave_firm_write_pkt()
254 packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1] = checksum; in __ziirave_firm_write_pkt()
259 dev_err(&client->dev, in __ziirave_firm_write_pkt()
266 dev_err(&client->dev, in __ziirave_firm_write_pkt()
267 "Failed to write firmware packet at address 0x%04x: %d\n", in __ziirave_firm_write_pkt()
276 const u8 max_write_len = ZIIRAVE_FIRM_PAGE_SIZE - in ziirave_firm_write_pkt()
277 (addr - ALIGN_DOWN(addr, ZIIRAVE_FIRM_PAGE_SIZE)); in ziirave_firm_write_pkt()
291 len -= max_write_len; in ziirave_firm_write_pkt()
298 const struct firmware *fw) in ziirave_firm_verify()
300 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_verify()
305 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { in ziirave_firm_verify()
306 const u16 len = be16_to_cpu(rec->len); in ziirave_firm_verify()
307 const u32 addr = be32_to_cpu(rec->addr); in ziirave_firm_verify()
314 dev_err(&client->dev, in ziirave_firm_verify()
324 dev_err(&client->dev, in ziirave_firm_verify()
331 if (memcmp(data, rec->data, len)) { in ziirave_firm_verify()
332 dev_err(&client->dev, in ziirave_firm_verify()
333 "Firmware mismatch at address 0x%04x\n", addr); in ziirave_firm_verify()
334 return -EINVAL; in ziirave_firm_verify()
342 const struct firmware *fw) in ziirave_firm_upload()
344 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_upload()
352 dev_err(&client->dev, "Failed to jump to bootloader\n"); in ziirave_firm_upload()
360 dev_err(&client->dev, "Failed to start download\n"); in ziirave_firm_upload()
366 dev_err(&client->dev, "No ACK for start download\n"); in ziirave_firm_upload()
372 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { in ziirave_firm_upload()
373 ret = ziirave_firm_write_pkt(wdd, be32_to_cpu(rec->addr), in ziirave_firm_upload()
374 rec->data, be16_to_cpu(rec->len)); in ziirave_firm_upload()
380 * Finish firmware download process by sending a zero length in ziirave_firm_upload()
385 dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret); in ziirave_firm_upload()
392 /* Start firmware verification */ in ziirave_firm_upload()
395 dev_err(&client->dev, in ziirave_firm_upload()
396 "Failed to verify firmware: %d\n", ret); in ziirave_firm_upload()
403 dev_err(&client->dev, in ziirave_firm_upload()
404 "Failed to end firmware download: %d\n", ret); in ziirave_firm_upload()
408 /* Reset the processor */ in ziirave_firm_upload()
413 dev_err(&client->dev, in ziirave_firm_upload()
414 "Failed to reset the watchdog: %d\n", ret); in ziirave_firm_upload()
441 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_show_firm()
445 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_firm()
449 ret = sprintf(buf, ZIIRAVE_FW_VERSION_FMT, w_priv->firmware_rev.major, in ziirave_wdt_sysfs_show_firm()
450 w_priv->firmware_rev.minor); in ziirave_wdt_sysfs_show_firm()
452 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_firm()
464 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_show_boot()
468 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_boot()
472 ret = sprintf(buf, ZIIRAVE_BL_VERSION_FMT, w_priv->bootloader_rev.major, in ziirave_wdt_sysfs_show_boot()
473 w_priv->bootloader_rev.minor); in ziirave_wdt_sysfs_show_boot()
475 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_boot()
487 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_show_reason()
491 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_reason()
495 ret = sprintf(buf, "%s", ziirave_reasons[w_priv->reset_reason]); in ziirave_wdt_sysfs_show_reason()
497 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_reason()
509 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_store_firm()
511 const struct firmware *fw; in ziirave_wdt_sysfs_store_firm()
516 dev_err(&client->dev, "Failed to request ihex firmware\n"); in ziirave_wdt_sysfs_store_firm()
520 err = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_store_firm()
524 err = ziirave_firm_upload(&w_priv->wdd, fw); in ziirave_wdt_sysfs_store_firm()
526 dev_err(&client->dev, "The firmware update failed: %d\n", err); in ziirave_wdt_sysfs_store_firm()
530 /* Update firmware version */ in ziirave_wdt_sysfs_store_firm()
531 err = ziirave_wdt_revision(client, &w_priv->firmware_rev, in ziirave_wdt_sysfs_store_firm()
534 dev_err(&client->dev, "Failed to read firmware version: %d\n", in ziirave_wdt_sysfs_store_firm()
539 dev_info(&client->dev, in ziirave_wdt_sysfs_store_firm()
540 "Firmware updated to version " ZIIRAVE_FW_VERSION_FMT "\n", in ziirave_wdt_sysfs_store_firm()
541 w_priv->firmware_rev.major, w_priv->firmware_rev.minor); in ziirave_wdt_sysfs_store_firm()
544 err = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout); in ziirave_wdt_sysfs_store_firm()
546 dev_err(&client->dev, "Failed to set timeout: %d\n", err); in ziirave_wdt_sysfs_store_firm()
549 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_store_firm()
574 /* See if the reset pulse duration is provided in an of_node */ in ziirave_wdt_init_duration()
575 if (!client->dev.of_node) in ziirave_wdt_init_duration()
576 ret = -ENODEV; in ziirave_wdt_init_duration()
578 ret = of_property_read_u32(client->dev.of_node, in ziirave_wdt_init_duration()
579 "reset-duration-ms", in ziirave_wdt_init_duration()
582 dev_info(&client->dev, in ziirave_wdt_init_duration()
583 "No reset pulse duration specified, using default\n"); in ziirave_wdt_init_duration()
589 return -EINVAL; in ziirave_wdt_init_duration()
591 dev_info(&client->dev, "Setting reset duration to %dms", in ziirave_wdt_init_duration()
605 if (!i2c_check_functionality(client->adapter, in ziirave_wdt_probe()
609 return -ENODEV; in ziirave_wdt_probe()
611 w_priv = devm_kzalloc(&client->dev, sizeof(*w_priv), GFP_KERNEL); in ziirave_wdt_probe()
613 return -ENOMEM; in ziirave_wdt_probe()
615 mutex_init(&w_priv->sysfs_mutex); in ziirave_wdt_probe()
617 w_priv->wdd.info = &ziirave_wdt_info; in ziirave_wdt_probe()
618 w_priv->wdd.ops = &ziirave_wdt_ops; in ziirave_wdt_probe()
619 w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN; in ziirave_wdt_probe()
620 w_priv->wdd.max_timeout = ZIIRAVE_TIMEOUT_MAX; in ziirave_wdt_probe()
621 w_priv->wdd.parent = &client->dev; in ziirave_wdt_probe()
622 w_priv->wdd.groups = ziirave_wdt_groups; in ziirave_wdt_probe()
624 watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev); in ziirave_wdt_probe()
631 if (w_priv->wdd.timeout == 0) { in ziirave_wdt_probe()
634 dev_err(&client->dev, "Failed to read timeout\n"); in ziirave_wdt_probe()
642 w_priv->wdd.timeout = val; in ziirave_wdt_probe()
645 ret = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout); in ziirave_wdt_probe()
647 dev_err(&client->dev, "Failed to set timeout\n"); in ziirave_wdt_probe()
651 dev_info(&client->dev, "Timeout set to %ds\n", w_priv->wdd.timeout); in ziirave_wdt_probe()
653 watchdog_set_nowayout(&w_priv->wdd, nowayout); in ziirave_wdt_probe()
660 dev_err(&client->dev, "Failed to read state\n"); in ziirave_wdt_probe()
665 ziirave_wdt_stop(&w_priv->wdd); in ziirave_wdt_probe()
669 dev_err(&client->dev, "Failed to init duration\n"); in ziirave_wdt_probe()
673 ret = ziirave_wdt_revision(client, &w_priv->firmware_rev, in ziirave_wdt_probe()
676 dev_err(&client->dev, "Failed to read firmware version\n"); in ziirave_wdt_probe()
680 dev_info(&client->dev, in ziirave_wdt_probe()
681 "Firmware version: " ZIIRAVE_FW_VERSION_FMT "\n", in ziirave_wdt_probe()
682 w_priv->firmware_rev.major, w_priv->firmware_rev.minor); in ziirave_wdt_probe()
684 ret = ziirave_wdt_revision(client, &w_priv->bootloader_rev, in ziirave_wdt_probe()
687 dev_err(&client->dev, "Failed to read bootloader version\n"); in ziirave_wdt_probe()
691 dev_info(&client->dev, in ziirave_wdt_probe()
693 w_priv->bootloader_rev.major, w_priv->bootloader_rev.minor); in ziirave_wdt_probe()
695 w_priv->reset_reason = i2c_smbus_read_byte_data(client, in ziirave_wdt_probe()
697 if (w_priv->reset_reason < 0) { in ziirave_wdt_probe()
698 dev_err(&client->dev, "Failed to read reset reason\n"); in ziirave_wdt_probe()
699 return w_priv->reset_reason; in ziirave_wdt_probe()
702 if (w_priv->reset_reason >= ARRAY_SIZE(ziirave_reasons) || in ziirave_wdt_probe()
703 !ziirave_reasons[w_priv->reset_reason]) { in ziirave_wdt_probe()
704 dev_err(&client->dev, "Invalid reset reason\n"); in ziirave_wdt_probe()
705 return -ENODEV; in ziirave_wdt_probe()
708 ret = watchdog_register_device(&w_priv->wdd); in ziirave_wdt_probe()
717 watchdog_unregister_device(&w_priv->wdd); in ziirave_wdt_remove()
723 { "rave-wdt", 0 },
729 { .compatible = "zii,rave-wdt", },