diff options
author | David Brownell <david-b@pacbell.net> | 2007-07-17 07:04:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 13:23:04 -0400 |
commit | dccd573bb02aa011a4a7146c02c409ac0bd722a0 (patch) | |
tree | 743eeca4fbbea8272ca4f341b806d776e404d704 /drivers/spi/spi_imx.c | |
parent | ff294cba8a62fa8334b88692da6d48683900f015 (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/spi_imx.c')
-rw-r--r-- | drivers/spi/spi_imx.c | 24 |
1 files changed, 9 insertions, 15 deletions
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); |