diff options
Diffstat (limited to 'drivers/spi/spi-octeon.c')
-rw-r--r-- | drivers/spi/spi-octeon.c | 80 |
1 files changed, 10 insertions, 70 deletions
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index 67249a48b391..c5e2f718eebd 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/io.h> | 14 | #include <linux/io.h> |
16 | #include <linux/of.h> | 15 | #include <linux/of.h> |
17 | 16 | ||
@@ -33,13 +32,6 @@ struct octeon_spi { | |||
33 | u64 cs_enax; | 32 | u64 cs_enax; |
34 | }; | 33 | }; |
35 | 34 | ||
36 | struct octeon_spi_setup { | ||
37 | u32 max_speed_hz; | ||
38 | u8 chip_select; | ||
39 | u8 mode; | ||
40 | u8 bits_per_word; | ||
41 | }; | ||
42 | |||
43 | static void octeon_spi_wait_ready(struct octeon_spi *p) | 35 | static void octeon_spi_wait_ready(struct octeon_spi *p) |
44 | { | 36 | { |
45 | union cvmx_mpi_sts mpi_sts; | 37 | union cvmx_mpi_sts mpi_sts; |
@@ -57,6 +49,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, | |||
57 | struct spi_transfer *xfer, | 49 | struct spi_transfer *xfer, |
58 | bool last_xfer) | 50 | bool last_xfer) |
59 | { | 51 | { |
52 | struct spi_device *spi = msg->spi; | ||
60 | union cvmx_mpi_cfg mpi_cfg; | 53 | union cvmx_mpi_cfg mpi_cfg; |
61 | union cvmx_mpi_tx mpi_tx; | 54 | union cvmx_mpi_tx mpi_tx; |
62 | unsigned int clkdiv; | 55 | unsigned int clkdiv; |
@@ -68,18 +61,11 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, | |||
68 | int len; | 61 | int len; |
69 | int i; | 62 | int i; |
70 | 63 | ||
71 | struct octeon_spi_setup *msg_setup = spi_get_ctldata(msg->spi); | 64 | mode = spi->mode; |
72 | |||
73 | speed_hz = msg_setup->max_speed_hz; | ||
74 | mode = msg_setup->mode; | ||
75 | cpha = mode & SPI_CPHA; | 65 | cpha = mode & SPI_CPHA; |
76 | cpol = mode & SPI_CPOL; | 66 | cpol = mode & SPI_CPOL; |
77 | 67 | ||
78 | if (xfer->speed_hz) | 68 | speed_hz = xfer->speed_hz ? : spi->max_speed_hz; |
79 | speed_hz = xfer->speed_hz; | ||
80 | |||
81 | if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ) | ||
82 | speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; | ||
83 | 69 | ||
84 | clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz); | 70 | clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz); |
85 | 71 | ||
@@ -93,8 +79,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, | |||
93 | mpi_cfg.s.cslate = cpha ? 1 : 0; | 79 | mpi_cfg.s.cslate = cpha ? 1 : 0; |
94 | mpi_cfg.s.enable = 1; | 80 | mpi_cfg.s.enable = 1; |
95 | 81 | ||
96 | if (msg_setup->chip_select < 4) | 82 | if (spi->chip_select < 4) |
97 | p->cs_enax |= 1ull << (12 + msg_setup->chip_select); | 83 | p->cs_enax |= 1ull << (12 + spi->chip_select); |
98 | mpi_cfg.u64 |= p->cs_enax; | 84 | mpi_cfg.u64 |= p->cs_enax; |
99 | 85 | ||
100 | if (mpi_cfg.u64 != p->last_cfg) { | 86 | if (mpi_cfg.u64 != p->last_cfg) { |
@@ -114,7 +100,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, | |||
114 | cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d); | 100 | cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d); |
115 | } | 101 | } |
116 | mpi_tx.u64 = 0; | 102 | mpi_tx.u64 = 0; |
117 | mpi_tx.s.csid = msg_setup->chip_select; | 103 | mpi_tx.s.csid = spi->chip_select; |
118 | mpi_tx.s.leavecs = 1; | 104 | mpi_tx.s.leavecs = 1; |
119 | mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0; | 105 | mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0; |
120 | mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES; | 106 | mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES; |
@@ -139,7 +125,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, | |||
139 | } | 125 | } |
140 | 126 | ||
141 | mpi_tx.u64 = 0; | 127 | mpi_tx.u64 = 0; |
142 | mpi_tx.s.csid = msg_setup->chip_select; | 128 | mpi_tx.s.csid = spi->chip_select; |
143 | if (last_xfer) | 129 | if (last_xfer) |
144 | mpi_tx.s.leavecs = xfer->cs_change; | 130 | mpi_tx.s.leavecs = xfer->cs_change; |
145 | else | 131 | else |
@@ -169,17 +155,9 @@ static int octeon_spi_transfer_one_message(struct spi_master *master, | |||
169 | int status = 0; | 155 | int status = 0; |
170 | struct spi_transfer *xfer; | 156 | struct spi_transfer *xfer; |
171 | 157 | ||
172 | /* | ||
173 | * We better have set the configuration via a call to .setup | ||
174 | * before we get here. | ||
175 | */ | ||
176 | if (spi_get_ctldata(msg->spi) == NULL) { | ||
177 | status = -EINVAL; | ||
178 | goto err; | ||
179 | } | ||
180 | |||
181 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 158 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
182 | bool last_xfer = &xfer->transfer_list == msg->transfers.prev; | 159 | bool last_xfer = list_is_last(&xfer->transfer_list, |
160 | &msg->transfers); | ||
183 | int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer); | 161 | int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer); |
184 | if (r < 0) { | 162 | if (r < 0) { |
185 | status = r; | 163 | status = r; |
@@ -194,41 +172,6 @@ err: | |||
194 | return status; | 172 | return status; |
195 | } | 173 | } |
196 | 174 | ||
197 | static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi) | ||
198 | { | ||
199 | struct octeon_spi_setup *setup = kzalloc(sizeof(*setup), GFP_KERNEL); | ||
200 | if (!setup) | ||
201 | return NULL; | ||
202 | |||
203 | setup->max_speed_hz = spi->max_speed_hz; | ||
204 | setup->chip_select = spi->chip_select; | ||
205 | setup->mode = spi->mode; | ||
206 | setup->bits_per_word = spi->bits_per_word; | ||
207 | return setup; | ||
208 | } | ||
209 | |||
210 | static int octeon_spi_setup(struct spi_device *spi) | ||
211 | { | ||
212 | struct octeon_spi_setup *new_setup; | ||
213 | struct octeon_spi_setup *old_setup = spi_get_ctldata(spi); | ||
214 | |||
215 | new_setup = octeon_spi_new_setup(spi); | ||
216 | if (!new_setup) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | spi_set_ctldata(spi, new_setup); | ||
220 | kfree(old_setup); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static void octeon_spi_cleanup(struct spi_device *spi) | ||
226 | { | ||
227 | struct octeon_spi_setup *old_setup = spi_get_ctldata(spi); | ||
228 | spi_set_ctldata(spi, NULL); | ||
229 | kfree(old_setup); | ||
230 | } | ||
231 | |||
232 | static int octeon_spi_probe(struct platform_device *pdev) | 175 | static int octeon_spi_probe(struct platform_device *pdev) |
233 | { | 176 | { |
234 | struct resource *res_mem; | 177 | struct resource *res_mem; |
@@ -257,8 +200,6 @@ static int octeon_spi_probe(struct platform_device *pdev) | |||
257 | p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start, | 200 | p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start, |
258 | resource_size(res_mem)); | 201 | resource_size(res_mem)); |
259 | 202 | ||
260 | /* Dynamic bus numbering */ | ||
261 | master->bus_num = -1; | ||
262 | master->num_chipselect = 4; | 203 | master->num_chipselect = 4; |
263 | master->mode_bits = SPI_CPHA | | 204 | master->mode_bits = SPI_CPHA | |
264 | SPI_CPOL | | 205 | SPI_CPOL | |
@@ -266,10 +207,9 @@ static int octeon_spi_probe(struct platform_device *pdev) | |||
266 | SPI_LSB_FIRST | | 207 | SPI_LSB_FIRST | |
267 | SPI_3WIRE; | 208 | SPI_3WIRE; |
268 | 209 | ||
269 | master->setup = octeon_spi_setup; | ||
270 | master->cleanup = octeon_spi_cleanup; | ||
271 | master->transfer_one_message = octeon_spi_transfer_one_message; | 210 | master->transfer_one_message = octeon_spi_transfer_one_message; |
272 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 211 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
212 | master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; | ||
273 | 213 | ||
274 | master->dev.of_node = pdev->dev.of_node; | 214 | master->dev.of_node = pdev->dev.of_node; |
275 | err = devm_spi_register_master(&pdev->dev, master); | 215 | err = devm_spi_register_master(&pdev->dev, master); |