"Das U-Boot" Source Tree
at master 95 lines 2.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2019 Collabora 4 * (C) Copyright 2019 GE 5 */ 6 7#include <bootcount.h> 8#include <dm.h> 9#include <i2c_eeprom.h> 10#include <log.h> 11 12static const u8 bootcount_magic = 0xbc; 13 14struct bootcount_i2c_eeprom_priv { 15 struct udevice *i2c_eeprom; 16 u32 offset; 17}; 18 19static int bootcount_i2c_eeprom_set(struct udevice *dev, const u32 a) 20{ 21 struct bootcount_i2c_eeprom_priv *priv = dev_get_priv(dev); 22 const u16 val = bootcount_magic << 8 | (a & 0xff); 23 24 if (i2c_eeprom_write(priv->i2c_eeprom, priv->offset, 25 (uint8_t *)&val, 2) < 0) { 26 debug("%s: write failed\n", __func__); 27 return -EIO; 28 } 29 30 return 0; 31} 32 33static int bootcount_i2c_eeprom_get(struct udevice *dev, u32 *a) 34{ 35 struct bootcount_i2c_eeprom_priv *priv = dev_get_priv(dev); 36 u16 val; 37 38 if (i2c_eeprom_read(priv->i2c_eeprom, priv->offset, 39 (uint8_t *)&val, 2) < 0) { 40 debug("%s: read failed\n", __func__); 41 return -EIO; 42 } 43 44 if (val >> 8 == bootcount_magic) { 45 *a = val & 0xff; 46 return 0; 47 } 48 49 debug("%s: bootcount magic does not match on %04x\n", __func__, val); 50 return -EIO; 51} 52 53static int bootcount_i2c_eeprom_probe(struct udevice *dev) 54{ 55 struct ofnode_phandle_args phandle_args; 56 struct bootcount_i2c_eeprom_priv *priv = dev_get_priv(dev); 57 struct udevice *i2c_eeprom; 58 59 if (dev_read_phandle_with_args(dev, "i2c-eeprom", NULL, 0, 0, 60 &phandle_args)) { 61 debug("%s: i2c-eeprom backing device not specified\n", 62 dev->name); 63 return -ENOENT; 64 } 65 66 if (uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, phandle_args.node, 67 &i2c_eeprom)) { 68 debug("%s: could not get backing device\n", dev->name); 69 return -ENODEV; 70 } 71 72 priv->i2c_eeprom = i2c_eeprom; 73 priv->offset = dev_read_u32_default(dev, "offset", 0); 74 75 return 0; 76} 77 78static const struct bootcount_ops bootcount_i2c_eeprom_ops = { 79 .get = bootcount_i2c_eeprom_get, 80 .set = bootcount_i2c_eeprom_set, 81}; 82 83static const struct udevice_id bootcount_i2c_eeprom_ids[] = { 84 { .compatible = "u-boot,bootcount-i2c-eeprom" }, 85 { } 86}; 87 88U_BOOT_DRIVER(bootcount_spi_flash) = { 89 .name = "bootcount-i2c-eeprom", 90 .id = UCLASS_BOOTCOUNT, 91 .priv_auto = sizeof(struct bootcount_i2c_eeprom_priv), 92 .probe = bootcount_i2c_eeprom_probe, 93 .of_match = bootcount_i2c_eeprom_ids, 94 .ops = &bootcount_i2c_eeprom_ops, 95};