#define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL (1 << 3)
#define USBOTGSS_IRQMISC_IDPULLUP_FALL (1 << 0)
+#define USBOTGSS_INTERRUPTS (USBOTGSS_IRQMISC_OEVT | \
+ USBOTGSS_IRQMISC_DRVVBUS_RISE | \
+ USBOTGSS_IRQMISC_CHRGVBUS_RISE | \
+ USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | \
+ USBOTGSS_IRQMISC_IDPULLUP_RISE | \
+ USBOTGSS_IRQMISC_DRVVBUS_FALL | \
+ USBOTGSS_IRQMISC_CHRGVBUS_FALL | \
+ USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | \
+ USBOTGSS_IRQMISC_IDPULLUP_FALL)
+
/* UTMI_OTG_CTRL REGISTER */
#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5)
#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4)
u32 irq0_offset;
u32 dma_status:1;
+ struct list_head list;
+ u32 index;
};
-struct dwc3_omap *omap;
+static LIST_HEAD(dwc3_omap_list);
static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
{
omap->irq0_offset, value);
}
+static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
+{
+ dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
+ omap->irqmisc_offset, value);
+}
+
+static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
+{
+ dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
+ omap->irq0_offset, value);
+}
+
static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
enum omap_dwc3_vbus_id_status status)
{
static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
{
- u32 reg;
-
/* enable all IRQs */
- reg = USBOTGSS_IRQO_COREIRQ_ST;
- dwc3_omap_write_irq0_set(omap, reg);
-
- reg = (USBOTGSS_IRQMISC_OEVT |
- USBOTGSS_IRQMISC_DRVVBUS_RISE |
- USBOTGSS_IRQMISC_CHRGVBUS_RISE |
- USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
- USBOTGSS_IRQMISC_IDPULLUP_RISE |
- USBOTGSS_IRQMISC_DRVVBUS_FALL |
- USBOTGSS_IRQMISC_CHRGVBUS_FALL |
- USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
- USBOTGSS_IRQMISC_IDPULLUP_FALL);
-
- dwc3_omap_write_irqmisc_set(omap, reg);
+ dwc3_omap_write_irq0_set(omap, USBOTGSS_IRQO_COREIRQ_ST);
+
+ dwc3_omap_write_irqmisc_set(omap, USBOTGSS_INTERRUPTS);
}
static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
{
/* disable all IRQs */
- dwc3_omap_write_irqmisc_set(omap, 0x00);
- dwc3_omap_write_irq0_set(omap, 0x00);
+ dwc3_omap_write_irq0_clr(omap, USBOTGSS_IRQO_COREIRQ_ST);
+
+ dwc3_omap_write_irqmisc_clr(omap, USBOTGSS_INTERRUPTS);
}
static void dwc3_omap_map_offset(struct dwc3_omap *omap)
{
u32 reg;
struct device *dev;
+ struct dwc3_omap *omap;
omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
if (!omap)
return -ENOMEM;
omap->base = omap_dev->base;
+ omap->index = omap_dev->index;
dwc3_omap_map_offset(omap);
dwc3_omap_set_utmi_mode(omap, omap_dev->utmi_mode);
dwc3_omap_set_mailbox(omap, omap_dev->vbus_id_status);
dwc3_omap_enable_irqs(omap);
+ list_add_tail(&omap->list, &dwc3_omap_list);
return 0;
}
* @index: index of this controller
*
* Performs cleanup of memory allocated in dwc3_omap_uboot_init
- * (equivalent to dwc3_omap_remove in linux).
+ * (equivalent to dwc3_omap_remove in linux). index of _this_ controller
+ * should be passed and should match with the index passed in
+ * dwc3_omap_device during init.
*
* Generally called from board file.
*/
-void dwc3_omap_uboot_exit(void)
+void dwc3_omap_uboot_exit(int index)
{
- dwc3_omap_disable_irqs(omap);
- kfree(omap);
+ struct dwc3_omap *omap = NULL;
+
+ list_for_each_entry(omap, &dwc3_omap_list, list) {
+ if (omap->index != index)
+ continue;
+
+ dwc3_omap_disable_irqs(omap);
+ list_del(&omap->list);
+ kfree(omap);
+ break;
+ }
+}
+
+/**
+ * dwc3_omap_uboot_interrupt_status - check the status of interrupt
+ * @index: index of this controller
+ *
+ * Checks the status of interrupts and returns true if an interrupt
+ * is detected or false otherwise.
+ *
+ * Generally called from board file.
+ */
+int dwc3_omap_uboot_interrupt_status(int index)
+{
+ struct dwc3_omap *omap = NULL;
+
+ list_for_each_entry(omap, &dwc3_omap_list, list)
+ if (omap->index == index)
+ return dwc3_omap_interrupt(-1, omap);
return 0;
}