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.

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 <vijaykhemka@fb.com>
Reviewed-by: Asmaa Mnebhi <asmaa@mellanox.com>
Message-Id: <20191211185604.1266063-1-vijaykhemka@fb.com>
[IPMB.txt had moved to driver-api/ipmb.rst, I adjusted]
Signed-off-by: Corey Minyard <cminyard@mvista.com>

authored by

Vijay Khemka and committed by
Corey Minyard
042f057f 6794862a

+33
+4
Documentation/driver-api/ipmb.rst
··· 71 71 ipmb@10 { 72 72 compatible = "ipmb-dev"; 73 73 reg = <0x10>; 74 + i2c-protocol; 74 75 }; 75 76 }; 77 + 78 + If xmit of data to be done using raw i2c block vs smbus 79 + then "i2c-protocol" needs to be defined as above. 76 80 77 81 2) Manually from Linux:: 78 82
+29
drivers/char/ipmi/ipmb_dev_int.c
··· 63 63 spinlock_t lock; 64 64 wait_queue_head_t wait_queue; 65 65 struct mutex file_mutex; 66 + bool is_i2c_protocol; 66 67 }; 67 68 68 69 static inline struct ipmb_dev *to_ipmb_dev(struct file *file) ··· 113 112 return ret < 0 ? ret : count; 114 113 } 115 114 115 + static int ipmb_i2c_write(struct i2c_client *client, u8 *msg, u8 addr) 116 + { 117 + struct i2c_msg i2c_msg; 118 + 119 + /* 120 + * subtract 1 byte (rq_sa) from the length of the msg passed to 121 + * raw i2c_transfer 122 + */ 123 + i2c_msg.len = msg[IPMB_MSG_LEN_IDX] - 1; 124 + 125 + /* Assign message to buffer except first 2 bytes (length and address) */ 126 + i2c_msg.buf = msg + 2; 127 + 128 + i2c_msg.addr = addr; 129 + i2c_msg.flags = client->flags & I2C_CLIENT_PEC; 130 + 131 + return i2c_transfer(client->adapter, &i2c_msg, 1); 132 + } 133 + 116 134 static ssize_t ipmb_write(struct file *file, const char __user *buf, 117 135 size_t count, loff_t *ppos) 118 136 { ··· 152 132 153 133 rq_sa = GET_7BIT_ADDR(msg[RQ_SA_8BIT_IDX]); 154 134 netf_rq_lun = msg[NETFN_LUN_IDX]; 135 + 136 + /* Check i2c block transfer vs smbus */ 137 + if (ipmb_dev->is_i2c_protocol) { 138 + ret = ipmb_i2c_write(ipmb_dev->client, msg, rq_sa); 139 + return (ret == 1) ? count : ret; 140 + } 155 141 156 142 /* 157 143 * subtract rq_sa and netf_rq_lun from the length of the msg passed to ··· 327 301 ret = misc_register(&ipmb_dev->miscdev); 328 302 if (ret) 329 303 return ret; 304 + 305 + ipmb_dev->is_i2c_protocol 306 + = device_property_read_bool(&client->dev, "i2c-protocol"); 330 307 331 308 ipmb_dev->client = client; 332 309 i2c_set_clientdata(client, ipmb_dev);