From: Robert Beckett Date: Mon, 28 Oct 2019 18:29:05 +0000 (+0000) Subject: misc: i2c_eeprom: add fixed partitions support X-Git-Url: http://git.dujemihanovic.xyz/img/static/git-favicon.png?a=commitdiff_plain;h=1a59cb426d50082821df941146a9ec20decd118f;p=u-boot.git misc: i2c_eeprom: add fixed partitions support Add ability to partition eeprom via devicetree bindings Signed-off-by: Robert Beckett Reviewed-by: Heiko Schocher --- diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c index 3755dbf74b..741bae2727 100644 --- a/drivers/misc/i2c_eeprom.c +++ b/drivers/misc/i2c_eeprom.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,29 @@ static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) return 0; } +static int i2c_eeprom_std_bind(struct udevice *dev) +{ + ofnode partitions = ofnode_find_subnode(dev_ofnode(dev), "partitions"); + ofnode partition; + const char *name; + + if (!ofnode_valid(partitions)) + return 0; + if (!ofnode_device_is_compatible(partitions, "fixed-partitions")) + return -ENOTSUPP; + + ofnode_for_each_subnode(partition, partitions) { + name = ofnode_get_name(partition); + if (!name) + continue; + + device_bind_ofnode(dev, DM_GET_DRIVER(i2c_eeprom_partition), + name, NULL, partition, NULL); + } + + return 0; +} + static int i2c_eeprom_std_probe(struct udevice *dev) { u8 test_byte; @@ -118,12 +142,86 @@ U_BOOT_DRIVER(i2c_eeprom_std) = { .name = "i2c_eeprom", .id = UCLASS_I2C_EEPROM, .of_match = i2c_eeprom_std_ids, + .bind = i2c_eeprom_std_bind, .probe = i2c_eeprom_std_probe, .ofdata_to_platdata = i2c_eeprom_std_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct i2c_eeprom), .ops = &i2c_eeprom_std_ops, }; +struct i2c_eeprom_partition { + u32 offset; + u32 size; +}; + +static int i2c_eeprom_partition_probe(struct udevice *dev) +{ + return 0; +} + +static int i2c_eeprom_partition_ofdata_to_platdata(struct udevice *dev) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + u32 offset, size; + int ret; + + ret = dev_read_u32(dev, "offset", &offset); + if (ret) + return ret; + + ret = dev_read_u32(dev, "size", &size); + if (ret) + return ret; + + priv->offset = offset; + priv->size = size; + + return 0; +} + +static int i2c_eeprom_partition_read(struct udevice *dev, int offset, + u8 *buf, int size) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + struct udevice *parent = dev_get_parent(dev); + + if (!parent) + return -ENODEV; + if (offset + size > priv->size) + return -EINVAL; + + return i2c_eeprom_read(parent, offset + priv->offset, buf, size); +} + +static int i2c_eeprom_partition_write(struct udevice *dev, int offset, + const u8 *buf, int size) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + struct udevice *parent = dev_get_parent(dev); + + if (!parent) + return -ENODEV; + if (offset + size > priv->size) + return -EINVAL; + + return i2c_eeprom_write(parent, offset + priv->offset, (uint8_t *)buf, + size); +} + +static const struct i2c_eeprom_ops i2c_eeprom_partition_ops = { + .read = i2c_eeprom_partition_read, + .write = i2c_eeprom_partition_write, +}; + +U_BOOT_DRIVER(i2c_eeprom_partition) = { + .name = "i2c_eeprom_partition", + .id = UCLASS_I2C_EEPROM, + .probe = i2c_eeprom_partition_probe, + .ofdata_to_platdata = i2c_eeprom_partition_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct i2c_eeprom_partition), + .ops = &i2c_eeprom_partition_ops, +}; + UCLASS_DRIVER(i2c_eeprom) = { .id = UCLASS_I2C_EEPROM, .name = "i2c_eeprom",