irqreturn_t msm_slim_port_irq_handler(struct msm_slim_ctrl *dev, u32 pstat)
{
	int i;
	u32 int_en = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
							dev->ver));
	if ((pstat & int_en) == 0)
		return IRQ_HANDLED;
	for (i = dev->port_b; i < MSM_SLIM_NPORTS; i++) {
		if (pstat & (1 << i)) {
			u32 val = readl_relaxed(PGD_PORT(PGD_PORT_STATn,
						i, dev->ver));
			if (val & MSM_PORT_OVERFLOW) {
				dev->ctrl.ports[i-dev->port_b].err =
						SLIM_P_OVERFLOW;
			} else if (val & MSM_PORT_UNDERFLOW) {
				dev->ctrl.ports[i-dev->port_b].err =
					SLIM_P_UNDERFLOW;
			}
		}
	}
	writel_relaxed((int_en & (~pstat)),
			PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
					dev->ver));
	
	writel_relaxed(pstat, PGD_THIS_EE(PGD_PORT_INT_CL_EEn,
							dev->ver));
	SLIM_INFO(dev, "disabled overflow/underflow for port 0x%x", pstat);

	mb();
	return IRQ_HANDLED;
}
Exemple #2
0
irqreturn_t msm_slim_port_irq_handler(struct msm_slim_ctrl *dev, u32 pstat)
{
	int i;
	u32 int_en = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
							dev->ver));
	/*
	 * different port-interrupt than what we enabled, ignore.
	 * This may happen if overflow/underflow is reported, but
	 * was disabled due to unavailability of buffers provided by
	 * client.
	 */
	if ((pstat & int_en) == 0)
		return IRQ_HANDLED;
	for (i = 0; i < dev->port_nums; i++) {
		struct msm_slim_endp *endpoint = &dev->pipes[i];
		if (pstat & (1 << endpoint->port_b)) {
			u32 val = readl_relaxed(PGD_PORT(PGD_PORT_STATn,
					endpoint->port_b, dev->ver));
			if (val & MSM_PORT_OVERFLOW) {
				dev->ctrl.ports[i].err =
						SLIM_P_OVERFLOW;
			} else if (val & MSM_PORT_UNDERFLOW) {
				dev->ctrl.ports[i].err =
					SLIM_P_UNDERFLOW;
			}
		}
	}
	/*
	 * Disable port interrupt here. Re-enable when more
	 * buffers are provided for this port.
	 */
	writel_relaxed((int_en & (~pstat)),
			PGD_THIS_EE(PGD_PORT_INT_EN_EEn,
					dev->ver));
	/* clear port interrupts */
	writel_relaxed(pstat, PGD_THIS_EE(PGD_PORT_INT_CL_EEn,
							dev->ver));
	SLIM_INFO(dev, "disabled overflow/underflow for port 0x%x", pstat);

	/*
	 * Guarantee that port interrupt bit(s) clearing writes go
	 * through before exiting ISR
	 */
	mb();
	return IRQ_HANDLED;
}