aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2008-10-09 00:52:23 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-10-09 01:01:21 -0400
commite8f462d202026d8e99f553ed5a09422321226ac9 (patch)
treee5351b7855cf9ec60120468e36381af286277aa1
parent2d517cab01075610a615ebda0a1c16ba3fb081ae (diff)
Input: ads7846 - fix cache line sharing issue
We had a report a while back that the ads7846 driver had some issues when used with DMA-based SPI controllers (like atmel_spi) on systems where main memory is not DMA-coherent (most non-x86 boards). Allocate memory potentially used for DMA separately to avoid cache line issues. Reported-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/touchscreen/ads7846.c87
1 files changed, 51 insertions, 36 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 6020a7dcce33..b9b7fc6ff1eb 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -69,6 +69,17 @@ struct ts_event {
69 int ignore; 69 int ignore;
70}; 70};
71 71
72/*
73 * We allocate this separately to avoid cache line sharing issues when
74 * driver is used with DMA-based SPI controllers (like atmel_spi) on
75 * systems where main memory is not DMA-coherent (most non-x86 boards).
76 */
77struct ads7846_packet {
78 u8 read_x, read_y, read_z1, read_z2, pwrdown;
79 u16 dummy; /* for the pwrdown read */
80 struct ts_event tc;
81};
82
72struct ads7846 { 83struct ads7846 {
73 struct input_dev *input; 84 struct input_dev *input;
74 char phys[32]; 85 char phys[32];
@@ -86,9 +97,7 @@ struct ads7846 {
86 u16 x_plate_ohms; 97 u16 x_plate_ohms;
87 u16 pressure_max; 98 u16 pressure_max;
88 99
89 u8 read_x, read_y, read_z1, read_z2, pwrdown; 100 struct ads7846_packet *packet;
90 u16 dummy; /* for the pwrdown read */
91 struct ts_event tc;
92 101
93 struct spi_transfer xfer[18]; 102 struct spi_transfer xfer[18];
94 struct spi_message msg[5]; 103 struct spi_message msg[5];
@@ -513,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
513static void ads7846_rx(void *ads) 522static void ads7846_rx(void *ads)
514{ 523{
515 struct ads7846 *ts = ads; 524 struct ads7846 *ts = ads;
525 struct ads7846_packet *packet = ts->packet;
516 unsigned Rt; 526 unsigned Rt;
517 u16 x, y, z1, z2; 527 u16 x, y, z1, z2;
518 528
519 /* ads7846_rx_val() did in-place conversion (including byteswap) from 529 /* ads7846_rx_val() did in-place conversion (including byteswap) from
520 * on-the-wire format as part of debouncing to get stable readings. 530 * on-the-wire format as part of debouncing to get stable readings.
521 */ 531 */
522 x = ts->tc.x; 532 x = packet->tc.x;
523 y = ts->tc.y; 533 y = packet->tc.y;
524 z1 = ts->tc.z1; 534 z1 = packet->tc.z1;
525 z2 = ts->tc.z2; 535 z2 = packet->tc.z2;
526 536
527 /* range filtering */ 537 /* range filtering */
528 if (x == MAX_12BIT) 538 if (x == MAX_12BIT)
@@ -546,10 +556,10 @@ static void ads7846_rx(void *ads)
546 * the maximum. Don't report it to user space, repeat at least 556 * the maximum. Don't report it to user space, repeat at least
547 * once more the measurement 557 * once more the measurement
548 */ 558 */
549 if (ts->tc.ignore || Rt > ts->pressure_max) { 559 if (packet->tc.ignore || Rt > ts->pressure_max) {
550#ifdef VERBOSE 560#ifdef VERBOSE
551 pr_debug("%s: ignored %d pressure %d\n", 561 pr_debug("%s: ignored %d pressure %d\n",
552 ts->spi->dev.bus_id, ts->tc.ignore, Rt); 562 ts->spi->dev.bus_id, packet->tc.ignore, Rt);
553#endif 563#endif
554 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 564 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
555 HRTIMER_MODE_REL); 565 HRTIMER_MODE_REL);
@@ -642,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
642static void ads7846_rx_val(void *ads) 652static void ads7846_rx_val(void *ads)
643{ 653{
644 struct ads7846 *ts = ads; 654 struct ads7846 *ts = ads;
655 struct ads7846_packet *packet = ts->packet;
645 struct spi_message *m; 656 struct spi_message *m;
646 struct spi_transfer *t; 657 struct spi_transfer *t;
647 int val; 658 int val;
@@ -661,7 +672,7 @@ static void ads7846_rx_val(void *ads)
661 case ADS7846_FILTER_REPEAT: 672 case ADS7846_FILTER_REPEAT:
662 break; 673 break;
663 case ADS7846_FILTER_IGNORE: 674 case ADS7846_FILTER_IGNORE:
664 ts->tc.ignore = 1; 675 packet->tc.ignore = 1;
665 /* Last message will contain ads7846_rx() as the 676 /* Last message will contain ads7846_rx() as the
666 * completion function. 677 * completion function.
667 */ 678 */
@@ -669,7 +680,7 @@ static void ads7846_rx_val(void *ads)
669 break; 680 break;
670 case ADS7846_FILTER_OK: 681 case ADS7846_FILTER_OK:
671 *(u16 *)t->rx_buf = val; 682 *(u16 *)t->rx_buf = val;
672 ts->tc.ignore = 0; 683 packet->tc.ignore = 0;
673 m = &ts->msg[++ts->msg_idx]; 684 m = &ts->msg[++ts->msg_idx];
674 break; 685 break;
675 default: 686 default:
@@ -774,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
774 /* we know the chip's in lowpower mode since we always 785 /* we know the chip's in lowpower mode since we always
775 * leave it that way after every request 786 * leave it that way after every request
776 */ 787 */
777
778} 788}
779 789
780/* Must be called with ts->lock held */ 790/* Must be called with ts->lock held */
@@ -850,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
850static int __devinit ads7846_probe(struct spi_device *spi) 860static int __devinit ads7846_probe(struct spi_device *spi)
851{ 861{
852 struct ads7846 *ts; 862 struct ads7846 *ts;
863 struct ads7846_packet *packet;
853 struct input_dev *input_dev; 864 struct input_dev *input_dev;
854 struct ads7846_platform_data *pdata = spi->dev.platform_data; 865 struct ads7846_platform_data *pdata = spi->dev.platform_data;
855 struct spi_message *m; 866 struct spi_message *m;
@@ -885,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
885 return err; 896 return err;
886 897
887 ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); 898 ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
899 packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
888 input_dev = input_allocate_device(); 900 input_dev = input_allocate_device();
889 if (!ts || !input_dev) { 901 if (!ts || !packet || !input_dev) {
890 err = -ENOMEM; 902 err = -ENOMEM;
891 goto err_free_mem; 903 goto err_free_mem;
892 } 904 }
893 905
894 dev_set_drvdata(&spi->dev, ts); 906 dev_set_drvdata(&spi->dev, ts);
895 907
908 ts->packet = packet;
896 ts->spi = spi; 909 ts->spi = spi;
897 ts->input = input_dev; 910 ts->input = input_dev;
898 ts->vref_mv = pdata->vref_mv; 911 ts->vref_mv = pdata->vref_mv;
@@ -964,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
964 spi_message_init(m); 977 spi_message_init(m);
965 978
966 /* y- still on; turn on only y+ (and ADC) */ 979 /* y- still on; turn on only y+ (and ADC) */
967 ts->read_y = READ_Y(vref); 980 packet->read_y = READ_Y(vref);
968 x->tx_buf = &ts->read_y; 981 x->tx_buf = &packet->read_y;
969 x->len = 1; 982 x->len = 1;
970 spi_message_add_tail(x, m); 983 spi_message_add_tail(x, m);
971 984
972 x++; 985 x++;
973 x->rx_buf = &ts->tc.y; 986 x->rx_buf = &packet->tc.y;
974 x->len = 2; 987 x->len = 2;
975 spi_message_add_tail(x, m); 988 spi_message_add_tail(x, m);
976 989
@@ -982,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
982 x->delay_usecs = pdata->settle_delay_usecs; 995 x->delay_usecs = pdata->settle_delay_usecs;
983 996
984 x++; 997 x++;
985 x->tx_buf = &ts->read_y; 998 x->tx_buf = &packet->read_y;
986 x->len = 1; 999 x->len = 1;
987 spi_message_add_tail(x, m); 1000 spi_message_add_tail(x, m);
988 1001
989 x++; 1002 x++;
990 x->rx_buf = &ts->tc.y; 1003 x->rx_buf = &packet->tc.y;
991 x->len = 2; 1004 x->len = 2;
992 spi_message_add_tail(x, m); 1005 spi_message_add_tail(x, m);
993 } 1006 }
@@ -1000,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1000 1013
1001 /* turn y- off, x+ on, then leave in lowpower */ 1014 /* turn y- off, x+ on, then leave in lowpower */
1002 x++; 1015 x++;
1003 ts->read_x = READ_X(vref); 1016 packet->read_x = READ_X(vref);
1004 x->tx_buf = &ts->read_x; 1017 x->tx_buf = &packet->read_x;
1005 x->len = 1; 1018 x->len = 1;
1006 spi_message_add_tail(x, m); 1019 spi_message_add_tail(x, m);
1007 1020
1008 x++; 1021 x++;
1009 x->rx_buf = &ts->tc.x; 1022 x->rx_buf = &packet->tc.x;
1010 x->len = 2; 1023 x->len = 2;
1011 spi_message_add_tail(x, m); 1024 spi_message_add_tail(x, m);
1012 1025
@@ -1015,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1015 x->delay_usecs = pdata->settle_delay_usecs; 1028 x->delay_usecs = pdata->settle_delay_usecs;
1016 1029
1017 x++; 1030 x++;
1018 x->tx_buf = &ts->read_x; 1031 x->tx_buf = &packet->read_x;
1019 x->len = 1; 1032 x->len = 1;
1020 spi_message_add_tail(x, m); 1033 spi_message_add_tail(x, m);
1021 1034
1022 x++; 1035 x++;
1023 x->rx_buf = &ts->tc.x; 1036 x->rx_buf = &packet->tc.x;
1024 x->len = 2; 1037 x->len = 2;
1025 spi_message_add_tail(x, m); 1038 spi_message_add_tail(x, m);
1026 } 1039 }
@@ -1034,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1034 spi_message_init(m); 1047 spi_message_init(m);
1035 1048
1036 x++; 1049 x++;
1037 ts->read_z1 = READ_Z1(vref); 1050 packet->read_z1 = READ_Z1(vref);
1038 x->tx_buf = &ts->read_z1; 1051 x->tx_buf = &packet->read_z1;
1039 x->len = 1; 1052 x->len = 1;
1040 spi_message_add_tail(x, m); 1053 spi_message_add_tail(x, m);
1041 1054
1042 x++; 1055 x++;
1043 x->rx_buf = &ts->tc.z1; 1056 x->rx_buf = &packet->tc.z1;
1044 x->len = 2; 1057 x->len = 2;
1045 spi_message_add_tail(x, m); 1058 spi_message_add_tail(x, m);
1046 1059
@@ -1049,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1049 x->delay_usecs = pdata->settle_delay_usecs; 1062 x->delay_usecs = pdata->settle_delay_usecs;
1050 1063
1051 x++; 1064 x++;
1052 x->tx_buf = &ts->read_z1; 1065 x->tx_buf = &packet->read_z1;
1053 x->len = 1; 1066 x->len = 1;
1054 spi_message_add_tail(x, m); 1067 spi_message_add_tail(x, m);
1055 1068
1056 x++; 1069 x++;
1057 x->rx_buf = &ts->tc.z1; 1070 x->rx_buf = &packet->tc.z1;
1058 x->len = 2; 1071 x->len = 2;
1059 spi_message_add_tail(x, m); 1072 spi_message_add_tail(x, m);
1060 } 1073 }
@@ -1066,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1066 spi_message_init(m); 1079 spi_message_init(m);
1067 1080
1068 x++; 1081 x++;
1069 ts->read_z2 = READ_Z2(vref); 1082 packet->read_z2 = READ_Z2(vref);
1070 x->tx_buf = &ts->read_z2; 1083 x->tx_buf = &packet->read_z2;
1071 x->len = 1; 1084 x->len = 1;
1072 spi_message_add_tail(x, m); 1085 spi_message_add_tail(x, m);
1073 1086
1074 x++; 1087 x++;
1075 x->rx_buf = &ts->tc.z2; 1088 x->rx_buf = &packet->tc.z2;
1076 x->len = 2; 1089 x->len = 2;
1077 spi_message_add_tail(x, m); 1090 spi_message_add_tail(x, m);
1078 1091
@@ -1081,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1081 x->delay_usecs = pdata->settle_delay_usecs; 1094 x->delay_usecs = pdata->settle_delay_usecs;
1082 1095
1083 x++; 1096 x++;
1084 x->tx_buf = &ts->read_z2; 1097 x->tx_buf = &packet->read_z2;
1085 x->len = 1; 1098 x->len = 1;
1086 spi_message_add_tail(x, m); 1099 spi_message_add_tail(x, m);
1087 1100
1088 x++; 1101 x++;
1089 x->rx_buf = &ts->tc.z2; 1102 x->rx_buf = &packet->tc.z2;
1090 x->len = 2; 1103 x->len = 2;
1091 spi_message_add_tail(x, m); 1104 spi_message_add_tail(x, m);
1092 } 1105 }
@@ -1100,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1100 spi_message_init(m); 1113 spi_message_init(m);
1101 1114
1102 x++; 1115 x++;
1103 ts->pwrdown = PWRDOWN; 1116 packet->pwrdown = PWRDOWN;
1104 x->tx_buf = &ts->pwrdown; 1117 x->tx_buf = &packet->pwrdown;
1105 x->len = 1; 1118 x->len = 1;
1106 spi_message_add_tail(x, m); 1119 spi_message_add_tail(x, m);
1107 1120
1108 x++; 1121 x++;
1109 x->rx_buf = &ts->dummy; 1122 x->rx_buf = &packet->dummy;
1110 x->len = 2; 1123 x->len = 2;
1111 CS_CHANGE(*x); 1124 CS_CHANGE(*x);
1112 spi_message_add_tail(x, m); 1125 spi_message_add_tail(x, m);
@@ -1159,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1159 ts->filter_cleanup(ts->filter_data); 1172 ts->filter_cleanup(ts->filter_data);
1160 err_free_mem: 1173 err_free_mem:
1161 input_free_device(input_dev); 1174 input_free_device(input_dev);
1175 kfree(packet);
1162 kfree(ts); 1176 kfree(ts);
1163 return err; 1177 return err;
1164} 1178}
@@ -1184,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
1184 if (ts->filter_cleanup) 1198 if (ts->filter_cleanup)
1185 ts->filter_cleanup(ts->filter_data); 1199 ts->filter_cleanup(ts->filter_data);
1186 1200
1201 kfree(ts->packet);
1187 kfree(ts); 1202 kfree(ts);
1188 1203
1189 dev_dbg(&spi->dev, "unregistered touchscreen\n"); 1204 dev_dbg(&spi->dev, "unregistered touchscreen\n");