@@ -2739,9 +2739,9 @@ static int pmbus_regulator_disable(struct regulator_dev *rdev)
return _pmbus_regulator_on_off(rdev, 0);
}
-/* A PMBus status flag and the corresponding REGULATOR_ERROR_* flag */
+/* A PMBus status flag and the corresponding REGULATOR_ERROR_* and REGULATOR_EVENTS_* flag */
struct pmbus_regulator_status_assoc {
- int pflag, rflag;
+ int pflag, rflag, eflag;
};
/* PMBus->regulator bit mappings for a PMBus status register */
@@ -2756,27 +2756,36 @@ static const struct pmbus_regulator_status_category pmbus_regulator_flag_map[] =
.func = PMBUS_HAVE_STATUS_VOUT,
.reg = PMBUS_STATUS_VOUT,
.bits = (const struct pmbus_regulator_status_assoc[]) {
- { PB_VOLTAGE_UV_WARNING, REGULATOR_ERROR_UNDER_VOLTAGE_WARN },
- { PB_VOLTAGE_UV_FAULT, REGULATOR_ERROR_UNDER_VOLTAGE },
- { PB_VOLTAGE_OV_WARNING, REGULATOR_ERROR_OVER_VOLTAGE_WARN },
- { PB_VOLTAGE_OV_FAULT, REGULATOR_ERROR_REGULATION_OUT },
+ { PB_VOLTAGE_UV_WARNING, REGULATOR_ERROR_UNDER_VOLTAGE_WARN,
+ REGULATOR_EVENT_UNDER_VOLTAGE_WARN },
+ { PB_VOLTAGE_UV_FAULT, REGULATOR_ERROR_UNDER_VOLTAGE,
+ REGULATOR_EVENT_UNDER_VOLTAGE },
+ { PB_VOLTAGE_OV_WARNING, REGULATOR_ERROR_OVER_VOLTAGE_WARN,
+ REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+ { PB_VOLTAGE_OV_FAULT, REGULATOR_ERROR_REGULATION_OUT,
+ REGULATOR_EVENT_OVER_VOLTAGE_WARN },
{ },
},
}, {
.func = PMBUS_HAVE_STATUS_IOUT,
.reg = PMBUS_STATUS_IOUT,
.bits = (const struct pmbus_regulator_status_assoc[]) {
- { PB_IOUT_OC_WARNING, REGULATOR_ERROR_OVER_CURRENT_WARN },
- { PB_IOUT_OC_FAULT, REGULATOR_ERROR_OVER_CURRENT },
- { PB_IOUT_OC_LV_FAULT, REGULATOR_ERROR_OVER_CURRENT },
+ { PB_IOUT_OC_WARNING, REGULATOR_ERROR_OVER_CURRENT_WARN,
+ REGULATOR_EVENT_OVER_CURRENT_WARN },
+ { PB_IOUT_OC_FAULT, REGULATOR_ERROR_OVER_CURRENT,
+ REGULATOR_EVENT_OVER_CURRENT },
+ { PB_IOUT_OC_LV_FAULT, REGULATOR_ERROR_OVER_CURRENT,
+ REGULATOR_EVENT_OVER_CURRENT },
{ },
},
}, {
.func = PMBUS_HAVE_STATUS_TEMP,
.reg = PMBUS_STATUS_TEMPERATURE,
.bits = (const struct pmbus_regulator_status_assoc[]) {
- { PB_TEMP_OT_WARNING, REGULATOR_ERROR_OVER_TEMP_WARN },
- { PB_TEMP_OT_FAULT, REGULATOR_ERROR_OVER_TEMP },
+ { PB_TEMP_OT_WARNING, REGULATOR_ERROR_OVER_TEMP_WARN,
+ REGULATOR_EVENT_OVER_TEMP_WARN },
+ { PB_TEMP_OT_FAULT, REGULATOR_ERROR_OVER_TEMP,
+ REGULATOR_EVENT_OVER_TEMP },
{ },
},
},
@@ -2810,7 +2819,7 @@ static void pmbus_notify(struct pmbus_data *data, int page, int reg, int flags)
}
static int pmbus_regulator_get_flags(struct regulator_dev *rdev, unsigned int *error,
- bool notify)
+ unsigned int *event, bool notify)
{
int i, status;
const struct pmbus_regulator_status_category *cat;
@@ -2821,7 +2830,8 @@ static int pmbus_regulator_get_flags(struct regulator_dev *rdev, unsigned int *e
u8 page = rdev_get_id(rdev);
int func = data->info->func[page];
- *flags = 0;
+ *error = 0;
+ *event = 0;
mutex_lock(&data->update_lock);
@@ -2836,10 +2846,11 @@ static int pmbus_regulator_get_flags(struct regulator_dev *rdev, unsigned int *e
return status;
}
- for (bit = cat->bits; bit->pflag; bit++) {
- if (status & bit->pflag)
- *flags |= bit->rflag;
- }
+ for (bit = cat->bits; bit->pflag; bit++)
+ if (status & bit->pflag) {
+ *error |= bit->rflag;
+ *event |= bit->eflag;
+ }
if (notify && status)
pmbus_notify(data, page, cat->reg, status);
@@ -2860,36 +2871,48 @@ static int pmbus_regulator_get_flags(struct regulator_dev *rdev, unsigned int *e
return status;
if (pmbus_regulator_is_enabled(rdev)) {
- if (status & PB_STATUS_OFF)
- *flags |= REGULATOR_ERROR_FAIL;
+ if (status & PB_STATUS_OFF) {
+ *error |= REGULATOR_ERROR_FAIL;
+ *event |= REGULATOR_EVENT_FAIL;
+ }
- if (status & PB_STATUS_POWER_GOOD_N)
- *flags |= REGULATOR_ERROR_REGULATION_OUT;
+ if (status & PB_STATUS_POWER_GOOD_N) {
+ *error |= REGULATOR_ERROR_REGULATION_OUT;
+ *event |= REGULATOR_EVENT_REGULATION_OUT;
+ }
}
/*
* Unlike most other status bits, PB_STATUS_{IOUT_OC,VOUT_OV} are
* defined strictly as fault indicators (not warnings).
*/
- if (status & PB_STATUS_IOUT_OC)
- *flags |= REGULATOR_ERROR_OVER_CURRENT;
- if (status & PB_STATUS_VOUT_OV)
- *flags |= REGULATOR_ERROR_REGULATION_OUT;
+ if (status & PB_STATUS_IOUT_OC) {
+ *error |= REGULATOR_ERROR_OVER_CURRENT;
+ *event |= REGULATOR_EVENT_OVER_CURRENT;
+ }
+ if (status & PB_STATUS_VOUT_OV) {
+ *error |= REGULATOR_ERROR_REGULATION_OUT;
+ *event |= REGULATOR_EVENT_FAIL;
+ }
/*
* If we haven't discovered any thermal faults or warnings via
* PMBUS_STATUS_TEMPERATURE, map PB_STATUS_TEMPERATURE to a warning as
* a (conservative) best-effort interpretation.
*/
- if (!(*flags & (REGULATOR_ERROR_OVER_TEMP | REGULATOR_ERROR_OVER_TEMP_WARN)) &&
- (status & PB_STATUS_TEMPERATURE))
- *flags |= REGULATOR_ERROR_OVER_TEMP_WARN;
+ if (!(*error & (REGULATOR_ERROR_OVER_TEMP | REGULATOR_ERROR_OVER_TEMP_WARN)) &&
+ (status & PB_STATUS_TEMPERATURE)) {
+ *error |= REGULATOR_ERROR_OVER_TEMP_WARN;
+ *event |= REGULATOR_EVENT_OVER_TEMP_WARN;
+ }
return 0;
}
static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
{
- return pmbus_regulator_get_flags(rdev, flags, false);
+ int event;
+
+ return pmbus_regulator_get_flags(rdev, flags, &event, false);
}
static int pmbus_regulator_get_status(struct regulator_dev *rdev)
@@ -3123,7 +3146,7 @@ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
{
struct pmbus_data *data = pdata;
struct i2c_client *client = to_i2c_client(data->dev);
- int i, ret = IRQ_NONE, status;
+ int i, ret = IRQ_NONE, status, event;
u8 page;
for (i = 0; i < data->info->num_regulators; i++) {
@@ -3131,7 +3154,7 @@ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
if (!data->rdevs[i])
continue;
- ret = pmbus_regulator_get_flags(data->rdevs[i], &status, true);
+ ret = pmbus_regulator_get_flags(data->rdevs[i], &status, &event, true);
if (ret)
return ret;