* [PATCH 0/5] hw/i2c: PMBus updates
@ 2026-07-06 23:00 Titus Rwantare
2026-07-06 23:00 ` [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST Titus Rwantare
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
Titus Rwantare
This series adds various fixes to PMBus and SMBus support.
The maximum SMBus data length is increased to 257 bytes, (payload is 255 bytes) to support SMBus 3.0 block transfers. SMBus devices don’t have to report their specification version, and this change allows us to enable newer PMBus devices that are based on top of SMBus 3.0.
Additionally, this series:
- Adds the `DIV_ROUND_CLOSEST` helper macro, lifted from the linux implementation, to match the rounding in linux drivers.
- Adds PMBus helper functions to convert sensor values in milliunits to/from linear mode format (Linear16).
- Adds helper functions for converting data to PMBus Linear11 format.
- Adds a fix that the PMBus output buffer is cleared on new write transactions to prevent stale data reads, this resolves an issue with guests performing incomplete reads.
Changes to the adm1266 are in a separate patch series.
Titus Rwantare (3):
osdep: add DIV_ROUND_CLOSEST
hw/i2c: pmbus: add milliunits linear mode functions
hw/i2c: pmbus: add Linear11 format helpers
titusr (2):
hw/i2c: pmbus: clear output buffer on write
hw/i2c: smbus: increase MAX_DATA_LEN
hw/i2c/pmbus_device.c | 61 +++++++++++++++++++++++++++++++++
hw/i2c/smbus_slave.c | 4 +--
include/hw/i2c/pmbus_device.h | 64 +++++++++++++++++++++++++++++++++++
include/hw/i2c/smbus_slave.h | 2 +-
include/qemu/osdep.h | 14 ++++++++
tests/qtest/adm1266-test.c | 10 +++---
6 files changed, 148 insertions(+), 7 deletions(-)
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
@ 2026-07-06 23:00 ` Titus Rwantare
2026-07-09 11:09 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 2/5] hw/i2c: pmbus: add milliunits linear mode functions Titus Rwantare
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
Titus Rwantare
This is taken from linux/include/uapi/linux/const.h to match the driver
behaviour when reading sensor values.
Signed-off-by: Titus Rwantare <titusr@google.com>
---
include/qemu/osdep.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 1ec5b42230..a6a40ab8df 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -522,6 +522,20 @@ void QEMU_ERROR("code path is reachable")
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#endif
+#ifndef DIV_ROUND_CLOSEST
+#define DIV_ROUND_CLOSEST(n, d) \
+({ \
+ typeof(n) __n = n; \
+ typeof(d) __d = d; \
+ (((typeof(n))-1) > 0 || \
+ ((typeof(d))-1) > 0 || \
+ (((__n) > 0) == ((__d) > 0))) ? \
+ (((__n) + ((__d) / 2)) / (__d)) : \
+ (((__n) - ((__d) / 2)) / (__d)); \
+})
+#endif
+
+
/*
* &(x)[0] is always a pointer - if it's same type as x then the argument is a
* pointer, not an array.
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/5] hw/i2c: pmbus: add milliunits linear mode functions
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
2026-07-06 23:00 ` [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST Titus Rwantare
@ 2026-07-06 23:00 ` Titus Rwantare
2026-07-06 23:00 ` [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write Titus Rwantare
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
Titus Rwantare
Because we are limited by unsigned ints, we need to be able to provide
inputs in milliunits which can get scaled up to fit in the linear mode
registers.
For example: 3.4 is a valid input, and now we can provide 3400 and scale
it into the register without losing the 0.4
Signed-off-by: Titus Rwantare <titusr@google.com>
---
hw/i2c/pmbus_device.c | 39 +++++++++++++++++++++++++++++++++++
include/hw/i2c/pmbus_device.h | 18 ++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index b1f9843f52..e2e1e0e945 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -8,6 +8,7 @@
#include "qemu/osdep.h"
#include <math.h>
+#include <stdint.h>
#include "hw/i2c/pmbus_device.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
@@ -38,6 +39,25 @@ uint16_t pmbus_data2linear_mode(uint16_t value, int exp)
return value >> exp;
}
+uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp)
+{
+ uint32_t ret;
+
+ /* L = D * 2^(-e) */
+ if (exp < 0) {
+ ret = DIV_ROUND_CLOSEST((value << (-exp)), 1000);
+ } else {
+ ret = DIV_ROUND_CLOSEST((value >> exp), 1000);
+ }
+
+ /* clamp value to maximum if it exceeds representable value*/
+ if (ret > UINT16_MAX) {
+ return UINT16_MAX;
+ }
+
+ return ret;
+}
+
uint16_t pmbus_linear_mode2data(uint16_t value, int exp)
{
/* D = L * 2^e */
@@ -47,6 +67,25 @@ uint16_t pmbus_linear_mode2data(uint16_t value, int exp)
return value << exp;
}
+uint32_t pmbus_linear_mode2milliunits(uint16_t value, int exp)
+{
+ /* D = L * 2^e */
+ uint64_t v = (uint64_t)value;
+ uint64_t ret;
+
+ if (exp < 0) {
+ ret = (v * 1000) >> (-exp);
+ } else {
+ ret = (v << exp) * 1000;
+ }
+
+ if (ret > UINT32_MAX) {
+ return UINT32_MAX;
+ }
+
+ return (uint32_t)ret;
+}
+
void pmbus_send(PMBusDevice *pmdev, const uint8_t *data, uint16_t len)
{
if (pmdev->out_buf_len + len > SMBUS_DATA_MAX_LEN) {
diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
index f195c11384..9f3569e997 100644
--- a/include/hw/i2c/pmbus_device.h
+++ b/include/hw/i2c/pmbus_device.h
@@ -481,6 +481,15 @@ uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value);
*/
uint16_t pmbus_data2linear_mode(uint16_t value, int exp);
+/**
+ * Convert milliunit sensor value to linear mode format
+ *
+ * L = D * 2^(-e)
+ *
+ * @return uint16
+ */
+uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp);
+
/**
* Convert linear mode formatted data into sensor reading
*
@@ -490,6 +499,15 @@ uint16_t pmbus_data2linear_mode(uint16_t value, int exp);
*/
uint16_t pmbus_linear_mode2data(uint16_t value, int exp);
+/**
+ * Convert linear mode formatted data into sensor reading in milliunits
+ *
+ * D = L * 2^e
+ *
+ * @return uint32 value in milliunits
+ */
+uint32_t pmbus_linear_mode2milliunits(uint16_t value, int exp);
+
/**
* @brief Send a block of data over PMBus
* Assumes that the bytes in the block are already ordered correctly,
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
2026-07-06 23:00 ` [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST Titus Rwantare
2026-07-06 23:00 ` [PATCH 2/5] hw/i2c: pmbus: add milliunits linear mode functions Titus Rwantare
@ 2026-07-06 23:00 ` Titus Rwantare
2026-07-07 9:20 ` Philippe Mathieu-Daudé
2026-07-09 15:35 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN Titus Rwantare
2026-07-06 23:00 ` [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers Titus Rwantare
4 siblings, 2 replies; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
titusr
From: titusr <titusr@google.com>
Generally we expect a PMBus sensor to issue writes after all pending
reads have completed. If a data read needs to be resumed, this state can
be tracked in the device model and the pending data placed in the output
buffer.
Signed-off-by: Titus Rwantare <titusr@google.com>
---
hw/i2c/pmbus_device.c | 10 ++++++++++
tests/qtest/adm1266-test.c | 10 ++++++----
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index e2e1e0e945..8befc27895 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -1284,6 +1284,16 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
pmdev->in_buf_len = len;
pmdev->in_buf = buf;
+ /* clear the output buffer on any new write transaction */
+ if (pmdev->out_buf_len != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: previous read was not completed, %d bytes dropped\n",
+ __func__, pmdev->out_buf_len);
+
+ pmdev->out_buf_len = 0;
+ memset(pmdev->out_buf, 0, sizeof(pmdev->out_buf));
+ }
+
pmdev->code = buf[0]; /* PMBus command code */
if (pmdev->code == PMBUS_CLEAR_FAULTS) {
diff --git a/tests/qtest/adm1266-test.c b/tests/qtest/adm1266-test.c
index 5ae8206234..726e475938 100644
--- a/tests/qtest/adm1266-test.c
+++ b/tests/qtest/adm1266-test.c
@@ -48,11 +48,13 @@
static void compare_string(QI2CDevice *i2cdev, uint8_t reg,
const char *test_str)
{
- uint8_t len = i2c_get8(i2cdev, reg);
- char i2c_str[SMBUS_DATA_MAX_LEN] = {0};
+ uint8_t expected_len = strlen(test_str);
+ uint8_t resp[SMBUS_DATA_MAX_LEN] = {0};
- i2c_read_block(i2cdev, reg, (uint8_t *)i2c_str, len);
- g_assert_cmpstr(i2c_str, ==, test_str);
+ g_assert(expected_len + 1 < SMBUS_DATA_MAX_LEN);
+ i2c_read_block(i2cdev, reg, resp, expected_len + 1);
+ g_assert_cmpint(resp[0], ==, expected_len);
+ g_assert_cmpstr((char *)resp + 1, ==, test_str);
}
static void write_and_compare_string(QI2CDevice *i2cdev, uint8_t reg,
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
` (2 preceding siblings ...)
2026-07-06 23:00 ` [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write Titus Rwantare
@ 2026-07-06 23:00 ` Titus Rwantare
2026-07-07 9:18 ` Philippe Mathieu-Daudé
2026-07-09 11:25 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers Titus Rwantare
4 siblings, 2 replies; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
titusr
From: titusr <titusr@google.com>
The 32 byte payload was raised to 255 for block reads in the SMBus 3.0
specification. SMBus does not provide a way for devices to declare which
version of the spec they are designed to so we must allow newer devices
to return as much data as they allow.
Specification: https://smbus.org/specs/SMBus_3_3_20240512.pdf
> 6.5.7 Block Write/Read
The Block Write begins with a slave address and a write condition. After the command code the host issues a byte count which describes how many more bytes will follow in the message. If a slave has 20 bytes to send, the byte count field will have the value 20 (14h), followed by the 20 bytes of data. The byte count does not include the PEC byte. The byte count may be 0. A Block Read or Block Write is allowed to transfer a maximum of 255 data bytes.
Signed-off-by: Titus Rwantare <titusr@google.com>
---
hw/i2c/smbus_slave.c | 4 ++--
include/hw/i2c/smbus_slave.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index cfb61c879e..407a118d24 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -217,8 +217,8 @@ bool smbus_vmstate_needed(SMBusDevice *dev)
const VMStateDescription vmstate_smbus_device = {
.name = TYPE_SMBUS_DEVICE,
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (const VMStateField[]) {
VMSTATE_I2C_SLAVE(i2c, SMBusDevice),
VMSTATE_INT32(mode, SMBusDevice),
diff --git a/include/hw/i2c/smbus_slave.h b/include/hw/i2c/smbus_slave.h
index 86bfe0a79e..59522ff1b1 100644
--- a/include/hw/i2c/smbus_slave.h
+++ b/include/hw/i2c/smbus_slave.h
@@ -64,7 +64,7 @@ struct SMBusDeviceClass {
uint8_t (*receive_byte)(SMBusDevice *dev);
};
-#define SMBUS_DATA_MAX_LEN 34 /* command + len + 32 bytes of data. */
+#define SMBUS_DATA_MAX_LEN 257 /* command + len + 255 bytes of data. */
struct SMBusDevice {
/* The SMBus protocol is implemented on top of I2C. */
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
` (3 preceding siblings ...)
2026-07-06 23:00 ` [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN Titus Rwantare
@ 2026-07-06 23:00 ` Titus Rwantare
2026-07-09 11:14 ` Peter Maydell
4 siblings, 1 reply; 13+ messages in thread
From: Titus Rwantare @ 2026-07-06 23:00 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd,
Titus Rwantare
Signed-off-by: Titus Rwantare <titusr@google.com>
---
hw/i2c/pmbus_device.c | 12 +++++++++
include/hw/i2c/pmbus_device.h | 46 +++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 8befc27895..5039975520 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -39,6 +39,12 @@ uint16_t pmbus_data2linear_mode(uint16_t value, int exp)
return value >> exp;
}
+uint16_t pmbus_data2linear11(uint16_t value, int exp)
+{
+ return (uint16_t)((exp & 0x1F) << 11 |
+ (pmbus_data2linear_mode(value, exp) & 0x7FF));
+}
+
uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp)
{
uint32_t ret;
@@ -58,6 +64,12 @@ uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp)
return ret;
}
+uint16_t pmbus_milliunits2linear11(uint32_t value, int exp)
+{
+ return (uint16_t)((exp & 0x1F) << 11 |
+ (pmbus_milliunits2linear_mode(value, exp) & 0x7FF));
+}
+
uint16_t pmbus_linear_mode2data(uint16_t value, int exp)
{
/* D = L * 2^e */
diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
index 9f3569e997..44cd908fe7 100644
--- a/include/hw/i2c/pmbus_device.h
+++ b/include/hw/i2c/pmbus_device.h
@@ -477,10 +477,56 @@ uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value);
*
* L = D * 2^(-e)
*
+ * Exponent is retrieved from VOUT_MODE register
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---+---+---+---+---+---+---+---+
+ * | 0 | 0 | 0 | N |
+ * +---+---+---+---+---+---+---+---+
+ * |_______| |_______________|
+ * Mode Exponent (N)
+ * = 000b
+ *
* @return uint16
*/
uint16_t pmbus_data2linear_mode(uint16_t value, int exp);
+/**
+ * Convert sensor values to linear11 format
+ *
+ * L = e << 11 | D * 2^(-e)
+ *
+ * | Data Byte High | Data Byte Low |
+ * +---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+
+ * | 7 | 6 | 5 | 4 | 3 | | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ * +---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+
+ * | MSB | | MSB |
+ * |_________ _________| |_____________________ _____________________|
+ * N Y
+ * Exponent Mantissa
+ *
+ * @return uint16
+ */
+uint16_t pmbus_data2linear11(uint16_t value, int exp);
+
+/**
+ * Convert sensor values in milliunits to linear11 format
+ *
+ * L = e << 11 | D * 2^(-e)
+ *
+ * | Data Byte High | Data Byte Low |
+ * +---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+
+ * | 7 | 6 | 5 | 4 | 3 | | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ * +---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+
+ * | MSB | | MSB |
+ * |_________ _________| |_____________________ _____________________|
+ * N Y
+ * Exponent Mantissa
+ *
+ * @return uint16
+ */
+uint16_t pmbus_milliunits2linear11(uint32_t value, int exp);
+
/**
* Convert milliunit sensor value to linear mode format
*
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN
2026-07-06 23:00 ` [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN Titus Rwantare
@ 2026-07-07 9:18 ` Philippe Mathieu-Daudé
2026-07-09 11:25 ` Peter Maydell
1 sibling, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-07 9:18 UTC (permalink / raw)
To: Titus Rwantare, peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On 7/7/26 01:00, Titus Rwantare wrote:
> From: titusr <titusr@google.com>
>
> The 32 byte payload was raised to 255 for block reads in the SMBus 3.0
> specification. SMBus does not provide a way for devices to declare which
> version of the spec they are designed to so we must allow newer devices
> to return as much data as they allow.
>
> Specification: https://smbus.org/specs/SMBus_3_3_20240512.pdf
>
>> 6.5.7 Block Write/Read
> The Block Write begins with a slave address and a write condition. After the command code the host issues a byte count which describes how many more bytes will follow in the message. If a slave has 20 bytes to send, the byte count field will have the value 20 (14h), followed by the 20 bytes of data. The byte count does not include the PEC byte. The byte count may be 0. A Block Read or Block Write is allowed to transfer a maximum of 255 data bytes.
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
> ---
> hw/i2c/smbus_slave.c | 4 ++--
> include/hw/i2c/smbus_slave.h | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write
2026-07-06 23:00 ` [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write Titus Rwantare
@ 2026-07-07 9:20 ` Philippe Mathieu-Daudé
2026-07-09 15:35 ` Peter Maydell
1 sibling, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-07 9:20 UTC (permalink / raw)
To: Titus Rwantare, peter.maydell
Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On 7/7/26 01:00, Titus Rwantare wrote:
> From: titusr <titusr@google.com>
>
> Generally we expect a PMBus sensor to issue writes after all pending
> reads have completed. If a data read needs to be resumed, this state can
> be tracked in the device model and the pending data placed in the output
> buffer.
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
> ---
> hw/i2c/pmbus_device.c | 10 ++++++++++
> tests/qtest/adm1266-test.c | 10 ++++++----
> 2 files changed, 16 insertions(+), 4 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST
2026-07-06 23:00 ` [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST Titus Rwantare
@ 2026-07-09 11:09 ` Peter Maydell
2026-07-09 11:16 ` Peter Maydell
0 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2026-07-09 11:09 UTC (permalink / raw)
To: Titus Rwantare; +Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On Tue, 7 Jul 2026 at 00:01, Titus Rwantare <titusr@google.com> wrote:
>
> This is taken from linux/include/uapi/linux/const.h to match the driver
> behaviour when reading sensor values.
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
> ---
> include/qemu/osdep.h | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index 1ec5b42230..a6a40ab8df 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -522,6 +522,20 @@ void QEMU_ERROR("code path is reachable")
> #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
> #endif
>
> +#ifndef DIV_ROUND_CLOSEST
> +#define DIV_ROUND_CLOSEST(n, d) \
> +({ \
> + typeof(n) __n = n; \
> + typeof(d) __d = d; \
> + (((typeof(n))-1) > 0 || \
> + ((typeof(d))-1) > 0 || \
> + (((__n) > 0) == ((__d) > 0))) ? \
> + (((__n) + ((__d) / 2)) / (__d)) : \
> + (((__n) - ((__d) / 2)) / (__d)); \
> +})
> +#endif
Can we also have the comment from the kernel header that
tells us what it does, please?
/*
* Divide positive or negative dividend by positive or negative divisor
* and round to closest integer. Result is undefined for negative
* divisors if the dividend variable type is unsigned and for negative
* dividends if the divisor variable type is unsigned.
*/
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers
2026-07-06 23:00 ` [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers Titus Rwantare
@ 2026-07-09 11:14 ` Peter Maydell
0 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-07-09 11:14 UTC (permalink / raw)
To: Titus Rwantare; +Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On Tue, 7 Jul 2026 at 00:01, Titus Rwantare <titusr@google.com> wrote:
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
> ---
> hw/i2c/pmbus_device.c | 12 +++++++++
> include/hw/i2c/pmbus_device.h | 46 +++++++++++++++++++++++++++++++++++
> 2 files changed, 58 insertions(+)
> +uint16_t pmbus_data2linear11(uint16_t value, int exp)
> +{
> + return (uint16_t)((exp & 0x1F) << 11 |
> + (pmbus_data2linear_mode(value, exp) & 0x7FF));
> +}
> +
> uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp)
> {
> uint32_t ret;
> @@ -58,6 +64,12 @@ uint16_t pmbus_milliunits2linear_mode(uint32_t value, int exp)
> return ret;
> }
>
> +uint16_t pmbus_milliunits2linear11(uint32_t value, int exp)
> +{
> + return (uint16_t)((exp & 0x1F) << 11 |
> + (pmbus_milliunits2linear_mode(value, exp) & 0x7FF));
> +}
Nothing calls these functions, and they are the only users of
the new functions added in patch 2. We should add these when
we have some actual callers, otherwise this is all dead code.
thanks
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST
2026-07-09 11:09 ` Peter Maydell
@ 2026-07-09 11:16 ` Peter Maydell
0 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-07-09 11:16 UTC (permalink / raw)
To: Titus Rwantare; +Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On Thu, 9 Jul 2026 at 12:09, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 7 Jul 2026 at 00:01, Titus Rwantare <titusr@google.com> wrote:
> >
> > This is taken from linux/include/uapi/linux/const.h to match the driver
> > behaviour when reading sensor values.
> >
> > Signed-off-by: Titus Rwantare <titusr@google.com>
> > ---
> > include/qemu/osdep.h | 14 ++++++++++++++
> > 1 file changed, 14 insertions(+)
> >
> > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> > index 1ec5b42230..a6a40ab8df 100644
> > --- a/include/qemu/osdep.h
> > +++ b/include/qemu/osdep.h
> > @@ -522,6 +522,20 @@ void QEMU_ERROR("code path is reachable")
> > #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
> > #endif
> >
> > +#ifndef DIV_ROUND_CLOSEST
> > +#define DIV_ROUND_CLOSEST(n, d) \
> > +({ \
> > + typeof(n) __n = n; \
> > + typeof(d) __d = d; \
> > + (((typeof(n))-1) > 0 || \
> > + ((typeof(d))-1) > 0 || \
> > + (((__n) > 0) == ((__d) > 0))) ? \
> > + (((__n) + ((__d) / 2)) / (__d)) : \
> > + (((__n) - ((__d) / 2)) / (__d)); \
> > +})
> > +#endif
>
> Can we also have the comment from the kernel header that
> tells us what it does, please?
Also, the only use of this macro is the unused functions
in patch 2 and 5, as far as I can tell.
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN
2026-07-06 23:00 ` [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN Titus Rwantare
2026-07-07 9:18 ` Philippe Mathieu-Daudé
@ 2026-07-09 11:25 ` Peter Maydell
1 sibling, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-07-09 11:25 UTC (permalink / raw)
To: Titus Rwantare; +Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On Tue, 7 Jul 2026 at 00:01, Titus Rwantare <titusr@google.com> wrote:
>
> From: titusr <titusr@google.com>
>
> The 32 byte payload was raised to 255 for block reads in the SMBus 3.0
> specification. SMBus does not provide a way for devices to declare which
> version of the spec they are designed to so we must allow newer devices
> to return as much data as they allow.
>
> Specification: https://smbus.org/specs/SMBus_3_3_20240512.pdf
>
> > 6.5.7 Block Write/Read
> The Block Write begins with a slave address and a write condition. After the command code the host issues a byte count which describes how many more bytes will follow in the message. If a slave has 20 bytes to send, the byte count field will have the value 20 (14h), followed by the 20 bytes of data. The byte count does not include the PEC byte. The byte count may be 0. A Block Read or Block Write is allowed to transfer a maximum of 255 data bytes.
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
> ---
> hw/i2c/smbus_slave.c | 4 ++--
> include/hw/i2c/smbus_slave.h | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
> index cfb61c879e..407a118d24 100644
> --- a/hw/i2c/smbus_slave.c
> +++ b/hw/i2c/smbus_slave.c
> @@ -217,8 +217,8 @@ bool smbus_vmstate_needed(SMBusDevice *dev)
>
> const VMStateDescription vmstate_smbus_device = {
> .name = TYPE_SMBUS_DEVICE,
> - .version_id = 1,
> - .minimum_version_id = 1,
> + .version_id = 2,
> + .minimum_version_id = 2,
> .fields = (const VMStateField[]) {
> VMSTATE_I2C_SLAVE(i2c, SMBusDevice),
> VMSTATE_INT32(mode, SMBusDevice),
> diff --git a/include/hw/i2c/smbus_slave.h b/include/hw/i2c/smbus_slave.h
> index 86bfe0a79e..59522ff1b1 100644
> --- a/include/hw/i2c/smbus_slave.h
> +++ b/include/hw/i2c/smbus_slave.h
> @@ -64,7 +64,7 @@ struct SMBusDeviceClass {
> uint8_t (*receive_byte)(SMBusDevice *dev);
> };
>
> -#define SMBUS_DATA_MAX_LEN 34 /* command + len + 32 bytes of data. */
> +#define SMBUS_DATA_MAX_LEN 257 /* command + len + 255 bytes of data. */
This is a migration compatibility break, and you can use this with
machines like q35 where we care about migration compat (e.g. via
the smbus-impi device creatable on the command line), so we need
to do this in a way that maintains migration compat from older
versions of QEMU, I'm afraid.
thanks
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write
2026-07-06 23:00 ` [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write Titus Rwantare
2026-07-07 9:20 ` Philippe Mathieu-Daudé
@ 2026-07-09 15:35 ` Peter Maydell
1 sibling, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-07-09 15:35 UTC (permalink / raw)
To: Titus Rwantare; +Cc: qemu-arm, qemu-devel, kfting, imaginos32, wuhaotsh, philmd
On Tue, 7 Jul 2026 at 00:01, Titus Rwantare <titusr@google.com> wrote:
>
> From: titusr <titusr@google.com>
>
> Generally we expect a PMBus sensor to issue writes after all pending
> reads have completed. If a data read needs to be resumed, this state can
> be tracked in the device model and the pending data placed in the output
> buffer.
>
> Signed-off-by: Titus Rwantare <titusr@google.com>
I'm going to apply this patch to target-arm.next for 11.1,
as it fixes a bug.
thanks
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-07-09 15:36 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06 23:00 [PATCH 0/5] hw/i2c: PMBus updates Titus Rwantare
2026-07-06 23:00 ` [PATCH 1/5] osdep: add DIV_ROUND_CLOSEST Titus Rwantare
2026-07-09 11:09 ` Peter Maydell
2026-07-09 11:16 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 2/5] hw/i2c: pmbus: add milliunits linear mode functions Titus Rwantare
2026-07-06 23:00 ` [PATCH 3/5] hw/i2c: pmbus: clear output buffer on write Titus Rwantare
2026-07-07 9:20 ` Philippe Mathieu-Daudé
2026-07-09 15:35 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 4/5] hw/i2c: smbus: increase MAX_DATA_LEN Titus Rwantare
2026-07-07 9:18 ` Philippe Mathieu-Daudé
2026-07-09 11:25 ` Peter Maydell
2026-07-06 23:00 ` [PATCH 5/5] hw/i2c: pmbus: add Linear11 format helpers Titus Rwantare
2026-07-09 11:14 ` Peter Maydell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.