summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml59
-rw-r--r--drivers/char/ipmi/ipmi_ipmb.c39
2 files changed, 93 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml b/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml
new file mode 100644
index 000000000000..93d8f8e88cf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ipmi/ipmi-ipmb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: IPMI IPMB device bindings
+
+description: IPMI IPMB device bindings
+
+maintainers:
+ - Corey Minyard <cminyard@mvista.com>
+
+properties:
+ compatible:
+ enum:
+ - ipmi-ipmb
+
+ device_type:
+ items:
+ - const: "ipmi"
+
+ reg:
+ maxItems: 1
+
+ bmcaddr:
+ $ref: /schemas/types.yaml#/definitions/uint8
+ description: The address of the BMC on the IPMB bus. Defaults to 0x20.
+
+ retry-time:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Time between retries of sends, in milliseconds. Defaults to 250.
+
+ max-retries:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of retries before a failure is declared. Defaults to 1.
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ipmi-ipmb@40 {
+ compatible = "ipmi-ipmb";
+ device_type = "ipmi";
+ reg = <0x40>;
+ bmcaddr = /bits/ 8 <0x20>;
+ retry-time = <250>;
+ max-retries = <1>;
+ };
+ };
diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c
index 856e432fa04c..ba0c2d2c6bbe 100644
--- a/drivers/char/ipmi/ipmi_ipmb.c
+++ b/drivers/char/ipmi/ipmi_ipmb.c
@@ -44,10 +44,12 @@ struct ipmi_ipmb_dev {
bool ready;
- u8 bmcaddr;
-
u8 curr_seq;
+ u8 bmcaddr;
+ u32 retry_time_ms;
+ u32 max_retries;
+
struct ipmi_smi_msg *next_msg;
struct ipmi_smi_msg *working_msg;
@@ -333,7 +335,7 @@ retry:
/* A command was sent, wait for its response. */
ret = down_timeout(&iidev->got_rsp,
- msecs_to_jiffies(retry_time_ms));
+ msecs_to_jiffies(iidev->retry_time_ms));
/*
* Grab the message if we can. If the handler hasn't
@@ -353,7 +355,7 @@ retry:
* the semaphore.
*/
down(&iidev->got_rsp);
- } else if (msg && ++retries <= max_retries) {
+ } else if (msg && ++retries <= iidev->max_retries) {
spin_lock_irqsave(&iidev->lock, flags);
iidev->working_msg = msg;
spin_unlock_irqrestore(&iidev->lock, flags);
@@ -437,6 +439,7 @@ static int ipmi_ipmb_remove(struct i2c_client *client)
static int ipmi_ipmb_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct ipmi_ipmb_dev *iidev;
int rv;
@@ -444,7 +447,22 @@ static int ipmi_ipmb_probe(struct i2c_client *client,
if (!iidev)
return -ENOMEM;
- iidev->bmcaddr = bmcaddr;
+ if (of_property_read_u8(dev->of_node, "bmcaddr", &iidev->bmcaddr) != 0)
+ iidev->bmcaddr = bmcaddr;
+ if (iidev->bmcaddr == 0 || iidev->bmcaddr & 1) {
+ /* Can't have the write bit set. */
+ dev_notice(&client->dev,
+ "Invalid bmc address value %2.2x\n", iidev->bmcaddr);
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(dev->of_node, "retry-time",
+ &iidev->retry_time_ms) != 0)
+ iidev->retry_time_ms = retry_time_ms;
+
+ if (of_property_read_u32(dev->of_node, "max-retries",
+ &iidev->max_retries) != 0)
+ iidev->max_retries = max_retries;
i2c_set_clientdata(client, iidev);
client->flags |= I2C_CLIENT_SLAVE;
@@ -488,6 +506,16 @@ out_err:
return rv;
}
+#ifdef CONFIG_OF
+static const struct of_device_id of_ipmi_ipmb_match[] = {
+ { .type = "ipmi", .compatible = DEVICE_NAME },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_ipmi_ipmb_match);
+#else
+#define of_ipmi_ipmb_match NULL
+#endif
+
static const struct i2c_device_id ipmi_ipmb_id[] = {
{ DEVICE_NAME, 0 },
{},
@@ -498,6 +526,7 @@ static struct i2c_driver ipmi_ipmb_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = DEVICE_NAME,
+ .of_match_table = of_ipmi_ipmb_match,
},
.probe = ipmi_ipmb_probe,
.remove = ipmi_ipmb_remove,