aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/sh_mobile_hdmi.c44
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
1439static 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
1450static 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
1472static const struct dev_pm_ops sh_hdmi_pm_ops = {
1473 .suspend = sh_hdmi_suspend,
1474 .resume = sh_hdmi_resume,
1475};
1476
1438static struct platform_driver sh_hdmi_driver = { 1477static 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