* Loop through all the tuples in the resets= property for a device, asserting * or deasserting each reset. * * Be liberal about errors for now: warn about a failure to (de)assert but keep * trying with any other resets in the list. Return ENXIO if any errors were * found, and let the caller decide whether the problem is fatal. */
| 50 | * found, and let the caller decide whether the problem is fatal. |
| 51 | */ |
| 52 | static int |
| 53 | assert_deassert_all(device_t consumer, boolean_t assert) |
| 54 | { |
| 55 | phandle_t rnode; |
| 56 | device_t resetdev; |
| 57 | int resetnum, err, i, ncells; |
| 58 | uint32_t *resets; |
| 59 | boolean_t anyerrors; |
| 60 | |
| 61 | rnode = ofw_bus_get_node(consumer); |
| 62 | ncells = OF_getencprop_alloc_multi(rnode, "resets", sizeof(*resets), |
| 63 | (void **)&resets); |
| 64 | if (!assert && ncells < 2) { |
| 65 | device_printf(consumer, "Warning: No resets specified in fdt " |
| 66 | "data; device may not function."); |
| 67 | return (ENXIO); |
| 68 | } |
| 69 | anyerrors = false; |
| 70 | for (i = 0; i < ncells; i += 2) { |
| 71 | resetdev = OF_device_from_xref(resets[i]); |
| 72 | resetnum = resets[i + 1]; |
| 73 | if (resetdev == NULL) { |
| 74 | if (!assert) |
| 75 | device_printf(consumer, "Warning: can not find " |
| 76 | "driver for reset number %u; device may " |
| 77 | "not function\n", resetnum); |
| 78 | anyerrors = true; |
| 79 | continue; |
| 80 | } |
| 81 | if (assert) |
| 82 | err = FDT_RESET_ASSERT(resetdev, resetnum); |
| 83 | else |
| 84 | err = FDT_RESET_DEASSERT(resetdev, resetnum); |
| 85 | if (err != 0) { |
| 86 | if (!assert) |
| 87 | device_printf(consumer, "Warning: failed to " |
| 88 | "deassert reset number %u; device may not " |
| 89 | "function\n", resetnum); |
| 90 | anyerrors = true; |
| 91 | } |
| 92 | } |
| 93 | OF_prop_free(resets); |
| 94 | return (anyerrors ? ENXIO : 0); |
| 95 | } |
| 96 | |
| 97 | int |
| 98 | fdt_reset_assert_all(device_t consumer) |
no test coverage detected