Skip to content

Commit

Permalink
hwmon: (pmbus) Detect if chip is write protected
Browse files Browse the repository at this point in the history
If a chip is write protected, we can not change any limits, and we can
not clear status flags. This may be the reason why clearing status flags
is reported to not work for some chips. Detect the condition in the pmbus
core. If the chip is write protected, set limit attributes as read-only,
and set the flag indicating that the status flag should be ignored.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
  • Loading branch information
Guenter Roeck committed Jan 23, 2020
1 parent d21ed22 commit 9e34772
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
11 changes: 11 additions & 0 deletions drivers/hwmon/pmbus/pmbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ enum pmbus_regs {
PMBUS_CLEAR_FAULTS = 0x03,
PMBUS_PHASE = 0x04,

PMBUS_WRITE_PROTECT = 0x10,

PMBUS_CAPABILITY = 0x19,
PMBUS_QUERY = 0x1A,

Expand Down Expand Up @@ -225,6 +227,15 @@ enum pmbus_regs {
*/
#define PB_OPERATION_CONTROL_ON BIT(7)

/*
* WRITE_PROTECT
*/
#define PB_WP_ALL BIT(7) /* all but WRITE_PROTECT */
#define PB_WP_OP BIT(6) /* all but WP, OPERATION, PAGE */
#define PB_WP_VOUT BIT(5) /* all but WP, OPERATION, PAGE, VOUT, ON_OFF */

#define PB_WP_ANY (PB_WP_ALL | PB_WP_OP | PB_WP_VOUT)

/*
* CAPABILITY
*/
Expand Down
12 changes: 12 additions & 0 deletions drivers/hwmon/pmbus/pmbus_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,9 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
snprintf(sensor->name, sizeof(sensor->name), "%s%d",
name, seq);

if (data->flags & PMBUS_WRITE_PROTECTED)
readonly = true;

sensor->page = page;
sensor->reg = reg;
sensor->class = class;
Expand Down Expand Up @@ -2141,6 +2144,15 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK))
client->flags |= I2C_CLIENT_PEC;

/*
* Check if the chip is write protected. If it is, we can not clear
* faults, and we should not try it. Also, in that case, writes into
* limit registers need to be disabled.
*/
ret = i2c_smbus_read_byte_data(client, PMBUS_WRITE_PROTECT);
if (ret > 0 && (ret & PB_WP_ANY))
data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK;

if (data->info->pages)
pmbus_clear_faults(client);
else
Expand Down
11 changes: 10 additions & 1 deletion include/linux/pmbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#ifndef _PMBUS_H_
#define _PMBUS_H_

#include <linux/bits.h>

/* flags */

/*
Expand All @@ -23,7 +25,14 @@
* communication errors for no explicable reason. For such chips, checking
* the status register must be disabled.
*/
#define PMBUS_SKIP_STATUS_CHECK (1 << 0)
#define PMBUS_SKIP_STATUS_CHECK BIT(0)

/*
* PMBUS_WRITE_PROTECTED
* Set if the chip is write protected and write protection is not determined
* by the standard WRITE_PROTECT command.
*/
#define PMBUS_WRITE_PROTECTED BIT(1)

struct pmbus_platform_data {
u32 flags; /* Device specific flags */
Expand Down

0 comments on commit 9e34772

Please sign in to comment.