diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/sh_mobile_hdmi.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/video/fbdev/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c index 9a33ee0413fb..7c72a3f02056 100644 --- a/drivers/video/fbdev/sh_mobile_hdmi.c +++ b/drivers/video/fbdev/sh_mobile_hdmi.c | |||
@@ -281,6 +281,7 @@ struct sh_hdmi { | |||
281 | u8 edid_block_addr; | 281 | u8 edid_block_addr; |
282 | u8 edid_segment_nr; | 282 | u8 edid_segment_nr; |
283 | u8 edid_blocks; | 283 | u8 edid_blocks; |
284 | int irq; | ||
284 | struct clk *hdmi_clk; | 285 | struct clk *hdmi_clk; |
285 | struct device *dev; | 286 | struct device *dev; |
286 | struct delayed_work edid_work; | 287 | struct delayed_work edid_work; |
@@ -1299,6 +1300,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
1299 | hdmi->dev = &pdev->dev; | 1300 | hdmi->dev = &pdev->dev; |
1300 | hdmi->entity.owner = THIS_MODULE; | 1301 | hdmi->entity.owner = THIS_MODULE; |
1301 | hdmi->entity.ops = &sh_hdmi_ops; | 1302 | hdmi->entity.ops = &sh_hdmi_ops; |
1303 | hdmi->irq = irq; | ||
1302 | 1304 | ||
1303 | hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); | 1305 | hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); |
1304 | if (IS_ERR(hdmi->hdmi_clk)) { | 1306 | if (IS_ERR(hdmi->hdmi_clk)) { |
@@ -1415,12 +1417,11 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev) | |||
1415 | { | 1417 | { |
1416 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); | 1418 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); |
1417 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1419 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1418 | int irq = platform_get_irq(pdev, 0); | ||
1419 | 1420 | ||
1420 | snd_soc_unregister_codec(&pdev->dev); | 1421 | snd_soc_unregister_codec(&pdev->dev); |
1421 | 1422 | ||
1422 | /* No new work will be scheduled, wait for running ISR */ | 1423 | /* No new work will be scheduled, wait for running ISR */ |
1423 | free_irq(irq, hdmi); | 1424 | free_irq(hdmi->irq, hdmi); |
1424 | /* Wait for already scheduled work */ | 1425 | /* Wait for already scheduled work */ |
1425 | cancel_delayed_work_sync(&hdmi->edid_work); | 1426 | cancel_delayed_work_sync(&hdmi->edid_work); |
1426 | pm_runtime_put(&pdev->dev); | 1427 | pm_runtime_put(&pdev->dev); |
@@ -1435,10 +1436,49 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev) | |||
1435 | return 0; | 1436 | return 0; |
1436 | } | 1437 | } |
1437 | 1438 | ||
1439 | static int sh_hdmi_suspend(struct device *dev) | ||
1440 | { | ||
1441 | struct platform_device *pdev = to_platform_device(dev); | ||
1442 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); | ||
1443 | |||
1444 | disable_irq(hdmi->irq); | ||
1445 | /* Wait for already scheduled work */ | ||
1446 | cancel_delayed_work_sync(&hdmi->edid_work); | ||
1447 | return 0; | ||
1448 | } | ||
1449 | |||
1450 | static int sh_hdmi_resume(struct device *dev) | ||
1451 | { | ||
1452 | struct platform_device *pdev = to_platform_device(dev); | ||
1453 | struct sh_mobile_hdmi_info *pdata = dev_get_platdata(dev); | ||
1454 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); | ||
1455 | |||
1456 | /* Re-init interrupt polarity */ | ||
1457 | if (pdata->flags & HDMI_OUTPUT_PUSH_PULL) | ||
1458 | hdmi_bit_set(hdmi, 0x02, 0x02, HDMI_SYSTEM_CTRL); | ||
1459 | |||
1460 | if (pdata->flags & HDMI_OUTPUT_POLARITY_HI) | ||
1461 | hdmi_bit_set(hdmi, 0x01, 0x01, HDMI_SYSTEM_CTRL); | ||
1462 | |||
1463 | /* Re-init htop1 */ | ||
1464 | if (hdmi->htop1) | ||
1465 | sh_hdmi_htop1_init(hdmi); | ||
1466 | |||
1467 | /* Now it's safe to enable interrupts again */ | ||
1468 | enable_irq(hdmi->irq); | ||
1469 | return 0; | ||
1470 | } | ||
1471 | |||
1472 | static const struct dev_pm_ops sh_hdmi_pm_ops = { | ||
1473 | .suspend = sh_hdmi_suspend, | ||
1474 | .resume = sh_hdmi_resume, | ||
1475 | }; | ||
1476 | |||
1438 | static struct platform_driver sh_hdmi_driver = { | 1477 | static struct platform_driver sh_hdmi_driver = { |
1439 | .remove = __exit_p(sh_hdmi_remove), | 1478 | .remove = __exit_p(sh_hdmi_remove), |
1440 | .driver = { | 1479 | .driver = { |
1441 | .name = "sh-mobile-hdmi", | 1480 | .name = "sh-mobile-hdmi", |
1481 | .pm = &sh_hdmi_pm_ops, | ||
1442 | }, | 1482 | }, |
1443 | }; | 1483 | }; |
1444 | 1484 | ||