diff options
author | Michael Welling <mwelling@ieee.org> | 2015-05-07 19:36:53 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-05-08 07:48:42 -0400 |
commit | b28cb9414db9f8e42ac18c9e360e4e99cda42489 (patch) | |
tree | 6e311df6a477dfac15c93c68fcba3b39b1aa3b9c | |
parent | 7d769802427ef9a91eaf9b5a9a6283e71f2ba9d8 (diff) |
spi: omap2-mcspi: Switch driver to use transfer_one
Switches from transfer_one_message to transfer_one to prepare driver for
use of GPIO chip selects.
Signed-off-by: Michael Welling <mwelling@ieee.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 244 |
1 files changed, 110 insertions, 134 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index d1a5b9fc3eba..3ac06ade23d0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -1052,7 +1052,8 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
1052 | } | 1052 | } |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | 1055 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, |
1056 | struct spi_device *spi, struct spi_transfer *t) | ||
1056 | { | 1057 | { |
1057 | 1058 | ||
1058 | /* We only enable one channel at a time -- the one whose message is | 1059 | /* We only enable one channel at a time -- the one whose message is |
@@ -1062,8 +1063,6 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1062 | * chipselect with the FORCE bit ... CS != channel enable. | 1063 | * chipselect with the FORCE bit ... CS != channel enable. |
1063 | */ | 1064 | */ |
1064 | 1065 | ||
1065 | struct spi_device *spi; | ||
1066 | struct spi_transfer *t = NULL; | ||
1067 | struct spi_master *master; | 1066 | struct spi_master *master; |
1068 | struct omap2_mcspi_dma *mcspi_dma; | 1067 | struct omap2_mcspi_dma *mcspi_dma; |
1069 | int cs_active = 0; | 1068 | int cs_active = 0; |
@@ -1073,7 +1072,6 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1073 | int status = 0; | 1072 | int status = 0; |
1074 | u32 chconf; | 1073 | u32 chconf; |
1075 | 1074 | ||
1076 | spi = m->spi; | ||
1077 | master = spi->master; | 1075 | master = spi->master; |
1078 | mcspi_dma = mcspi->dma_channels + spi->chip_select; | 1076 | mcspi_dma = mcspi->dma_channels + spi->chip_select; |
1079 | cs = spi->controller_state; | 1077 | cs = spi->controller_state; |
@@ -1090,94 +1088,89 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1090 | par_override = 1; | 1088 | par_override = 1; |
1091 | 1089 | ||
1092 | omap2_mcspi_set_enable(spi, 0); | 1090 | omap2_mcspi_set_enable(spi, 0); |
1093 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
1094 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | ||
1095 | status = -EINVAL; | ||
1096 | break; | ||
1097 | } | ||
1098 | if (par_override || | ||
1099 | (t->speed_hz != spi->max_speed_hz) || | ||
1100 | (t->bits_per_word != spi->bits_per_word)) { | ||
1101 | par_override = 1; | ||
1102 | status = omap2_mcspi_setup_transfer(spi, t); | ||
1103 | if (status < 0) | ||
1104 | break; | ||
1105 | if (t->speed_hz == spi->max_speed_hz && | ||
1106 | t->bits_per_word == spi->bits_per_word) | ||
1107 | par_override = 0; | ||
1108 | } | ||
1109 | if (cd && cd->cs_per_word) { | ||
1110 | chconf = mcspi->ctx.modulctrl; | ||
1111 | chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE; | ||
1112 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); | ||
1113 | mcspi->ctx.modulctrl = | ||
1114 | mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); | ||
1115 | } | ||
1116 | 1091 | ||
1092 | if (par_override || | ||
1093 | (t->speed_hz != spi->max_speed_hz) || | ||
1094 | (t->bits_per_word != spi->bits_per_word)) { | ||
1095 | par_override = 1; | ||
1096 | status = omap2_mcspi_setup_transfer(spi, t); | ||
1097 | if (status < 0) | ||
1098 | goto out; | ||
1099 | if (t->speed_hz == spi->max_speed_hz && | ||
1100 | t->bits_per_word == spi->bits_per_word) | ||
1101 | par_override = 0; | ||
1102 | } | ||
1103 | if (cd && cd->cs_per_word) { | ||
1104 | chconf = mcspi->ctx.modulctrl; | ||
1105 | chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE; | ||
1106 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); | ||
1107 | mcspi->ctx.modulctrl = | ||
1108 | mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); | ||
1109 | } | ||
1117 | 1110 | ||
1118 | if (!cs_active) { | 1111 | if (!cs_active) { |
1119 | omap2_mcspi_force_cs(spi, 1); | 1112 | omap2_mcspi_force_cs(spi, 1); |
1120 | cs_active = 1; | 1113 | cs_active = 1; |
1121 | } | 1114 | } |
1122 | |||
1123 | chconf = mcspi_cached_chconf0(spi); | ||
1124 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; | ||
1125 | chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; | ||
1126 | 1115 | ||
1127 | if (t->tx_buf == NULL) | 1116 | chconf = mcspi_cached_chconf0(spi); |
1128 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; | 1117 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; |
1129 | else if (t->rx_buf == NULL) | 1118 | chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; |
1130 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; | 1119 | |
1131 | 1120 | if (t->tx_buf == NULL) | |
1132 | if (cd && cd->turbo_mode && t->tx_buf == NULL) { | 1121 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; |
1133 | /* Turbo mode is for more than one word */ | 1122 | else if (t->rx_buf == NULL) |
1134 | if (t->len > ((cs->word_len + 7) >> 3)) | 1123 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; |
1135 | chconf |= OMAP2_MCSPI_CHCONF_TURBO; | 1124 | |
1136 | } | 1125 | if (cd && cd->turbo_mode && t->tx_buf == NULL) { |
1126 | /* Turbo mode is for more than one word */ | ||
1127 | if (t->len > ((cs->word_len + 7) >> 3)) | ||
1128 | chconf |= OMAP2_MCSPI_CHCONF_TURBO; | ||
1129 | } | ||
1137 | 1130 | ||
1138 | mcspi_write_chconf0(spi, chconf); | 1131 | mcspi_write_chconf0(spi, chconf); |
1139 | 1132 | ||
1140 | if (t->len) { | 1133 | if (t->len) { |
1141 | unsigned count; | 1134 | unsigned count; |
1142 | 1135 | ||
1143 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && | 1136 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && |
1144 | (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)) | 1137 | (t->len >= DMA_MIN_BYTES)) |
1145 | omap2_mcspi_set_fifo(spi, t, 1); | 1138 | omap2_mcspi_set_fifo(spi, t, 1); |
1146 | 1139 | ||
1147 | omap2_mcspi_set_enable(spi, 1); | 1140 | omap2_mcspi_set_enable(spi, 1); |
1148 | 1141 | ||
1149 | /* RX_ONLY mode needs dummy data in TX reg */ | 1142 | /* RX_ONLY mode needs dummy data in TX reg */ |
1150 | if (t->tx_buf == NULL) | 1143 | if (t->tx_buf == NULL) |
1151 | writel_relaxed(0, cs->base | 1144 | writel_relaxed(0, cs->base |
1152 | + OMAP2_MCSPI_TX0); | 1145 | + OMAP2_MCSPI_TX0); |
1153 | 1146 | ||
1154 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && | 1147 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && |
1155 | (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)) | 1148 | (t->len >= DMA_MIN_BYTES)) |
1156 | count = omap2_mcspi_txrx_dma(spi, t); | 1149 | count = omap2_mcspi_txrx_dma(spi, t); |
1157 | else | 1150 | else |
1158 | count = omap2_mcspi_txrx_pio(spi, t); | 1151 | count = omap2_mcspi_txrx_pio(spi, t); |
1159 | m->actual_length += count; | ||
1160 | 1152 | ||
1161 | if (count != t->len) { | 1153 | if (count != t->len) { |
1162 | status = -EIO; | 1154 | status = -EIO; |
1163 | break; | 1155 | goto out; |
1164 | } | ||
1165 | } | 1156 | } |
1157 | } | ||
1166 | 1158 | ||
1167 | if (t->delay_usecs) | 1159 | if (t->delay_usecs) |
1168 | udelay(t->delay_usecs); | 1160 | udelay(t->delay_usecs); |
1169 | 1161 | ||
1170 | /* ignore the "leave it on after last xfer" hint */ | 1162 | /* ignore the "leave it on after last xfer" hint */ |
1171 | if (t->cs_change) { | 1163 | if (t->cs_change) { |
1172 | omap2_mcspi_force_cs(spi, 0); | 1164 | omap2_mcspi_force_cs(spi, 0); |
1173 | cs_active = 0; | 1165 | cs_active = 0; |
1174 | } | 1166 | } |
1175 | 1167 | ||
1176 | omap2_mcspi_set_enable(spi, 0); | 1168 | omap2_mcspi_set_enable(spi, 0); |
1177 | 1169 | ||
1178 | if (mcspi->fifo_depth > 0) | 1170 | if (mcspi->fifo_depth > 0) |
1179 | omap2_mcspi_set_fifo(spi, t, 0); | 1171 | omap2_mcspi_set_fifo(spi, t, 0); |
1180 | } | 1172 | |
1173 | out: | ||
1181 | /* Restore defaults if they were overriden */ | 1174 | /* Restore defaults if they were overriden */ |
1182 | if (par_override) { | 1175 | if (par_override) { |
1183 | par_override = 0; | 1176 | par_override = 0; |
@@ -1200,75 +1193,58 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1200 | if (mcspi->fifo_depth > 0 && t) | 1193 | if (mcspi->fifo_depth > 0 && t) |
1201 | omap2_mcspi_set_fifo(spi, t, 0); | 1194 | omap2_mcspi_set_fifo(spi, t, 0); |
1202 | 1195 | ||
1203 | m->status = status; | 1196 | return status; |
1204 | } | 1197 | } |
1205 | 1198 | ||
1206 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, | 1199 | static int omap2_mcspi_transfer_one(struct spi_master *master, |
1207 | struct spi_message *m) | 1200 | struct spi_device *spi, struct spi_transfer *t) |
1208 | { | 1201 | { |
1209 | struct spi_device *spi; | ||
1210 | struct omap2_mcspi *mcspi; | 1202 | struct omap2_mcspi *mcspi; |
1211 | struct omap2_mcspi_dma *mcspi_dma; | 1203 | struct omap2_mcspi_dma *mcspi_dma; |
1212 | struct spi_transfer *t; | 1204 | const void *tx_buf = t->tx_buf; |
1213 | int status; | 1205 | void *rx_buf = t->rx_buf; |
1206 | unsigned len = t->len; | ||
1214 | 1207 | ||
1215 | spi = m->spi; | ||
1216 | mcspi = spi_master_get_devdata(master); | 1208 | mcspi = spi_master_get_devdata(master); |
1217 | mcspi_dma = mcspi->dma_channels + spi->chip_select; | 1209 | mcspi_dma = mcspi->dma_channels + spi->chip_select; |
1218 | m->actual_length = 0; | ||
1219 | m->status = 0; | ||
1220 | |||
1221 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
1222 | const void *tx_buf = t->tx_buf; | ||
1223 | void *rx_buf = t->rx_buf; | ||
1224 | unsigned len = t->len; | ||
1225 | |||
1226 | if ((len && !(rx_buf || tx_buf))) { | ||
1227 | dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", | ||
1228 | t->speed_hz, | ||
1229 | len, | ||
1230 | tx_buf ? "tx" : "", | ||
1231 | rx_buf ? "rx" : "", | ||
1232 | t->bits_per_word); | ||
1233 | status = -EINVAL; | ||
1234 | goto out; | ||
1235 | } | ||
1236 | 1210 | ||
1237 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) | 1211 | if ((len && !(rx_buf || tx_buf))) { |
1238 | continue; | 1212 | dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", |
1239 | 1213 | t->speed_hz, | |
1240 | if (mcspi_dma->dma_tx && tx_buf != NULL) { | 1214 | len, |
1241 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | 1215 | tx_buf ? "tx" : "", |
1242 | len, DMA_TO_DEVICE); | 1216 | rx_buf ? "rx" : "", |
1243 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | 1217 | t->bits_per_word); |
1244 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | 1218 | return -EINVAL; |
1245 | 'T', len); | 1219 | } |
1246 | status = -EINVAL; | 1220 | |
1247 | goto out; | 1221 | if (len < DMA_MIN_BYTES) |
1248 | } | 1222 | goto skip_dma_map; |
1223 | |||
1224 | if (mcspi_dma->dma_tx && tx_buf != NULL) { | ||
1225 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | ||
1226 | len, DMA_TO_DEVICE); | ||
1227 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | ||
1228 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1229 | 'T', len); | ||
1230 | return -EINVAL; | ||
1249 | } | 1231 | } |
1250 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | 1232 | } |
1251 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, | 1233 | if (mcspi_dma->dma_rx && rx_buf != NULL) { |
1252 | DMA_FROM_DEVICE); | 1234 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, |
1253 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { | 1235 | DMA_FROM_DEVICE); |
1254 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | 1236 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { |
1255 | 'R', len); | 1237 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", |
1256 | if (tx_buf != NULL) | 1238 | 'R', len); |
1257 | dma_unmap_single(mcspi->dev, t->tx_dma, | 1239 | if (tx_buf != NULL) |
1258 | len, DMA_TO_DEVICE); | 1240 | dma_unmap_single(mcspi->dev, t->tx_dma, |
1259 | status = -EINVAL; | 1241 | len, DMA_TO_DEVICE); |
1260 | goto out; | 1242 | return -EINVAL; |
1261 | } | ||
1262 | } | 1243 | } |
1263 | } | 1244 | } |
1264 | 1245 | ||
1265 | omap2_mcspi_work(mcspi, m); | 1246 | skip_dma_map: |
1266 | /* spi_finalize_current_message() changes the status inside the | 1247 | return omap2_mcspi_work_one(mcspi, spi, t); |
1267 | * spi_message, save the status here. */ | ||
1268 | status = m->status; | ||
1269 | out: | ||
1270 | spi_finalize_current_message(master); | ||
1271 | return status; | ||
1272 | } | 1248 | } |
1273 | 1249 | ||
1274 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1250 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
@@ -1347,7 +1323,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
1347 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | 1323 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
1348 | master->setup = omap2_mcspi_setup; | 1324 | master->setup = omap2_mcspi_setup; |
1349 | master->auto_runtime_pm = true; | 1325 | master->auto_runtime_pm = true; |
1350 | master->transfer_one_message = omap2_mcspi_transfer_one_message; | 1326 | master->transfer_one = omap2_mcspi_transfer_one; |
1351 | master->cleanup = omap2_mcspi_cleanup; | 1327 | master->cleanup = omap2_mcspi_cleanup; |
1352 | master->dev.of_node = node; | 1328 | master->dev.of_node = node; |
1353 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; | 1329 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; |