]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/arm/mach-omap2/prm44xx.c
Merge tag 'for-linus-20170825' of git://git.infradead.org/linux-mtd
[mirror_ubuntu-artful-kernel.git] / arch / arm / mach-omap2 / prm44xx.c
index 87e86a4a9eadd7f6a544fb04e228a791268e6d73..3ab5df1ce900b26f91b8b582a36188bd281c6c3c 100644 (file)
@@ -336,6 +336,27 @@ static void omap44xx_prm_reconfigure_io_chain(void)
        return;
 }
 
+/**
+ * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM.  For I/O wakeups
+ * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
+ * omap44xx_prm_reconfigure_io_chain() must be called.  No return value.
+ */
+static void __init omap44xx_prm_enable_io_wakeup(void)
+{
+       s32 inst = omap4_prmst_get_prm_dev_inst();
+
+       if (inst == PRM_INSTANCE_UNKNOWN)
+               return;
+
+       omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+                                   OMAP4430_GLOBAL_WUEN_MASK,
+                                   inst,
+                                   omap4_prcm_irq_setup.pm_ctrl);
+}
+
 /**
  * omap44xx_prm_read_reset_sources - return the last SoC reset source
  *
@@ -668,6 +689,8 @@ struct pwrdm_ops omap4_pwrdm_operations = {
        .pwrdm_has_voltdm       = omap4_check_vcvp,
 };
 
+static int omap44xx_prm_late_init(void);
+
 /*
  * XXX document
  */
@@ -675,6 +698,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
        .read_reset_sources = &omap44xx_prm_read_reset_sources,
        .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
        .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+       .late_init = &omap44xx_prm_late_init,
        .assert_hardreset       = omap4_prminst_assert_hardreset,
        .deassert_hardreset     = omap4_prminst_deassert_hardreset,
        .is_hardreset_asserted  = omap4_prminst_is_hardreset_asserted,
@@ -711,6 +735,37 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
        return prm_register(&omap44xx_prm_ll_data);
 }
 
+static int omap44xx_prm_late_init(void)
+{
+       int irq_num;
+
+       if (!(prm_features & PRM_HAS_IO_WAKEUP))
+               return 0;
+
+       irq_num = of_irq_get(prm_init_data->np, 0);
+       /*
+        * Already have OMAP4 IRQ num. For all other platforms, we need
+        * IRQ numbers from DT
+        */
+       if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) {
+               if (irq_num == -EPROBE_DEFER)
+                       return irq_num;
+
+               /* Have nothing to do */
+               return 0;
+       }
+
+       /* Once OMAP4 DT is filled as well */
+       if (irq_num >= 0) {
+               omap4_prcm_irq_setup.irq = irq_num;
+               omap4_prcm_irq_setup.xlate_irq = NULL;
+       }
+
+       omap44xx_prm_enable_io_wakeup();
+
+       return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+}
+
 static void __exit omap44xx_prm_exit(void)
 {
        prm_unregister(&omap44xx_prm_ll_data);