Пример #1
0
static void qpnpint_irq_unmask(struct irq_data *d)
{
	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
	struct q_chip_data *chip_d = irq_d->chip_d;
	struct q_perip_data *per_d = irq_d->per_d;
	int rc;

	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);

	if (!chip_d->cb) {
		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
				chip_d->bus_nr, irq_d->spmi_slave,
				irq_d->spmi_offset);
		return;
	}

	qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);

	per_d->int_en |= irq_d->mask_shift;
	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_SET,
					&irq_d->mask_shift, 1);
	if (rc) {
		pr_err("spmi failure on irq %d\n", d->irq);
		return;
	}
}
static void qpnpint_irq_unmask(struct irq_data *d)
{
	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
	struct q_chip_data *chip_d = irq_d->chip_d;
	struct q_perip_data *per_d = irq_d->per_d;
	int rc;
	uint8_t buf[2];
	uint8_t prev_int_en;

	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);

	if (!chip_d->cb) {
		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
				chip_d->bus_nr, irq_d->spmi_slave,
				irq_d->spmi_offset);
		return;
	}

	spin_lock(&per_d->lock);
	prev_int_en = per_d->int_en;
	per_d->int_en |= irq_d->mask_shift;
	if (!prev_int_en && per_d->int_en) {
		/*
		 * no interrupt prior to this call was enabled for the
		 * peripheral. Ask the arbiter to enable interrupts for
		 * this peripheral
		 */
		qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);
	}
	spin_unlock(&per_d->lock);

	/* Check the current state of the interrupt enable bit. */
	rc = qpnpint_spmi_read(irq_d, QPNPINT_REG_EN_SET, buf, 1);
	if (rc) {
		pr_err("SPMI read failure for IRQ %d, rc=%d\n", d->irq, rc);
		return;
	}

	if (!(buf[0] & irq_d->mask_shift)) {
		/*
		 * Since the interrupt is currently disabled, write to both the
		 * LATCHED_CLR and EN_SET registers so that a spurious interrupt
		 * cannot be triggered when the interrupt is enabled.
		 */
		buf[0] = irq_d->mask_shift;
		buf[1] = irq_d->mask_shift;
		rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_LATCHED_CLR, buf, 2);
		if (rc) {
			pr_err("SPMI write failure for IRQ %d, rc=%d\n", d->irq,
				rc);
			return;
		}
	}
}
static void qpnpint_irq_mask(struct irq_data *d)
{
	struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
	struct q_chip_data *chip_d = irq_d->chip_d;
	struct q_perip_data *per_d = irq_d->per_d;
	int rc;
	uint8_t prev_int_en;

	pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);

	if (!chip_d->cb) {
		pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
				chip_d->bus_nr, irq_d->spmi_slave,
				irq_d->spmi_offset);
		return;
	}

	spin_lock(&per_d->lock);
	prev_int_en = per_d->int_en;
	per_d->int_en &= ~irq_d->mask_shift;

	if (prev_int_en && !(per_d->int_en)) {
		/*
		 * no interrupt on this peripheral is enabled
		 * ask the arbiter to ignore this peripheral
		 */
		qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
	}
	spin_unlock(&per_d->lock);

	rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
					(u8 *)&irq_d->mask_shift, 1);
	if (rc) {
		pr_err_ratelimited("spmi failure on irq %d\n", d->irq);
		return;
	}

	pr_debug("done hwirq %lu irq: %d\n", d->hwirq, d->irq);
}