aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/exynos
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2012-11-08 23:55:08 -0500
committerJingoo Han <jg1.han@samsung.com>2012-11-28 20:33:28 -0500
commit784fa9a10b684b452ff01531c1b5eafd7215564d (patch)
tree99fb4de2ac9d8b38709731153ff049676cf49e4f /drivers/video/exynos
parent2c95a81032065b6f4efa4be2a9e193feb23f2435 (diff)
video: exynos_dp: Move hotplug into a workqueue
Move the hotplug related code from probe and resume into a workqueue. This allows us to initialize the DP driver (and resume it) when there is no monitor connected. Signed-off-by: Sean Paul <seanpaul@chromium.org> Reviewed-by: Olof Johansson <olofj@chromium.org> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Diffstat (limited to 'drivers/video/exynos')
-rw-r--r--drivers/video/exynos/exynos_dp_core.c94
-rw-r--r--drivers/video/exynos/exynos_dp_core.h1
2 files changed, 51 insertions, 44 deletions
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 119f272deeda..617ba9568f0c 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -838,6 +838,45 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
838 return IRQ_HANDLED; 838 return IRQ_HANDLED;
839} 839}
840 840
841static void exynos_dp_hotplug(struct work_struct *work)
842{
843 struct exynos_dp_device *dp;
844 int ret;
845
846 dp = container_of(work, struct exynos_dp_device, hotplug_work);
847
848 ret = exynos_dp_detect_hpd(dp);
849 if (ret) {
850 dev_err(dp->dev, "unable to detect hpd\n");
851 return;
852 }
853
854 ret = exynos_dp_handle_edid(dp);
855 if (ret) {
856 dev_err(dp->dev, "unable to handle edid\n");
857 return;
858 }
859
860 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
861 dp->video_info->link_rate);
862 if (ret) {
863 dev_err(dp->dev, "unable to do link train\n");
864 return;
865 }
866
867 exynos_dp_enable_scramble(dp, 1);
868 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
869 exynos_dp_enable_enhanced_mode(dp, 1);
870
871 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
872 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
873
874 exynos_dp_init_video(dp);
875 ret = exynos_dp_config_video(dp, dp->video_info);
876 if (ret)
877 dev_err(dp->dev, "unable to config video\n");
878}
879
841#ifdef CONFIG_OF 880#ifdef CONFIG_OF
842static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) 881static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
843{ 882{
@@ -1032,6 +1071,8 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
1032 return -ENODEV; 1071 return -ENODEV;
1033 } 1072 }
1034 1073
1074 INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
1075
1035 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, 1076 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
1036 "exynos-dp", dp); 1077 "exynos-dp", dp);
1037 if (ret) { 1078 if (ret) {
@@ -1051,36 +1092,8 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
1051 1092
1052 exynos_dp_init_dp(dp); 1093 exynos_dp_init_dp(dp);
1053 1094
1054 ret = exynos_dp_detect_hpd(dp);
1055 if (ret) {
1056 dev_err(&pdev->dev, "unable to detect hpd\n");
1057 return ret;
1058 }
1059
1060 exynos_dp_handle_edid(dp);
1061
1062 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
1063 dp->video_info->link_rate);
1064 if (ret) {
1065 dev_err(&pdev->dev, "unable to do link train\n");
1066 return ret;
1067 }
1068
1069 exynos_dp_enable_scramble(dp, 1);
1070 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
1071 exynos_dp_enable_enhanced_mode(dp, 1);
1072
1073 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
1074 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
1075
1076 exynos_dp_init_video(dp);
1077 ret = exynos_dp_config_video(dp, dp->video_info);
1078 if (ret) {
1079 dev_err(&pdev->dev, "unable to config video\n");
1080 return ret;
1081 }
1082
1083 platform_set_drvdata(pdev, dp); 1095 platform_set_drvdata(pdev, dp);
1096 schedule_work(&dp->hotplug_work);
1084 1097
1085 return 0; 1098 return 0;
1086} 1099}
@@ -1090,6 +1103,9 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
1090 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1103 struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
1091 struct exynos_dp_device *dp = platform_get_drvdata(pdev); 1104 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
1092 1105
1106 if (work_pending(&dp->hotplug_work))
1107 flush_work(&dp->hotplug_work);
1108
1093 if (pdev->dev.of_node) { 1109 if (pdev->dev.of_node) {
1094 if (dp->phy_addr) 1110 if (dp->phy_addr)
1095 exynos_dp_phy_exit(dp); 1111 exynos_dp_phy_exit(dp);
@@ -1100,6 +1116,7 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
1100 1116
1101 clk_disable_unprepare(dp->clock); 1117 clk_disable_unprepare(dp->clock);
1102 1118
1119
1103 return 0; 1120 return 0;
1104} 1121}
1105 1122
@@ -1109,6 +1126,9 @@ static int exynos_dp_suspend(struct device *dev)
1109 struct exynos_dp_platdata *pdata = dev->platform_data; 1126 struct exynos_dp_platdata *pdata = dev->platform_data;
1110 struct exynos_dp_device *dp = dev_get_drvdata(dev); 1127 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1111 1128
1129 if (work_pending(&dp->hotplug_work))
1130 flush_work(&dp->hotplug_work);
1131
1112 if (dev->of_node) { 1132 if (dev->of_node) {
1113 if (dp->phy_addr) 1133 if (dp->phy_addr)
1114 exynos_dp_phy_exit(dp); 1134 exynos_dp_phy_exit(dp);
@@ -1139,21 +1159,7 @@ static int exynos_dp_resume(struct device *dev)
1139 1159
1140 exynos_dp_init_dp(dp); 1160 exynos_dp_init_dp(dp);
1141 1161
1142 exynos_dp_detect_hpd(dp); 1162 schedule_work(&dp->hotplug_work);
1143 exynos_dp_handle_edid(dp);
1144
1145 exynos_dp_set_link_train(dp, dp->video_info->lane_count,
1146 dp->video_info->link_rate);
1147
1148 exynos_dp_enable_scramble(dp, 1);
1149 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
1150 exynos_dp_enable_enhanced_mode(dp, 1);
1151
1152 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
1153 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
1154
1155 exynos_dp_init_video(dp);
1156 exynos_dp_config_video(dp, dp->video_info);
1157 1163
1158 return 0; 1164 return 0;
1159} 1165}
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 6dbeeb2c7bcb..5ef7135039fa 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -34,6 +34,7 @@ struct exynos_dp_device {
34 34
35 struct video_info *video_info; 35 struct video_info *video_info;
36 struct link_train link_train; 36 struct link_train link_train;
37 struct work_struct hotplug_work;
37}; 38};
38 39
39/* exynos_dp_reg.c */ 40/* exynos_dp_reg.c */