Commit 5512c33c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hwmon-for-v6.5-rc6' of...

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

Pull hwmon fixes from Guenter Roeck:

 - Fix sporadic comunication errors in pmbus/bel-pfe and
   aquacomputer_d5next drivers

* tag 'hwmon-for-v6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (aquacomputer_d5next) Add selective 200ms delay after sending ctrl report
  hwmon: (pmbus/bel-pfe) Enable PMBUS_SKIP_STATUS_CHECK for pfe1100
parents 190bf7b1 56b930dc
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -13,9 +13,11 @@

#include <linux/crc16.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/hid.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>
@@ -63,6 +65,8 @@ static const char *const aqc_device_names[] = {
#define CTRL_REPORT_ID			0x03
#define AQUAERO_CTRL_REPORT_ID		0x0b

#define CTRL_REPORT_DELAY		200	/* ms */

/* The HID report that the official software always sends
 * after writing values, currently same for all devices
 */
@@ -527,6 +531,9 @@ struct aqc_data {
	int secondary_ctrl_report_size;
	u8 *secondary_ctrl_report;

	ktime_t last_ctrl_report_op;
	int ctrl_report_delay;	/* Delay between two ctrl report operations, in ms */

	int buffer_size;
	u8 *buffer;
	int checksum_start;
@@ -611,17 +618,35 @@ static int aqc_aquastreamxt_convert_fan_rpm(u16 val)
	return 0;
}

static void aqc_delay_ctrl_report(struct aqc_data *priv)
{
	/*
	 * If previous read or write is too close to this one, delay the current operation
	 * to give the device enough time to process the previous one.
	 */
	if (priv->ctrl_report_delay) {
		s64 delta = ktime_ms_delta(ktime_get(), priv->last_ctrl_report_op);

		if (delta < priv->ctrl_report_delay)
			msleep(priv->ctrl_report_delay - delta);
	}
}

/* Expects the mutex to be locked */
static int aqc_get_ctrl_data(struct aqc_data *priv)
{
	int ret;

	aqc_delay_ctrl_report(priv);

	memset(priv->buffer, 0x00, priv->buffer_size);
	ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
	if (ret < 0)
		ret = -ENODATA;

	priv->last_ctrl_report_op = ktime_get();

	return ret;
}

@@ -631,6 +656,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
	int ret;
	u16 checksum;

	aqc_delay_ctrl_report(priv);

	/* Checksum is not needed for Aquaero */
	if (priv->kind != aquaero) {
		/* Init and xorout value for CRC-16/USB is 0xffff */
@@ -646,12 +673,16 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
	ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
	if (ret < 0)
		return ret;
		goto record_access_and_ret;

	/* The official software sends this report after every change, so do it here as well */
	ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id,
				 priv->secondary_ctrl_report, priv->secondary_ctrl_report_size,
				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);

record_access_and_ret:
	priv->last_ctrl_report_op = ktime_get();

	return ret;
}

@@ -1524,6 +1555,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)

		priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE;
		priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET;
		priv->ctrl_report_delay = CTRL_REPORT_DELAY;

		priv->temp_label = label_temp_sensors;
		priv->virtual_temp_label = label_virtual_temp_sensors;
@@ -1547,6 +1579,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
		priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;

		priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
		priv->ctrl_report_delay = CTRL_REPORT_DELAY;

		priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;

@@ -1597,6 +1630,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
		priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;

		priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
		priv->ctrl_report_delay = CTRL_REPORT_DELAY;

		priv->power_cycle_count_offset = OCTO_POWER_CYCLES;

@@ -1624,6 +1658,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
		priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;

		priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
		priv->ctrl_report_delay = CTRL_REPORT_DELAY;

		priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET;
		priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
+8 −8
Original line number Diff line number Diff line
@@ -17,12 +17,13 @@
enum chips {pfe1100, pfe3000};

/*
 * Disable status check for pfe3000 devices, because some devices report
 * communication error (invalid command) for VOUT_MODE command (0x20)
 * although correct VOUT_MODE (0x16) is returned: it leads to incorrect
 * exponent in linear mode.
 * Disable status check because some devices report communication error
 * (invalid command) for VOUT_MODE command (0x20) although the correct
 * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear
 * mode.
 * This affects both pfe3000 and pfe1100.
 */
static struct pmbus_platform_data pfe3000_plat_data = {
static struct pmbus_platform_data pfe_plat_data = {
	.flags = PMBUS_SKIP_STATUS_CHECK,
};

@@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client)
	int model;

	model = (int)i2c_match_id(pfe_device_id, client)->driver_data;
	client->dev.platform_data = &pfe_plat_data;

	/*
	 * PFE3000-12-069RA devices may not stay in page 0 during device
	 * probe which leads to probe failure (read status word failed).
	 * So let's set the device to page 0 at the beginning.
	 */
	if (model == pfe3000) {
		client->dev.platform_data = &pfe3000_plat_data;
	if (model == pfe3000)
		i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
	}

	return pmbus_do_probe(client, &pfe_driver_info[model]);
}