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

Merge tag 'for-linus-2023101101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Benjamin Tissoires:

- regression fix for i2c-hid when used on DT platforms (Johan Hovold)

- kernel crash fix on removal of the Logitech USB receiver (Hans de
Goede)

* tag 'for-linus-2023101101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect
HID: i2c-hid: fix handling of unpopulated devices

+83 -64
+2 -1
drivers/hid/hid-logitech-hidpp.c
··· 4515 4515 goto hid_hw_init_fail; 4516 4516 } 4517 4517 4518 - hidpp_connect_event(hidpp); 4518 + schedule_work(&hidpp->work); 4519 + flush_work(&hidpp->work); 4519 4520 4520 4521 if (will_restart) { 4521 4522 /* Reset the HID node state */
+81 -63
drivers/hid/i2c-hid/i2c-hid-core.c
··· 998 998 return hid_driver_reset_resume(hid); 999 999 } 1000 1000 1001 - /** 1002 - * __do_i2c_hid_core_initial_power_up() - First time power up of the i2c-hid device. 1003 - * @ihid: The ihid object created during probe. 1004 - * 1005 - * This function is called at probe time. 1006 - * 1007 - * The initial power on is where we do some basic validation that the device 1008 - * exists, where we fetch the HID descriptor, and where we create the actual 1009 - * HID devices. 1010 - * 1011 - * Return: 0 or error code. 1001 + /* 1002 + * Check that the device exists and parse the HID descriptor. 1012 1003 */ 1013 - static int __do_i2c_hid_core_initial_power_up(struct i2c_hid *ihid) 1004 + static int __i2c_hid_core_probe(struct i2c_hid *ihid) 1014 1005 { 1015 1006 struct i2c_client *client = ihid->client; 1016 1007 struct hid_device *hid = ihid->hid; 1017 1008 int ret; 1018 1009 1019 - ret = i2c_hid_core_power_up(ihid); 1020 - if (ret) 1021 - return ret; 1022 - 1023 1010 /* Make sure there is something at this address */ 1024 1011 ret = i2c_smbus_read_byte(client); 1025 1012 if (ret < 0) { 1026 1013 i2c_hid_dbg(ihid, "nothing at this address: %d\n", ret); 1027 - ret = -ENXIO; 1028 - goto err; 1014 + return -ENXIO; 1029 1015 } 1030 1016 1031 1017 ret = i2c_hid_fetch_hid_descriptor(ihid); 1032 1018 if (ret < 0) { 1033 1019 dev_err(&client->dev, 1034 1020 "Failed to fetch the HID Descriptor\n"); 1035 - goto err; 1021 + return ret; 1036 1022 } 1037 - 1038 - enable_irq(client->irq); 1039 1023 1040 1024 hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); 1041 1025 hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); ··· 1034 1050 1035 1051 ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); 1036 1052 1053 + return 0; 1054 + } 1055 + 1056 + static int i2c_hid_core_register_hid(struct i2c_hid *ihid) 1057 + { 1058 + struct i2c_client *client = ihid->client; 1059 + struct hid_device *hid = ihid->hid; 1060 + int ret; 1061 + 1062 + enable_irq(client->irq); 1063 + 1037 1064 ret = hid_add_device(hid); 1038 1065 if (ret) { 1039 1066 if (ret != -ENODEV) 1040 1067 hid_err(client, "can't add hid device: %d\n", ret); 1041 - goto err; 1068 + disable_irq(client->irq); 1069 + return ret; 1042 1070 } 1043 1071 1044 1072 return 0; 1073 + } 1045 1074 1046 - err: 1075 + static int i2c_hid_core_probe_panel_follower(struct i2c_hid *ihid) 1076 + { 1077 + int ret; 1078 + 1079 + ret = i2c_hid_core_power_up(ihid); 1080 + if (ret) 1081 + return ret; 1082 + 1083 + ret = __i2c_hid_core_probe(ihid); 1084 + if (ret) 1085 + goto err_power_down; 1086 + 1087 + ret = i2c_hid_core_register_hid(ihid); 1088 + if (ret) 1089 + goto err_power_down; 1090 + 1091 + return 0; 1092 + 1093 + err_power_down: 1047 1094 i2c_hid_core_power_down(ihid); 1095 + 1048 1096 return ret; 1049 1097 } 1050 1098 ··· 1093 1077 * steps. 1094 1078 */ 1095 1079 if (!hid->version) 1096 - ret = __do_i2c_hid_core_initial_power_up(ihid); 1080 + ret = i2c_hid_core_probe_panel_follower(ihid); 1097 1081 else 1098 1082 ret = i2c_hid_core_resume(ihid); 1099 1083 ··· 1152 1136 struct device *dev = &ihid->client->dev; 1153 1137 int ret; 1154 1138 1155 - ihid->is_panel_follower = true; 1156 1139 ihid->panel_follower.funcs = &i2c_hid_core_panel_follower_funcs; 1157 1140 1158 1141 /* ··· 1169 1154 return ret; 1170 1155 1171 1156 return 0; 1172 - } 1173 - 1174 - static int i2c_hid_core_initial_power_up(struct i2c_hid *ihid) 1175 - { 1176 - /* 1177 - * If we're a panel follower, we'll register and do our initial power 1178 - * up when the panel turns on; otherwise we do it right away. 1179 - */ 1180 - if (drm_is_panel_follower(&ihid->client->dev)) 1181 - return i2c_hid_core_register_panel_follower(ihid); 1182 - else 1183 - return __do_i2c_hid_core_initial_power_up(ihid); 1184 - } 1185 - 1186 - static void i2c_hid_core_final_power_down(struct i2c_hid *ihid) 1187 - { 1188 - /* 1189 - * If we're a follower, the act of unfollowing will cause us to be 1190 - * powered down. Otherwise we need to manually do it. 1191 - */ 1192 - if (ihid->is_panel_follower) 1193 - drm_panel_remove_follower(&ihid->panel_follower); 1194 - else 1195 - i2c_hid_core_suspend(ihid, true); 1196 1157 } 1197 1158 1198 1159 int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, ··· 1202 1211 ihid->ops = ops; 1203 1212 ihid->client = client; 1204 1213 ihid->wHIDDescRegister = cpu_to_le16(hid_descriptor_address); 1214 + ihid->is_panel_follower = drm_is_panel_follower(&client->dev); 1205 1215 1206 1216 init_waitqueue_head(&ihid->wait); 1207 1217 mutex_init(&ihid->reset_lock); ··· 1216 1224 return ret; 1217 1225 device_enable_async_suspend(&client->dev); 1218 1226 1219 - ret = i2c_hid_init_irq(client); 1220 - if (ret < 0) 1221 - goto err_buffers_allocated; 1222 - 1223 1227 hid = hid_allocate_device(); 1224 1228 if (IS_ERR(hid)) { 1225 1229 ret = PTR_ERR(hid); 1226 - goto err_irq; 1230 + goto err_free_buffers; 1227 1231 } 1228 1232 1229 1233 ihid->hid = hid; ··· 1230 1242 hid->bus = BUS_I2C; 1231 1243 hid->initial_quirks = quirks; 1232 1244 1233 - ret = i2c_hid_core_initial_power_up(ihid); 1245 + /* Power on and probe unless device is a panel follower. */ 1246 + if (!ihid->is_panel_follower) { 1247 + ret = i2c_hid_core_power_up(ihid); 1248 + if (ret < 0) 1249 + goto err_destroy_device; 1250 + 1251 + ret = __i2c_hid_core_probe(ihid); 1252 + if (ret < 0) 1253 + goto err_power_down; 1254 + } 1255 + 1256 + ret = i2c_hid_init_irq(client); 1257 + if (ret < 0) 1258 + goto err_power_down; 1259 + 1260 + /* 1261 + * If we're a panel follower, we'll register when the panel turns on; 1262 + * otherwise we do it right away. 1263 + */ 1264 + if (ihid->is_panel_follower) 1265 + ret = i2c_hid_core_register_panel_follower(ihid); 1266 + else 1267 + ret = i2c_hid_core_register_hid(ihid); 1234 1268 if (ret) 1235 - goto err_mem_free; 1269 + goto err_free_irq; 1236 1270 1237 1271 return 0; 1238 1272 1239 - err_mem_free: 1240 - hid_destroy_device(hid); 1241 - 1242 - err_irq: 1273 + err_free_irq: 1243 1274 free_irq(client->irq, ihid); 1244 - 1245 - err_buffers_allocated: 1275 + err_power_down: 1276 + if (!ihid->is_panel_follower) 1277 + i2c_hid_core_power_down(ihid); 1278 + err_destroy_device: 1279 + hid_destroy_device(hid); 1280 + err_free_buffers: 1246 1281 i2c_hid_free_buffers(ihid); 1247 1282 1248 1283 return ret; ··· 1277 1266 struct i2c_hid *ihid = i2c_get_clientdata(client); 1278 1267 struct hid_device *hid; 1279 1268 1280 - i2c_hid_core_final_power_down(ihid); 1269 + /* 1270 + * If we're a follower, the act of unfollowing will cause us to be 1271 + * powered down. Otherwise we need to manually do it. 1272 + */ 1273 + if (ihid->is_panel_follower) 1274 + drm_panel_remove_follower(&ihid->panel_follower); 1275 + else 1276 + i2c_hid_core_suspend(ihid, true); 1281 1277 1282 1278 hid = ihid->hid; 1283 1279 hid_destroy_device(hid);