コード例 #1
0
static void do_hsi_tasklet(unsigned long hsi_port)
{
	struct hsi_port *pport = (struct hsi_port *)hsi_port;
	struct hsi_dev *hsi_ctrl = pport->hsi_controller;
	void __iomem *base = hsi_ctrl->base;
	unsigned int port = pport->port_number;
	unsigned int irq = pport->n_irq;
	u32 status_reg;
	struct platform_device *pd = to_platform_device(hsi_ctrl->dev);

	hsi_driver_int_proc(pport,
			HSI_SYS_MPU_STATUS_REG(port, irq),
			HSI_SYS_MPU_ENABLE_REG(port, irq),
			0, min(pport->max_ch, (u8) HSI_SSI_CHANNELS_MAX));

	if (pport->max_ch > HSI_SSI_CHANNELS_MAX)
		hsi_driver_int_proc(pport,
				HSI_SYS_MPU_U_STATUS_REG(port, irq),
				HSI_SYS_MPU_U_ENABLE_REG(port, irq),
				HSI_SSI_CHANNELS_MAX, pport->max_ch);

	status_reg = hsi_inl(base, HSI_SYS_MPU_STATUS_REG(port, irq)) &
			hsi_inl(base, HSI_SYS_MPU_ENABLE_REG(port, irq));

	if (hsi_driver_device_is_hsi(pd))
		status_reg |=
			(hsi_inl(base, HSI_SYS_MPU_U_STATUS_REG(port, irq)) &
			hsi_inl(base, HSI_SYS_MPU_U_ENABLE_REG(port, irq)));

	if (status_reg)
		tasklet_hi_schedule(&pport->hsi_tasklet);
	else
		enable_irq(pport->irq);
}
コード例 #2
0
static u32 hsi_process_int_event(struct hsi_port *pport)
{
	unsigned int port = pport->port_number;
	unsigned int irq = pport->n_irq;
	u32 status_reg;
	bool cawake_double_int = false;

	/* Clear CAWAKE backup interrupt */
	hsi_driver_ack_interrupt(pport, HSI_CAWAKEDETECTED, true);

	/* Process events for channels 0..7 */
	status_reg = hsi_driver_int_proc(pport,
			    HSI_SYS_MPU_STATUS_REG(port, irq),
			    HSI_SYS_MPU_ENABLE_REG(port, irq),
			    0,
			    min(pport->max_ch, (u8) HSI_SSI_CHANNELS_MAX) - 1,
			    cawake_double_int);

	/* If another CAWAKE interrupt occured while previous is still being
	 * processed, mark it for extra processing */
	if (hsi_driver_is_interrupt_pending(pport, HSI_CAWAKEDETECTED, true) &&
		(status_reg & HSI_CAWAKEDETECTED)) {
		dev_warn(pport->hsi_controller->dev, "New CAWAKE interrupt "
			 "detected during interrupt processing\n");
		/* Force processing of backup CAWAKE interrupt */
		cawake_double_int = true;
	}

	/* Process events for channels 8..15 or backup interrupt if needed */
	if ((pport->max_ch > HSI_SSI_CHANNELS_MAX) || cawake_double_int)
		status_reg |= hsi_driver_int_proc(pport,
				    HSI_SYS_MPU_U_STATUS_REG(port, irq),
				    HSI_SYS_MPU_U_ENABLE_REG(port, irq),
				    HSI_SSI_CHANNELS_MAX, pport->max_ch - 1,
				    cawake_double_int);

	return status_reg;
}