/* * The service status is stored in bits 31:16 of the SERVICES_SR * register & is only valid when the system controller is not busy. * Failed services are intended to generated interrupts, but in reality * this does not happen, so the status must be checked here.
*/ if (mbox->control_scb)
regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &val); else
val = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
if (!response->resp_msg) {
dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM); return;
}
/* * We should *never* get an interrupt while the controller is * still in the busy state. If we do, something has gone badly * wrong & the content of the mailbox would not be valid.
*/ if (mpfs_mbox_busy(mbox)) {
dev_err(mbox->dev, "got an interrupt but system controller is busy\n");
response->resp_status = 0xDEAD; return;
}
for (i = 0; i < num_words; i++) {
response->resp_msg[i] =
readl_relaxed(mbox->mbox_base
+ mbox->resp_offset + i * 0x4);
}
mbox->sysreg_scb = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb"); if (IS_ERR(mbox->sysreg_scb)) return PTR_ERR(mbox->sysreg_scb);
mbox->mbox_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mbox->mbox_base)) return PTR_ERR(mbox->mbox_base);
return 0;
}
staticinlineint mpfs_mbox_old_format_probe(struct mpfs_mbox *mbox, struct platform_device *pdev)
{
dev_warn(&pdev->dev, "falling back to old devicetree format");
mbox->ctrl_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mbox->ctrl_base)) return PTR_ERR(mbox->ctrl_base);
mbox->int_reg = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(mbox->int_reg)) return PTR_ERR(mbox->int_reg);
mbox->mbox_base = devm_platform_ioremap_resource(pdev, 2); if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs
mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET;
return 0;
}
staticint mpfs_mbox_probe(struct platform_device *pdev)
{ struct mpfs_mbox *mbox; int ret;
mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL); if (!mbox) return -ENOMEM;
ret = mpfs_mbox_syscon_probe(mbox, pdev); if (ret) { /* * set this to null, so it can be used as the decision for to * regmap or not to regmap
*/
mbox->control_scb = NULL;
ret = mpfs_mbox_old_format_probe(mbox, pdev); if (ret) return ret;
}
mbox->irq = platform_get_irq(pdev, 0); if (mbox->irq < 0) return mbox->irq;
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.