aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@nokia.com>2010-03-03 07:31:45 -0500
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-05-18 07:14:30 -0400
commita3201a0eaed38dd7ece72393a778b4408ec79627 (patch)
treeb7539e0059653e124c56c4829a9a4a8f11789240 /drivers/video/omap2
parentf49a951f8a2dacbbb145b6199297fcc3e493b90f (diff)
OMAP: DSS2: Taal: add mutex to protect panel data
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/displays/panel-taal.c140
1 files changed, 119 insertions, 21 deletions
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 4f3988a41082..1799096a1388 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -31,6 +31,7 @@
31#include <linux/completion.h> 31#include <linux/completion.h>
32#include <linux/workqueue.h> 32#include <linux/workqueue.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/mutex.h>
34 35
35#include <plat/display.h> 36#include <plat/display.h>
36 37
@@ -67,6 +68,8 @@
67static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 68static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
68 69
69struct taal_data { 70struct taal_data {
71 struct mutex lock;
72
70 struct backlight_device *bldev; 73 struct backlight_device *bldev;
71 74
72 unsigned long hw_guard_end; /* next value of jiffies when we can 75 unsigned long hw_guard_end; /* next value of jiffies when we can
@@ -510,6 +513,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
510 } 513 }
511 td->dssdev = dssdev; 514 td->dssdev = dssdev;
512 515
516 mutex_init(&td->lock);
517
513 td->esd_wq = create_singlethread_workqueue("taal_esd"); 518 td->esd_wq = create_singlethread_workqueue("taal_esd");
514 if (td->esd_wq == NULL) { 519 if (td->esd_wq == NULL) {
515 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 520 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
@@ -733,54 +738,96 @@ static void taal_power_off(struct omap_dss_device *dssdev)
733 738
734static int taal_enable(struct omap_dss_device *dssdev) 739static int taal_enable(struct omap_dss_device *dssdev)
735{ 740{
741 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
736 int r; 742 int r;
743
737 dev_dbg(&dssdev->dev, "enable\n"); 744 dev_dbg(&dssdev->dev, "enable\n");
738 745
739 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 746 mutex_lock(&td->lock);
740 return -EINVAL; 747
748 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
749 r = -EINVAL;
750 goto err;
751 }
741 752
742 r = taal_power_on(dssdev); 753 r = taal_power_on(dssdev);
743 if (r) 754 if (r)
744 return r; 755 goto err;
745 756
746 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 757 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
747 758
759 mutex_unlock(&td->lock);
760
761 return 0;
762err:
763 dev_dbg(&dssdev->dev, "enable failed\n");
764 mutex_unlock(&td->lock);
748 return r; 765 return r;
749} 766}
750 767
751static void taal_disable(struct omap_dss_device *dssdev) 768static void taal_disable(struct omap_dss_device *dssdev)
752{ 769{
770 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
771
753 dev_dbg(&dssdev->dev, "disable\n"); 772 dev_dbg(&dssdev->dev, "disable\n");
754 773
774 mutex_lock(&td->lock);
775
755 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 776 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
756 taal_power_off(dssdev); 777 taal_power_off(dssdev);
757 778
758 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 779 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
780
781 mutex_unlock(&td->lock);
759} 782}
760 783
761static int taal_suspend(struct omap_dss_device *dssdev) 784static int taal_suspend(struct omap_dss_device *dssdev)
762{ 785{
786 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
787 int r;
788
763 dev_dbg(&dssdev->dev, "suspend\n"); 789 dev_dbg(&dssdev->dev, "suspend\n");
764 790
765 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 791 mutex_lock(&td->lock);
766 return -EINVAL; 792
793 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
794 r = -EINVAL;
795 goto err;
796 }
767 797
768 taal_power_off(dssdev); 798 taal_power_off(dssdev);
769 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 799 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
770 800
801 mutex_unlock(&td->lock);
802
771 return 0; 803 return 0;
804err:
805 mutex_unlock(&td->lock);
806 return r;
772} 807}
773 808
774static int taal_resume(struct omap_dss_device *dssdev) 809static int taal_resume(struct omap_dss_device *dssdev)
775{ 810{
811 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
776 int r; 812 int r;
813
777 dev_dbg(&dssdev->dev, "resume\n"); 814 dev_dbg(&dssdev->dev, "resume\n");
778 815
779 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) 816 mutex_lock(&td->lock);
780 return -EINVAL; 817
818 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
819 r = -EINVAL;
820 goto err;
821 }
781 822
782 r = taal_power_on(dssdev); 823 r = taal_power_on(dssdev);
783 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 824 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
825
826 mutex_unlock(&td->lock);
827
828 return r;
829err:
830 mutex_unlock(&td->lock);
784 return r; 831 return r;
785} 832}
786 833
@@ -799,6 +846,7 @@ static int taal_update(struct omap_dss_device *dssdev,
799 846
800 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 847 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
801 848
849 mutex_lock(&td->lock);
802 dsi_bus_lock(); 850 dsi_bus_lock();
803 851
804 if (!td->enabled) { 852 if (!td->enabled) {
@@ -820,18 +868,24 @@ static int taal_update(struct omap_dss_device *dssdev,
820 goto err; 868 goto err;
821 869
822 /* note: no bus_unlock here. unlock is in framedone_cb */ 870 /* note: no bus_unlock here. unlock is in framedone_cb */
871 mutex_unlock(&td->lock);
823 return 0; 872 return 0;
824err: 873err:
825 dsi_bus_unlock(); 874 dsi_bus_unlock();
875 mutex_unlock(&td->lock);
826 return r; 876 return r;
827} 877}
828 878
829static int taal_sync(struct omap_dss_device *dssdev) 879static int taal_sync(struct omap_dss_device *dssdev)
830{ 880{
881 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
882
831 dev_dbg(&dssdev->dev, "sync\n"); 883 dev_dbg(&dssdev->dev, "sync\n");
832 884
885 mutex_lock(&td->lock);
833 dsi_bus_lock(); 886 dsi_bus_lock();
834 dsi_bus_unlock(); 887 dsi_bus_unlock();
888 mutex_unlock(&td->lock);
835 889
836 dev_dbg(&dssdev->dev, "sync done\n"); 890 dev_dbg(&dssdev->dev, "sync done\n");
837 891
@@ -861,13 +915,16 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
861 915
862static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) 916static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
863{ 917{
918 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
864 int r; 919 int r;
865 920
921 mutex_lock(&td->lock);
866 dsi_bus_lock(); 922 dsi_bus_lock();
867 923
868 r = _taal_enable_te(dssdev, enable); 924 r = _taal_enable_te(dssdev, enable);
869 925
870 dsi_bus_unlock(); 926 dsi_bus_unlock();
927 mutex_unlock(&td->lock);
871 928
872 return r; 929 return r;
873} 930}
@@ -875,7 +932,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
875static int taal_get_te(struct omap_dss_device *dssdev) 932static int taal_get_te(struct omap_dss_device *dssdev)
876{ 933{
877 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 934 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
878 return td->te_enabled; 935 int r;
936
937 mutex_lock(&td->lock);
938 r = td->te_enabled;
939 mutex_unlock(&td->lock);
940
941 return r;
879} 942}
880 943
881static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) 944static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
@@ -885,6 +948,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
885 948
886 dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 949 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
887 950
951 mutex_lock(&td->lock);
888 dsi_bus_lock(); 952 dsi_bus_lock();
889 953
890 if (td->enabled) { 954 if (td->enabled) {
@@ -896,16 +960,24 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
896 td->rotate = rotate; 960 td->rotate = rotate;
897 961
898 dsi_bus_unlock(); 962 dsi_bus_unlock();
963 mutex_unlock(&td->lock);
899 return 0; 964 return 0;
900err: 965err:
901 dsi_bus_unlock(); 966 dsi_bus_unlock();
967 mutex_unlock(&td->lock);
902 return r; 968 return r;
903} 969}
904 970
905static u8 taal_get_rotate(struct omap_dss_device *dssdev) 971static u8 taal_get_rotate(struct omap_dss_device *dssdev)
906{ 972{
907 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 973 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
908 return td->rotate; 974 int r;
975
976 mutex_lock(&td->lock);
977 r = td->rotate;
978 mutex_unlock(&td->lock);
979
980 return r;
909} 981}
910 982
911static int taal_mirror(struct omap_dss_device *dssdev, bool enable) 983static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
@@ -915,6 +987,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
915 987
916 dev_dbg(&dssdev->dev, "mirror %d\n", enable); 988 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
917 989
990 mutex_lock(&td->lock);
918 dsi_bus_lock(); 991 dsi_bus_lock();
919 if (td->enabled) { 992 if (td->enabled) {
920 r = taal_set_addr_mode(td->rotate, enable); 993 r = taal_set_addr_mode(td->rotate, enable);
@@ -925,23 +998,33 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
925 td->mirror = enable; 998 td->mirror = enable;
926 999
927 dsi_bus_unlock(); 1000 dsi_bus_unlock();
1001 mutex_unlock(&td->lock);
928 return 0; 1002 return 0;
929err: 1003err:
930 dsi_bus_unlock(); 1004 dsi_bus_unlock();
1005 mutex_unlock(&td->lock);
931 return r; 1006 return r;
932} 1007}
933 1008
934static bool taal_get_mirror(struct omap_dss_device *dssdev) 1009static bool taal_get_mirror(struct omap_dss_device *dssdev)
935{ 1010{
936 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1011 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
937 return td->mirror; 1012 int r;
1013
1014 mutex_lock(&td->lock);
1015 r = td->mirror;
1016 mutex_unlock(&td->lock);
1017
1018 return r;
938} 1019}
939 1020
940static int taal_run_test(struct omap_dss_device *dssdev, int test_num) 1021static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
941{ 1022{
1023 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
942 u8 id1, id2, id3; 1024 u8 id1, id2, id3;
943 int r; 1025 int r;
944 1026
1027 mutex_lock(&td->lock);
945 dsi_bus_lock(); 1028 dsi_bus_lock();
946 1029
947 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1030 r = taal_dcs_read_1(DCS_GET_ID1, &id1);
@@ -955,9 +1038,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
955 goto err; 1038 goto err;
956 1039
957 dsi_bus_unlock(); 1040 dsi_bus_unlock();
1041 mutex_unlock(&td->lock);
958 return 0; 1042 return 0;
959err: 1043err:
960 dsi_bus_unlock(); 1044 dsi_bus_unlock();
1045 mutex_unlock(&td->lock);
961 return r; 1046 return r;
962} 1047}
963 1048
@@ -971,12 +1056,16 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
971 unsigned buf_used = 0; 1056 unsigned buf_used = 0;
972 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1057 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
973 1058
974 if (!td->enabled)
975 return -ENODEV;
976
977 if (size < w * h * 3) 1059 if (size < w * h * 3)
978 return -ENOMEM; 1060 return -ENOMEM;
979 1061
1062 mutex_lock(&td->lock);
1063
1064 if (!td->enabled) {
1065 r = -ENODEV;
1066 goto err1;
1067 }
1068
980 size = min(w * h * 3, 1069 size = min(w * h * 3,
981 dssdev->panel.timings.x_res * 1070 dssdev->panel.timings.x_res *
982 dssdev->panel.timings.y_res * 3); 1071 dssdev->panel.timings.y_res * 3);
@@ -995,7 +1084,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
995 1084
996 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1085 r = dsi_vc_set_max_rx_packet_size(TCH, plen);
997 if (r) 1086 if (r)
998 goto err0; 1087 goto err2;
999 1088
1000 while (buf_used < size) { 1089 while (buf_used < size) {
1001 u8 dcs_cmd = first ? 0x2e : 0x3e; 1090 u8 dcs_cmd = first ? 0x2e : 0x3e;
@@ -1006,7 +1095,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1006 1095
1007 if (r < 0) { 1096 if (r < 0) {
1008 dev_err(&dssdev->dev, "read error\n"); 1097 dev_err(&dssdev->dev, "read error\n");
1009 goto err; 1098 goto err3;
1010 } 1099 }
1011 1100
1012 buf_used += r; 1101 buf_used += r;
@@ -1020,16 +1109,18 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1020 dev_err(&dssdev->dev, "signal pending, " 1109 dev_err(&dssdev->dev, "signal pending, "
1021 "aborting memory read\n"); 1110 "aborting memory read\n");
1022 r = -ERESTARTSYS; 1111 r = -ERESTARTSYS;
1023 goto err; 1112 goto err3;
1024 } 1113 }
1025 } 1114 }
1026 1115
1027 r = buf_used; 1116 r = buf_used;
1028 1117
1029err: 1118err3:
1030 dsi_vc_set_max_rx_packet_size(TCH, 1); 1119 dsi_vc_set_max_rx_packet_size(TCH, 1);
1031err0: 1120err2:
1032 dsi_bus_unlock(); 1121 dsi_bus_unlock();
1122err1:
1123 mutex_unlock(&td->lock);
1033 return r; 1124 return r;
1034} 1125}
1035 1126
@@ -1041,8 +1132,12 @@ static void taal_esd_work(struct work_struct *work)
1041 u8 state1, state2; 1132 u8 state1, state2;
1042 int r; 1133 int r;
1043 1134
1044 if (!td->enabled) 1135 mutex_lock(&td->lock);
1136
1137 if (!td->enabled) {
1138 mutex_unlock(&td->lock);
1045 return; 1139 return;
1140 }
1046 1141
1047 dsi_bus_lock(); 1142 dsi_bus_lock();
1048 1143
@@ -1084,16 +1179,19 @@ static void taal_esd_work(struct work_struct *work)
1084 1179
1085 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1180 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
1086 1181
1182 mutex_unlock(&td->lock);
1087 return; 1183 return;
1088err: 1184err:
1089 dev_err(&dssdev->dev, "performing LCD reset\n"); 1185 dev_err(&dssdev->dev, "performing LCD reset\n");
1090 1186
1091 taal_disable(dssdev); 1187 taal_power_off(dssdev);
1092 taal_enable(dssdev); 1188 taal_power_on(dssdev);
1093 1189
1094 dsi_bus_unlock(); 1190 dsi_bus_unlock();
1095 1191
1096 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1192 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
1193
1194 mutex_unlock(&td->lock);
1097} 1195}
1098 1196
1099static int taal_set_update_mode(struct omap_dss_device *dssdev, 1197static int taal_set_update_mode(struct omap_dss_device *dssdev,