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.

Merge tag 'hwmon-for-v6.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:

- pmbus/ucd9000: Increase chip access delay to avoid random access
errors

- corsair-cpro: Protect kernel code against parallel hidraw access from
userspace

* tag 'hwmon-for-v6.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us
hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
hwmon: (corsair-cpro) Use complete_all() instead of complete() in ccp_raw_event()
hwmon: (corsair-cpro) Use a separate buffer for sending commands

+34 -15
+31 -12
drivers/hwmon/corsair-cpro.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/mutex.h> 18 18 #include <linux/slab.h> 19 + #include <linux/spinlock.h> 19 20 #include <linux/types.h> 20 21 21 22 #define USB_VENDOR_ID_CORSAIR 0x1b1c ··· 78 77 struct ccp_device { 79 78 struct hid_device *hdev; 80 79 struct device *hwmon_dev; 80 + /* For reinitializing the completion below */ 81 + spinlock_t wait_input_report_lock; 81 82 struct completion wait_input_report; 82 83 struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */ 84 + u8 *cmd_buffer; 83 85 u8 *buffer; 84 86 int target[6]; 85 87 DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS); ··· 115 111 unsigned long t; 116 112 int ret; 117 113 118 - memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE); 119 - ccp->buffer[0] = command; 120 - ccp->buffer[1] = byte1; 121 - ccp->buffer[2] = byte2; 122 - ccp->buffer[3] = byte3; 114 + memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE); 115 + ccp->cmd_buffer[0] = command; 116 + ccp->cmd_buffer[1] = byte1; 117 + ccp->cmd_buffer[2] = byte2; 118 + ccp->cmd_buffer[3] = byte3; 123 119 120 + /* 121 + * Disable raw event parsing for a moment to safely reinitialize the 122 + * completion. Reinit is done because hidraw could have triggered 123 + * the raw event parsing and marked the ccp->wait_input_report 124 + * completion as done. 125 + */ 126 + spin_lock_bh(&ccp->wait_input_report_lock); 124 127 reinit_completion(&ccp->wait_input_report); 128 + spin_unlock_bh(&ccp->wait_input_report_lock); 125 129 126 - ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE); 130 + ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE); 127 131 if (ret < 0) 128 132 return ret; 129 133 ··· 147 135 struct ccp_device *ccp = hid_get_drvdata(hdev); 148 136 149 137 /* only copy buffer when requested */ 150 - if (completion_done(&ccp->wait_input_report)) 151 - return 0; 152 - 153 - memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size)); 154 - complete(&ccp->wait_input_report); 138 + spin_lock(&ccp->wait_input_report_lock); 139 + if (!completion_done(&ccp->wait_input_report)) { 140 + memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size)); 141 + complete_all(&ccp->wait_input_report); 142 + } 143 + spin_unlock(&ccp->wait_input_report_lock); 155 144 156 145 return 0; 157 146 } ··· 505 492 if (!ccp) 506 493 return -ENOMEM; 507 494 508 - ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL); 495 + ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL); 496 + if (!ccp->cmd_buffer) 497 + return -ENOMEM; 498 + 499 + ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL); 509 500 if (!ccp->buffer) 510 501 return -ENOMEM; 511 502 ··· 527 510 528 511 ccp->hdev = hdev; 529 512 hid_set_drvdata(hdev, ccp); 513 + 530 514 mutex_init(&ccp->mutex); 515 + spin_lock_init(&ccp->wait_input_report_lock); 531 516 init_completion(&ccp->wait_input_report); 532 517 533 518 hid_device_io_start(hdev);
+3 -3
drivers/hwmon/pmbus/ucd9000.c
··· 80 80 * It has been observed that the UCD90320 randomly fails register access when 81 81 * doing another access right on the back of a register write. To mitigate this 82 82 * make sure that there is a minimum delay between a write access and the 83 - * following access. The 250us is based on experimental data. At a delay of 84 - * 200us the issue seems to go away. Add a bit of extra margin to allow for 83 + * following access. The 500 is based on experimental data. At a delay of 84 + * 350us the issue seems to go away. Add a bit of extra margin to allow for 85 85 * system to system differences. 86 86 */ 87 - #define UCD90320_WAIT_DELAY_US 250 87 + #define UCD90320_WAIT_DELAY_US 500 88 88 89 89 static inline void ucd90320_wait(const struct ucd9000_data *data) 90 90 {