max3421_handle_irqs(struct usb_hcd *hcd)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	u32 chg, old_port_status;
	unsigned long flags;
	u8 hirq;

	/*
	 * Read and ack pending interrupts (CPU must never
	 * clear SNDBAV directly and RCVDAV must be cleared by
	 * max3421_recv_data_available()!):
	 */
	hirq = spi_rd8(hcd, MAX3421_REG_HIRQ);
	hirq &= max3421_hcd->hien;
	if (!hirq)
		return 0;

	spi_wr8(hcd, MAX3421_REG_HIRQ,
		hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) |
			 BIT(MAX3421_HI_RCVDAV_BIT)));

	if (hirq & BIT(MAX3421_HI_FRAME_BIT)) {
		max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1)
					     & USB_MAX_FRAME_NUMBER);
		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC;
	}

	if (hirq & BIT(MAX3421_HI_RCVDAV_BIT))
		max3421_recv_data_available(hcd);

	if (hirq & BIT(MAX3421_HI_HXFRDN_BIT))
		max3421_host_transfer_done(hcd);

	if (hirq & BIT(MAX3421_HI_CONDET_BIT))
		max3421_detect_conn(hcd);

	/*
	 * Now process interrupts that may affect HCD state
	 * other than the end-points:
	 */
	spin_lock_irqsave(&max3421_hcd->lock, flags);

	old_port_status = max3421_hcd->port_status;
	if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) {
		if (max3421_hcd->port_status & USB_PORT_STAT_RESET) {
			/* BUSEVENT due to completion of Bus Reset */
			max3421_hcd->port_status &= ~USB_PORT_STAT_RESET;
			max3421_hcd->port_status |=  USB_PORT_STAT_ENABLE;
		} else {
			/* BUSEVENT due to completion of Bus Resume */
			pr_info("%s: BUSEVENT Bus Resume Done\n", __func__);
		}
	}
	if (hirq & BIT(MAX3421_HI_RWU_BIT))
		pr_info("%s: RWU\n", __func__);
	if (hirq & BIT(MAX3421_HI_SUSDN_BIT))
		pr_info("%s: SUSDN\n", __func__);

	chg = (old_port_status ^ max3421_hcd->port_status);
	max3421_hcd->port_status |= chg << 16;

	spin_unlock_irqrestore(&max3421_hcd->lock, flags);

#ifdef DEBUG
	{
		static unsigned long last_time;
		char sbuf[16 * 16], *dp, *end;
		int i;

		if (time_after(jiffies, last_time + 5*HZ)) {
			dp = sbuf;
			end = sbuf + sizeof(sbuf);
			*dp = '\0';
			for (i = 0; i < 16; ++i) {
				int ret = snprintf(dp, end - dp, " %lu",
						   max3421_hcd->err_stat[i]);
				if (ret < 0 || ret >= end - dp)
					break;	/* error or buffer full */
				dp += ret;
			}
			pr_info("%s: hrsl_stats %s\n", __func__, sbuf);
			memset(max3421_hcd->err_stat, 0,
			       sizeof(max3421_hcd->err_stat));
			last_time = jiffies;

			dump_eps(hcd);
		}
	}
#endif
	return 1;
}
max3421_handle_irqs(struct usb_hcd *hcd)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	u32 chg, old_port_status;
	unsigned long flags;
	u8 hirq;

	 
	hirq = spi_rd8(hcd, MAX3421_REG_HIRQ);
	hirq &= max3421_hcd->hien;
	if (!hirq)
		return 0;

	spi_wr8(hcd, MAX3421_REG_HIRQ,
		hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) |
			 BIT(MAX3421_HI_RCVDAV_BIT)));

	if (hirq & BIT(MAX3421_HI_FRAME_BIT)) {
		max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1)
					     & USB_MAX_FRAME_NUMBER);
		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC;
	}

	if (hirq & BIT(MAX3421_HI_RCVDAV_BIT))
		max3421_recv_data_available(hcd);

	if (hirq & BIT(MAX3421_HI_HXFRDN_BIT))
		max3421_host_transfer_done(hcd);

	if (hirq & BIT(MAX3421_HI_CONDET_BIT))
		max3421_detect_conn(hcd);

	 
	spin_lock_irqsave(&max3421_hcd->lock, flags);

	old_port_status = max3421_hcd->port_status;
	if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) {
		if (max3421_hcd->port_status & USB_PORT_STAT_RESET) {
			 
			max3421_hcd->port_status &= ~USB_PORT_STAT_RESET;
			max3421_hcd->port_status |=  USB_PORT_STAT_ENABLE;
		} else {
			 
			pr_info("%s: BUSEVENT Bus Resume Done\n", __func__);
		}
	}
	if (hirq & BIT(MAX3421_HI_RWU_BIT))
		pr_info("%s: RWU\n", __func__);
	if (hirq & BIT(MAX3421_HI_SUSDN_BIT))
		pr_info("%s: SUSDN\n", __func__);

	chg = (old_port_status ^ max3421_hcd->port_status);
	max3421_hcd->port_status |= chg << 16;

	spin_unlock_irqrestore(&max3421_hcd->lock, flags);

#ifdef DEBUG
	{
		static unsigned long last_time;
		char sbuf[16 * 16], *dp, *end;
		int i;

		if (time_after(jiffies, last_time + 5*HZ)) {
			dp = sbuf;
			end = sbuf + sizeof(sbuf);
			*dp = '\0';
			for (i = 0; i < 16; ++i) {
				int ret = snprintf(dp, end - dp, " %lu",
						   max3421_hcd->err_stat[i]);
				if (ret < 0 || ret >= end - dp)
					break;	 
				dp += ret;
			}
			pr_info("%s: hrsl_stats %s\n", __func__, sbuf);
			memset(max3421_hcd->err_stat, 0,
			       sizeof(max3421_hcd->err_stat));
			last_time = jiffies;

			dump_eps(hcd);
		}
	}
#endif
	return 1;
}