sta = th1520_mbox_read(priv, TH_1520_MBOX_STA); if (!(sta & BIT(mapbit))) return IRQ_NONE;
/* clear chan irq bit in STA register */
th1520_mbox_rmw(priv, TH_1520_MBOX_CLR, BIT(mapbit), 0);
/* info0 is the protocol word, should not be zero! */
info0_data = th1520_mbox_chan_read(cp, TH_1520_MBOX_INFO0, false); if (info0_data) { /* read info0~info6 data */
th1520_mbox_chan_rd_data(cp, dat, false);
/* clear local info0 */
th1520_mbox_chan_write(cp, 0x0, TH_1520_MBOX_INFO0, false);
/* notify remote cpu */
th1520_mbox_chan_wr_ack(cp, &ack_magic, true); /* CPU1 902/906 use polling mode to monitor info7 */ if (cp->idx != TH_1520_MBOX_ICU_CPU1 &&
cp->idx != TH_1520_MBOX_ICU_CPU2)
th1520_mbox_chan_rmw(cp, TH_1520_MBOX_GEN,
TH_1520_MBOX_GEN_TX_ACK, 0, true);
/* transfer the data to client */
mbox_chan_received_data(chan, (void *)dat);
}
/* info7 magic value mean the real ack signal, not generate bit7 */
info7_data = th1520_mbox_chan_read(cp, TH_1520_MBOX_INFO7, false); if (info7_data == TH_1520_MBOX_ACK_MAGIC) { /* clear local info7 */
th1520_mbox_chan_write(cp, 0x0, TH_1520_MBOX_INFO7, false);
/* notify framework the last TX has completed */
mbox_chan_txdone(chan, 0);
}
/* * Mixing devm_ managed resources with manual IRQ handling is generally * discouraged due to potential complexities with resource management, * especially when dealing with shared interrupts. However, in this case, * the approach is safe and effective because: * * 1. Each mailbox channel requests its IRQ within the .startup() callback * and frees it within the .shutdown() callback. * 2. During device unbinding, the devm_ managed mailbox controller first * iterates through all channels, ensuring that their IRQs are freed before * any other devm_ resources are released. * * This ordering guarantees that no interrupts can be triggered from the device * while it is being unbound, preventing race conditions and ensuring system * stability.
*/
ret = request_irq(priv->irq, th1520_mbox_isr,
IRQF_SHARED | IRQF_NO_SUSPEND, cp->irq_desc, chan); if (ret) {
dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq); return ret;
}
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks),
priv->clocks); if (ret) {
dev_err(dev, "Failed to get clocks\n"); return ret;
}
ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks); if (ret) {
dev_err(dev, "Failed to enable clocks\n"); return ret;
}
ret = devm_add_action_or_reset(dev, th1520_disable_clk, priv); if (ret) {
clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); return ret;
}
/* * The address mappings in the device tree align precisely with those * outlined in the manual. However, register offsets within these * mapped regions are irregular, particularly for remote-icu0. * Consequently, th1520_map_mmio() requires an additional parameter to * handle this quirk.
*/
priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] =
th1520_map_mmio(pdev, "local", 0x0); if (IS_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0])) return PTR_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]);
priv->remote_icu[0] = th1520_map_mmio(pdev, "remote-icu0", 0x4000); if (IS_ERR(priv->remote_icu[0])) return PTR_ERR(priv->remote_icu[0]);
priv->remote_icu[1] = th1520_map_mmio(pdev, "remote-icu1", 0x0); if (IS_ERR(priv->remote_icu[1])) return PTR_ERR(priv->remote_icu[1]);
priv->remote_icu[2] = th1520_map_mmio(pdev, "remote-icu2", 0x0); if (IS_ERR(priv->remote_icu[2])) return PTR_ERR(priv->remote_icu[2]);
#ifdef CONFIG_PM_SLEEP staticint __maybe_unused th1520_mbox_suspend_noirq(struct device *dev)
{ struct th1520_mbox_priv *priv = dev_get_drvdata(dev); struct th1520_mbox_context *ctx = priv->ctx;
u32 i; /* * ONLY interrupt mask bit should be stored and restores. * INFO data all assumed to be lost.
*/ for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
ctx->intr_mask[i] =
ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
} return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.