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

misc: amd-sbi: Add support for Turin platform

- RMI registers addresses in AMD new platforms are 2 bytes,
on previous processors the address size is 1 byte.
- Implement logic to identify register address size at runtime.
- The identification is done in first transaction using the
Revision register.
- The revision register can be read using 1 byte in both, older and
newer platforms.
- However, sending 1 byte on later platform can cause unrecoverable error.

Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
Link: https://patch.msgid.link/20250915103649.1705078-3-akshay.gupta@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Akshay Gupta and committed by
Greg Kroah-Hartman
45392fd4 5c7dddd7

+47
+47
drivers/misc/amd-sbi/rmi-i2c.c
··· 18 18 #include <linux/regmap.h> 19 19 #include "rmi-core.h" 20 20 21 + #define REV_TWO_BYTE_ADDR 0x21 22 + 21 23 static int sbrmi_enable_alert(struct sbrmi_data *data) 22 24 { 23 25 int ctrl, ret; ··· 91 89 .val_bits = 8, 92 90 }; 93 91 92 + static struct regmap_config sbrmi_regmap_config_ext = { 93 + .reg_bits = 16, 94 + .val_bits = 8, 95 + .reg_format_endian = REGMAP_ENDIAN_LITTLE, 96 + }; 97 + 94 98 static int sbrmi_i2c_probe(struct i2c_client *client) 95 99 { 96 100 struct device *dev = &client->dev; 97 101 struct regmap *regmap; 102 + int rev, ret; 98 103 99 104 regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config); 100 105 if (IS_ERR(regmap)) 101 106 return PTR_ERR(regmap); 102 107 108 + ret = regmap_read(regmap, SBRMI_REV, &rev); 109 + if (ret) 110 + return ret; 111 + 112 + /* 113 + * For Turin and newer platforms, revision is 0x21 or later. This is 114 + * to identify the two byte register address size. However, one 115 + * byte transaction can be successful. 116 + * Verify if revision is 0x21 or later, if yes, switch to 2 byte 117 + * address size. 118 + * Continuously using 1 byte address for revision 0x21 or later can lead 119 + * to bus corruption. 120 + */ 121 + if (rev >= REV_TWO_BYTE_ADDR) { 122 + regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config_ext); 123 + if (IS_ERR(regmap)) 124 + return PTR_ERR(regmap); 125 + } 103 126 return sbrmi_common_probe(dev, regmap, client->addr); 104 127 } 105 128 ··· 168 141 { 169 142 struct device *dev = i3cdev_to_dev(i3cdev); 170 143 struct regmap *regmap; 144 + int rev, ret; 171 145 172 146 regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config); 173 147 if (IS_ERR(regmap)) 174 148 return PTR_ERR(regmap); 149 + 150 + ret = regmap_read(regmap, SBRMI_REV, &rev); 151 + if (ret) 152 + return ret; 153 + 154 + /* 155 + * For Turin and newer platforms, revision is 0x21 or later. This is 156 + * to identify the two byte register address size. However, one 157 + * byte transaction can be successful. 158 + * Verify if revision is 0x21 or later, if yes, switch to 2 byte 159 + * address size. 160 + * Continuously using 1 byte address for revision 0x21 or later can lead 161 + * to bus corruption. 162 + */ 163 + if (rev >= REV_TWO_BYTE_ADDR) { 164 + regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config_ext); 165 + if (IS_ERR(regmap)) 166 + return PTR_ERR(regmap); 167 + } 175 168 176 169 /* 177 170 * AMD APML I3C devices support static address.