diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-24 16:22:33 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-24 16:22:33 -0400 |
commit | baea7b946f00a291b166ccae7fcfed6c01530cc6 (patch) | |
tree | 4aa275fbdbec9c7b9b4629e8bee2bbecd3c6a6af /drivers/spi/omap2_mcspi.c | |
parent | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (diff) | |
parent | 94e0fb086fc5663c38bbc0fe86d698be8314f82f (diff) |
Merge branch 'origin' into for-linus
Conflicts:
MAINTAINERS
Diffstat (limited to 'drivers/spi/omap2_mcspi.c')
-rw-r--r-- | drivers/spi/omap2_mcspi.c | 210 |
1 files changed, 147 insertions, 63 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 9b80ad36dbba..ba1a872b221e 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -41,6 +41,9 @@ | |||
41 | 41 | ||
42 | #define OMAP2_MCSPI_MAX_FREQ 48000000 | 42 | #define OMAP2_MCSPI_MAX_FREQ 48000000 |
43 | 43 | ||
44 | /* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */ | ||
45 | #define OMAP2_MCSPI_MAX_CTRL 4 | ||
46 | |||
44 | #define OMAP2_MCSPI_REVISION 0x00 | 47 | #define OMAP2_MCSPI_REVISION 0x00 |
45 | #define OMAP2_MCSPI_SYSCONFIG 0x10 | 48 | #define OMAP2_MCSPI_SYSCONFIG 0x10 |
46 | #define OMAP2_MCSPI_SYSSTATUS 0x14 | 49 | #define OMAP2_MCSPI_SYSSTATUS 0x14 |
@@ -59,40 +62,40 @@ | |||
59 | 62 | ||
60 | /* per-register bitmasks: */ | 63 | /* per-register bitmasks: */ |
61 | 64 | ||
62 | #define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) | 65 | #define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE BIT(4) |
63 | #define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP (1 << 2) | 66 | #define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) |
64 | #define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0) | 67 | #define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) |
65 | #define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1) | 68 | #define OMAP2_MCSPI_SYSCONFIG_SOFTRESET BIT(1) |
66 | 69 | ||
67 | #define OMAP2_MCSPI_SYSSTATUS_RESETDONE (1 << 0) | 70 | #define OMAP2_MCSPI_SYSSTATUS_RESETDONE BIT(0) |
68 | 71 | ||
69 | #define OMAP2_MCSPI_MODULCTRL_SINGLE (1 << 0) | 72 | #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) |
70 | #define OMAP2_MCSPI_MODULCTRL_MS (1 << 2) | 73 | #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) |
71 | #define OMAP2_MCSPI_MODULCTRL_STEST (1 << 3) | 74 | #define OMAP2_MCSPI_MODULCTRL_STEST BIT(3) |
72 | 75 | ||
73 | #define OMAP2_MCSPI_CHCONF_PHA (1 << 0) | 76 | #define OMAP2_MCSPI_CHCONF_PHA BIT(0) |
74 | #define OMAP2_MCSPI_CHCONF_POL (1 << 1) | 77 | #define OMAP2_MCSPI_CHCONF_POL BIT(1) |
75 | #define OMAP2_MCSPI_CHCONF_CLKD_MASK (0x0f << 2) | 78 | #define OMAP2_MCSPI_CHCONF_CLKD_MASK (0x0f << 2) |
76 | #define OMAP2_MCSPI_CHCONF_EPOL (1 << 6) | 79 | #define OMAP2_MCSPI_CHCONF_EPOL BIT(6) |
77 | #define OMAP2_MCSPI_CHCONF_WL_MASK (0x1f << 7) | 80 | #define OMAP2_MCSPI_CHCONF_WL_MASK (0x1f << 7) |
78 | #define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY (0x01 << 12) | 81 | #define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY BIT(12) |
79 | #define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY (0x02 << 12) | 82 | #define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY BIT(13) |
80 | #define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12) | 83 | #define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12) |
81 | #define OMAP2_MCSPI_CHCONF_DMAW (1 << 14) | 84 | #define OMAP2_MCSPI_CHCONF_DMAW BIT(14) |
82 | #define OMAP2_MCSPI_CHCONF_DMAR (1 << 15) | 85 | #define OMAP2_MCSPI_CHCONF_DMAR BIT(15) |
83 | #define OMAP2_MCSPI_CHCONF_DPE0 (1 << 16) | 86 | #define OMAP2_MCSPI_CHCONF_DPE0 BIT(16) |
84 | #define OMAP2_MCSPI_CHCONF_DPE1 (1 << 17) | 87 | #define OMAP2_MCSPI_CHCONF_DPE1 BIT(17) |
85 | #define OMAP2_MCSPI_CHCONF_IS (1 << 18) | 88 | #define OMAP2_MCSPI_CHCONF_IS BIT(18) |
86 | #define OMAP2_MCSPI_CHCONF_TURBO (1 << 19) | 89 | #define OMAP2_MCSPI_CHCONF_TURBO BIT(19) |
87 | #define OMAP2_MCSPI_CHCONF_FORCE (1 << 20) | 90 | #define OMAP2_MCSPI_CHCONF_FORCE BIT(20) |
88 | 91 | ||
89 | #define OMAP2_MCSPI_CHSTAT_RXS (1 << 0) | 92 | #define OMAP2_MCSPI_CHSTAT_RXS BIT(0) |
90 | #define OMAP2_MCSPI_CHSTAT_TXS (1 << 1) | 93 | #define OMAP2_MCSPI_CHSTAT_TXS BIT(1) |
91 | #define OMAP2_MCSPI_CHSTAT_EOT (1 << 2) | 94 | #define OMAP2_MCSPI_CHSTAT_EOT BIT(2) |
92 | 95 | ||
93 | #define OMAP2_MCSPI_CHCTRL_EN (1 << 0) | 96 | #define OMAP2_MCSPI_CHCTRL_EN BIT(0) |
94 | 97 | ||
95 | #define OMAP2_MCSPI_WAKEUPENABLE_WKEN (1 << 0) | 98 | #define OMAP2_MCSPI_WAKEUPENABLE_WKEN BIT(0) |
96 | 99 | ||
97 | /* We have 2 DMA channels per CS, one for RX and one for TX */ | 100 | /* We have 2 DMA channels per CS, one for RX and one for TX */ |
98 | struct omap2_mcspi_dma { | 101 | struct omap2_mcspi_dma { |
@@ -131,8 +134,23 @@ struct omap2_mcspi_cs { | |||
131 | void __iomem *base; | 134 | void __iomem *base; |
132 | unsigned long phys; | 135 | unsigned long phys; |
133 | int word_len; | 136 | int word_len; |
137 | struct list_head node; | ||
138 | /* Context save and restore shadow register */ | ||
139 | u32 chconf0; | ||
140 | }; | ||
141 | |||
142 | /* used for context save and restore, structure members to be updated whenever | ||
143 | * corresponding registers are modified. | ||
144 | */ | ||
145 | struct omap2_mcspi_regs { | ||
146 | u32 sysconfig; | ||
147 | u32 modulctrl; | ||
148 | u32 wakeupenable; | ||
149 | struct list_head cs; | ||
134 | }; | 150 | }; |
135 | 151 | ||
152 | static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; | ||
153 | |||
136 | static struct workqueue_struct *omap2_mcspi_wq; | 154 | static struct workqueue_struct *omap2_mcspi_wq; |
137 | 155 | ||
138 | #define MOD_REG_BIT(val, mask, set) do { \ | 156 | #define MOD_REG_BIT(val, mask, set) do { \ |
@@ -172,12 +190,27 @@ static inline u32 mcspi_read_cs_reg(const struct spi_device *spi, int idx) | |||
172 | return __raw_readl(cs->base + idx); | 190 | return __raw_readl(cs->base + idx); |
173 | } | 191 | } |
174 | 192 | ||
193 | static inline u32 mcspi_cached_chconf0(const struct spi_device *spi) | ||
194 | { | ||
195 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
196 | |||
197 | return cs->chconf0; | ||
198 | } | ||
199 | |||
200 | static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val) | ||
201 | { | ||
202 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
203 | |||
204 | cs->chconf0 = val; | ||
205 | mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val); | ||
206 | } | ||
207 | |||
175 | static void omap2_mcspi_set_dma_req(const struct spi_device *spi, | 208 | static void omap2_mcspi_set_dma_req(const struct spi_device *spi, |
176 | int is_read, int enable) | 209 | int is_read, int enable) |
177 | { | 210 | { |
178 | u32 l, rw; | 211 | u32 l, rw; |
179 | 212 | ||
180 | l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); | 213 | l = mcspi_cached_chconf0(spi); |
181 | 214 | ||
182 | if (is_read) /* 1 is read, 0 write */ | 215 | if (is_read) /* 1 is read, 0 write */ |
183 | rw = OMAP2_MCSPI_CHCONF_DMAR; | 216 | rw = OMAP2_MCSPI_CHCONF_DMAR; |
@@ -185,7 +218,7 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi, | |||
185 | rw = OMAP2_MCSPI_CHCONF_DMAW; | 218 | rw = OMAP2_MCSPI_CHCONF_DMAW; |
186 | 219 | ||
187 | MOD_REG_BIT(l, rw, enable); | 220 | MOD_REG_BIT(l, rw, enable); |
188 | mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); | 221 | mcspi_write_chconf0(spi, l); |
189 | } | 222 | } |
190 | 223 | ||
191 | static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) | 224 | static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) |
@@ -200,9 +233,9 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active) | |||
200 | { | 233 | { |
201 | u32 l; | 234 | u32 l; |
202 | 235 | ||
203 | l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); | 236 | l = mcspi_cached_chconf0(spi); |
204 | MOD_REG_BIT(l, OMAP2_MCSPI_CHCONF_FORCE, cs_active); | 237 | MOD_REG_BIT(l, OMAP2_MCSPI_CHCONF_FORCE, cs_active); |
205 | mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); | 238 | mcspi_write_chconf0(spi, l); |
206 | } | 239 | } |
207 | 240 | ||
208 | static void omap2_mcspi_set_master_mode(struct spi_master *master) | 241 | static void omap2_mcspi_set_master_mode(struct spi_master *master) |
@@ -217,6 +250,46 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master) | |||
217 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0); | 250 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0); |
218 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); | 251 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); |
219 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); | 252 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); |
253 | |||
254 | omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l; | ||
255 | } | ||
256 | |||
257 | static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | ||
258 | { | ||
259 | struct spi_master *spi_cntrl; | ||
260 | struct omap2_mcspi_cs *cs; | ||
261 | spi_cntrl = mcspi->master; | ||
262 | |||
263 | /* McSPI: context restore */ | ||
264 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, | ||
265 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); | ||
266 | |||
267 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG, | ||
268 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig); | ||
269 | |||
270 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, | ||
271 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); | ||
272 | |||
273 | list_for_each_entry(cs, &omap2_mcspi_ctx[spi_cntrl->bus_num - 1].cs, | ||
274 | node) | ||
275 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | ||
276 | } | ||
277 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) | ||
278 | { | ||
279 | clk_disable(mcspi->ick); | ||
280 | clk_disable(mcspi->fck); | ||
281 | } | ||
282 | |||
283 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | ||
284 | { | ||
285 | if (clk_enable(mcspi->ick)) | ||
286 | return -ENODEV; | ||
287 | if (clk_enable(mcspi->fck)) | ||
288 | return -ENODEV; | ||
289 | |||
290 | omap2_mcspi_restore_ctx(mcspi); | ||
291 | |||
292 | return 0; | ||
220 | } | 293 | } |
221 | 294 | ||
222 | static unsigned | 295 | static unsigned |
@@ -357,7 +430,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
357 | c = count; | 430 | c = count; |
358 | word_len = cs->word_len; | 431 | word_len = cs->word_len; |
359 | 432 | ||
360 | l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); | 433 | l = mcspi_cached_chconf0(spi); |
361 | l &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; | 434 | l &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; |
362 | 435 | ||
363 | /* We store the pre-calculated register addresses on stack to speed | 436 | /* We store the pre-calculated register addresses on stack to speed |
@@ -397,8 +470,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
397 | * more word i/o: switch to rx+tx | 470 | * more word i/o: switch to rx+tx |
398 | */ | 471 | */ |
399 | if (c == 0 && tx == NULL) | 472 | if (c == 0 && tx == NULL) |
400 | mcspi_write_cs_reg(spi, | 473 | mcspi_write_chconf0(spi, l); |
401 | OMAP2_MCSPI_CHCONF0, l); | ||
402 | *rx++ = __raw_readl(rx_reg); | 474 | *rx++ = __raw_readl(rx_reg); |
403 | #ifdef VERBOSE | 475 | #ifdef VERBOSE |
404 | dev_dbg(&spi->dev, "read-%d %02x\n", | 476 | dev_dbg(&spi->dev, "read-%d %02x\n", |
@@ -436,8 +508,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
436 | * more word i/o: switch to rx+tx | 508 | * more word i/o: switch to rx+tx |
437 | */ | 509 | */ |
438 | if (c == 0 && tx == NULL) | 510 | if (c == 0 && tx == NULL) |
439 | mcspi_write_cs_reg(spi, | 511 | mcspi_write_chconf0(spi, l); |
440 | OMAP2_MCSPI_CHCONF0, l); | ||
441 | *rx++ = __raw_readl(rx_reg); | 512 | *rx++ = __raw_readl(rx_reg); |
442 | #ifdef VERBOSE | 513 | #ifdef VERBOSE |
443 | dev_dbg(&spi->dev, "read-%d %04x\n", | 514 | dev_dbg(&spi->dev, "read-%d %04x\n", |
@@ -475,8 +546,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
475 | * more word i/o: switch to rx+tx | 546 | * more word i/o: switch to rx+tx |
476 | */ | 547 | */ |
477 | if (c == 0 && tx == NULL) | 548 | if (c == 0 && tx == NULL) |
478 | mcspi_write_cs_reg(spi, | 549 | mcspi_write_chconf0(spi, l); |
479 | OMAP2_MCSPI_CHCONF0, l); | ||
480 | *rx++ = __raw_readl(rx_reg); | 550 | *rx++ = __raw_readl(rx_reg); |
481 | #ifdef VERBOSE | 551 | #ifdef VERBOSE |
482 | dev_dbg(&spi->dev, "read-%d %04x\n", | 552 | dev_dbg(&spi->dev, "read-%d %04x\n", |
@@ -505,10 +575,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
505 | { | 575 | { |
506 | struct omap2_mcspi_cs *cs = spi->controller_state; | 576 | struct omap2_mcspi_cs *cs = spi->controller_state; |
507 | struct omap2_mcspi *mcspi; | 577 | struct omap2_mcspi *mcspi; |
578 | struct spi_master *spi_cntrl; | ||
508 | u32 l = 0, div = 0; | 579 | u32 l = 0, div = 0; |
509 | u8 word_len = spi->bits_per_word; | 580 | u8 word_len = spi->bits_per_word; |
510 | 581 | ||
511 | mcspi = spi_master_get_devdata(spi->master); | 582 | mcspi = spi_master_get_devdata(spi->master); |
583 | spi_cntrl = mcspi->master; | ||
512 | 584 | ||
513 | if (t != NULL && t->bits_per_word) | 585 | if (t != NULL && t->bits_per_word) |
514 | word_len = t->bits_per_word; | 586 | word_len = t->bits_per_word; |
@@ -522,7 +594,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
522 | } else | 594 | } else |
523 | div = 15; | 595 | div = 15; |
524 | 596 | ||
525 | l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); | 597 | l = mcspi_cached_chconf0(spi); |
526 | 598 | ||
527 | /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS | 599 | /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS |
528 | * REVISIT: this controller could support SPI_3WIRE mode. | 600 | * REVISIT: this controller could support SPI_3WIRE mode. |
@@ -554,7 +626,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
554 | else | 626 | else |
555 | l &= ~OMAP2_MCSPI_CHCONF_PHA; | 627 | l &= ~OMAP2_MCSPI_CHCONF_PHA; |
556 | 628 | ||
557 | mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); | 629 | mcspi_write_chconf0(spi, l); |
558 | 630 | ||
559 | dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", | 631 | dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", |
560 | OMAP2_MCSPI_MAX_FREQ / (1 << div), | 632 | OMAP2_MCSPI_MAX_FREQ / (1 << div), |
@@ -647,7 +719,11 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
647 | return -ENOMEM; | 719 | return -ENOMEM; |
648 | cs->base = mcspi->base + spi->chip_select * 0x14; | 720 | cs->base = mcspi->base + spi->chip_select * 0x14; |
649 | cs->phys = mcspi->phys + spi->chip_select * 0x14; | 721 | cs->phys = mcspi->phys + spi->chip_select * 0x14; |
722 | cs->chconf0 = 0; | ||
650 | spi->controller_state = cs; | 723 | spi->controller_state = cs; |
724 | /* Link this to context save list */ | ||
725 | list_add_tail(&cs->node, | ||
726 | &omap2_mcspi_ctx[mcspi->master->bus_num - 1].cs); | ||
651 | } | 727 | } |
652 | 728 | ||
653 | if (mcspi_dma->dma_rx_channel == -1 | 729 | if (mcspi_dma->dma_rx_channel == -1 |
@@ -657,11 +733,11 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
657 | return ret; | 733 | return ret; |
658 | } | 734 | } |
659 | 735 | ||
660 | clk_enable(mcspi->ick); | 736 | if (omap2_mcspi_enable_clocks(mcspi)) |
661 | clk_enable(mcspi->fck); | 737 | return -ENODEV; |
738 | |||
662 | ret = omap2_mcspi_setup_transfer(spi, NULL); | 739 | ret = omap2_mcspi_setup_transfer(spi, NULL); |
663 | clk_disable(mcspi->fck); | 740 | omap2_mcspi_disable_clocks(mcspi); |
664 | clk_disable(mcspi->ick); | ||
665 | 741 | ||
666 | return ret; | 742 | return ret; |
667 | } | 743 | } |
@@ -670,10 +746,15 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
670 | { | 746 | { |
671 | struct omap2_mcspi *mcspi; | 747 | struct omap2_mcspi *mcspi; |
672 | struct omap2_mcspi_dma *mcspi_dma; | 748 | struct omap2_mcspi_dma *mcspi_dma; |
749 | struct omap2_mcspi_cs *cs; | ||
673 | 750 | ||
674 | mcspi = spi_master_get_devdata(spi->master); | 751 | mcspi = spi_master_get_devdata(spi->master); |
675 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 752 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
676 | 753 | ||
754 | /* Unlink controller state from context save list */ | ||
755 | cs = spi->controller_state; | ||
756 | list_del(&cs->node); | ||
757 | |||
677 | kfree(spi->controller_state); | 758 | kfree(spi->controller_state); |
678 | 759 | ||
679 | if (mcspi_dma->dma_rx_channel != -1) { | 760 | if (mcspi_dma->dma_rx_channel != -1) { |
@@ -693,8 +774,8 @@ static void omap2_mcspi_work(struct work_struct *work) | |||
693 | mcspi = container_of(work, struct omap2_mcspi, work); | 774 | mcspi = container_of(work, struct omap2_mcspi, work); |
694 | spin_lock_irq(&mcspi->lock); | 775 | spin_lock_irq(&mcspi->lock); |
695 | 776 | ||
696 | clk_enable(mcspi->ick); | 777 | if (omap2_mcspi_enable_clocks(mcspi)) |
697 | clk_enable(mcspi->fck); | 778 | goto out; |
698 | 779 | ||
699 | /* We only enable one channel at a time -- the one whose message is | 780 | /* We only enable one channel at a time -- the one whose message is |
700 | * at the head of the queue -- although this controller would gladly | 781 | * at the head of the queue -- although this controller would gladly |
@@ -741,13 +822,13 @@ static void omap2_mcspi_work(struct work_struct *work) | |||
741 | cs_active = 1; | 822 | cs_active = 1; |
742 | } | 823 | } |
743 | 824 | ||
744 | chconf = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); | 825 | chconf = mcspi_cached_chconf0(spi); |
745 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; | 826 | chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; |
746 | if (t->tx_buf == NULL) | 827 | if (t->tx_buf == NULL) |
747 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; | 828 | chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; |
748 | else if (t->rx_buf == NULL) | 829 | else if (t->rx_buf == NULL) |
749 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; | 830 | chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; |
750 | mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, chconf); | 831 | mcspi_write_chconf0(spi, chconf); |
751 | 832 | ||
752 | if (t->len) { | 833 | if (t->len) { |
753 | unsigned count; | 834 | unsigned count; |
@@ -796,9 +877,9 @@ static void omap2_mcspi_work(struct work_struct *work) | |||
796 | spin_lock_irq(&mcspi->lock); | 877 | spin_lock_irq(&mcspi->lock); |
797 | } | 878 | } |
798 | 879 | ||
799 | clk_disable(mcspi->fck); | 880 | omap2_mcspi_disable_clocks(mcspi); |
800 | clk_disable(mcspi->ick); | ||
801 | 881 | ||
882 | out: | ||
802 | spin_unlock_irq(&mcspi->lock); | 883 | spin_unlock_irq(&mcspi->lock); |
803 | } | 884 | } |
804 | 885 | ||
@@ -885,8 +966,8 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) | |||
885 | struct spi_master *master = mcspi->master; | 966 | struct spi_master *master = mcspi->master; |
886 | u32 tmp; | 967 | u32 tmp; |
887 | 968 | ||
888 | clk_enable(mcspi->ick); | 969 | if (omap2_mcspi_enable_clocks(mcspi)) |
889 | clk_enable(mcspi->fck); | 970 | return -1; |
890 | 971 | ||
891 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, | 972 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, |
892 | OMAP2_MCSPI_SYSCONFIG_SOFTRESET); | 973 | OMAP2_MCSPI_SYSCONFIG_SOFTRESET); |
@@ -894,18 +975,18 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) | |||
894 | tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS); | 975 | tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS); |
895 | } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); | 976 | } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); |
896 | 977 | ||
897 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, | 978 | tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | |
898 | OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | | 979 | OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | |
899 | OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | | 980 | OMAP2_MCSPI_SYSCONFIG_SMARTIDLE; |
900 | OMAP2_MCSPI_SYSCONFIG_SMARTIDLE); | 981 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp); |
982 | omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp; | ||
901 | 983 | ||
902 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, | 984 | tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; |
903 | OMAP2_MCSPI_WAKEUPENABLE_WKEN); | 985 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); |
986 | omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp; | ||
904 | 987 | ||
905 | omap2_mcspi_set_master_mode(master); | 988 | omap2_mcspi_set_master_mode(master); |
906 | 989 | omap2_mcspi_disable_clocks(mcspi); | |
907 | clk_disable(mcspi->fck); | ||
908 | clk_disable(mcspi->ick); | ||
909 | return 0; | 990 | return 0; |
910 | } | 991 | } |
911 | 992 | ||
@@ -933,7 +1014,8 @@ static u8 __initdata spi2_txdma_id[] = { | |||
933 | OMAP24XX_DMA_SPI2_TX1, | 1014 | OMAP24XX_DMA_SPI2_TX1, |
934 | }; | 1015 | }; |
935 | 1016 | ||
936 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) | 1017 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) \ |
1018 | || defined(CONFIG_ARCH_OMAP4) | ||
937 | static u8 __initdata spi3_rxdma_id[] = { | 1019 | static u8 __initdata spi3_rxdma_id[] = { |
938 | OMAP24XX_DMA_SPI3_RX0, | 1020 | OMAP24XX_DMA_SPI3_RX0, |
939 | OMAP24XX_DMA_SPI3_RX1, | 1021 | OMAP24XX_DMA_SPI3_RX1, |
@@ -945,7 +1027,7 @@ static u8 __initdata spi3_txdma_id[] = { | |||
945 | }; | 1027 | }; |
946 | #endif | 1028 | #endif |
947 | 1029 | ||
948 | #ifdef CONFIG_ARCH_OMAP3 | 1030 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
949 | static u8 __initdata spi4_rxdma_id[] = { | 1031 | static u8 __initdata spi4_rxdma_id[] = { |
950 | OMAP34XX_DMA_SPI4_RX0, | 1032 | OMAP34XX_DMA_SPI4_RX0, |
951 | }; | 1033 | }; |
@@ -975,14 +1057,15 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
975 | txdma_id = spi2_txdma_id; | 1057 | txdma_id = spi2_txdma_id; |
976 | num_chipselect = 2; | 1058 | num_chipselect = 2; |
977 | break; | 1059 | break; |
978 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 1060 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ |
1061 | || defined(CONFIG_ARCH_OMAP4) | ||
979 | case 3: | 1062 | case 3: |
980 | rxdma_id = spi3_rxdma_id; | 1063 | rxdma_id = spi3_rxdma_id; |
981 | txdma_id = spi3_txdma_id; | 1064 | txdma_id = spi3_txdma_id; |
982 | num_chipselect = 2; | 1065 | num_chipselect = 2; |
983 | break; | 1066 | break; |
984 | #endif | 1067 | #endif |
985 | #ifdef CONFIG_ARCH_OMAP3 | 1068 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
986 | case 4: | 1069 | case 4: |
987 | rxdma_id = spi4_rxdma_id; | 1070 | rxdma_id = spi4_rxdma_id; |
988 | txdma_id = spi4_txdma_id; | 1071 | txdma_id = spi4_txdma_id; |
@@ -1038,6 +1121,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1038 | 1121 | ||
1039 | spin_lock_init(&mcspi->lock); | 1122 | spin_lock_init(&mcspi->lock); |
1040 | INIT_LIST_HEAD(&mcspi->msg_queue); | 1123 | INIT_LIST_HEAD(&mcspi->msg_queue); |
1124 | INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); | ||
1041 | 1125 | ||
1042 | mcspi->ick = clk_get(&pdev->dev, "ick"); | 1126 | mcspi->ick = clk_get(&pdev->dev, "ick"); |
1043 | if (IS_ERR(mcspi->ick)) { | 1127 | if (IS_ERR(mcspi->ick)) { |