1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <bootcount.h> 10 11 int dm_bootcount_get(struct udevice *dev, u32 *bootcount) 12 { 13 struct bootcount_ops *ops = bootcount_get_ops(dev); 14 15 assert(ops); 16 if (!ops->get) 17 return -ENOSYS; 18 return ops->get(dev, bootcount); 19 } 20 21 int dm_bootcount_set(struct udevice *dev, const u32 bootcount) 22 { 23 struct bootcount_ops *ops = bootcount_get_ops(dev); 24 25 assert(ops); 26 if (!ops->set) 27 return -ENOSYS; 28 return ops->set(dev, bootcount); 29 } 30 31 /* Now implement the generic default functions */ 32 void bootcount_store(ulong val) 33 { 34 struct udevice *dev = NULL; 35 ofnode node; 36 const char *propname = "u-boot,bootcount-device"; 37 int ret = -ENODEV; 38 39 /* 40 * If there's a preferred bootcount device selected by the user (by 41 * setting '/chosen/u-boot,bootcount-device' in the DTS), try to use 42 * it if available. 43 */ 44 node = ofnode_get_chosen_node(propname); 45 if (ofnode_valid(node)) 46 ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev); 47 48 /* If there was no user-selected device, use the first available one */ 49 if (ret) 50 ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev); 51 52 if (dev) 53 ret = dm_bootcount_set(dev, val); 54 55 if (ret) 56 pr_debug("%s: failed to store 0x%lx\n", __func__, val); 57 } 58 59 ulong bootcount_load(void) 60 { 61 struct udevice *dev = NULL; 62 ofnode node; 63 const char *propname = "u-boot,bootcount-device"; 64 int ret = -ENODEV; 65 u32 val; 66 67 /* 68 * If there's a preferred bootcount device selected by the user (by 69 * setting '/chosen/u-boot,bootcount-device' in the DTS), try to use 70 * it if available. 71 */ 72 node = ofnode_get_chosen_node(propname); 73 if (ofnode_valid(node)) 74 ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev); 75 76 /* If there was no user-selected device, use the first available one */ 77 if (ret) 78 ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev); 79 80 if (dev) 81 ret = dm_bootcount_get(dev, &val); 82 83 if (ret) 84 pr_debug("%s: failed to load bootcount\n", __func__); 85 86 /* Return the 0, if the call to dm_bootcount_get failed */ 87 return ret ? 0 : val; 88 } 89 90 UCLASS_DRIVER(bootcount) = { 91 .name = "bootcount", 92 .id = UCLASS_BOOTCOUNT, 93 }; 94