mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-26 13:19:26 +07:00
media: meson/ao-cec: move cec_notifier_cec_adap_register after hw setup
When probed after the HDMI notifier, calling cec_notifier_cec_adap_register()
calls the enable() adapter callback, but the HW is not yet set up.
Moving cec_notifier_cec_adap_register() right before cec_register_adapter()
fixes the following crash:
Ignoring spurious kernel translation fault at virtual address 0000000000000008
[...]
Hardware name: Khadas VIM (DT)
[...]
pc : __do_kernel_fault+0xdc/0x120
lr : __do_kernel_fault+0xdc/0x120
[...]
Call trace:
__do_kernel_fault+0xdc/0x120
do_page_fault+0x180/0x458
do_translation_fault+0x64/0x70
do_mem_abort+0x3c/0x98
el1_da+0x20/0x94
meson_ao_cec_adap_enable+0x30/0x218 [ao_cec]
__cec_s_phys_addr+0x184/0x270
cec_s_phys_addr+0x44/0x60
cec_notifier_cec_adap_register+0x68/0x90
meson_ao_cec_probe+0xb0/0x288 [ao_cec]
[...]
el0_svc_compat+0x8/0x10
Reported-by: Christian Hewitt <christianshewitt@gmail.com>
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: 20958f9d5c
("media: meson/ao-cec: use cec_notifier_cec_adap_(un)register")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
54ecb8f702
commit
3e84a18a25
@ -662,34 +662,27 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ao_cec->adap))
|
||||
return PTR_ERR(ao_cec->adap);
|
||||
|
||||
ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
|
||||
ao_cec->adap);
|
||||
if (!ao_cec->notify) {
|
||||
ret = -ENOMEM;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->adap->owner = THIS_MODULE;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base)) {
|
||||
ret = PTR_ERR(base);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
|
||||
&meson_ao_cec_g12a_regmap_conf);
|
||||
if (IS_ERR(ao_cec->regmap)) {
|
||||
ret = PTR_ERR(ao_cec->regmap);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec,
|
||||
&meson_ao_cec_g12a_cec_regmap_conf);
|
||||
if (IS_ERR(ao_cec->regmap_cec)) {
|
||||
ret = PTR_ERR(ao_cec->regmap_cec);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
@ -699,45 +692,52 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
|
||||
0, NULL, ao_cec);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "irq request failed\n");
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin");
|
||||
if (IS_ERR(ao_cec->oscin)) {
|
||||
dev_err(&pdev->dev, "oscin clock request failed\n");
|
||||
ret = PTR_ERR(ao_cec->oscin);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ret = meson_ao_cec_g12a_setup_clk(ao_cec);
|
||||
if (ret)
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
|
||||
ret = clk_prepare_enable(ao_cec->core);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "core clock enable failed\n");
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
device_reset_optional(&pdev->dev);
|
||||
|
||||
platform_set_drvdata(pdev, ao_cec);
|
||||
|
||||
ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
|
||||
ao_cec->adap);
|
||||
if (!ao_cec->notify) {
|
||||
ret = -ENOMEM;
|
||||
goto out_probe_core_clk;
|
||||
}
|
||||
|
||||
ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
|
||||
if (ret < 0)
|
||||
goto out_probe_core_clk;
|
||||
goto out_probe_notify;
|
||||
|
||||
/* Setup Hardware */
|
||||
regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET);
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe_core_clk:
|
||||
clk_disable_unprepare(ao_cec->core);
|
||||
|
||||
out_probe_notify:
|
||||
cec_notifier_cec_adap_unregister(ao_cec->notify);
|
||||
|
||||
out_probe_core_clk:
|
||||
clk_disable_unprepare(ao_cec->core);
|
||||
|
||||
out_probe_adapter:
|
||||
cec_delete_adapter(ao_cec->adap);
|
||||
|
||||
|
@ -624,20 +624,13 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ao_cec->adap))
|
||||
return PTR_ERR(ao_cec->adap);
|
||||
|
||||
ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
|
||||
ao_cec->adap);
|
||||
if (!ao_cec->notify) {
|
||||
ret = -ENOMEM;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->adap->owner = THIS_MODULE;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ao_cec->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(ao_cec->base)) {
|
||||
ret = PTR_ERR(ao_cec->base);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
@ -647,20 +640,20 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
|
||||
0, NULL, ao_cec);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "irq request failed\n");
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ao_cec->core = devm_clk_get(&pdev->dev, "core");
|
||||
if (IS_ERR(ao_cec->core)) {
|
||||
dev_err(&pdev->dev, "core clock request failed\n");
|
||||
ret = PTR_ERR(ao_cec->core);
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(ao_cec->core);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "core clock enable failed\n");
|
||||
goto out_probe_notify;
|
||||
goto out_probe_adapter;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
|
||||
@ -674,9 +667,16 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
|
||||
ao_cec->pdev = pdev;
|
||||
platform_set_drvdata(pdev, ao_cec);
|
||||
|
||||
ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
|
||||
ao_cec->adap);
|
||||
if (!ao_cec->notify) {
|
||||
ret = -ENOMEM;
|
||||
goto out_probe_clk;
|
||||
}
|
||||
|
||||
ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
|
||||
if (ret < 0)
|
||||
goto out_probe_clk;
|
||||
goto out_probe_notify;
|
||||
|
||||
/* Setup Hardware */
|
||||
writel_relaxed(CEC_GEN_CNTL_RESET,
|
||||
@ -684,12 +684,12 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe_clk:
|
||||
clk_disable_unprepare(ao_cec->core);
|
||||
|
||||
out_probe_notify:
|
||||
cec_notifier_cec_adap_unregister(ao_cec->notify);
|
||||
|
||||
out_probe_clk:
|
||||
clk_disable_unprepare(ao_cec->core);
|
||||
|
||||
out_probe_adapter:
|
||||
cec_delete_adapter(ao_cec->adap);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user