Lines Matching +full:firmware +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-or-later
15 #include <linux/firmware.h>
60 /* Firmware commands */
92 "Watchdog reset pulse duration in milliseconds");
108 rev->major = ret; in ziirave_wdt_revision()
114 rev->minor = ret; in ziirave_wdt_revision()
121 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_set_state()
138 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_ping()
147 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_set_timeout()
152 wdd->timeout = timeout; in ziirave_wdt_set_timeout()
159 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_wdt_get_timeleft()
171 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_read_ack()
176 dev_err(&client->dev, "Failed to read status byte\n"); in ziirave_firm_read_ack()
180 return ret == ZIIRAVE_FIRM_DOWNLOAD_ACK ? 0 : -EIO; in ziirave_firm_read_ack()
185 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_set_read_addr()
203 * ziirave_firm_write_pkt() - Build and write a firmware packet
205 * A packet to send to the firmware is composed by following bytes:
218 struct i2c_client *client = to_i2c_client(wdd->parent); in __ziirave_firm_write_pkt()
224 dev_err(&client->dev, "Firmware packet too long (%d)\n", in __ziirave_firm_write_pkt()
226 return -EMSGSIZE; in __ziirave_firm_write_pkt()
234 * of firmware update in __ziirave_firm_write_pkt()
245 memset(packet + 3 + len, 0, ZIIRAVE_FIRM_PKT_DATA_SIZE - len); in __ziirave_firm_write_pkt()
250 packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1] = checksum; in __ziirave_firm_write_pkt()
255 dev_err(&client->dev, in __ziirave_firm_write_pkt()
262 dev_err(&client->dev, in __ziirave_firm_write_pkt()
263 "Failed to write firmware packet at address 0x%04x: %d\n", in __ziirave_firm_write_pkt()
272 const u8 max_write_len = ZIIRAVE_FIRM_PAGE_SIZE - in ziirave_firm_write_pkt()
273 (addr - ALIGN_DOWN(addr, ZIIRAVE_FIRM_PAGE_SIZE)); in ziirave_firm_write_pkt()
287 len -= max_write_len; in ziirave_firm_write_pkt()
294 const struct firmware *fw) in ziirave_firm_verify()
296 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_verify()
301 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { in ziirave_firm_verify()
302 const u16 len = be16_to_cpu(rec->len); in ziirave_firm_verify()
303 const u32 addr = be32_to_cpu(rec->addr); in ziirave_firm_verify()
306 return -EINVAL; in ziirave_firm_verify()
313 dev_err(&client->dev, in ziirave_firm_verify()
323 dev_err(&client->dev, in ziirave_firm_verify()
330 if (memcmp(data, rec->data, len)) { in ziirave_firm_verify()
331 dev_err(&client->dev, in ziirave_firm_verify()
332 "Firmware mismatch at address 0x%04x\n", addr); in ziirave_firm_verify()
333 return -EINVAL; in ziirave_firm_verify()
341 const struct firmware *fw) in ziirave_firm_upload()
343 struct i2c_client *client = to_i2c_client(wdd->parent); in ziirave_firm_upload()
351 dev_err(&client->dev, "Failed to jump to bootloader\n"); in ziirave_firm_upload()
359 dev_err(&client->dev, "Failed to start download\n"); in ziirave_firm_upload()
365 dev_err(&client->dev, "No ACK for start download\n"); in ziirave_firm_upload()
371 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { in ziirave_firm_upload()
372 ret = ziirave_firm_write_pkt(wdd, be32_to_cpu(rec->addr), in ziirave_firm_upload()
373 rec->data, be16_to_cpu(rec->len)); in ziirave_firm_upload()
379 * Finish firmware download process by sending a zero length in ziirave_firm_upload()
384 dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret); in ziirave_firm_upload()
391 /* Start firmware verification */ in ziirave_firm_upload()
394 dev_err(&client->dev, in ziirave_firm_upload()
395 "Failed to verify firmware: %d\n", ret); in ziirave_firm_upload()
402 dev_err(&client->dev, in ziirave_firm_upload()
403 "Failed to end firmware download: %d\n", ret); in ziirave_firm_upload()
407 /* Reset the processor */ in ziirave_firm_upload()
412 dev_err(&client->dev, in ziirave_firm_upload()
413 "Failed to reset the watchdog: %d\n", ret); in ziirave_firm_upload()
440 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_show_firm()
444 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_firm()
449 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()
473 w_priv->bootloader_rev.major, in ziirave_wdt_sysfs_show_boot()
474 w_priv->bootloader_rev.minor); in ziirave_wdt_sysfs_show_boot()
476 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_boot()
488 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_show_reason()
492 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_reason()
496 ret = sysfs_emit(buf, "%s\n", ziirave_reasons[w_priv->reset_reason]); in ziirave_wdt_sysfs_show_reason()
498 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_show_reason()
510 struct i2c_client *client = to_i2c_client(dev->parent); in ziirave_wdt_sysfs_store_firm()
512 const struct firmware *fw; in ziirave_wdt_sysfs_store_firm()
517 dev_err(&client->dev, "Failed to request ihex firmware\n"); in ziirave_wdt_sysfs_store_firm()
521 err = mutex_lock_interruptible(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_store_firm()
525 err = ziirave_firm_upload(&w_priv->wdd, fw); in ziirave_wdt_sysfs_store_firm()
527 dev_err(&client->dev, "The firmware update failed: %d\n", err); in ziirave_wdt_sysfs_store_firm()
531 /* Update firmware version */ in ziirave_wdt_sysfs_store_firm()
532 err = ziirave_wdt_revision(client, &w_priv->firmware_rev, in ziirave_wdt_sysfs_store_firm()
535 dev_err(&client->dev, "Failed to read firmware version: %d\n", in ziirave_wdt_sysfs_store_firm()
540 dev_info(&client->dev, in ziirave_wdt_sysfs_store_firm()
541 "Firmware updated to version 02.%02u.%02u\n", in ziirave_wdt_sysfs_store_firm()
542 w_priv->firmware_rev.major, w_priv->firmware_rev.minor); in ziirave_wdt_sysfs_store_firm()
545 err = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout); in ziirave_wdt_sysfs_store_firm()
547 dev_err(&client->dev, "Failed to set timeout: %d\n", err); in ziirave_wdt_sysfs_store_firm()
550 mutex_unlock(&w_priv->sysfs_mutex); in ziirave_wdt_sysfs_store_firm()
575 /* See if the reset pulse duration is provided in an of_node */ in ziirave_wdt_init_duration()
576 if (!client->dev.of_node) in ziirave_wdt_init_duration()
577 ret = -ENODEV; in ziirave_wdt_init_duration()
579 ret = of_property_read_u32(client->dev.of_node, in ziirave_wdt_init_duration()
580 "reset-duration-ms", in ziirave_wdt_init_duration()
583 dev_info(&client->dev, in ziirave_wdt_init_duration()
584 "No reset pulse duration specified, using default\n"); in ziirave_wdt_init_duration()
590 return -EINVAL; in ziirave_wdt_init_duration()
592 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: 02.%02u.%02u\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()
721 { "rave-wdt" },
727 { .compatible = "zii,rave-wdt", },