Skip to content

Commit 52d543b

Browse files
committed
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
2 parents a452c4e + 8d10ea1 commit 52d543b

File tree

6 files changed

+70
-72
lines changed

6 files changed

+70
-72
lines changed

Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ properties:
3636
$ref: /schemas/types.yaml#/definitions/uint32
3737
description: Number of retries before a failure is declared. Defaults to 1.
3838

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+
3947
required:
4048
- compatible
4149
- reg

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10171,6 +10171,7 @@ M: Corey Minyard <[email protected]>
1017110171
L: [email protected] (moderated for non-subscribers)
1017210172
S: Supported
1017310173
W: http://openipmi.sourceforge.net/
10174+
T: git https://github.com/cminyard/linux-ipmi.git for-next
1017410175
F: Documentation/driver-api/ipmi.rst
1017510176
F: Documentation/devicetree/bindings/ipmi/
1017610177
F: drivers/char/ipmi/

drivers/char/ipmi/ipmi_ipmb.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ MODULE_PARM_DESC(max_retries, "Max resends of a command before timing out.");
3939
struct ipmi_ipmb_dev {
4040
struct ipmi_smi *intf;
4141
struct i2c_client *client;
42+
struct i2c_client *slave;
4243

4344
struct ipmi_smi_handlers handlers;
4445

@@ -257,7 +258,7 @@ static void ipmi_ipmb_format_for_xmit(struct ipmi_ipmb_dev *iidev,
257258
memcpy(iidev->xmitmsg + 5, msg->data + 1, msg->data_size - 1);
258259
iidev->xmitlen = msg->data_size + 4;
259260
}
260-
iidev->xmitmsg[3] = iidev->client->addr << 1;
261+
iidev->xmitmsg[3] = iidev->slave->addr << 1;
261262
if (((msg->data[0] >> 2) & 1) == 0)
262263
/* If it's a command, put in our own sequence number. */
263264
iidev->xmitmsg[4] = ((iidev->xmitmsg[4] & 0x03) |
@@ -427,12 +428,17 @@ static int ipmi_ipmb_remove(struct i2c_client *client)
427428
{
428429
struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client);
429430

430-
if (iidev->client) {
431-
iidev->client = NULL;
432-
i2c_slave_unregister(client);
431+
if (iidev->slave) {
432+
i2c_slave_unregister(iidev->slave);
433+
if (iidev->slave != iidev->client)
434+
i2c_unregister_device(iidev->slave);
433435
}
436+
iidev->slave = NULL;
437+
iidev->client = NULL;
434438
ipmi_ipmb_stop_thread(iidev);
435439

440+
ipmi_unregister_smi(iidev->intf);
441+
436442
return 0;
437443
}
438444

@@ -441,6 +447,9 @@ static int ipmi_ipmb_probe(struct i2c_client *client,
441447
{
442448
struct device *dev = &client->dev;
443449
struct ipmi_ipmb_dev *iidev;
450+
struct device_node *slave_np;
451+
struct i2c_adapter *slave_adap = NULL;
452+
struct i2c_client *slave = NULL;
444453
int rv;
445454

446455
iidev = devm_kzalloc(&client->dev, sizeof(*iidev), GFP_KERNEL);
@@ -464,14 +473,45 @@ static int ipmi_ipmb_probe(struct i2c_client *client,
464473
&iidev->max_retries) != 0)
465474
iidev->max_retries = max_retries;
466475

476+
slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0);
477+
if (slave_np) {
478+
slave_adap = of_get_i2c_adapter_by_node(slave_np);
479+
if (!slave_adap) {
480+
dev_notice(&client->dev,
481+
"Could not find slave adapter\n");
482+
return -EINVAL;
483+
}
484+
}
485+
486+
iidev->client = client;
487+
488+
if (slave_adap) {
489+
struct i2c_board_info binfo;
490+
491+
memset(&binfo, 0, sizeof(binfo));
492+
strscpy(binfo.type, "ipmb-slave", I2C_NAME_SIZE);
493+
binfo.addr = client->addr;
494+
binfo.flags = I2C_CLIENT_SLAVE;
495+
slave = i2c_new_client_device(slave_adap, &binfo);
496+
i2c_put_adapter(slave_adap);
497+
if (IS_ERR(slave)) {
498+
rv = PTR_ERR(slave);
499+
dev_notice(&client->dev,
500+
"Could not allocate slave device: %d\n", rv);
501+
return rv;
502+
}
503+
i2c_set_clientdata(slave, iidev);
504+
} else {
505+
slave = client;
506+
}
467507
i2c_set_clientdata(client, iidev);
468-
client->flags |= I2C_CLIENT_SLAVE;
508+
slave->flags |= I2C_CLIENT_SLAVE;
469509

470-
rv = i2c_slave_register(client, ipmi_ipmb_slave_cb);
510+
rv = i2c_slave_register(slave, ipmi_ipmb_slave_cb);
471511
if (rv)
472-
return rv;
473-
474-
iidev->client = client;
512+
goto out_err;
513+
iidev->slave = slave;
514+
slave = NULL;
475515

476516
iidev->handlers.flags = IPMI_SMI_CAN_HANDLE_IPMB_DIRECT;
477517
iidev->handlers.start_processing = ipmi_ipmb_start_processing;
@@ -502,6 +542,8 @@ static int ipmi_ipmb_probe(struct i2c_client *client,
502542
return 0;
503543

504544
out_err:
545+
if (slave && slave != client)
546+
i2c_unregister_device(slave);
505547
ipmi_ipmb_remove(client);
506548
return rv;
507549
}

drivers/char/ipmi/ipmi_ssif.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info)
13541354
if (rv)
13551355
rv = -ENODEV;
13561356
else
1357-
strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE);
1357+
strscpy(info->type, DEVICE_NAME, I2C_NAME_SIZE);
13581358
kfree(resp);
13591359
return rv;
13601360
}
@@ -1625,7 +1625,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
16251625
unsigned char *resp;
16261626
struct ssif_info *ssif_info;
16271627
int rv = 0;
1628-
int len;
1628+
int len = 0;
16291629
int i;
16301630
u8 slave_addr = 0;
16311631
struct ssif_addr_info *addr_info = NULL;

