|
@@ -275,3 +275,181 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
|
|
|
GFP_KERNEL);
|
|
|
|
|
|
if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
|
|
|
+ !prcm_irq_setup->priority_mask) {
|
|
|
+ pr_err("PRCM: kzalloc failed\n");
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(mask, 0, sizeof(mask));
|
|
|
+
|
|
|
+ for (i = 0; i < irq_setup->nr_irqs; i++) {
|
|
|
+ offset = irq_setup->irqs[i].offset;
|
|
|
+ mask[offset >> 5] |= 1 << (offset & 0x1f);
|
|
|
+ if (irq_setup->irqs[i].priority)
|
|
|
+ irq_setup->priority_mask[offset >> 5] |=
|
|
|
+ 1 << (offset & 0x1f);
|
|
|
+ }
|
|
|
+
|
|
|
+ irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
|
|
|
+
|
|
|
+ irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
|
|
|
+ 0);
|
|
|
+
|
|
|
+ if (irq_setup->base_irq < 0) {
|
|
|
+ pr_err("PRCM: failed to allocate irq descs: %d\n",
|
|
|
+ irq_setup->base_irq);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < irq_setup->nr_regs; i++) {
|
|
|
+ gc = irq_alloc_generic_chip("PRCM", 1,
|
|
|
+ irq_setup->base_irq + i * 32, prm_base,
|
|
|
+ handle_level_irq);
|
|
|
+
|
|
|
+ if (!gc) {
|
|
|
+ pr_err("PRCM: failed to allocate generic chip\n");
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ ct = gc->chip_types;
|
|
|
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
|
|
|
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
|
|
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
|
|
+
|
|
|
+ ct->regs.ack = irq_setup->ack + i * 4;
|
|
|
+ ct->regs.mask = irq_setup->mask + i * 4;
|
|
|
+
|
|
|
+ irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
|
|
|
+ prcm_irq_chips[i] = gc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err:
|
|
|
+ omap_prcm_irq_cleanup();
|
|
|
+ return -ENOMEM;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * omap2_set_globals_prm - set the PRM base address (for early use)
|
|
|
+ * @prm: PRM base virtual address
|
|
|
+ *
|
|
|
+ * XXX Will be replaced when the PRM/CM drivers are completed.
|
|
|
+ */
|
|
|
+void __init omap2_set_globals_prm(void __iomem *prm)
|
|
|
+{
|
|
|
+ prm_base = prm;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * prm_read_reset_sources - return the sources of the SoC's last reset
|
|
|
+ *
|
|
|
+ * Return a u32 bitmask representing the reset sources that caused the
|
|
|
+ * SoC to reset. The low-level per-SoC functions called by this
|
|
|
+ * function remap the SoC-specific reset source bits into an
|
|
|
+ * OMAP-common set of reset source bits, defined in
|
|
|
+ * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
|
|
|
+ * u32 bitmask from the hardware upon success, or returns (1 <<
|
|
|
+ * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
|
|
|
+ * function was registered.
|
|
|
+ */
|
|
|
+u32 prm_read_reset_sources(void)
|
|
|
+{
|
|
|
+ u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
|
|
|
+
|
|
|
+ if (prm_ll_data->read_reset_sources)
|
|
|
+ ret = prm_ll_data->read_reset_sources();
|
|
|
+ else
|
|
|
+ WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * prm_was_any_context_lost_old - was device context lost? (old API)
|
|
|
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
|
|
|
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
|
|
|
+ * @idx: CONTEXT register offset
|
|
|
+ *
|
|
|
+ * Return 1 if any bits were set in the *_CONTEXT_* register
|
|
|
+ * identified by (@part, @inst, @idx), which means that some context
|
|
|
+ * was lost for that module; otherwise, return 0. XXX Deprecated;
|
|
|
+ * callers need to use a less-SoC-dependent way to identify hardware
|
|
|
+ * IP blocks.
|
|
|
+ */
|
|
|
+bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
|
|
|
+{
|
|
|
+ bool ret = true;
|
|
|
+
|
|
|
+ if (prm_ll_data->was_any_context_lost_old)
|
|
|
+ ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
|
|
|
+ else
|
|
|
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
|
|
|
+ __func__);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * prm_clear_context_lost_flags_old - clear context loss flags (old API)
|
|
|
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
|
|
|
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
|
|
|
+ * @idx: CONTEXT register offset
|
|
|
+ *
|
|
|
+ * Clear hardware context loss bits for the module identified by
|
|
|
+ * (@part, @inst, @idx). No return value. XXX Deprecated; callers
|
|
|
+ * need to use a less-SoC-dependent way to identify hardware IP
|
|
|
+ * blocks.
|
|
|
+ */
|
|
|
+void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
|
|
|
+{
|
|
|
+ if (prm_ll_data->clear_context_loss_flags_old)
|
|
|
+ prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
|
|
|
+ else
|
|
|
+ WARN_ONCE(1, "prm: %s: no mapping function defined\n",
|
|
|
+ __func__);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * prm_register - register per-SoC low-level data with the PRM
|
|
|
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to register
|
|
|
+ *
|
|
|
+ * Register per-SoC low-level OMAP PRM data and function pointers with
|
|
|
+ * the OMAP PRM common interface. The caller must keep the data
|
|
|
+ * pointed to by @pld valid until it calls prm_unregister() and
|
|
|
+ * it returns successfully. Returns 0 upon success, -EINVAL if @pld
|
|
|
+ * is NULL, or -EEXIST if prm_register() has already been called
|
|
|
+ * without an intervening prm_unregister().
|
|
|
+ */
|
|
|
+int prm_register(struct prm_ll_data *pld)
|
|
|
+{
|
|
|
+ if (!pld)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (prm_ll_data != &null_prm_ll_data)
|
|
|
+ return -EEXIST;
|
|
|
+
|
|
|
+ prm_ll_data = pld;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * prm_unregister - unregister per-SoC low-level data & function pointers
|
|
|
+ * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
|
|
|
+ *
|
|
|
+ * Unregister per-SoC low-level OMAP PRM data and function pointers
|
|
|
+ * that were previously registered with prm_register(). The
|
|
|
+ * caller may not destroy any of the data pointed to by @pld until
|
|
|
+ * this function returns successfully. Returns 0 upon success, or
|
|
|
+ * -EINVAL if @pld is NULL or if @pld does not match the struct
|
|
|
+ * prm_ll_data * previously registered by prm_register().
|
|
|
+ */
|
|
|
+int prm_unregister(struct prm_ll_data *pld)
|
|
|
+{
|
|
|
+ if (!pld || prm_ll_data != pld)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ prm_ll_data = &null_prm_ll_data;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|