static irqreturn_t usbhs_interrupt(int irq, void *data)
{
    struct usbhs_priv *priv = data;
    struct usbhs_irq_state irq_state;

    usbhs_status_get_each_irq(priv, &irq_state);

    usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
    usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);

    usbhs_write(priv, BRDYSTS, 0);
    usbhs_write(priv, NRDYSTS, 0);
    usbhs_write(priv, BEMPSTS, 0);



    if (irq_state.intsts0 & VBINT)
        usbhs_mod_info_call(priv, irq_vbus, priv, &irq_state);

    if (irq_state.intsts0 & DVST)
        usbhs_mod_call(priv, irq_dev_state, priv, &irq_state);

    if (irq_state.intsts0 & CTRT)
        usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state);

    if (irq_state.intsts0 & BEMP)
        usbhs_mod_call(priv, irq_empty, priv, &irq_state);

    if (irq_state.intsts0 & BRDY)
        usbhs_mod_call(priv, irq_ready, priv, &irq_state);


    if (irq_state.intsts1 & ATTCH)
        usbhs_mod_call(priv, irq_attch, priv, &irq_state);

    if (irq_state.intsts1 & DTCH)
        usbhs_mod_call(priv, irq_dtch, priv, &irq_state);

    if (irq_state.intsts1 & SIGN)
        usbhs_mod_call(priv, irq_sign, priv, &irq_state);

    if (irq_state.intsts1 & SACK)
        usbhs_mod_call(priv, irq_sack, priv, &irq_state);

    return IRQ_HANDLED;
}
Beispiel #2
0
/*
 *		interrupt
 */
#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */
#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */
static irqreturn_t usbhs_interrupt(int irq, void *data)
{
	struct usbhs_priv *priv = data;
	struct usbhs_irq_state irq_state;

	usbhs_status_get_each_irq(priv, &irq_state);

	/*
	 * clear interrupt
	 *
	 * The hardware is _very_ picky to clear interrupt bit.
	 * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value.
	 *
	 * see
	 *	"Operation"
	 *	 - "Control Transfer (DCP)"
	 *	   - Function :: VALID bit should 0
	 */
	usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
	usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);

	usbhs_write(priv, BRDYSTS, 0);
	usbhs_write(priv, NRDYSTS, 0);
	usbhs_write(priv, BEMPSTS, 0);

	/*
	 * call irq callback functions
	 * see also
	 *	usbhs_irq_setting_update
	 */

	/* INTSTS0 */
	if (irq_state.intsts0 & VBINT)
		usbhs_mod_info_call(priv, irq_vbus, priv, &irq_state);

	if (irq_state.intsts0 & DVST)
		usbhs_mod_call(priv, irq_dev_state, priv, &irq_state);

	if (irq_state.intsts0 & CTRT)
		usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state);

	if (irq_state.intsts0 & BEMP)
		usbhs_mod_call(priv, irq_empty, priv, &irq_state);

	if (irq_state.intsts0 & BRDY)
		usbhs_mod_call(priv, irq_ready, priv, &irq_state);

	/* INTSTS1 */
	if (irq_state.intsts1 & ATTCH)
		usbhs_mod_call(priv, irq_attch, priv, &irq_state);

	if (irq_state.intsts1 & DTCH)
		usbhs_mod_call(priv, irq_dtch, priv, &irq_state);

	if (irq_state.intsts1 & SIGN)
		usbhs_mod_call(priv, irq_sign, priv, &irq_state);

	if (irq_state.intsts1 & SACK)
		usbhs_mod_call(priv, irq_sack, priv, &irq_state);

	return IRQ_HANDLED;
}
Beispiel #3
0
/*
 *		interrupt
 */
#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */
#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */
static irqreturn_t usbhs_interrupt(int irq, void *data)
{
	struct usbhs_priv *priv = data;
	struct usbhs_irq_state irq_state;

	if (usbhs_status_get_each_irq(priv, &irq_state) < 0)
		return IRQ_NONE;

	/*
	 * clear interrupt
	 *
	 * The hardware is _very_ picky to clear interrupt bit.
	 * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value.
	 *
	 * see
	 *	"Operation"
	 *	 - "Control Transfer (DCP)"
	 *	   - Function :: VALID bit should 0
	 */
	usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
	if (usbhs_mod_is_host(priv))
		usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);

	/*
	 * The driver should not clear the xxxSTS after the line of
	 * "call irq callback functions" because each "if" statement is
	 * possible to call the callback function for avoiding any side effects.
	 */
	if (irq_state.intsts0 & BRDY)
		usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
	usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
	if (irq_state.intsts0 & BEMP)
		usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);

	/*
	 * call irq callback functions
	 * see also
	 *	usbhs_irq_setting_update
	 */

	/* INTSTS0 */
	if (irq_state.intsts0 & VBINT)
		usbhs_mod_info_call(priv, irq_vbus, priv, &irq_state);

	if (irq_state.intsts0 & DVST)
		usbhs_mod_call(priv, irq_dev_state, priv, &irq_state);

	if (irq_state.intsts0 & CTRT)
		usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state);

	if (irq_state.intsts0 & BEMP)
		usbhs_mod_call(priv, irq_empty, priv, &irq_state);

	if (irq_state.intsts0 & BRDY)
		usbhs_mod_call(priv, irq_ready, priv, &irq_state);

	if (usbhs_mod_is_host(priv)) {
		/* INTSTS1 */
		if (irq_state.intsts1 & ATTCH)
			usbhs_mod_call(priv, irq_attch, priv, &irq_state);

		if (irq_state.intsts1 & DTCH)
			usbhs_mod_call(priv, irq_dtch, priv, &irq_state);

		if (irq_state.intsts1 & SIGN)
			usbhs_mod_call(priv, irq_sign, priv, &irq_state);

		if (irq_state.intsts1 & SACK)
			usbhs_mod_call(priv, irq_sack, priv, &irq_state);
	}
	return IRQ_HANDLED;
}