Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

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

Merge tag 'for-linus-5.17-1' of https://github.com/cminyard/linux-ipmi

Pull IPMI updates from Corey Minyard:

- Little fixes for various things people have noticed.

- One enhancement, the IPMI over IPMB (I2c) is modified to allow it to
take a separate sender and receiver device. The Raspberry Pi has an
I2C slave device that cannot send.

* tag 'for-linus-5.17-1' of https://github.com/cminyard/linux-ipmi:
ipmi: initialize len variable
ipmi: kcs: aspeed: Remove old bindings support
ipmi:ipmb: Add the ability to have a separate slave and master device
ipmi:ipmi_ipmb: Unregister the SMI on remove
ipmi: kcs: aspeed: Add AST2600 compatible string
ipmi: ssif: replace strlcpy with strscpy
ipmi/watchdog: Constify ident
ipmi: Add the git repository to the MAINTAINERS file

+71 -73
+8
Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml
··· 36 36 $ref: /schemas/types.yaml#/definitions/uint32 37 37 description: Number of retries before a failure is declared. Defaults to 1. 38 38 39 + slave-dev: 40 + $ref: /schemas/types.yaml#/definitions/phandle 41 + description: | 42 + The slave i2c device. If not present, the main device is used. This 43 + lets you use two devices on the IPMB, one for master and one for slave, 44 + in case you have a slave device that can only be a slave. The slave 45 + will receive messages and the master will transmit. 46 + 39 47 required: 40 48 - compatible 41 49 - reg
+1
MAINTAINERS
··· 10171 10171 L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers) 10172 10172 S: Supported 10173 10173 W: http://openipmi.sourceforge.net/ 10174 + T: git https://github.com/cminyard/linux-ipmi.git for-next 10174 10175 F: Documentation/driver-api/ipmi.rst 10175 10176 F: Documentation/devicetree/bindings/ipmi/ 10176 10177 F: drivers/char/ipmi/
+52 -10
drivers/char/ipmi/ipmi_ipmb.c
··· 39 39 struct ipmi_ipmb_dev { 40 40 struct ipmi_smi *intf; 41 41 struct i2c_client *client; 42 + struct i2c_client *slave; 42 43 43 44 struct ipmi_smi_handlers handlers; 44 45 ··· 258 257 memcpy(iidev->xmitmsg + 5, msg->data + 1, msg->data_size - 1); 259 258 iidev->xmitlen = msg->data_size + 4; 260 259 } 261 - iidev->xmitmsg[3] = iidev->client->addr << 1; 260 + iidev->xmitmsg[3] = iidev->slave->addr << 1; 262 261 if (((msg->data[0] >> 2) & 1) == 0) 263 262 /* If it's a command, put in our own sequence number. */ 264 263 iidev->xmitmsg[4] = ((iidev->xmitmsg[4] & 0x03) | ··· 428 427 { 429 428 struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client); 430 429 431 - if (iidev->client) { 432 - iidev->client = NULL; 433 - i2c_slave_unregister(client); 430 + if (iidev->slave) { 431 + i2c_slave_unregister(iidev->slave); 432 + if (iidev->slave != iidev->client) 433 + i2c_unregister_device(iidev->slave); 434 434 } 435 + iidev->slave = NULL; 436 + iidev->client = NULL; 435 437 ipmi_ipmb_stop_thread(iidev); 438 + 439 + ipmi_unregister_smi(iidev->intf); 436 440 437 441 return 0; 438 442 } ··· 447 441 { 448 442 struct device *dev = &client->dev; 449 443 struct ipmi_ipmb_dev *iidev; 444 + struct device_node *slave_np; 445 + struct i2c_adapter *slave_adap = NULL; 446 + struct i2c_client *slave = NULL; 450 447 int rv; 451 448 452 449 iidev = devm_kzalloc(&client->dev, sizeof(*iidev), GFP_KERNEL); ··· 473 464 &iidev->max_retries) != 0) 474 465 iidev->max_retries = max_retries; 475 466 476 - i2c_set_clientdata(client, iidev); 477 - client->flags |= I2C_CLIENT_SLAVE; 478 - 479 - rv = i2c_slave_register(client, ipmi_ipmb_slave_cb); 480 - if (rv) 481 - return rv; 467 + slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0); 468 + if (slave_np) { 469 + slave_adap = of_get_i2c_adapter_by_node(slave_np); 470 + if (!slave_adap) { 471 + dev_notice(&client->dev, 472 + "Could not find slave adapter\n"); 473 + return -EINVAL; 474 + } 475 + } 482 476 483 477 iidev->client = client; 478 + 479 + if (slave_adap) { 480 + struct i2c_board_info binfo; 481 + 482 + memset(&binfo, 0, sizeof(binfo)); 483 + strscpy(binfo.type, "ipmb-slave", I2C_NAME_SIZE); 484 + binfo.addr = client->addr; 485 + binfo.flags = I2C_CLIENT_SLAVE; 486 + slave = i2c_new_client_device(slave_adap, &binfo); 487 + i2c_put_adapter(slave_adap); 488 + if (IS_ERR(slave)) { 489 + rv = PTR_ERR(slave); 490 + dev_notice(&client->dev, 491 + "Could not allocate slave device: %d\n", rv); 492 + return rv; 493 + } 494 + i2c_set_clientdata(slave, iidev); 495 + } else { 496 + slave = client; 497 + } 498 + i2c_set_clientdata(client, iidev); 499 + slave->flags |= I2C_CLIENT_SLAVE; 500 + 501 + rv = i2c_slave_register(slave, ipmi_ipmb_slave_cb); 502 + if (rv) 503 + goto out_err; 504 + iidev->slave = slave; 505 + slave = NULL; 484 506 485 507 iidev->handlers.flags = IPMI_SMI_CAN_HANDLE_IPMB_DIRECT; 486 508 iidev->handlers.start_processing = ipmi_ipmb_start_processing; ··· 542 502 return 0; 543 503 544 504 out_err: 505 + if (slave && slave != client) 506 + i2c_unregister_device(slave); 545 507 ipmi_ipmb_remove(client); 546 508 return rv; 547 509 }
+2 -2
drivers/char/ipmi/ipmi_ssif.c
··· 1354 1354 if (rv) 1355 1355 rv = -ENODEV; 1356 1356 else 1357 - strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); 1357 + strscpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); 1358 1358 kfree(resp); 1359 1359 return rv; 1360 1360 } ··· 1625 1625 unsigned char *resp; 1626 1626 struct ssif_info *ssif_info; 1627 1627 int rv = 0; 1628 - int len; 1628 + int len = 0; 1629 1629 int i; 1630 1630 u8 slave_addr = 0; 1631 1631 struct ssif_addr_info *addr_info = NULL;
+1 -1
drivers/char/ipmi/ipmi_watchdog.c
··· 668 668 return rv; 669 669 } 670 670 671 - static struct watchdog_info ident = { 671 + static const struct watchdog_info ident = { 672 672 .options = 0, /* WDIOF_SETTIMEOUT, */ 673 673 .firmware_version = 1, 674 674 .identity = "IPMI"
+7 -60
drivers/char/ipmi/kcs_bmc_aspeed.c
··· 128 128 } obe; 129 129 }; 130 130 131 - struct aspeed_kcs_of_ops { 132 - int (*get_channel)(struct platform_device *pdev); 133 - int (*get_io_address)(struct platform_device *pdev, u32 addrs[2]); 134 - }; 135 - 136 131 static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc) 137 132 { 138 133 return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc); ··· 470 475 { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, 471 476 }; 472 477 473 - static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev) 474 - { 475 - struct device_node *np; 476 - u32 channel; 477 - int rc; 478 - 479 - np = pdev->dev.of_node; 480 - 481 - rc = of_property_read_u32(np, "kcs_chan", &channel); 482 - if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) { 483 - dev_err(&pdev->dev, "no valid 'kcs_chan' configured\n"); 484 - return -EINVAL; 485 - } 486 - 487 - return channel; 488 - } 489 - 490 - static int 491 - aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev, u32 addrs[2]) 492 - { 493 - int rc; 494 - 495 - rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", addrs); 496 - if (rc || addrs[0] > 0xffff) { 497 - dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n"); 498 - return -EINVAL; 499 - } 500 - 501 - return 1; 502 - } 503 - 504 - static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) 478 + static int aspeed_kcs_of_get_channel(struct platform_device *pdev) 505 479 { 506 480 struct device_node *np; 507 481 struct kcs_ioreg ioreg; ··· 499 535 if (!memcmp(&ast_kcs_bmc_ioregs[i], &ioreg, sizeof(ioreg))) 500 536 return i + 1; 501 537 } 502 - 503 538 return -EINVAL; 504 539 } 505 540 506 541 static int 507 - aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2]) 542 + aspeed_kcs_of_get_io_address(struct platform_device *pdev, u32 addrs[2]) 508 543 { 509 544 int rc; 510 545 ··· 530 567 531 568 static int aspeed_kcs_probe(struct platform_device *pdev) 532 569 { 533 - const struct aspeed_kcs_of_ops *ops; 534 570 struct kcs_bmc_device *kcs_bmc; 535 571 struct aspeed_kcs_bmc *priv; 536 572 struct device_node *np; ··· 547 585 return -ENODEV; 548 586 } 549 587 550 - ops = of_device_get_match_data(&pdev->dev); 551 - if (!ops) 552 - return -EINVAL; 553 - 554 - channel = ops->get_channel(pdev); 588 + channel = aspeed_kcs_of_get_channel(pdev); 555 589 if (channel < 0) 556 590 return channel; 557 591 558 - nr_addrs = ops->get_io_address(pdev, addrs); 592 + nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs); 559 593 if (nr_addrs < 0) 560 594 return nr_addrs; 561 595 ··· 636 678 return 0; 637 679 } 638 680 639 - static const struct aspeed_kcs_of_ops of_v1_ops = { 640 - .get_channel = aspeed_kcs_of_v1_get_channel, 641 - .get_io_address = aspeed_kcs_of_v1_get_io_address, 642 - }; 643 - 644 - static const struct aspeed_kcs_of_ops of_v2_ops = { 645 - .get_channel = aspeed_kcs_of_v2_get_channel, 646 - .get_io_address = aspeed_kcs_of_v2_get_io_address, 647 - }; 648 - 649 681 static const struct of_device_id ast_kcs_bmc_match[] = { 650 - { .compatible = "aspeed,ast2400-kcs-bmc", .data = &of_v1_ops }, 651 - { .compatible = "aspeed,ast2500-kcs-bmc", .data = &of_v1_ops }, 652 - { .compatible = "aspeed,ast2400-kcs-bmc-v2", .data = &of_v2_ops }, 653 - { .compatible = "aspeed,ast2500-kcs-bmc-v2", .data = &of_v2_ops }, 682 + { .compatible = "aspeed,ast2400-kcs-bmc-v2" }, 683 + { .compatible = "aspeed,ast2500-kcs-bmc-v2" }, 684 + { .compatible = "aspeed,ast2600-kcs-bmc" }, 654 685 { } 655 686 }; 656 687 MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match);