예제 #1
0
파일: ltc3676.c 프로젝트: acton393/linux
static irqreturn_t ltc3676_isr(int irq, void *dev_id)
{
	struct ltc3676 *ltc3676 = dev_id;
	struct device *dev = ltc3676->dev;
	unsigned int i, irqstat, event;

	regmap_read(ltc3676->regmap, LTC3676_IRQSTAT, &irqstat);

	dev_dbg(dev, "irq%d irqstat=0x%02x\n", irq, irqstat);
	if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) {
		dev_warn(dev, "Over-temperature Warning\n");
		event = REGULATOR_EVENT_OVER_TEMP;
		for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
			regulator_notifier_call_chain(ltc3676->regulators[i],
						      event, NULL);
	}

	if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) {
		dev_info(dev, "Undervoltage Warning\n");
		event = REGULATOR_EVENT_UNDER_VOLTAGE;
		for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
			regulator_notifier_call_chain(ltc3676->regulators[i],
						      event, NULL);
	}

	/* Clear warning condition */
	regmap_write(ltc3676->regmap, LTC3676_CLIRQ, 0);

	return IRQ_HANDLED;
}
예제 #2
0
static irqreturn_t lp8755_irq_handler(int irq, void *data)
{
	int ret, icnt;
	unsigned int flag0, flag1;
	struct lp8755_chip *pchip = data;

	/* read flag0 register */
	ret = lp8755_read(pchip, 0x0D, &flag0);
	if (ret < 0)
		goto err_i2c;
	/* clear flag register to pull up int. pin */
	ret = lp8755_write(pchip, 0x0D, 0x00);
	if (ret < 0)
		goto err_i2c;

	/* sent power fault detection event to specific regulator */
	for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
		if ((flag0 & (0x4 << icnt))
		    && (pchip->irqmask & (0x04 << icnt))
		    && (pchip->rdev[icnt] != NULL))
			regulator_notifier_call_chain(pchip->rdev[icnt],
						      LP8755_EVENT_PWR_FAULT,
						      NULL);

	/* read flag1 register */
	ret = lp8755_read(pchip, 0x0E, &flag1);
	if (ret < 0)
		goto err_i2c;
	/* clear flag register to pull up int. pin */
	ret = lp8755_write(pchip, 0x0E, 0x00);
	if (ret < 0)
		goto err_i2c;

	/* send OCP event to all regualtor devices */
	if ((flag1 & 0x01) && (pchip->irqmask & 0x01))
		for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
			if (pchip->rdev[icnt] != NULL)
				regulator_notifier_call_chain(pchip->rdev[icnt],
							      LP8755_EVENT_OCP,
							      NULL);

	/* send OVP event to all regualtor devices */
	if ((flag1 & 0x02) && (pchip->irqmask & 0x02))
		for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
			if (pchip->rdev[icnt] != NULL)
				regulator_notifier_call_chain(pchip->rdev[icnt],
							      LP8755_EVENT_OVP,
							      NULL);
	return IRQ_HANDLED;

err_i2c:
	dev_err(pchip->dev, "i2c acceess error %s\n", __func__);
	return IRQ_NONE;
}
예제 #3
0
static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{
	struct regulator_dev *rdev = (struct regulator_dev *)data;

	mutex_lock(&rdev->mutex);
	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
		regulator_notifier_call_chain(rdev,
					      REGULATOR_EVENT_REGULATION_OUT,
					      wm8350);
	else
		regulator_notifier_call_chain(rdev,
					      REGULATOR_EVENT_UNDER_VOLTAGE,
					      wm8350);
	mutex_unlock(&rdev->mutex);
}
예제 #4
0
/* Regulator interrupt handlers */
static irqreturn_t da9062_ldo_lim_event(int irq, void *data)
{
	struct da9062_regulators *regulators = data;
	struct da9062 *hw = regulators->regulator[0].hw;
	struct da9062_regulator *regl;
	int handled = IRQ_NONE;
	int bits, i, ret;

	ret = regmap_read(hw->regmap, DA9062AA_STATUS_D, &bits);
	if (ret < 0) {
		dev_err(hw->dev,
			"Failed to read LDO overcurrent indicator\n");
		goto ldo_lim_error;
	}

	for (i = regulators->n_regulators - 1; i >= 0; i--) {
		regl = &regulators->regulator[i];
		if (regl->info->oc_event.reg != DA9062AA_STATUS_D)
			continue;

		if (BIT(regl->info->oc_event.lsb) & bits) {
			regulator_notifier_call_chain(regl->rdev,
					REGULATOR_EVENT_OVER_CURRENT, NULL);
			handled = IRQ_HANDLED;
		}
	}

ldo_lim_error:
	return handled;
}
예제 #5
0
static irqreturn_t pmic_uv_handler(int irq, void *data)
{
	struct regulator_dev *rdev = (struct regulator_dev *)data;

	mutex_lock(&rdev->mutex);
	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
		regulator_notifier_call_chain(rdev,
					      REGULATOR_EVENT_REGULATION_OUT,
					      NULL);
	else
		regulator_notifier_call_chain(rdev,
					      REGULATOR_EVENT_UNDER_VOLTAGE,
					      NULL);
	mutex_unlock(&rdev->mutex);

	return IRQ_HANDLED;
}
static irqreturn_t wm831x_isink_irq(int irq, void *data)
{
	struct wm831x_isink *isink = data;

	regulator_notifier_call_chain(isink->regulator,
				      REGULATOR_EVENT_OVER_CURRENT,
				      NULL);

	return IRQ_HANDLED;
}
예제 #7
0
static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
{
	struct wm831x_dcdc *dcdc = data;

	regulator_notifier_call_chain(dcdc->regulator,
				      REGULATOR_EVENT_OVER_CURRENT,
				      NULL);

	return IRQ_HANDLED;
}
예제 #8
0
static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
{
	struct wm831x_dcdc *dcdc = data;

	regulator_notifier_call_chain(dcdc->regulator,
				      REGULATOR_EVENT_UNDER_VOLTAGE,
				      NULL);

	return IRQ_HANDLED;
}
예제 #9
0
/* Regulator interrupt handlers */
static irqreturn_t da9063_ldo_lim_event(int irq, void *data)
{
	struct da9063_regulators *regulators = data;
	struct da9063 *hw = regulators->regulator[0].hw;
	struct da9063_regulator *regl;
	int bits, i , ret;

	ret = regmap_read(hw->regmap, DA9063_REG_STATUS_D, &bits);
	if (ret < 0)
		return IRQ_NONE;

	for (i = regulators->n_regulators - 1; i >= 0; i--) {
		regl = &regulators->regulator[i];
		if (regl->info->oc_event.reg != DA9063_REG_STATUS_D)
			continue;

		if (BIT(regl->info->oc_event.lsb) & bits)
			regulator_notifier_call_chain(regl->rdev,
					REGULATOR_EVENT_OVER_CURRENT, NULL);
	}

	return IRQ_HANDLED;
}