drivers/char/ipmi/ipmi_watchdog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ static int ipmi_heartbeat(void)
668668
return rv;
669669
}
670670

671-
static struct watchdog_info ident = {
671+
static const struct watchdog_info ident = {
672672
.options = 0, /* WDIOF_SETTIMEOUT, */
673673
.firmware_version = 1,
674674
.identity = "IPMI"

drivers/char/ipmi/kcs_bmc_aspeed.c

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,6 @@ struct aspeed_kcs_bmc {
128128
} obe;
129129
};
130130

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-
136131
static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc)
137132
{
138133
return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc);
@@ -475,38 +470,7 @@ static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
475470
{ .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
476471
};
477472

478-
static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev)
479-
{
480-
struct device_node *np;
481-
u32 channel;
482-
int rc;
483-
484-
np = pdev->dev.of_node;
485-
486-
rc = of_property_read_u32(np, "kcs_chan", &channel);
487-
if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) {
488-
dev_err(&pdev->dev, "no valid 'kcs_chan' configured\n");
489-
return -EINVAL;
490-
}
491-
492-
return channel;
493-
}
494-
495-
static int
496-
aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev, u32 addrs[2])
497-
{
498-
int rc;
499-
500-
rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", addrs);
501-
if (rc || addrs[0] > 0xffff) {
502-
dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n");
503-
return -EINVAL;
504-
}
505-
506-
return 1;
507-
}
508-
509-
static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev)
473+
static int aspeed_kcs_of_get_channel(struct platform_device *pdev)
510474
{
511475
struct device_node *np;
512476
struct kcs_ioreg ioreg;
@@ -535,12 +499,11 @@ static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev)
535499
if (!memcmp(&ast_kcs_bmc_ioregs[i], &ioreg, sizeof(ioreg)))
536500
return i + 1;
537501
}
538-
539502
return -EINVAL;
540503
}
541504

542505
static int
543-
aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2])
506+
aspeed_kcs_of_get_io_address(struct platform_device *pdev, u32 addrs[2])
544507
{
545508
int rc;
546509

@@ -567,7 +530,6 @@ aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2])
567530

568531
static int aspeed_kcs_probe(struct platform_device *pdev)
569532
{
570-
const struct aspeed_kcs_of_ops *ops;
571533
struct kcs_bmc_device *kcs_bmc;
572534
struct aspeed_kcs_bmc *priv;
573535
struct device_node *np;
@@ -585,15 +547,11 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
585547
return -ENODEV;
586548
}
587549

588-
ops = of_device_get_match_data(&pdev->dev);
589-
if (!ops)
590-
return -EINVAL;
591-
592-
channel = ops->get_channel(pdev);
550+
channel = aspeed_kcs_of_get_channel(pdev);
593551
if (channel < 0)
594552
return channel;
595553

596-
nr_addrs = ops->get_io_address(pdev, addrs);
554+
nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs);
597555
if (nr_addrs < 0)
598556
return nr_addrs;
599557

@@ -678,21 +636,10 @@ static int aspeed_kcs_remove(struct platform_device *pdev)
678636
return 0;
679637
}
680638

681-
static const struct aspeed_kcs_of_ops of_v1_ops = {
682-
.get_channel = aspeed_kcs_of_v1_get_channel,
683-
.get_io_address = aspeed_kcs_of_v1_get_io_address,
684-
};
685-
686-
static const struct aspeed_kcs_of_ops of_v2_ops = {
687-
.get_channel = aspeed_kcs_of_v2_get_channel,
688-
.get_io_address = aspeed_kcs_of_v2_get_io_address,
689-
};
690-
691639
static const struct of_device_id ast_kcs_bmc_match[] = {
692-
{ .compatible = "aspeed,ast2400-kcs-bmc", .data = &of_v1_ops },
693-
{ .compatible = "aspeed,ast2500-kcs-bmc", .data = &of_v1_ops },
694-
{ .compatible = "aspeed,ast2400-kcs-bmc-v2", .data = &of_v2_ops },
695-
{ .compatible = "aspeed,ast2500-kcs-bmc-v2", .data = &of_v2_ops },
640+
{ .compatible = "aspeed,ast2400-kcs-bmc-v2" },
641+
{ .compatible = "aspeed,ast2500-kcs-bmc-v2" },
642+
{ .compatible = "aspeed,ast2600-kcs-bmc" },
696643
{ }
697644
};
698645
MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match);

0 commit comments

Comments
 (0)