1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <linux/array_size.h>
4 #include <linux/bitfield.h>
5 #include <linux/bits.h>
6 #include <linux/delay.h>
7 #include <linux/dev_printk.h>
8 #include <linux/errno.h>
9 #include <linux/jiffies.h>
10 #include <linux/minmax.h>
11 #include <linux/netlink.h>
12 #include <linux/sched/signal.h>
13 #include <linux/sizes.h>
14 #include <linux/sprintf.h>
15 #include <linux/string.h>
16 #include <linux/types.h>
17 #include <linux/unaligned.h>
18 #include <net/devlink.h>
19
20 #include "core.h"
21 #include "devlink.h"
22 #include "flash.h"
23
24 #define ZL_FLASH_ERR_PFX "FW update failed: "
25 #define ZL_FLASH_ERR_MSG(_extack, _msg, ...) \
26 NL_SET_ERR_MSG_FMT_MOD((_extack), ZL_FLASH_ERR_PFX _msg, \
27 ## __VA_ARGS__)
28
29 /**
30 * zl3073x_flash_download - Download image block to device memory
31 * @zldev: zl3073x device structure
32 * @component: name of the component to be downloaded
33 * @addr: device memory target address
34 * @data: pointer to data to download
35 * @size: size of data to download
36 * @extack: netlink extack pointer to report errors
37 *
38 * Return: 0 on success, <0 on error
39 */
40 static int
zl3073x_flash_download(struct zl3073x_dev * zldev,const char * component,u32 addr,const void * data,size_t size,struct netlink_ext_ack * extack)41 zl3073x_flash_download(struct zl3073x_dev *zldev, const char *component,
42 u32 addr, const void *data, size_t size,
43 struct netlink_ext_ack *extack)
44 {
45 #define ZL_CHECK_DELAY 5000 /* Check for interrupt each 5 seconds */
46 unsigned long check_time;
47 const void *ptr, *end;
48 int rc = 0;
49
50 dev_dbg(zldev->dev, "Downloading %zu bytes to device memory at 0x%0x\n",
51 size, addr);
52
53 check_time = jiffies + msecs_to_jiffies(ZL_CHECK_DELAY);
54
55 for (ptr = data, end = data + size; ptr < end; ptr += 4, addr += 4) {
56 /* Write current word to HW memory */
57 rc = zl3073x_write_hwreg(zldev, addr,
58 get_unaligned((u32 *)ptr));
59 if (rc) {
60 ZL_FLASH_ERR_MSG(extack,
61 "failed to write to memory at 0x%0x",
62 addr);
63 return rc;
64 }
65
66 if (time_is_before_jiffies(check_time)) {
67 if (signal_pending(current)) {
68 ZL_FLASH_ERR_MSG(extack,
69 "Flashing interrupted");
70 return -EINTR;
71 }
72
73 check_time = jiffies + msecs_to_jiffies(ZL_CHECK_DELAY);
74 }
75
76 /* Report status each 1 kB block */
77 if ((ptr - data) % 1024 == 0)
78 zl3073x_devlink_flash_notify(zldev, "Downloading image",
79 component, ptr - data,
80 size);
81 }
82
83 zl3073x_devlink_flash_notify(zldev, "Downloading image", component,
84 ptr - data, size);
85
86 dev_dbg(zldev->dev, "%zu bytes downloaded to device memory\n", size);
87
88 return rc;
89 }
90
91 /**
92 * zl3073x_flash_error_check - Check for flash utility errors
93 * @zldev: zl3073x device structure
94 * @extack: netlink extack pointer to report errors
95 *
96 * The function checks for errors detected by the flash utility and
97 * reports them if any were found.
98 *
99 * Return: 0 on success, -EIO when errors are detected
100 */
101 static int
zl3073x_flash_error_check(struct zl3073x_dev * zldev,struct netlink_ext_ack * extack)102 zl3073x_flash_error_check(struct zl3073x_dev *zldev,
103 struct netlink_ext_ack *extack)
104 {
105 u32 count, cause;
106 int rc;
107
108 rc = zl3073x_read_u32(zldev, ZL_REG_ERROR_COUNT, &count);
109 if (rc)
110 return rc;
111 else if (!count)
112 return 0; /* No error */
113
114 rc = zl3073x_read_u32(zldev, ZL_REG_ERROR_CAUSE, &cause);
115 if (rc)
116 return rc;
117
118 /* Report errors */
119 ZL_FLASH_ERR_MSG(extack,
120 "utility error occurred: count=%u cause=0x%x", count,
121 cause);
122
123 return -EIO;
124 }
125
126 /**
127 * zl3073x_flash_wait_ready - Check or wait for utility to be ready to flash
128 * @zldev: zl3073x device structure
129 * @timeout_ms: timeout for the waiting
130 *
131 * Return: 0 on success, <0 on error
132 */
133 static int
zl3073x_flash_wait_ready(struct zl3073x_dev * zldev,unsigned int timeout_ms)134 zl3073x_flash_wait_ready(struct zl3073x_dev *zldev, unsigned int timeout_ms)
135 {
136 #define ZL_FLASH_POLL_DELAY_MS 100
137 unsigned long timeout;
138 int rc, i;
139
140 dev_dbg(zldev->dev, "Waiting for flashing to be ready\n");
141
142 timeout = jiffies + msecs_to_jiffies(timeout_ms);
143
144 for (i = 0; time_is_after_jiffies(timeout); i++) {
145 u8 value;
146
147 /* Check for interrupt each 1s */
148 if (i > 9) {
149 if (signal_pending(current))
150 return -EINTR;
151 i = 0;
152 }
153
154 rc = zl3073x_read_u8(zldev, ZL_REG_WRITE_FLASH, &value);
155 if (rc)
156 return rc;
157
158 value = FIELD_GET(ZL_WRITE_FLASH_OP, value);
159
160 if (value == ZL_WRITE_FLASH_OP_DONE)
161 return 0; /* Successfully done */
162
163 msleep(ZL_FLASH_POLL_DELAY_MS);
164 }
165
166 return -ETIMEDOUT;
167 }
168
169 /**
170 * zl3073x_flash_cmd_wait - Perform flash operation and wait for finish
171 * @zldev: zl3073x device structure
172 * @operation: operation to perform
173 * @extack: netlink extack pointer to report errors
174 *
175 * Return: 0 on success, <0 on error
176 */
177 static int
zl3073x_flash_cmd_wait(struct zl3073x_dev * zldev,u32 operation,struct netlink_ext_ack * extack)178 zl3073x_flash_cmd_wait(struct zl3073x_dev *zldev, u32 operation,
179 struct netlink_ext_ack *extack)
180 {
181 #define ZL_FLASH_PHASE1_TIMEOUT_MS 60000 /* up to 1 minute */
182 #define ZL_FLASH_PHASE2_TIMEOUT_MS 120000 /* up to 2 minutes */
183 u8 value;
184 int rc;
185
186 dev_dbg(zldev->dev, "Sending flash command: 0x%x\n", operation);
187
188 rc = zl3073x_flash_wait_ready(zldev, ZL_FLASH_PHASE1_TIMEOUT_MS);
189 if (rc)
190 return rc;
191
192 /* Issue the requested operation */
193 rc = zl3073x_read_u8(zldev, ZL_REG_WRITE_FLASH, &value);
194 if (rc)
195 return rc;
196
197 value &= ~ZL_WRITE_FLASH_OP;
198 value |= FIELD_PREP(ZL_WRITE_FLASH_OP, operation);
199
200 rc = zl3073x_write_u8(zldev, ZL_REG_WRITE_FLASH, value);
201 if (rc)
202 return rc;
203
204 /* Wait for command completion */
205 rc = zl3073x_flash_wait_ready(zldev, ZL_FLASH_PHASE2_TIMEOUT_MS);
206 if (rc)
207 return rc;
208
209 return zl3073x_flash_error_check(zldev, extack);
210 }
211
212 /**
213 * zl3073x_flash_get_sector_size - Get flash sector size
214 * @zldev: zl3073x device structure
215 * @sector_size: sector size returned by the function
216 *
217 * The function reads the flash sector size detected by flash utility and
218 * stores it into @sector_size.
219 *
220 * Return: 0 on success, <0 on error
221 */
222 static int
zl3073x_flash_get_sector_size(struct zl3073x_dev * zldev,size_t * sector_size)223 zl3073x_flash_get_sector_size(struct zl3073x_dev *zldev, size_t *sector_size)
224 {
225 u8 flash_info;
226 int rc;
227
228 rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_INFO, &flash_info);
229 if (rc)
230 return rc;
231
232 switch (FIELD_GET(ZL_FLASH_INFO_SECTOR_SIZE, flash_info)) {
233 case ZL_FLASH_INFO_SECTOR_4K:
234 *sector_size = SZ_4K;
235 break;
236 case ZL_FLASH_INFO_SECTOR_64K:
237 *sector_size = SZ_64K;
238 break;
239 default:
240 rc = -EINVAL;
241 break;
242 }
243
244 return rc;
245 }
246
247 /**
248 * zl3073x_flash_block - Download and flash memory block
249 * @zldev: zl3073x device structure
250 * @component: component name
251 * @operation: flash operation to perform
252 * @page: destination flash page
253 * @addr: device memory address to load data
254 * @data: pointer to data to be flashed
255 * @size: size of data
256 * @extack: netlink extack pointer to report errors
257 *
258 * The function downloads the memory block given by the @data pointer and
259 * the size @size and flashes it into internal memory on flash page @page.
260 * The internal flash operation performed by the firmware is specified by
261 * the @operation parameter.
262 *
263 * Return: 0 on success, <0 on error
264 */
265 static int
zl3073x_flash_block(struct zl3073x_dev * zldev,const char * component,u32 operation,u32 page,u32 addr,const void * data,size_t size,struct netlink_ext_ack * extack)266 zl3073x_flash_block(struct zl3073x_dev *zldev, const char *component,
267 u32 operation, u32 page, u32 addr, const void *data,
268 size_t size, struct netlink_ext_ack *extack)
269 {
270 int rc;
271
272 /* Download block to device memory */
273 rc = zl3073x_flash_download(zldev, component, addr, data, size, extack);
274 if (rc)
275 return rc;
276
277 /* Set address to flash from */
278 rc = zl3073x_write_u32(zldev, ZL_REG_IMAGE_START_ADDR, addr);
279 if (rc)
280 return rc;
281
282 /* Set size of block to flash */
283 rc = zl3073x_write_u32(zldev, ZL_REG_IMAGE_SIZE, size);
284 if (rc)
285 return rc;
286
287 /* Set destination page to flash */
288 rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_WRITE, page);
289 if (rc)
290 return rc;
291
292 /* Set filling pattern */
293 rc = zl3073x_write_u32(zldev, ZL_REG_FILL_PATTERN, U32_MAX);
294 if (rc)
295 return rc;
296
297 zl3073x_devlink_flash_notify(zldev, "Flashing image", component, 0,
298 size);
299
300 dev_dbg(zldev->dev, "Flashing %zu bytes to page %u\n", size, page);
301
302 /* Execute sectors flash operation */
303 rc = zl3073x_flash_cmd_wait(zldev, operation, extack);
304 if (rc)
305 return rc;
306
307 zl3073x_devlink_flash_notify(zldev, "Flashing image", component, size,
308 size);
309
310 return 0;
311 }
312
313 /**
314 * zl3073x_flash_sectors - Flash sectors
315 * @zldev: zl3073x device structure
316 * @component: component name
317 * @page: destination flash page
318 * @addr: device memory address to load data
319 * @data: pointer to data to be flashed
320 * @size: size of data
321 * @extack: netlink extack pointer to report errors
322 *
323 * The function flashes given @data with size of @size to the internal flash
324 * memory block starting from page @page. The function uses sector flash
325 * method and has to take into account the flash sector size reported by
326 * flashing utility. Input data are spliced into blocks according this
327 * sector size and each block is flashed separately.
328 *
329 * Return: 0 on success, <0 on error
330 */
zl3073x_flash_sectors(struct zl3073x_dev * zldev,const char * component,u32 page,u32 addr,const void * data,size_t size,struct netlink_ext_ack * extack)331 int zl3073x_flash_sectors(struct zl3073x_dev *zldev, const char *component,
332 u32 page, u32 addr, const void *data, size_t size,
333 struct netlink_ext_ack *extack)
334 {
335 #define ZL_FLASH_MAX_BLOCK_SIZE 0x0001E000
336 #define ZL_FLASH_PAGE_SIZE 256
337 size_t max_block_size, block_size, sector_size;
338 const void *ptr, *end;
339 int rc;
340
341 /* Get flash sector size */
342 rc = zl3073x_flash_get_sector_size(zldev, §or_size);
343 if (rc) {
344 ZL_FLASH_ERR_MSG(extack, "Failed to get flash sector size");
345 return rc;
346 }
347
348 /* Determine max block size depending on sector size */
349 max_block_size = ALIGN_DOWN(ZL_FLASH_MAX_BLOCK_SIZE, sector_size);
350
351 for (ptr = data, end = data + size; ptr < end; ptr += block_size) {
352 char comp_str[32];
353
354 block_size = min_t(size_t, max_block_size, end - ptr);
355
356 /* Add suffix '-partN' if the requested component size is
357 * greater than max_block_size.
358 */
359 if (max_block_size < size)
360 snprintf(comp_str, sizeof(comp_str), "%s-part%zu",
361 component, (ptr - data) / max_block_size + 1);
362 else
363 strscpy(comp_str, component);
364
365 /* Flash the memory block */
366 rc = zl3073x_flash_block(zldev, comp_str,
367 ZL_WRITE_FLASH_OP_SECTORS, page, addr,
368 ptr, block_size, extack);
369 if (rc)
370 goto finish;
371
372 /* Move to next page */
373 page += block_size / ZL_FLASH_PAGE_SIZE;
374 }
375
376 finish:
377 zl3073x_devlink_flash_notify(zldev,
378 rc ? "Flashing failed" : "Flashing done",
379 component, 0, 0);
380
381 return rc;
382 }
383
384 /**
385 * zl3073x_flash_page - Flash page
386 * @zldev: zl3073x device structure
387 * @component: component name
388 * @page: destination flash page
389 * @addr: device memory address to load data
390 * @data: pointer to data to be flashed
391 * @size: size of data
392 * @extack: netlink extack pointer to report errors
393 *
394 * The function flashes given @data with size of @size to the internal flash
395 * memory block starting with page @page.
396 *
397 * Return: 0 on success, <0 on error
398 */
zl3073x_flash_page(struct zl3073x_dev * zldev,const char * component,u32 page,u32 addr,const void * data,size_t size,struct netlink_ext_ack * extack)399 int zl3073x_flash_page(struct zl3073x_dev *zldev, const char *component,
400 u32 page, u32 addr, const void *data, size_t size,
401 struct netlink_ext_ack *extack)
402 {
403 int rc;
404
405 /* Flash the memory block */
406 rc = zl3073x_flash_block(zldev, component, ZL_WRITE_FLASH_OP_PAGE, page,
407 addr, data, size, extack);
408
409 zl3073x_devlink_flash_notify(zldev,
410 rc ? "Flashing failed" : "Flashing done",
411 component, 0, 0);
412
413 return rc;
414 }
415
416 /**
417 * zl3073x_flash_page_copy - Copy flash page
418 * @zldev: zl3073x device structure
419 * @component: component name
420 * @src_page: source page to copy
421 * @dst_page: destination page
422 * @extack: netlink extack pointer to report errors
423 *
424 * The function copies one flash page specified by @src_page into the flash
425 * page specified by @dst_page.
426 *
427 * Return: 0 on success, <0 on error
428 */
zl3073x_flash_page_copy(struct zl3073x_dev * zldev,const char * component,u32 src_page,u32 dst_page,struct netlink_ext_ack * extack)429 int zl3073x_flash_page_copy(struct zl3073x_dev *zldev, const char *component,
430 u32 src_page, u32 dst_page,
431 struct netlink_ext_ack *extack)
432 {
433 int rc;
434
435 /* Set source page to be copied */
436 rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_READ, src_page);
437 if (rc)
438 return rc;
439
440 /* Set destination page for the copy */
441 rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_WRITE, dst_page);
442 if (rc)
443 return rc;
444
445 /* Perform copy operation */
446 rc = zl3073x_flash_cmd_wait(zldev, ZL_WRITE_FLASH_OP_COPY_PAGE, extack);
447 if (rc)
448 ZL_FLASH_ERR_MSG(extack, "Failed to copy page %u to page %u",
449 src_page, dst_page);
450
451 return rc;
452 }
453
454 /**
455 * zl3073x_flash_mode_verify - Check flash utility
456 * @zldev: zl3073x device structure
457 *
458 * Return: 0 if the flash utility is ready, <0 on error
459 */
460 static int
zl3073x_flash_mode_verify(struct zl3073x_dev * zldev)461 zl3073x_flash_mode_verify(struct zl3073x_dev *zldev)
462 {
463 u8 family, release;
464 u32 hash;
465 int rc;
466
467 rc = zl3073x_read_u32(zldev, ZL_REG_FLASH_HASH, &hash);
468 if (rc)
469 return rc;
470
471 rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_FAMILY, &family);
472 if (rc)
473 return rc;
474
475 rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_RELEASE, &release);
476 if (rc)
477 return rc;
478
479 dev_dbg(zldev->dev,
480 "Flash utility check: hash 0x%08x, fam 0x%02x, rel 0x%02x\n",
481 hash, family, release);
482
483 /* Return success for correct family */
484 return (family == 0x21) ? 0 : -ENODEV;
485 }
486
487 static int
zl3073x_flash_host_ctrl_enable(struct zl3073x_dev * zldev)488 zl3073x_flash_host_ctrl_enable(struct zl3073x_dev *zldev)
489 {
490 u8 host_ctrl;
491 int rc;
492
493 /* Enable host control */
494 rc = zl3073x_read_u8(zldev, ZL_REG_HOST_CONTROL, &host_ctrl);
495 if (rc)
496 return rc;
497
498 host_ctrl |= ZL_HOST_CONTROL_ENABLE;
499
500 return zl3073x_write_u8(zldev, ZL_REG_HOST_CONTROL, host_ctrl);
501 }
502
503 /**
504 * zl3073x_flash_mode_enter - Switch the device to flash mode
505 * @zldev: zl3073x device structure
506 * @util_ptr: buffer with flash utility
507 * @util_size: size of buffer with flash utility
508 * @extack: netlink extack pointer to report errors
509 *
510 * The function prepares and switches the device into flash mode.
511 *
512 * The procedure:
513 * 1) Stop device CPU by specific HW register sequence
514 * 2) Download flash utility to device memory
515 * 3) Resume device CPU by specific HW register sequence
516 * 4) Check communication with flash utility
517 * 5) Enable host control necessary to access flash API
518 * 6) Check for potential error detected by the utility
519 *
520 * The API provided by normal firmware is not available in flash mode
521 * so the caller has to ensure that this API is not used in this mode.
522 *
523 * After performing flash operation the caller should call
524 * @zl3073x_flash_mode_leave to return back to normal operation.
525 *
526 * Return: 0 on success, <0 on error.
527 */
zl3073x_flash_mode_enter(struct zl3073x_dev * zldev,const void * util_ptr,size_t util_size,struct netlink_ext_ack * extack)528 int zl3073x_flash_mode_enter(struct zl3073x_dev *zldev, const void *util_ptr,
529 size_t util_size, struct netlink_ext_ack *extack)
530 {
531 /* Sequence to be written prior utility download */
532 static const struct zl3073x_hwreg_seq_item pre_seq[] = {
533 HWREG_SEQ_ITEM(0x80000400, 1, BIT(0), 0),
534 HWREG_SEQ_ITEM(0x80206340, 1, BIT(4), 0),
535 HWREG_SEQ_ITEM(0x10000000, 1, BIT(2), 0),
536 HWREG_SEQ_ITEM(0x10000024, 0x00000001, U32_MAX, 0),
537 HWREG_SEQ_ITEM(0x10000020, 0x00000001, U32_MAX, 0),
538 HWREG_SEQ_ITEM(0x10000000, 1, BIT(10), 1000),
539 };
540 /* Sequence to be written after utility download */
541 static const struct zl3073x_hwreg_seq_item post_seq[] = {
542 HWREG_SEQ_ITEM(0x10400004, 0x000000C0, U32_MAX, 0),
543 HWREG_SEQ_ITEM(0x10400008, 0x00000000, U32_MAX, 0),
544 HWREG_SEQ_ITEM(0x10400010, 0x20000000, U32_MAX, 0),
545 HWREG_SEQ_ITEM(0x10400014, 0x20000004, U32_MAX, 0),
546 HWREG_SEQ_ITEM(0x10000000, 1, GENMASK(10, 9), 0),
547 HWREG_SEQ_ITEM(0x10000020, 0x00000000, U32_MAX, 0),
548 HWREG_SEQ_ITEM(0x10000000, 0, BIT(0), 1000),
549 };
550 int rc;
551
552 zl3073x_devlink_flash_notify(zldev, "Prepare flash mode", "utility",
553 0, 0);
554
555 /* Execure pre-load sequence */
556 rc = zl3073x_write_hwreg_seq(zldev, pre_seq, ARRAY_SIZE(pre_seq));
557 if (rc) {
558 ZL_FLASH_ERR_MSG(extack, "cannot execute pre-load sequence");
559 goto error;
560 }
561
562 /* Download utility image to device memory */
563 rc = zl3073x_flash_download(zldev, "utility", 0x20000000, util_ptr,
564 util_size, extack);
565 if (rc) {
566 ZL_FLASH_ERR_MSG(extack, "cannot download flash utility");
567 goto error;
568 }
569
570 /* Execute post-load sequence */
571 rc = zl3073x_write_hwreg_seq(zldev, post_seq, ARRAY_SIZE(post_seq));
572 if (rc) {
573 ZL_FLASH_ERR_MSG(extack, "cannot execute post-load sequence");
574 goto error;
575 }
576
577 /* Check that utility identifies itself correctly */
578 rc = zl3073x_flash_mode_verify(zldev);
579 if (rc) {
580 ZL_FLASH_ERR_MSG(extack, "flash utility check failed");
581 goto error;
582 }
583
584 /* Enable host control */
585 rc = zl3073x_flash_host_ctrl_enable(zldev);
586 if (rc) {
587 ZL_FLASH_ERR_MSG(extack, "cannot enable host control");
588 goto error;
589 }
590
591 zl3073x_devlink_flash_notify(zldev, "Flash mode enabled", "utility",
592 0, 0);
593
594 return 0;
595
596 error:
597 zl3073x_flash_mode_leave(zldev, extack);
598
599 return rc;
600 }
601
602 /**
603 * zl3073x_flash_mode_leave - Leave flash mode
604 * @zldev: zl3073x device structure
605 * @extack: netlink extack pointer to report errors
606 *
607 * The function instructs the device to leave the flash mode and
608 * to return back to normal operation.
609 *
610 * The procedure:
611 * 1) Set reset flag
612 * 2) Reset the device CPU by specific HW register sequence
613 * 3) Wait for the device to be ready
614 * 4) Check the reset flag was cleared
615 *
616 * Return: 0 on success, <0 on error
617 */
zl3073x_flash_mode_leave(struct zl3073x_dev * zldev,struct netlink_ext_ack * extack)618 int zl3073x_flash_mode_leave(struct zl3073x_dev *zldev,
619 struct netlink_ext_ack *extack)
620 {
621 /* Sequence to be written after flash */
622 static const struct zl3073x_hwreg_seq_item fw_reset_seq[] = {
623 HWREG_SEQ_ITEM(0x80000404, 1, BIT(0), 0),
624 HWREG_SEQ_ITEM(0x80000410, 1, BIT(0), 0),
625 };
626 u8 reset_status;
627 int rc;
628
629 zl3073x_devlink_flash_notify(zldev, "Leaving flash mode", "utility",
630 0, 0);
631
632 /* Read reset status register */
633 rc = zl3073x_read_u8(zldev, ZL_REG_RESET_STATUS, &reset_status);
634 if (rc)
635 return rc;
636
637 /* Set reset bit */
638 reset_status |= ZL_REG_RESET_STATUS_RESET;
639
640 /* Update reset status register */
641 rc = zl3073x_write_u8(zldev, ZL_REG_RESET_STATUS, reset_status);
642 if (rc)
643 return rc;
644
645 /* We do not check the return value here as the sequence resets
646 * the device CPU and the last write always return an error.
647 */
648 zl3073x_write_hwreg_seq(zldev, fw_reset_seq, ARRAY_SIZE(fw_reset_seq));
649
650 /* Wait for the device to be ready */
651 msleep(500);
652
653 /* Read again the reset status register */
654 rc = zl3073x_read_u8(zldev, ZL_REG_RESET_STATUS, &reset_status);
655 if (rc)
656 return rc;
657
658 /* Check the reset bit was cleared */
659 if (reset_status & ZL_REG_RESET_STATUS_RESET) {
660 dev_err(zldev->dev,
661 "Reset not confirmed after switch to normal mode\n");
662 return -EINVAL;
663 }
664
665 return 0;
666 }
667