X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fregulator%2Fda9210-regulator.c;fp=kernel%2Fdrivers%2Fregulator%2Fda9210-regulator.c;h=b3517830edb6f0ea2139cbc5ebe902ce8cf8265d;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hp=f0489cb9018b4e7895937d330d077e100783fc16;hpb=f93b97fd65072de626c074dbe099a1fff05ce060;p=kvmfornfv.git diff --git a/kernel/drivers/regulator/da9210-regulator.c b/kernel/drivers/regulator/da9210-regulator.c index f0489cb90..b3517830e 100644 --- a/kernel/drivers/regulator/da9210-regulator.c +++ b/kernel/drivers/regulator/da9210-regulator.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -120,6 +122,55 @@ static int da9210_get_current_limit(struct regulator_dev *rdev) return da9210_buck_limits[sel]; } +static irqreturn_t da9210_irq_handler(int irq, void *data) +{ + struct da9210 *chip = data; + unsigned int val, handled = 0; + int error, ret = IRQ_NONE; + + error = regmap_read(chip->regmap, DA9210_REG_EVENT_B, &val); + if (error < 0) + goto error_i2c; + + if (val & DA9210_E_OVCURR) { + regulator_notifier_call_chain(chip->rdev, + REGULATOR_EVENT_OVER_CURRENT, + NULL); + handled |= DA9210_E_OVCURR; + } + if (val & DA9210_E_NPWRGOOD) { + regulator_notifier_call_chain(chip->rdev, + REGULATOR_EVENT_UNDER_VOLTAGE, + NULL); + handled |= DA9210_E_NPWRGOOD; + } + if (val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT)) { + regulator_notifier_call_chain(chip->rdev, + REGULATOR_EVENT_OVER_TEMP, NULL); + handled |= val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT); + } + if (val & DA9210_E_VMAX) { + regulator_notifier_call_chain(chip->rdev, + REGULATOR_EVENT_REGULATION_OUT, + NULL); + handled |= DA9210_E_VMAX; + } + if (handled) { + /* Clear handled events */ + error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled); + if (error < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + return ret; + +error_i2c: + dev_err(regmap_get_device(chip->regmap), "I2C error : %d\n", error); + return ret; +} + /* * I2C driver interface functions */ @@ -168,6 +219,30 @@ static int da9210_i2c_probe(struct i2c_client *i2c, } chip->rdev = rdev; + if (i2c->irq) { + error = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, + da9210_irq_handler, + IRQF_TRIGGER_LOW | + IRQF_ONESHOT | IRQF_SHARED, + "da9210", chip); + if (error) { + dev_err(&i2c->dev, "Failed to request IRQ%u: %d\n", + i2c->irq, error); + return error; + } + + error = regmap_update_bits(chip->regmap, DA9210_REG_MASK_B, + DA9210_M_OVCURR | DA9210_M_NPWRGOOD | + DA9210_M_TEMP_WARN | + DA9210_M_TEMP_CRIT | DA9210_M_VMAX, 0); + if (error < 0) { + dev_err(&i2c->dev, "Failed to update mask reg: %d\n", + error); + return error; + } + } else { + dev_warn(&i2c->dev, "No IRQ configured\n"); + } i2c_set_clientdata(i2c, chip); @@ -184,7 +259,6 @@ MODULE_DEVICE_TABLE(i2c, da9210_i2c_id); static struct i2c_driver da9210_regulator_driver = { .driver = { .name = "da9210", - .owner = THIS_MODULE, }, .probe = da9210_i2c_probe, .id_table = da9210_i2c_id,