Skip to content

Commit 779b8d2

Browse files
AngeloGioacchino Del RegnoChun-Kuang Hu
authored andcommitted
drm/mediatek: dp: Enable event interrupt only when bridge attached
It is useless and error-prone to enable the DisplayPort event interrupt before finishing to probe and install the driver, as the DP training cannot happen before the entire pipeline is correctly set up, as the interrupt handler also requires the full hardware to be initialized by mtk_dp_bridge_attach(). Anyway, depending in which state the controller is left from the bootloader, this may cause an interrupt storm and consequently hang the kernel during boot, so, avoid enabling the interrupt until we reach a clean state by adding the IRQ_NOAUTOEN flag before requesting it at probe time and manage the enablement of the ISR in the .attach() and .detach() handlers for the DP bridge. Signed-off-by: AngeloGioacchino Del Regno <[email protected]> Tested-by: Chen-Yu Tsai <[email protected]> Reviewed-by: Alexandre Mergnat <[email protected]> Reviewed-by: CK Hu <[email protected]> Link: https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ Signed-off-by: Chun-Kuang Hu <[email protected]>
1 parent c3b9d21 commit 779b8d2

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

drivers/gpu/drm/mediatek/mtk_dp.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct mtk_dp_efuse_fmt {
100100
struct mtk_dp {
101101
bool enabled;
102102
bool need_debounce;
103+
int irq;
103104
u8 max_lanes;
104105
u8 max_linkrate;
105106
u8 rx_cap[DP_RECEIVER_CAP_SIZE];
@@ -2141,6 +2142,8 @@ static int mtk_dp_bridge_attach(struct drm_bridge *bridge,
21412142

21422143
mtk_dp->drm_dev = bridge->dev;
21432144

2145+
irq_clear_status_flags(mtk_dp->irq, IRQ_NOAUTOEN);
2146+
enable_irq(mtk_dp->irq);
21442147
mtk_dp_hwirq_enable(mtk_dp, true);
21452148

21462149
return 0;
@@ -2157,6 +2160,7 @@ static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
21572160
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
21582161

21592162
mtk_dp_hwirq_enable(mtk_dp, false);
2163+
disable_irq(mtk_dp->irq);
21602164
mtk_dp->drm_dev = NULL;
21612165
mtk_dp_poweroff(mtk_dp);
21622166
drm_dp_aux_unregister(&mtk_dp->aux);
@@ -2475,7 +2479,7 @@ static int mtk_dp_probe(struct platform_device *pdev)
24752479
{
24762480
struct mtk_dp *mtk_dp;
24772481
struct device *dev = &pdev->dev;
2478-
int ret, irq_num;
2482+
int ret;
24792483

24802484
mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
24812485
if (!mtk_dp)
@@ -2484,9 +2488,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
24842488
mtk_dp->dev = dev;
24852489
mtk_dp->data = (struct mtk_dp_data *)of_device_get_match_data(dev);
24862490

2487-
irq_num = platform_get_irq(pdev, 0);
2488-
if (irq_num < 0)
2489-
return dev_err_probe(dev, irq_num,
2491+
mtk_dp->irq = platform_get_irq(pdev, 0);
2492+
if (mtk_dp->irq < 0)
2493+
return dev_err_probe(dev, mtk_dp->irq,
24902494
"failed to request dp irq resource\n");
24912495

24922496
mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
@@ -2507,7 +2511,8 @@ static int mtk_dp_probe(struct platform_device *pdev)
25072511

25082512
spin_lock_init(&mtk_dp->irq_thread_lock);
25092513

2510-
ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
2514+
irq_set_status_flags(mtk_dp->irq, IRQ_NOAUTOEN);
2515+
ret = devm_request_threaded_irq(dev, mtk_dp->irq, mtk_dp_hpd_event,
25112516
mtk_dp_hpd_event_thread,
25122517
IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
25132518
mtk_dp);

0 commit comments

Comments
 (0)