aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-07-17 07:04:02 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:04 -0400
commitdccd573bb02aa011a4a7146c02c409ac0bd722a0 (patch)
tree743eeca4fbbea8272ca4f341b806d776e404d704 /drivers/spi
parentff294cba8a62fa8334b88692da6d48683900f015 (diff)
SPI controller drivers: check for unsupported modes
Minor SPI controller driver updates: make the setup() methods reject spi->mode bits they don't support, by masking aginst the inverse of bits they *do* support. This insures against misbehavior later when new mode bits get added. Most controllers can't support SPI_LSB_FIRST; more handle SPI_CS_HIGH. Support for all four SPI clock/transfer modes is routine. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/atmel_spi.c1
-rw-r--r--drivers/spi/au1550_spi.c9
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c9
-rw-r--r--drivers/spi/omap_uwire.c9
-rw-r--r--drivers/spi/pxa2xx_spi.c9
-rw-r--r--drivers/spi/spi_bitbang.c8
-rw-r--r--drivers/spi/spi_imx.c24
-rw-r--r--drivers/spi/spi_mpc83xx.c9
-rw-r--r--drivers/spi/spi_s3c24xx.c8
9 files changed, 65 insertions, 21 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 8b2601de3630..7524a84bdd50 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -350,6 +350,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
350 return ret; 350 return ret;
351} 351}
352 352
353/* the spi->mode bits understood by this driver: */
353#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) 354#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
354 355
355static int atmel_spi_setup(struct spi_device *spi) 356static int atmel_spi_setup(struct spi_device *spi)
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
index ae2b1af0dba4..c47a650183a1 100644
--- a/drivers/spi/au1550_spi.c
+++ b/drivers/spi/au1550_spi.c
@@ -280,6 +280,9 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
280 return 0; 280 return 0;
281} 281}
282 282
283/* the spi->mode bits understood by this driver: */
284#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST)
285
283static int au1550_spi_setup(struct spi_device *spi) 286static int au1550_spi_setup(struct spi_device *spi)
284{ 287{
285 struct au1550_spi *hw = spi_master_get_devdata(spi->master); 288 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
@@ -292,6 +295,12 @@ static int au1550_spi_setup(struct spi_device *spi)
292 return -EINVAL; 295 return -EINVAL;
293 } 296 }
294 297
298 if (spi->mode & ~MODEBITS) {
299 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
300 spi->mode & ~MODEBITS);
301 return -EINVAL;
302 }
303
295 if (spi->max_speed_hz == 0) 304 if (spi->max_speed_hz == 0)
296 spi->max_speed_hz = hw->freq_max; 305 spi->max_speed_hz = hw->freq_max;
297 if (spi->max_speed_hz > hw->freq_max 306 if (spi->max_speed_hz > hw->freq_max
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 11f36bef3057..d2a4b2bdb07b 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -270,6 +270,9 @@ static void mpc52xx_psc_spi_work(struct work_struct *work)
270 spin_unlock_irq(&mps->lock); 270 spin_unlock_irq(&mps->lock);
271} 271}
272 272
273/* the spi->mode bits understood by this driver: */
274#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST)
275
273static int mpc52xx_psc_spi_setup(struct spi_device *spi) 276static int mpc52xx_psc_spi_setup(struct spi_device *spi)
274{ 277{
275 struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); 278 struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
@@ -279,6 +282,12 @@ static int mpc52xx_psc_spi_setup(struct spi_device *spi)
279 if (spi->bits_per_word%8) 282 if (spi->bits_per_word%8)
280 return -EINVAL; 283 return -EINVAL;
281 284
285 if (spi->mode & ~MODEBITS) {
286 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
287 spi->mode & ~MODEBITS);
288 return -EINVAL;
289 }
290
282 if (!cs) { 291 if (!cs) {
283 cs = kzalloc(sizeof *cs, GFP_KERNEL); 292 cs = kzalloc(sizeof *cs, GFP_KERNEL);
284 if (!cs) 293 if (!cs)
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 95183e1df525..d275c615a73e 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -445,10 +445,19 @@ done:
445 return status; 445 return status;
446} 446}
447 447
448/* the spi->mode bits understood by this driver: */
449#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
450
448static int uwire_setup(struct spi_device *spi) 451static int uwire_setup(struct spi_device *spi)
449{ 452{
450 struct uwire_state *ust = spi->controller_state; 453 struct uwire_state *ust = spi->controller_state;
451 454
455 if (spi->mode & ~MODEBITS) {
456 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
457 spi->mode & ~MODEBITS);
458 return -EINVAL;
459 }
460
452 if (ust == NULL) { 461 if (ust == NULL) {
453 ust = kzalloc(sizeof(*ust), GFP_KERNEL); 462 ust = kzalloc(sizeof(*ust), GFP_KERNEL);
454 if (ust == NULL) 463 if (ust == NULL)
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 9f2c887ffa04..e51311b2da0b 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1067,6 +1067,9 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
1067 return 0; 1067 return 0;
1068} 1068}
1069 1069
1070/* the spi->mode bits understood by this driver: */
1071#define MODEBITS (SPI_CPOL | SPI_CPHA)
1072
1070static int setup(struct spi_device *spi) 1073static int setup(struct spi_device *spi)
1071{ 1074{
1072 struct pxa2xx_spi_chip *chip_info = NULL; 1075 struct pxa2xx_spi_chip *chip_info = NULL;
@@ -1093,6 +1096,12 @@ static int setup(struct spi_device *spi)
1093 return -EINVAL; 1096 return -EINVAL;
1094 } 1097 }
1095 1098
1099 if (spi->mode & ~MODEBITS) {
1100 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
1101 spi->mode & ~MODEBITS);
1102 return -EINVAL;
1103 }
1104
1096 /* Only alloc on first setup */ 1105 /* Only alloc on first setup */
1097 chip = spi_get_ctldata(spi); 1106 chip = spi_get_ctldata(spi);
1098 if (!chip) { 1107 if (!chip) {
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 88425e1af4d3..0c85c984ccb4 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -187,12 +187,10 @@ int spi_bitbang_setup(struct spi_device *spi)
187 187
188 bitbang = spi_master_get_devdata(spi->master); 188 bitbang = spi_master_get_devdata(spi->master);
189 189
190 /* REVISIT: some systems will want to support devices using lsb-first 190 /* Bitbangers can support SPI_CS_HIGH, SPI_3WIRE, and so on;
191 * bit encodings on the wire. In pure software that would be trivial, 191 * add those to master->flags, and provide the other support.
192 * just bitbang_txrx_le_cphaX() routines shifting the other way, and
193 * some hardware controllers also have this support.
194 */ 192 */
195 if ((spi->mode & SPI_LSB_FIRST) != 0) 193 if ((spi->mode & ~(SPI_CPOL|SPI_CPHA|bitbang->flags)) != 0)
196 return -EINVAL; 194 return -EINVAL;
197 195
198 if (!cs) { 196 if (!cs) {
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 656be4a5094a..aee9ad6f633c 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1163,6 +1163,9 @@ msg_rejected:
1163 return -EINVAL; 1163 return -EINVAL;
1164} 1164}
1165 1165
1166/* the spi->mode bits understood by this driver: */
1167#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
1168
1166/* On first setup bad values must free chip_data memory since will cause 1169/* On first setup bad values must free chip_data memory since will cause
1167 spi_new_device to fail. Bad value setup from protocol driver are simply not 1170 spi_new_device to fail. Bad value setup from protocol driver are simply not
1168 applied and notified to the calling driver. */ 1171 applied and notified to the calling driver. */
@@ -1174,6 +1177,12 @@ static int setup(struct spi_device *spi)
1174 u32 tmp; 1177 u32 tmp;
1175 int status = 0; 1178 int status = 0;
1176 1179
1180 if (spi->mode & ~MODEBITS) {
1181 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
1182 spi->mode & ~MODEBITS);
1183 return -EINVAL;
1184 }
1185
1177 /* Get controller data */ 1186 /* Get controller data */
1178 chip_info = spi->controller_data; 1187 chip_info = spi->controller_data;
1179 1188
@@ -1245,21 +1254,6 @@ static int setup(struct spi_device *spi)
1245 1254
1246 /* SPI mode */ 1255 /* SPI mode */
1247 tmp = spi->mode; 1256 tmp = spi->mode;
1248 if (tmp & SPI_LSB_FIRST) {
1249 status = -EINVAL;
1250 if (first_setup) {
1251 dev_err(&spi->dev,
1252 "setup - "
1253 "HW doesn't support LSB first transfer\n");
1254 goto err_first_setup;
1255 } else {
1256 dev_err(&spi->dev,
1257 "setup - "
1258 "HW doesn't support LSB first transfer, "
1259 "default to MSB first\n");
1260 spi->mode &= ~SPI_LSB_FIRST;
1261 }
1262 }
1263 if (tmp & SPI_CS_HIGH) { 1257 if (tmp & SPI_CS_HIGH) {
1264 u32_EDIT(chip->control, 1258 u32_EDIT(chip->control,
1265 SPI_CONTROL_SSPOL, SPI_CONTROL_SSPOL_ACT_HIGH); 1259 SPI_CONTROL_SSPOL, SPI_CONTROL_SSPOL_ACT_HIGH);
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index e9798bf7b8c6..9cdbc12278e5 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -232,12 +232,21 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
232 return 0; 232 return 0;
233} 233}
234 234
235/* the spi->mode bits understood by this driver: */
236#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
237
235static int mpc83xx_spi_setup(struct spi_device *spi) 238static int mpc83xx_spi_setup(struct spi_device *spi)
236{ 239{
237 struct spi_bitbang *bitbang; 240 struct spi_bitbang *bitbang;
238 struct mpc83xx_spi *mpc83xx_spi; 241 struct mpc83xx_spi *mpc83xx_spi;
239 int retval; 242 int retval;
240 243
244 if (spi->mode & ~MODEBITS) {
245 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
246 spi->mode & ~MODEBITS);
247 return -EINVAL;
248 }
249
241 if (!spi->max_speed_hz) 250 if (!spi->max_speed_hz)
242 return -EINVAL; 251 return -EINVAL;
243 252
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index d5a710f6e445..7071ff8da63e 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -146,6 +146,9 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi,
146 return 0; 146 return 0;
147} 147}
148 148
149/* the spi->mode bits understood by this driver: */
150#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
151
149static int s3c24xx_spi_setup(struct spi_device *spi) 152static int s3c24xx_spi_setup(struct spi_device *spi)
150{ 153{
151 int ret; 154 int ret;
@@ -153,8 +156,11 @@ static int s3c24xx_spi_setup(struct spi_device *spi)
153 if (!spi->bits_per_word) 156 if (!spi->bits_per_word)
154 spi->bits_per_word = 8; 157 spi->bits_per_word = 8;
155 158
156 if ((spi->mode & SPI_LSB_FIRST) != 0) 159 if (spi->mode & ~MODEBITS) {
160 dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
161 spi->mode & ~MODEBITS);
157 return -EINVAL; 162 return -EINVAL;
163 }
158 164
159 ret = s3c24xx_spi_setupxfer(spi, NULL); 165 ret = s3c24xx_spi_setupxfer(spi, NULL);
160 if (ret < 0) { 166 if (ret < 0) {