/** * imx8_get_registers() - This function is called in case of DSP oops * in order to gather information about the registers, filename and * linenumber and stack. * @sdev: SOF device * @xoops: Stores information about registers. * @panic_info: Stores information about filename and line number. * @stack: Stores the stack dump. * @stack_words: Size of the stack dump.
*/ void imx8_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, struct sof_ipc_panic_info *panic_info,
u32 *stack, size_t stack_words)
{
u32 offset = sdev->dsp_oops_offset;
/* first read registers */
sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
/* then get panic info */ if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
xoops->arch_hdr.totalsize); return;
}
offset += xoops->arch_hdr.totalsize;
sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
/* then get the stack */
offset += sizeof(*panic_info);
sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
}
/** * imx8_dump() - This function is called when a panic message is * received from the firmware. * @sdev: SOF device * @flags: parameter not used but required by ops prototype
*/ void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
{ struct sof_ipc_dsp_oops_xtensa xoops; struct sof_ipc_panic_info panic_info;
u32 stack[IMX8_STACK_DUMP_SIZE];
u32 status;
/* Get information about the panic status from the debug box area. * Compute the trace point based on the status.
*/
sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4);
/* Get information about the registers, the filename and line * number and the stack.
*/
imx8_get_registers(sdev, &xoops, &panic_info, stack,
IMX8_STACK_DUMP_SIZE);
/* Print the information to the console */
sof_print_oops_and_stack(sdev, KERN_ERR, status, status, &xoops,
&panic_info, stack, IMX8_STACK_DUMP_SIZE);
}
EXPORT_SYMBOL(imx8_dump);
if (!pm_runtime_suspended(sdev->dev)) {
ret = imx_common_suspend(sdev); if (ret < 0) {
dev_err(sdev->dev, "failed to common suspend: %d\n", ret); return ret;
}
}
for (i = 0; chip_info->memory[i].name; i++) {
blk_type = imx_region_name_to_blk_type(chip_info->memory[i].name); if (blk_type < 0) return dev_err_probe(sdev->dev, blk_type, "no blk type for region %s\n",
chip_info->memory[i].name);
if (!chip_info->memory[i].reserved) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
chip_info->memory[i].name); if (!res) return dev_err_probe(sdev->dev, -ENODEV, "failed to fetch %s resource\n",
chip_info->memory[i].name);
} else {
ret = of_reserved_mem_region_to_resource_byname(pdev->dev.of_node,
chip_info->memory[i].name,
&_res); if (ret < 0) return dev_err_probe(sdev->dev, ret, "no valid entry for %s\n",
chip_info->memory[i].name);
res = &_res;
}
sdev->bar[blk_type] = devm_ioremap_resource(sdev->dev, res); if (IS_ERR(sdev->bar[blk_type])) return dev_err_probe(sdev->dev,
PTR_ERR(sdev->bar[blk_type]), "failed to ioremap %s region\n",
chip_info->memory[i].name);
}
common = devm_kzalloc(sdev->dev, sizeof(*common), GFP_KERNEL); if (!common) return dev_err_probe(sdev->dev, -ENOMEM, "failed to allocate common data\n");
sdev->pdata->hw_pdata = common;
common->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp",
PLATFORM_DEVID_NONE,
pdev, sizeof(*pdev)); if (IS_ERR(common->ipc_dev)) return dev_err_probe(sdev->dev, PTR_ERR(common->ipc_dev), "failed to create IPC device\n");
if (get_chip_info(sdev)->has_dma_reserved) {
ret = of_reserved_mem_device_init_by_name(sdev->dev,
pdev->dev.of_node, "dma"); if (ret) {
platform_device_unregister(common->ipc_dev);
return dev_err_probe(sdev->dev, ret, "failed to bind DMA region\n");
}
}
/* let the devres API take care of the cleanup */
ret = devm_add_action_or_reset(sdev->dev,
imx_unregister_action,
sdev); if (ret) return dev_err_probe(sdev->dev, ret, "failed to add devm action\n");
common->ipc_handle = dev_get_drvdata(&common->ipc_dev->dev); if (!common->ipc_handle) return dev_err_probe(sdev->dev, -EPROBE_DEFER, "failed to fetch IPC handle\n");
ret = imx_parse_ioremap_memory(sdev); if (ret < 0) return dev_err_probe(sdev->dev, ret, "failed to parse/ioremap memory regions\n");
if (!sdev->dev->pm_domain) {
ret = devm_pm_domain_attach_list(sdev->dev,
&domain_data, &common->pd_list); if (ret < 0) return dev_err_probe(sdev->dev, ret, "failed to attach PDs\n");
}
ret = devm_clk_bulk_get_all(sdev->dev, &common->clks); if (ret < 0) return dev_err_probe(sdev->dev, ret, "failed to fetch clocks\n");
common->clk_num = ret;
ret = clk_bulk_prepare_enable(common->clk_num, common->clks); if (ret < 0) return dev_err_probe(sdev->dev, ret, "failed to enable clocks\n");
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.