Skip to content

Commit 042f057

Browse files
vijaykhemkacminyard
authored andcommitted
drivers: ipmi: Support raw i2c packet in IPMB
Many IPMB devices don't support smbus protocol and this driver only supports the smbus protocol at the moment. Added support for the i2c protocol as well. There will be a variable "i2c-protocol" passed by the device tree or ACPI table which determines whether the protocol is i2c or smbus. Signed-off-by: Vijay Khemka <[email protected]> Reviewed-by: Asmaa Mnebhi <[email protected]> Message-Id: <[email protected]> [IPMB.txt had moved to driver-api/ipmb.rst, I adjusted] Signed-off-by: Corey Minyard <[email protected]>
1 parent 6794862 commit 042f057

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

Documentation/driver-api/ipmb.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ b) Example for device tree::
7171
ipmb@10 {
7272
compatible = "ipmb-dev";
7373
reg = <0x10>;
74+
i2c-protocol;
7475
};
7576
};
7677

78+
If xmit of data to be done using raw i2c block vs smbus
79+
then "i2c-protocol" needs to be defined as above.
80+
7781
2) Manually from Linux::
7882

7983
modprobe ipmb-dev-int

drivers/char/ipmi/ipmb_dev_int.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct ipmb_dev {
6363
spinlock_t lock;
6464
wait_queue_head_t wait_queue;
6565
struct mutex file_mutex;
66+
bool is_i2c_protocol;
6667
};
6768

6869
static inline struct ipmb_dev *to_ipmb_dev(struct file *file)
@@ -112,6 +113,25 @@ static ssize_t ipmb_read(struct file *file, char __user *buf, size_t count,
112113
return ret < 0 ? ret : count;
113114
}
114115

116+
static int ipmb_i2c_write(struct i2c_client *client, u8 *msg, u8 addr)
117+
{
118+
struct i2c_msg i2c_msg;
119+
120+
/*
121+
* subtract 1 byte (rq_sa) from the length of the msg passed to
122+
* raw i2c_transfer
123+
*/
124+
i2c_msg.len = msg[IPMB_MSG_LEN_IDX] - 1;
125+
126+
/* Assign message to buffer except first 2 bytes (length and address) */
127+
i2c_msg.buf = msg + 2;
128+
129+
i2c_msg.addr = addr;
130+
i2c_msg.flags = client->flags & I2C_CLIENT_PEC;
131+
132+
return i2c_transfer(client->adapter, &i2c_msg, 1);
133+
}
134+
115135
static ssize_t ipmb_write(struct file *file, const char __user *buf,
116136
size_t count, loff_t *ppos)
117137
{
@@ -133,6 +153,12 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf,
133153
rq_sa = GET_7BIT_ADDR(msg[RQ_SA_8BIT_IDX]);
134154
netf_rq_lun = msg[NETFN_LUN_IDX];
135155

156+
/* Check i2c block transfer vs smbus */
157+
if (ipmb_dev->is_i2c_protocol) {
158+
ret = ipmb_i2c_write(ipmb_dev->client, msg, rq_sa);
159+
return (ret == 1) ? count : ret;
160+
}
161+
136162
/*
137163
* subtract rq_sa and netf_rq_lun from the length of the msg passed to
138164
* i2c_smbus_xfer
@@ -302,6 +328,9 @@ static int ipmb_probe(struct i2c_client *client,
302328
if (ret)
303329
return ret;
304330

331+
ipmb_dev->is_i2c_protocol
332+
= device_property_read_bool(&client->dev, "i2c-protocol");
333+
305334
ipmb_dev->client = client;
306335
i2c_set_clientdata(client, ipmb_dev);
307336
ret = i2c_slave_register(client, ipmb_slave_cb);

0 commit comments

Comments
 (0)