"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "'eeprom' command improvements"

Marek Behún <kabel@kernel.org> says:

This series contains improvements for the 'eeprom' command:
- refactors
- fixes
- improvements
- ability to use driver model EEPROMs (uclass UCLASS_I2C_EEPROM)
- more flexible EEPROM layout support

It should not cause any behavior change for any existing board.

This series is a dependency for some DDR issue fixes for Turris Omnia.
I will be sending that one separately.

github PR link (with CI):
https://github.com/u-boot/u-boot/pull/540
- there is a failure for
test.py for sandbox sandbox_clang
but it seems unrelated to these changes

Tom Rini 77ba281c 227be29d

+273 -105
+8 -1
cmd/Kconfig
··· 804 804 types of eeprom fields. Can be used for defining 805 805 custom layouts. 806 806 807 + config EEPROM_LAYOUT_VERSIONS 808 + bool "Support specifying eeprom layout version" 809 + depends on CMD_EEPROM_LAYOUT 810 + help 811 + Support specifying eeprom layout version in the 'eeprom' command 812 + via the -l option. 813 + 807 814 config EEPROM_LAYOUT_HELP_STRING 808 815 string "Tells user what layout names are supported" 809 - depends on CMD_EEPROM_LAYOUT 816 + depends on EEPROM_LAYOUT_VERSIONS 810 817 default "<not defined>" 811 818 help 812 819 Help printed with the LAYOUT VERSIONS part of the 'eeprom'
+222 -83
cmd/eeprom.c
··· 21 21 22 22 #include <config.h> 23 23 #include <command.h> 24 + #include <dm.h> 24 25 #include <eeprom.h> 25 26 #include <i2c.h> 27 + #include <i2c_eeprom.h> 26 28 #include <eeprom_layout.h> 27 29 #include <vsprintf.h> 28 30 #include <linux/delay.h> ··· 208 210 return (*endptr != '\0') ? -1 : value; 209 211 } 210 212 213 + struct eeprom_dev_spec { 214 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 215 + struct udevice *dev; 216 + #endif 217 + int i2c_bus; 218 + ulong i2c_addr; 219 + }; 220 + 221 + static void eeprom_dev_spec_init(struct eeprom_dev_spec *dev) 222 + { 223 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 224 + if (!dev->dev) 225 + #endif 226 + eeprom_init(dev->i2c_bus); 227 + } 228 + 229 + static int eeprom_dev_spec_read(struct eeprom_dev_spec *dev, 230 + unsigned offset, uchar *buffer, unsigned cnt) 231 + { 232 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 233 + if (dev->dev) 234 + return i2c_eeprom_read(dev->dev, offset, buffer, cnt); 235 + #endif 236 + return eeprom_read(dev->i2c_addr, offset, buffer, cnt); 237 + } 238 + 239 + static int eeprom_dev_spec_write(struct eeprom_dev_spec *dev, 240 + unsigned offset, uchar *buffer, unsigned cnt) 241 + { 242 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 243 + if (dev->dev) 244 + return i2c_eeprom_write(dev->dev, offset, buffer, cnt); 245 + #endif 246 + return eeprom_write(dev->i2c_addr, offset, buffer, cnt); 247 + } 248 + 211 249 /** 212 - * parse_i2c_bus_addr - parse the i2c bus and i2c devaddr parameters 250 + * parse_eeprom_dev_spec - parse the eeprom device specifier 213 251 * 214 - * @i2c_bus: address to store the i2c bus 215 - * @i2c_addr: address to store the device i2c address 216 - * @argc: count of command line arguments left to parse 252 + * @dev: pointer to eeprom device specifier 253 + * @argc: count of command line arguments that can be used to parse 254 + * the device specifier 217 255 * @argv: command line arguments left to parse 218 - * @argc_no_bus_addr: argc value we expect to see when bus & addr aren't given 219 256 * 220 257 * @returns: number of arguments parsed or CMD_RET_USAGE if error 221 258 */ 222 - static int parse_i2c_bus_addr(int *i2c_bus, ulong *i2c_addr, int argc, 223 - char *const argv[], int argc_no_bus_addr) 259 + static int parse_eeprom_dev_spec(struct eeprom_dev_spec *dev, int argc, 260 + char *const argv[]) 224 261 { 225 - int argc_no_bus = argc_no_bus_addr + 1; 226 - int argc_bus_addr = argc_no_bus_addr + 2; 262 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 263 + if (argc == 0) { 264 + if (!uclass_first_device_err(UCLASS_I2C_EEPROM, &dev->dev)) 265 + return 0; 266 + } 267 + 268 + if (argc == 1) { 269 + if (!uclass_get_device_by_name(UCLASS_I2C_EEPROM, argv[0], 270 + &dev->dev)) 271 + return 1; 272 + 273 + /* 274 + * If we could not find the device by name and the parameter is 275 + * not numeric (and so won't be handled later), fail. 276 + */ 277 + if (parse_numeric_param(argv[0]) == -1) { 278 + printf("Can't get eeprom device: %s\n", argv[0]); 279 + return CMD_RET_USAGE; 280 + } 281 + } 282 + #endif 227 283 228 284 #ifdef CONFIG_SYS_I2C_EEPROM_ADDR 229 - if (argc == argc_no_bus_addr) { 230 - *i2c_bus = -1; 231 - *i2c_addr = CONFIG_SYS_I2C_EEPROM_ADDR; 285 + if (argc == 0) { 286 + dev->i2c_bus = -1; 287 + dev->i2c_addr = CONFIG_SYS_I2C_EEPROM_ADDR; 232 288 233 289 return 0; 234 290 } 235 291 #endif 236 - if (argc == argc_no_bus) { 237 - *i2c_bus = -1; 238 - *i2c_addr = parse_numeric_param(argv[0]); 292 + if (argc == 1) { 293 + dev->i2c_bus = -1; 294 + dev->i2c_addr = parse_numeric_param(argv[0]); 239 295 240 296 return 1; 241 297 } 242 298 243 - if (argc == argc_bus_addr) { 244 - *i2c_bus = parse_numeric_param(argv[0]); 245 - *i2c_addr = parse_numeric_param(argv[1]); 299 + if (argc == 2) { 300 + dev->i2c_bus = parse_numeric_param(argv[0]); 301 + dev->i2c_addr = parse_numeric_param(argv[1]); 246 302 247 303 return 2; 248 304 } ··· 252 308 253 309 #ifdef CONFIG_CMD_EEPROM_LAYOUT 254 310 311 + #ifdef CONFIG_EEPROM_LAYOUT_VERSIONS 255 312 __weak int eeprom_parse_layout_version(char *str) 256 313 { 257 314 return LAYOUT_VERSION_UNRECOGNIZED; 258 315 } 316 + #endif 259 317 260 318 static unsigned char eeprom_buf[CONFIG_SYS_EEPROM_SIZE]; 261 319 262 320 #endif 263 321 264 322 enum eeprom_action { 323 + EEPROM_LIST, 265 324 EEPROM_READ, 266 325 EEPROM_WRITE, 267 326 EEPROM_PRINT, ··· 271 330 272 331 static enum eeprom_action parse_action(char *cmd) 273 332 { 333 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 334 + if (!strncmp(cmd, "list", 4)) 335 + return EEPROM_LIST; 336 + #endif 274 337 if (!strncmp(cmd, "read", 4)) 275 338 return EEPROM_READ; 276 339 if (!strncmp(cmd, "write", 5)) ··· 285 348 return EEPROM_ACTION_INVALID; 286 349 } 287 350 288 - static int eeprom_execute_command(enum eeprom_action action, int i2c_bus, 289 - ulong i2c_addr, int layout_ver, char *key, 290 - char *value, ulong addr, ulong off, ulong cnt) 351 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 352 + static int do_eeprom_list(void) 291 353 { 292 - int rcode = 0; 354 + struct udevice *dev; 355 + struct uclass *uc; 356 + int err; 357 + 358 + err = uclass_get(UCLASS_I2C_EEPROM, &uc); 359 + if (err) 360 + return CMD_RET_FAILURE; 361 + 362 + uclass_foreach_dev(dev, uc) 363 + printf("%s (%s)\n", dev->name, dev->driver->name); 364 + 365 + return CMD_RET_SUCCESS; 366 + } 367 + #endif 368 + 369 + static int do_eeprom_rw(struct eeprom_dev_spec *dev, bool read, 370 + ulong addr, ulong off, ulong cnt) 371 + { 293 372 const char *const fmt = 294 373 "\nEEPROM @0x%lX %s: addr 0x%08lx off 0x%04lx count %ld ... "; 374 + uchar *memloc = (uchar *)addr; 375 + int ret; 376 + 377 + printf(fmt, dev->i2c_addr, read ? "read" : "write", addr, off, cnt); 378 + if (read) 379 + ret = eeprom_dev_spec_read(dev, off, memloc, cnt); 380 + else 381 + ret = eeprom_dev_spec_write(dev, off, memloc, cnt); 382 + puts("done\n"); 383 + 384 + return ret; 385 + } 386 + 295 387 #ifdef CONFIG_CMD_EEPROM_LAYOUT 296 - struct eeprom_layout layout; 297 - #endif 298 388 299 - if (action == EEPROM_ACTION_INVALID) 300 - return CMD_RET_USAGE; 389 + static int do_eeprom_layout(struct eeprom_dev_spec *dev, int layout_ver, 390 + struct eeprom_layout *layout) 391 + { 392 + eeprom_layout_setup(layout, eeprom_buf, CONFIG_SYS_EEPROM_SIZE, 393 + layout_ver); 301 394 302 - eeprom_init(i2c_bus); 303 - if (action == EEPROM_READ) { 304 - printf(fmt, i2c_addr, "read", addr, off, cnt); 395 + return eeprom_dev_spec_read(dev, 0, eeprom_buf, layout->data_size); 396 + } 305 397 306 - rcode = eeprom_read(i2c_addr, off, (uchar *)addr, cnt); 398 + static int do_eeprom_print(struct eeprom_dev_spec *dev, int layout_ver) 399 + { 400 + struct eeprom_layout layout; 401 + int ret; 307 402 308 - puts("done\n"); 309 - return rcode; 310 - } else if (action == EEPROM_WRITE) { 311 - printf(fmt, i2c_addr, "write", addr, off, cnt); 403 + ret = do_eeprom_layout(dev, layout_ver, &layout); 404 + if (ret) 405 + return ret; 312 406 313 - rcode = eeprom_write(i2c_addr, off, (uchar *)addr, cnt); 407 + layout.print(&layout); 314 408 315 - puts("done\n"); 316 - return rcode; 317 - } 409 + return 0; 410 + } 318 411 319 - #ifdef CONFIG_CMD_EEPROM_LAYOUT 320 - rcode = eeprom_read(i2c_addr, 0, eeprom_buf, CONFIG_SYS_EEPROM_SIZE); 321 - if (rcode < 0) 322 - return rcode; 412 + static int do_eeprom_update(struct eeprom_dev_spec *dev, int layout_ver, 413 + char *key, char *value) 414 + { 415 + struct eeprom_layout layout; 416 + int ret; 323 417 324 - eeprom_layout_setup(&layout, eeprom_buf, CONFIG_SYS_EEPROM_SIZE, 325 - layout_ver); 418 + ret = do_eeprom_layout(dev, layout_ver, &layout); 419 + if (ret) 420 + return ret; 326 421 327 - if (action == EEPROM_PRINT) { 328 - layout.print(&layout); 329 - return 0; 330 - } 422 + ret = layout.update(&layout, key, value); 423 + if (ret) 424 + return CMD_RET_FAILURE; 331 425 332 - layout.update(&layout, key, value); 426 + return eeprom_dev_spec_write(dev, 0, layout.data, layout.data_size); 427 + } 333 428 334 - rcode = eeprom_write(i2c_addr, 0, layout.data, CONFIG_SYS_EEPROM_SIZE); 335 429 #endif 336 430 337 - return rcode; 431 + static int eeprom_action_expected_argc(enum eeprom_action action) 432 + { 433 + switch (action) { 434 + case EEPROM_LIST: 435 + return 0; 436 + case EEPROM_READ: 437 + case EEPROM_WRITE: 438 + return 3; 439 + case EEPROM_PRINT: 440 + return 0; 441 + case EEPROM_UPDATE: 442 + return 2; 443 + default: 444 + return CMD_RET_USAGE; 445 + } 338 446 } 339 447 340 448 #define NEXT_PARAM(argc, index) { (argc)--; (index)++; } 341 449 int do_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 342 450 { 343 - int layout_ver = LAYOUT_VERSION_AUTODETECT; 344 451 enum eeprom_action action = EEPROM_ACTION_INVALID; 345 - int i2c_bus = -1, index = 0; 346 - ulong i2c_addr = -1, addr = 0, cnt = 0, off = 0; 347 - int ret; 452 + struct eeprom_dev_spec dev; 453 + ulong addr = 0, cnt = 0, off = 0; 454 + int ret, index = 0; 455 + #ifdef CONFIG_CMD_EEPROM_LAYOUT 348 456 char *field_name = ""; 349 457 char *field_value = ""; 458 + int layout_ver = LAYOUT_VERSION_AUTODETECT; 459 + #endif 350 460 351 461 if (argc <= 1) 352 462 return CMD_RET_USAGE; ··· 359 469 if (action == EEPROM_ACTION_INVALID) 360 470 return CMD_RET_USAGE; 361 471 362 - #ifdef CONFIG_CMD_EEPROM_LAYOUT 472 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 473 + if (action == EEPROM_LIST) 474 + return do_eeprom_list(); 475 + #endif 476 + 477 + #ifdef CONFIG_EEPROM_LAYOUT_VERSIONS 363 478 if (action == EEPROM_PRINT || action == EEPROM_UPDATE) { 364 479 if (!strcmp(argv[index], "-l")) { 365 480 NEXT_PARAM(argc, index); ··· 369 484 } 370 485 #endif 371 486 372 - switch (action) { 373 - case EEPROM_READ: 374 - case EEPROM_WRITE: 375 - ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc, 376 - argv + index, 3); 377 - break; 378 - case EEPROM_PRINT: 379 - ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc, 380 - argv + index, 0); 381 - break; 382 - case EEPROM_UPDATE: 383 - ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc, 384 - argv + index, 2); 385 - break; 386 - default: 387 - /* Get compiler to stop whining */ 388 - return CMD_RET_USAGE; 389 - } 390 - 487 + ret = parse_eeprom_dev_spec(&dev, 488 + argc - eeprom_action_expected_argc(action), 489 + argv + index); 391 490 if (ret == CMD_RET_USAGE) 392 491 return ret; 393 492 ··· 411 510 } 412 511 #endif 413 512 414 - return eeprom_execute_command(action, i2c_bus, i2c_addr, layout_ver, 415 - field_name, field_value, addr, off, cnt); 513 + eeprom_dev_spec_init(&dev); 514 + 515 + switch (action) { 516 + case EEPROM_READ: 517 + case EEPROM_WRITE: 518 + return do_eeprom_rw(&dev, action == EEPROM_READ, 519 + addr, off, cnt); 520 + #ifdef CONFIG_CMD_EEPROM_LAYOUT 521 + case EEPROM_PRINT: 522 + return do_eeprom_print(&dev, layout_ver); 523 + case EEPROM_UPDATE: 524 + return do_eeprom_update(&dev, layout_ver, 525 + field_name, field_value); 526 + #endif 527 + default: 528 + return CMD_RET_USAGE; 529 + } 416 530 } 417 531 532 + #ifdef CONFIG_EEPROM_LAYOUT_VERSIONS 533 + #define EEPROM_LAYOUT_SPEC "[-l <layout_version>] " 534 + #else 535 + #define EEPROM_LAYOUT_SPEC "" 536 + #endif 537 + 538 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 539 + # define EEPROM_DEV_SPEC "[device_specifier]" 540 + #else 541 + # define EEPROM_DEV_SPEC "[[bus] devaddr]" 542 + #endif 543 + 418 544 U_BOOT_CMD( 419 545 eeprom, 8, 1, do_eeprom, 420 546 "EEPROM sub-system", 421 - "read <bus> <devaddr> addr off cnt\n" 422 - "eeprom write <bus> <devaddr> addr off cnt\n" 547 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 548 + "list\n" 549 + "eeprom " 550 + #endif 551 + "read " EEPROM_DEV_SPEC " addr off cnt\n" 552 + "eeprom write " EEPROM_DEV_SPEC " addr off cnt\n" 423 553 " - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'" 424 554 #ifdef CONFIG_CMD_EEPROM_LAYOUT 425 555 "\n" 426 - "eeprom print [-l <layout_version>] <bus> <devaddr>\n" 556 + "eeprom print " EEPROM_LAYOUT_SPEC EEPROM_DEV_SPEC "\n" 427 557 " - Print layout fields and their data in human readable format\n" 428 - "eeprom update [-l <layout_version>] <bus> <devaddr> field_name field_value\n" 558 + "eeprom update " EEPROM_LAYOUT_SPEC EEPROM_DEV_SPEC " field_name field_value\n" 429 559 " - Update a specific eeprom field with new data.\n" 430 - " The new data must be written in the same human readable format as shown by the print command.\n" 431 - "\n" 560 + " The new data must be written in the same human readable format as shown by the print command." 561 + #endif 562 + #if CONFIG_IS_ENABLED(I2C_EEPROM) 563 + "\n\n" 564 + "DEVICE SPECIFIER - the eeprom device can be specified\n" 565 + " [dev_name] - by device name (devices can listed with the eeprom list command)\n" 566 + " [[bus] devaddr] - or by I2C bus and I2C device address\n" 567 + "If no device specifier is given, the first driver-model found device is used." 568 + #endif 569 + #ifdef CONFIG_EEPROM_LAYOUT_VERSIONS 570 + "\n\n" 432 571 "LAYOUT VERSIONS\n" 433 572 "The -l option can be used to force the command to interpret the EEPROM data using the chosen layout.\n" 434 573 "If the -l option is omitted, the command will auto detect the layout based on the data in the EEPROM.\n"
+2 -2
common/eeprom/eeprom_field.c
··· 56 56 tmp[k] = value[reverse ? i - 1 + k : i + k]; 57 57 } 58 58 59 - byte = simple_strtoul(tmp, &endptr, 0); 60 - if (*endptr != '\0' || byte < 0) 59 + byte = simple_strtoul(tmp, &endptr, 16); 60 + if (*endptr != '\0') 61 61 return -1; 62 62 63 63 field->buf[j] = byte;
+35 -19
common/eeprom/eeprom_layout.c
··· 57 57 } 58 58 59 59 /* 60 + * eeprom_layout_find_field() - finds a layout field by name 61 + * @layout: A pointer to an existing struct layout. 62 + * @field_name: The name of the field to update. 63 + * @warn: Whether to print a warning if the field is not found. 64 + * 65 + * Returns: a pointer to the found field or NULL on failure. 66 + */ 67 + struct eeprom_field *eeprom_layout_find_field(struct eeprom_layout *layout, 68 + char *field_name, bool warn) 69 + { 70 + for (int i = 0; i < layout->num_of_fields; i++) 71 + if (layout->fields[i].name != RESERVED_FIELDS && 72 + !strcmp(layout->fields[i].name, field_name)) 73 + return &layout->fields[i]; 74 + 75 + if (warn) 76 + printf("No such field '%s'\n", field_name); 77 + 78 + return NULL; 79 + } 80 + 81 + /* 60 82 * eeprom_layout_update_field() - update a single field in the layout data. 61 83 * @layout: A pointer to an existing struct layout. 62 84 * @field_name: The name of the field to update. ··· 67 89 static int eeprom_layout_update_field(struct eeprom_layout *layout, 68 90 char *field_name, char *new_data) 69 91 { 70 - int i, err; 71 - struct eeprom_field *fields = layout->fields; 92 + struct eeprom_field *field; 93 + int err; 72 94 73 95 if (new_data == NULL) 74 96 return 0; ··· 76 98 if (field_name == NULL) 77 99 return -1; 78 100 79 - for (i = 0; i < layout->num_of_fields; i++) { 80 - if (fields[i].name == RESERVED_FIELDS || 81 - strcmp(fields[i].name, field_name)) 82 - continue; 101 + field = eeprom_layout_find_field(layout, field_name, true); 102 + if (field == NULL) 103 + return -1; 83 104 84 - err = fields[i].update(&fields[i], new_data); 85 - if (err) 86 - printf("Invalid data for field %s\n", field_name); 105 + err = field->update(field, new_data); 106 + if (err) 107 + printf("Invalid data for field %s\n", field_name); 87 108 88 - return err; 89 - } 90 - 91 - printf("No such field '%s'\n", field_name); 92 - 93 - return -1; 109 + return err; 94 110 } 95 111 96 112 /* ··· 111 127 else 112 128 layout->layout_version = layout_version; 113 129 130 + layout->data_size = buf_size; 131 + layout->print = eeprom_layout_print; 132 + layout->update = eeprom_layout_update_field; 133 + 114 134 eeprom_layout_assign(layout, layout_version); 115 135 layout->data = buf; 116 136 for (i = 0; i < layout->num_of_fields; i++) { 117 137 layout->fields[i].buf = buf; 118 138 buf += layout->fields[i].size; 119 139 } 120 - 121 - layout->data_size = buf_size; 122 - layout->print = eeprom_layout_print; 123 - layout->update = eeprom_layout_update_field; 124 140 }
+1
configs/cm_fx6_defconfig
··· 46 46 CONFIG_CMD_GREPENV=y 47 47 CONFIG_CMD_EEPROM=y 48 48 CONFIG_CMD_EEPROM_LAYOUT=y 49 + CONFIG_EEPROM_LAYOUT_VERSIONS=y 49 50 CONFIG_EEPROM_LAYOUT_HELP_STRING="v2, v3" 50 51 CONFIG_SYS_I2C_EEPROM_BUS=2 51 52 CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4
+1
configs/cm_t43_defconfig
··· 50 50 CONFIG_CMD_ASKENV=y 51 51 CONFIG_CMD_EEPROM=y 52 52 CONFIG_CMD_EEPROM_LAYOUT=y 53 + CONFIG_EEPROM_LAYOUT_VERSIONS=y 53 54 CONFIG_EEPROM_LAYOUT_HELP_STRING="v2, v3" 54 55 CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4 55 56 CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5
+4
include/eeprom_layout.h
··· 9 9 #ifndef _LAYOUT_ 10 10 #define _LAYOUT_ 11 11 12 + #include <eeprom_field.h> 13 + 12 14 #define RESERVED_FIELDS NULL 13 15 #define LAYOUT_VERSION_UNRECOGNIZED -1 14 16 #define LAYOUT_VERSION_AUTODETECT -2 ··· 24 26 char *new_data); 25 27 }; 26 28 29 + struct eeprom_field *eeprom_layout_find_field(struct eeprom_layout *layout, 30 + char *field_name, bool warn); 27 31 void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf, 28 32 unsigned int buf_size, int layout_version); 29 33 __weak void __eeprom_layout_assign(struct eeprom_layout *layout,