diff options
| -rw-r--r-- | drivers/hwmon/pmbus/adm1266.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/hwmon/pmbus/adm1266.c b/drivers/hwmon/pmbus/adm1266.c index 7f4dbc98d92a..aa353b6b9c99 100644 --- a/drivers/hwmon/pmbus/adm1266.c +++ b/drivers/hwmon/pmbus/adm1266.c @@ -371,6 +371,40 @@ static int adm1266_firmware_revision_read(struct seq_file *s, void *pdata) return 0; } +/* + * Clearing the blackbox is required when the device is configured in + * single-recording mode (BLACKBOX_CONFIG[0] = 0): once the 32-record + * buffer is full the device stops recording until cleared. + * + * The clear is issued as a 2-byte block-write to READ_BLACKBOX with + * payload {0xFE, 0x00} per the datasheet. READ_BLACKBOX is also used + * by adm1266_nvmem_read_blackbox() to walk records one at a time; + * both paths run under pmbus_lock so the clear cannot interleave + * mid-iteration and corrupt the read sequence. + */ +static ssize_t adm1266_clear_blackbox_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct i2c_client *client = file->private_data; + u8 payload[2] = { 0xFE, 0x00 }; + int ret; + + guard(pmbus_lock)(client); + ret = i2c_smbus_write_block_data(client, ADM1266_READ_BLACKBOX, + sizeof(payload), payload); + if (ret < 0) + return ret; + + return count; +} + +static const struct file_operations adm1266_clear_blackbox_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = adm1266_clear_blackbox_write, + .llseek = noop_llseek, +}; + static void adm1266_init_debugfs(struct adm1266_data *data) { struct dentry *root; @@ -385,6 +419,8 @@ static void adm1266_init_debugfs(struct adm1266_data *data) adm1266_state_read); debugfs_create_devm_seqfile(&data->client->dev, "firmware_revision", data->debugfs_dir, adm1266_firmware_revision_read); + debugfs_create_file("clear_blackbox", 0200, data->debugfs_dir, data->client, + &adm1266_clear_blackbox_fops); } static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff) |
