diff options
-rw-r--r-- | arch/mips/bcm63xx/dev-spi.c | 42 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 44 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/spi/spi-bcm53xx.c | 13 | ||||
-rw-r--r-- | drivers/spi/spi-bcm63xx.c | 210 | ||||
-rw-r--r-- | drivers/spi/spi-bfin-sport.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-bfin5xx.c | 6 | ||||
-rw-r--r-- | drivers/spi/spi-bitbang.c | 152 | ||||
-rw-r--r-- | drivers/spi/spi-ppc4xx.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-s3c24xx.c | 4 | ||||
-rw-r--r-- | include/linux/spi/spi_bitbang.h | 2 |
11 files changed, 240 insertions, 244 deletions
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index ad448e41e3bd..232385441e46 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c | |||
@@ -18,29 +18,6 @@ | |||
18 | #include <bcm63xx_dev_spi.h> | 18 | #include <bcm63xx_dev_spi.h> |
19 | #include <bcm63xx_regs.h> | 19 | #include <bcm63xx_regs.h> |
20 | 20 | ||
21 | /* | ||
22 | * register offsets | ||
23 | */ | ||
24 | static const unsigned long bcm6348_regs_spi[] = { | ||
25 | __GEN_SPI_REGS_TABLE(6348) | ||
26 | }; | ||
27 | |||
28 | static const unsigned long bcm6358_regs_spi[] = { | ||
29 | __GEN_SPI_REGS_TABLE(6358) | ||
30 | }; | ||
31 | |||
32 | const unsigned long *bcm63xx_regs_spi; | ||
33 | EXPORT_SYMBOL(bcm63xx_regs_spi); | ||
34 | |||
35 | static __init void bcm63xx_spi_regs_init(void) | ||
36 | { | ||
37 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) | ||
38 | bcm63xx_regs_spi = bcm6348_regs_spi; | ||
39 | if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || | ||
40 | BCMCPU_IS_6362() || BCMCPU_IS_6368()) | ||
41 | bcm63xx_regs_spi = bcm6358_regs_spi; | ||
42 | } | ||
43 | |||
44 | static struct resource spi_resources[] = { | 21 | static struct resource spi_resources[] = { |
45 | { | 22 | { |
46 | .start = -1, /* filled at runtime */ | 23 | .start = -1, /* filled at runtime */ |
@@ -53,19 +30,10 @@ static struct resource spi_resources[] = { | |||
53 | }, | 30 | }, |
54 | }; | 31 | }; |
55 | 32 | ||
56 | static struct bcm63xx_spi_pdata spi_pdata = { | ||
57 | .bus_num = 0, | ||
58 | .num_chipselect = 8, | ||
59 | }; | ||
60 | |||
61 | static struct platform_device bcm63xx_spi_device = { | 33 | static struct platform_device bcm63xx_spi_device = { |
62 | .name = "bcm63xx-spi", | ||
63 | .id = -1, | 34 | .id = -1, |
64 | .num_resources = ARRAY_SIZE(spi_resources), | 35 | .num_resources = ARRAY_SIZE(spi_resources), |
65 | .resource = spi_resources, | 36 | .resource = spi_resources, |
66 | .dev = { | ||
67 | .platform_data = &spi_pdata, | ||
68 | }, | ||
69 | }; | 37 | }; |
70 | 38 | ||
71 | int __init bcm63xx_spi_register(void) | 39 | int __init bcm63xx_spi_register(void) |
@@ -78,21 +46,15 @@ int __init bcm63xx_spi_register(void) | |||
78 | spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); | 46 | spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); |
79 | 47 | ||
80 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | 48 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { |
49 | bcm63xx_spi_device.name = "bcm6348-spi", | ||
81 | spi_resources[0].end += BCM_6348_RSET_SPI_SIZE - 1; | 50 | spi_resources[0].end += BCM_6348_RSET_SPI_SIZE - 1; |
82 | spi_pdata.fifo_size = SPI_6348_MSG_DATA_SIZE; | ||
83 | spi_pdata.msg_type_shift = SPI_6348_MSG_TYPE_SHIFT; | ||
84 | spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH; | ||
85 | } | 51 | } |
86 | 52 | ||
87 | if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() || | 53 | if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() || |
88 | BCMCPU_IS_6368()) { | 54 | BCMCPU_IS_6368()) { |
55 | bcm63xx_spi_device.name = "bcm6358-spi", | ||
89 | spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; | 56 | spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; |
90 | spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; | ||
91 | spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; | ||
92 | spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH; | ||
93 | } | 57 | } |
94 | 58 | ||
95 | bcm63xx_spi_regs_init(); | ||
96 | |||
97 | return platform_device_register(&bcm63xx_spi_device); | 59 | return platform_device_register(&bcm63xx_spi_device); |
98 | } | 60 | } |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 25737655d141..dd299548860d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | |||
@@ -7,48 +7,4 @@ | |||
7 | 7 | ||
8 | int __init bcm63xx_spi_register(void); | 8 | int __init bcm63xx_spi_register(void); |
9 | 9 | ||
10 | struct bcm63xx_spi_pdata { | ||
11 | unsigned int fifo_size; | ||
12 | unsigned int msg_type_shift; | ||
13 | unsigned int msg_ctl_width; | ||
14 | int bus_num; | ||
15 | int num_chipselect; | ||
16 | }; | ||
17 | |||
18 | enum bcm63xx_regs_spi { | ||
19 | SPI_CMD, | ||
20 | SPI_INT_STATUS, | ||
21 | SPI_INT_MASK_ST, | ||
22 | SPI_INT_MASK, | ||
23 | SPI_ST, | ||
24 | SPI_CLK_CFG, | ||
25 | SPI_FILL_BYTE, | ||
26 | SPI_MSG_TAIL, | ||
27 | SPI_RX_TAIL, | ||
28 | SPI_MSG_CTL, | ||
29 | SPI_MSG_DATA, | ||
30 | SPI_RX_DATA, | ||
31 | }; | ||
32 | |||
33 | #define __GEN_SPI_REGS_TABLE(__cpu) \ | ||
34 | [SPI_CMD] = SPI_## __cpu ##_CMD, \ | ||
35 | [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ | ||
36 | [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \ | ||
37 | [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \ | ||
38 | [SPI_ST] = SPI_## __cpu ##_ST, \ | ||
39 | [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \ | ||
40 | [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \ | ||
41 | [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \ | ||
42 | [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ | ||
43 | [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ | ||
44 | [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ | ||
45 | [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, | ||
46 | |||
47 | static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) | ||
48 | { | ||
49 | extern const unsigned long *bcm63xx_regs_spi; | ||
50 | |||
51 | return bcm63xx_regs_spi[reg]; | ||
52 | } | ||
53 | |||
54 | #endif /* BCM63XX_DEV_SPI_H */ | 10 | #endif /* BCM63XX_DEV_SPI_H */ |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 26b860534fa7..cac92245e3ef 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -136,7 +136,7 @@ config SPI_BCM53XX | |||
136 | 136 | ||
137 | config SPI_BCM63XX | 137 | config SPI_BCM63XX |
138 | tristate "Broadcom BCM63xx SPI controller" | 138 | tristate "Broadcom BCM63xx SPI controller" |
139 | depends on BCM63XX | 139 | depends on BCM63XX || COMPILE_TEST |
140 | help | 140 | help |
141 | Enable support for the SPI controller on the Broadcom BCM63xx SoCs. | 141 | Enable support for the SPI controller on the Broadcom BCM63xx SoCs. |
142 | 142 | ||
diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index 1520554978a3..cc3f938f0a6b 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c | |||
@@ -247,28 +247,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) | |||
247 | if (err) { | 247 | if (err) { |
248 | spi_master_put(master); | 248 | spi_master_put(master); |
249 | bcma_set_drvdata(core, NULL); | 249 | bcma_set_drvdata(core, NULL); |
250 | goto out; | 250 | return err; |
251 | } | 251 | } |
252 | 252 | ||
253 | /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ | 253 | /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ |
254 | spi_new_device(master, &bcm53xx_info); | 254 | spi_new_device(master, &bcm53xx_info); |
255 | 255 | ||
256 | out: | 256 | return 0; |
257 | return err; | ||
258 | } | ||
259 | |||
260 | static void bcm53xxspi_bcma_remove(struct bcma_device *core) | ||
261 | { | ||
262 | struct bcm53xxspi *b53spi = bcma_get_drvdata(core); | ||
263 | |||
264 | spi_unregister_master(b53spi->master); | ||
265 | } | 257 | } |
266 | 258 | ||
267 | static struct bcma_driver bcm53xxspi_bcma_driver = { | 259 | static struct bcma_driver bcm53xxspi_bcma_driver = { |
268 | .name = KBUILD_MODNAME, | 260 | .name = KBUILD_MODNAME, |
269 | .id_table = bcm53xxspi_bcma_tbl, | 261 | .id_table = bcm53xxspi_bcma_tbl, |
270 | .probe = bcm53xxspi_bcma_probe, | 262 | .probe = bcm53xxspi_bcma_probe, |
271 | .remove = bcm53xxspi_bcma_remove, | ||
272 | }; | 263 | }; |
273 | 264 | ||
274 | /************************************************** | 265 | /************************************************** |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index e73e2b052c9c..06858e04ec59 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -27,10 +27,117 @@ | |||
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | 29 | ||
30 | #include <bcm63xx_dev_spi.h> | 30 | /* BCM 6338/6348 SPI core */ |
31 | #define SPI_6348_RSET_SIZE 64 | ||
32 | #define SPI_6348_CMD 0x00 /* 16-bits register */ | ||
33 | #define SPI_6348_INT_STATUS 0x02 | ||
34 | #define SPI_6348_INT_MASK_ST 0x03 | ||
35 | #define SPI_6348_INT_MASK 0x04 | ||
36 | #define SPI_6348_ST 0x05 | ||
37 | #define SPI_6348_CLK_CFG 0x06 | ||
38 | #define SPI_6348_FILL_BYTE 0x07 | ||
39 | #define SPI_6348_MSG_TAIL 0x09 | ||
40 | #define SPI_6348_RX_TAIL 0x0b | ||
41 | #define SPI_6348_MSG_CTL 0x40 /* 8-bits register */ | ||
42 | #define SPI_6348_MSG_CTL_WIDTH 8 | ||
43 | #define SPI_6348_MSG_DATA 0x41 | ||
44 | #define SPI_6348_MSG_DATA_SIZE 0x3f | ||
45 | #define SPI_6348_RX_DATA 0x80 | ||
46 | #define SPI_6348_RX_DATA_SIZE 0x3f | ||
47 | |||
48 | /* BCM 3368/6358/6262/6368 SPI core */ | ||
49 | #define SPI_6358_RSET_SIZE 1804 | ||
50 | #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ | ||
51 | #define SPI_6358_MSG_CTL_WIDTH 16 | ||
52 | #define SPI_6358_MSG_DATA 0x02 | ||
53 | #define SPI_6358_MSG_DATA_SIZE 0x21e | ||
54 | #define SPI_6358_RX_DATA 0x400 | ||
55 | #define SPI_6358_RX_DATA_SIZE 0x220 | ||
56 | #define SPI_6358_CMD 0x700 /* 16-bits register */ | ||
57 | #define SPI_6358_INT_STATUS 0x702 | ||
58 | #define SPI_6358_INT_MASK_ST 0x703 | ||
59 | #define SPI_6358_INT_MASK 0x704 | ||
60 | #define SPI_6358_ST 0x705 | ||
61 | #define SPI_6358_CLK_CFG 0x706 | ||
62 | #define SPI_6358_FILL_BYTE 0x707 | ||
63 | #define SPI_6358_MSG_TAIL 0x709 | ||
64 | #define SPI_6358_RX_TAIL 0x70B | ||
65 | |||
66 | /* Shared SPI definitions */ | ||
67 | |||
68 | /* Message configuration */ | ||
69 | #define SPI_FD_RW 0x00 | ||
70 | #define SPI_HD_W 0x01 | ||
71 | #define SPI_HD_R 0x02 | ||
72 | #define SPI_BYTE_CNT_SHIFT 0 | ||
73 | #define SPI_6348_MSG_TYPE_SHIFT 6 | ||
74 | #define SPI_6358_MSG_TYPE_SHIFT 14 | ||
75 | |||
76 | /* Command */ | ||
77 | #define SPI_CMD_NOOP 0x00 | ||
78 | #define SPI_CMD_SOFT_RESET 0x01 | ||
79 | #define SPI_CMD_HARD_RESET 0x02 | ||
80 | #define SPI_CMD_START_IMMEDIATE 0x03 | ||
81 | #define SPI_CMD_COMMAND_SHIFT 0 | ||
82 | #define SPI_CMD_COMMAND_MASK 0x000f | ||
83 | #define SPI_CMD_DEVICE_ID_SHIFT 4 | ||
84 | #define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8 | ||
85 | #define SPI_CMD_ONE_BYTE_SHIFT 11 | ||
86 | #define SPI_CMD_ONE_WIRE_SHIFT 12 | ||
87 | #define SPI_DEV_ID_0 0 | ||
88 | #define SPI_DEV_ID_1 1 | ||
89 | #define SPI_DEV_ID_2 2 | ||
90 | #define SPI_DEV_ID_3 3 | ||
91 | |||
92 | /* Interrupt mask */ | ||
93 | #define SPI_INTR_CMD_DONE 0x01 | ||
94 | #define SPI_INTR_RX_OVERFLOW 0x02 | ||
95 | #define SPI_INTR_TX_UNDERFLOW 0x04 | ||
96 | #define SPI_INTR_TX_OVERFLOW 0x08 | ||
97 | #define SPI_INTR_RX_UNDERFLOW 0x10 | ||
98 | #define SPI_INTR_CLEAR_ALL 0x1f | ||
99 | |||
100 | /* Status */ | ||
101 | #define SPI_RX_EMPTY 0x02 | ||
102 | #define SPI_CMD_BUSY 0x04 | ||
103 | #define SPI_SERIAL_BUSY 0x08 | ||
104 | |||
105 | /* Clock configuration */ | ||
106 | #define SPI_CLK_20MHZ 0x00 | ||
107 | #define SPI_CLK_0_391MHZ 0x01 | ||
108 | #define SPI_CLK_0_781MHZ 0x02 /* default */ | ||
109 | #define SPI_CLK_1_563MHZ 0x03 | ||
110 | #define SPI_CLK_3_125MHZ 0x04 | ||
111 | #define SPI_CLK_6_250MHZ 0x05 | ||
112 | #define SPI_CLK_12_50MHZ 0x06 | ||
113 | #define SPI_CLK_MASK 0x07 | ||
114 | #define SPI_SSOFFTIME_MASK 0x38 | ||
115 | #define SPI_SSOFFTIME_SHIFT 3 | ||
116 | #define SPI_BYTE_SWAP 0x80 | ||
117 | |||
118 | enum bcm63xx_regs_spi { | ||
119 | SPI_CMD, | ||
120 | SPI_INT_STATUS, | ||
121 | SPI_INT_MASK_ST, | ||
122 | SPI_INT_MASK, | ||
123 | SPI_ST, | ||
124 | SPI_CLK_CFG, | ||
125 | SPI_FILL_BYTE, | ||
126 | SPI_MSG_TAIL, | ||
127 | SPI_RX_TAIL, | ||
128 | SPI_MSG_CTL, | ||
129 | SPI_MSG_DATA, | ||
130 | SPI_RX_DATA, | ||
131 | SPI_MSG_TYPE_SHIFT, | ||
132 | SPI_MSG_CTL_WIDTH, | ||
133 | SPI_MSG_DATA_SIZE, | ||
134 | }; | ||
31 | 135 | ||
32 | #define BCM63XX_SPI_MAX_PREPEND 15 | 136 | #define BCM63XX_SPI_MAX_PREPEND 15 |
33 | 137 | ||
138 | #define BCM63XX_SPI_MAX_CS 8 | ||
139 | #define BCM63XX_SPI_BUS_NUM 0 | ||
140 | |||
34 | struct bcm63xx_spi { | 141 | struct bcm63xx_spi { |
35 | struct completion done; | 142 | struct completion done; |
36 | 143 | ||
@@ -38,6 +145,7 @@ struct bcm63xx_spi { | |||
38 | int irq; | 145 | int irq; |
39 | 146 | ||
40 | /* Platform data */ | 147 | /* Platform data */ |
148 | const unsigned long *reg_offsets; | ||
41 | unsigned fifo_size; | 149 | unsigned fifo_size; |
42 | unsigned int msg_type_shift; | 150 | unsigned int msg_type_shift; |
43 | unsigned int msg_ctl_width; | 151 | unsigned int msg_ctl_width; |
@@ -51,27 +159,35 @@ struct bcm63xx_spi { | |||
51 | }; | 159 | }; |
52 | 160 | ||
53 | static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, | 161 | static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, |
54 | unsigned int offset) | 162 | unsigned int offset) |
55 | { | 163 | { |
56 | return bcm_readb(bs->regs + bcm63xx_spireg(offset)); | 164 | return readb(bs->regs + bs->reg_offsets[offset]); |
57 | } | 165 | } |
58 | 166 | ||
59 | static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, | 167 | static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, |
60 | unsigned int offset) | 168 | unsigned int offset) |
61 | { | 169 | { |
62 | return bcm_readw(bs->regs + bcm63xx_spireg(offset)); | 170 | #ifdef CONFIG_CPU_BIG_ENDIAN |
171 | return ioread16be(bs->regs + bs->reg_offsets[offset]); | ||
172 | #else | ||
173 | return readw(bs->regs + bs->reg_offsets[offset]); | ||
174 | #endif | ||
63 | } | 175 | } |
64 | 176 | ||
65 | static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, | 177 | static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, |
66 | u8 value, unsigned int offset) | 178 | u8 value, unsigned int offset) |
67 | { | 179 | { |
68 | bcm_writeb(value, bs->regs + bcm63xx_spireg(offset)); | 180 | writeb(value, bs->regs + bs->reg_offsets[offset]); |
69 | } | 181 | } |
70 | 182 | ||
71 | static inline void bcm_spi_writew(struct bcm63xx_spi *bs, | 183 | static inline void bcm_spi_writew(struct bcm63xx_spi *bs, |
72 | u16 value, unsigned int offset) | 184 | u16 value, unsigned int offset) |
73 | { | 185 | { |
74 | bcm_writew(value, bs->regs + bcm63xx_spireg(offset)); | 186 | #ifdef CONFIG_CPU_BIG_ENDIAN |
187 | iowrite16be(value, bs->regs + bs->reg_offsets[offset]); | ||
188 | #else | ||
189 | writew(value, bs->regs + bs->reg_offsets[offset]); | ||
190 | #endif | ||
75 | } | 191 | } |
76 | 192 | ||
77 | static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { | 193 | static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { |
@@ -122,7 +238,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, | |||
122 | struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); | 238 | struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); |
123 | u16 msg_ctl; | 239 | u16 msg_ctl; |
124 | u16 cmd; | 240 | u16 cmd; |
125 | u8 rx_tail; | ||
126 | unsigned int i, timeout = 0, prepend_len = 0, len = 0; | 241 | unsigned int i, timeout = 0, prepend_len = 0, len = 0; |
127 | struct spi_transfer *t = first; | 242 | struct spi_transfer *t = first; |
128 | bool do_rx = false; | 243 | bool do_rx = false; |
@@ -314,18 +429,71 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) | |||
314 | return IRQ_HANDLED; | 429 | return IRQ_HANDLED; |
315 | } | 430 | } |
316 | 431 | ||
432 | static const unsigned long bcm6348_spi_reg_offsets[] = { | ||
433 | [SPI_CMD] = SPI_6348_CMD, | ||
434 | [SPI_INT_STATUS] = SPI_6348_INT_STATUS, | ||
435 | [SPI_INT_MASK_ST] = SPI_6348_INT_MASK_ST, | ||
436 | [SPI_INT_MASK] = SPI_6348_INT_MASK, | ||
437 | [SPI_ST] = SPI_6348_ST, | ||
438 | [SPI_CLK_CFG] = SPI_6348_CLK_CFG, | ||
439 | [SPI_FILL_BYTE] = SPI_6348_FILL_BYTE, | ||
440 | [SPI_MSG_TAIL] = SPI_6348_MSG_TAIL, | ||
441 | [SPI_RX_TAIL] = SPI_6348_RX_TAIL, | ||
442 | [SPI_MSG_CTL] = SPI_6348_MSG_CTL, | ||
443 | [SPI_MSG_DATA] = SPI_6348_MSG_DATA, | ||
444 | [SPI_RX_DATA] = SPI_6348_RX_DATA, | ||
445 | [SPI_MSG_TYPE_SHIFT] = SPI_6348_MSG_TYPE_SHIFT, | ||
446 | [SPI_MSG_CTL_WIDTH] = SPI_6348_MSG_CTL_WIDTH, | ||
447 | [SPI_MSG_DATA_SIZE] = SPI_6348_MSG_DATA_SIZE, | ||
448 | }; | ||
449 | |||
450 | static const unsigned long bcm6358_spi_reg_offsets[] = { | ||
451 | [SPI_CMD] = SPI_6358_CMD, | ||
452 | [SPI_INT_STATUS] = SPI_6358_INT_STATUS, | ||
453 | [SPI_INT_MASK_ST] = SPI_6358_INT_MASK_ST, | ||
454 | [SPI_INT_MASK] = SPI_6358_INT_MASK, | ||
455 | [SPI_ST] = SPI_6358_ST, | ||
456 | [SPI_CLK_CFG] = SPI_6358_CLK_CFG, | ||
457 | [SPI_FILL_BYTE] = SPI_6358_FILL_BYTE, | ||
458 | [SPI_MSG_TAIL] = SPI_6358_MSG_TAIL, | ||
459 | [SPI_RX_TAIL] = SPI_6358_RX_TAIL, | ||
460 | [SPI_MSG_CTL] = SPI_6358_MSG_CTL, | ||
461 | [SPI_MSG_DATA] = SPI_6358_MSG_DATA, | ||
462 | [SPI_RX_DATA] = SPI_6358_RX_DATA, | ||
463 | [SPI_MSG_TYPE_SHIFT] = SPI_6358_MSG_TYPE_SHIFT, | ||
464 | [SPI_MSG_CTL_WIDTH] = SPI_6358_MSG_CTL_WIDTH, | ||
465 | [SPI_MSG_DATA_SIZE] = SPI_6358_MSG_DATA_SIZE, | ||
466 | }; | ||
467 | |||
468 | static const struct platform_device_id bcm63xx_spi_dev_match[] = { | ||
469 | { | ||
470 | .name = "bcm6348-spi", | ||
471 | .driver_data = (unsigned long)bcm6348_spi_reg_offsets, | ||
472 | }, | ||
473 | { | ||
474 | .name = "bcm6358-spi", | ||
475 | .driver_data = (unsigned long)bcm6358_spi_reg_offsets, | ||
476 | }, | ||
477 | { | ||
478 | }, | ||
479 | }; | ||
317 | 480 | ||
318 | static int bcm63xx_spi_probe(struct platform_device *pdev) | 481 | static int bcm63xx_spi_probe(struct platform_device *pdev) |
319 | { | 482 | { |
320 | struct resource *r; | 483 | struct resource *r; |
484 | const unsigned long *bcm63xx_spireg; | ||
321 | struct device *dev = &pdev->dev; | 485 | struct device *dev = &pdev->dev; |
322 | struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
323 | int irq; | 486 | int irq; |
324 | struct spi_master *master; | 487 | struct spi_master *master; |
325 | struct clk *clk; | 488 | struct clk *clk; |
326 | struct bcm63xx_spi *bs; | 489 | struct bcm63xx_spi *bs; |
327 | int ret; | 490 | int ret; |
328 | 491 | ||
492 | if (!pdev->id_entry->driver_data) | ||
493 | return -EINVAL; | ||
494 | |||
495 | bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data; | ||
496 | |||
329 | irq = platform_get_irq(pdev, 0); | 497 | irq = platform_get_irq(pdev, 0); |
330 | if (irq < 0) { | 498 | if (irq < 0) { |
331 | dev_err(dev, "no irq\n"); | 499 | dev_err(dev, "no irq\n"); |
@@ -359,7 +527,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) | |||
359 | 527 | ||
360 | bs->irq = irq; | 528 | bs->irq = irq; |
361 | bs->clk = clk; | 529 | bs->clk = clk; |
362 | bs->fifo_size = pdata->fifo_size; | 530 | bs->reg_offsets = bcm63xx_spireg; |
531 | bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE]; | ||
363 | 532 | ||
364 | ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0, | 533 | ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0, |
365 | pdev->name, master); | 534 | pdev->name, master); |
@@ -368,26 +537,16 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) | |||
368 | goto out_err; | 537 | goto out_err; |
369 | } | 538 | } |
370 | 539 | ||
371 | master->bus_num = pdata->bus_num; | 540 | master->bus_num = BCM63XX_SPI_BUS_NUM; |
372 | master->num_chipselect = pdata->num_chipselect; | 541 | master->num_chipselect = BCM63XX_SPI_MAX_CS; |
373 | master->transfer_one_message = bcm63xx_spi_transfer_one; | 542 | master->transfer_one_message = bcm63xx_spi_transfer_one; |
374 | master->mode_bits = MODEBITS; | 543 | master->mode_bits = MODEBITS; |
375 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 544 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
376 | master->auto_runtime_pm = true; | 545 | master->auto_runtime_pm = true; |
377 | bs->msg_type_shift = pdata->msg_type_shift; | 546 | bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; |
378 | bs->msg_ctl_width = pdata->msg_ctl_width; | 547 | bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; |
379 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); | 548 | bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]); |
380 | bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); | 549 | bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]); |
381 | |||
382 | switch (bs->msg_ctl_width) { | ||
383 | case 8: | ||
384 | case 16: | ||
385 | break; | ||
386 | default: | ||
387 | dev_err(dev, "unsupported MSG_CTL width: %d\n", | ||
388 | bs->msg_ctl_width); | ||
389 | goto out_err; | ||
390 | } | ||
391 | 550 | ||
392 | /* Initialize hardware */ | 551 | /* Initialize hardware */ |
393 | ret = clk_prepare_enable(bs->clk); | 552 | ret = clk_prepare_enable(bs->clk); |
@@ -467,6 +626,7 @@ static struct platform_driver bcm63xx_spi_driver = { | |||
467 | .name = "bcm63xx-spi", | 626 | .name = "bcm63xx-spi", |
468 | .pm = &bcm63xx_spi_pm_ops, | 627 | .pm = &bcm63xx_spi_pm_ops, |
469 | }, | 628 | }, |
629 | .id_table = bcm63xx_spi_dev_match, | ||
470 | .probe = bcm63xx_spi_probe, | 630 | .probe = bcm63xx_spi_probe, |
471 | .remove = bcm63xx_spi_remove, | 631 | .remove = bcm63xx_spi_remove, |
472 | }; | 632 | }; |
diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index a78693189f45..6c967555a56a 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c | |||
@@ -352,10 +352,7 @@ bfin_sport_spi_pump_transfers(unsigned long data) | |||
352 | transfer = drv_data->cur_transfer; | 352 | transfer = drv_data->cur_transfer; |
353 | chip = drv_data->cur_chip; | 353 | chip = drv_data->cur_chip; |
354 | 354 | ||
355 | if (transfer->speed_hz) | 355 | transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); |
356 | transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); | ||
357 | else | ||
358 | transfer_speed = chip->baud; | ||
359 | bfin_write(&drv_data->regs->tclkdiv, transfer_speed); | 356 | bfin_write(&drv_data->regs->tclkdiv, transfer_speed); |
360 | SSYNC(); | 357 | SSYNC(); |
361 | 358 | ||
diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index a3d65b4f4944..1e91325bf39c 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c | |||
@@ -661,11 +661,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
661 | message->state = RUNNING_STATE; | 661 | message->state = RUNNING_STATE; |
662 | dma_config = 0; | 662 | dma_config = 0; |
663 | 663 | ||
664 | /* Speed setup (surely valid because already checked) */ | 664 | bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz)); |
665 | if (transfer->speed_hz) | ||
666 | bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz)); | ||
667 | else | ||
668 | bfin_write(&drv_data->regs->baud, chip->baud); | ||
669 | 665 | ||
670 | bfin_write(&drv_data->regs->stat, BIT_STAT_CLR); | 666 | bfin_write(&drv_data->regs->stat, BIT_STAT_CLR); |
671 | bfin_spi_cs_active(drv_data, chip); | 667 | bfin_spi_cs_active(drv_data, chip); |
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 840a4984d365..3aa9e6e3dac8 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/spi/spi_bitbang.h> | 25 | #include <linux/spi/spi_bitbang.h> |
26 | 26 | ||
27 | #define SPI_BITBANG_CS_DELAY 100 | ||
28 | |||
27 | 29 | ||
28 | /*----------------------------------------------------------------------*/ | 30 | /*----------------------------------------------------------------------*/ |
29 | 31 | ||
@@ -180,7 +182,6 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
180 | { | 182 | { |
181 | struct spi_bitbang_cs *cs = spi->controller_state; | 183 | struct spi_bitbang_cs *cs = spi->controller_state; |
182 | struct spi_bitbang *bitbang; | 184 | struct spi_bitbang *bitbang; |
183 | unsigned long flags; | ||
184 | 185 | ||
185 | bitbang = spi_master_get_devdata(spi->master); | 186 | bitbang = spi_master_get_devdata(spi->master); |
186 | 187 | ||
@@ -210,12 +211,12 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
210 | */ | 211 | */ |
211 | 212 | ||
212 | /* deselect chip (low or high) */ | 213 | /* deselect chip (low or high) */ |
213 | spin_lock_irqsave(&bitbang->lock, flags); | 214 | mutex_lock(&bitbang->lock); |
214 | if (!bitbang->busy) { | 215 | if (!bitbang->busy) { |
215 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | 216 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); |
216 | ndelay(cs->nsecs); | 217 | ndelay(cs->nsecs); |
217 | } | 218 | } |
218 | spin_unlock_irqrestore(&bitbang->lock, flags); | 219 | mutex_unlock(&bitbang->lock); |
219 | 220 | ||
220 | return 0; | 221 | return 0; |
221 | } | 222 | } |
@@ -255,122 +256,39 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
255 | static int spi_bitbang_prepare_hardware(struct spi_master *spi) | 256 | static int spi_bitbang_prepare_hardware(struct spi_master *spi) |
256 | { | 257 | { |
257 | struct spi_bitbang *bitbang; | 258 | struct spi_bitbang *bitbang; |
258 | unsigned long flags; | ||
259 | 259 | ||
260 | bitbang = spi_master_get_devdata(spi); | 260 | bitbang = spi_master_get_devdata(spi); |
261 | 261 | ||
262 | spin_lock_irqsave(&bitbang->lock, flags); | 262 | mutex_lock(&bitbang->lock); |
263 | bitbang->busy = 1; | 263 | bitbang->busy = 1; |
264 | spin_unlock_irqrestore(&bitbang->lock, flags); | 264 | mutex_unlock(&bitbang->lock); |
265 | 265 | ||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int spi_bitbang_transfer_one(struct spi_master *master, | 269 | static int spi_bitbang_transfer_one(struct spi_master *master, |
270 | struct spi_message *m) | 270 | struct spi_device *spi, |
271 | struct spi_transfer *transfer) | ||
271 | { | 272 | { |
272 | struct spi_bitbang *bitbang; | 273 | struct spi_bitbang *bitbang = spi_master_get_devdata(master); |
273 | unsigned nsecs; | 274 | int status = 0; |
274 | struct spi_transfer *t = NULL; | ||
275 | unsigned cs_change; | ||
276 | int status; | ||
277 | int do_setup = -1; | ||
278 | struct spi_device *spi = m->spi; | ||
279 | |||
280 | bitbang = spi_master_get_devdata(master); | ||
281 | |||
282 | /* FIXME this is made-up ... the correct value is known to | ||
283 | * word-at-a-time bitbang code, and presumably chipselect() | ||
284 | * should enforce these requirements too? | ||
285 | */ | ||
286 | nsecs = 100; | ||
287 | |||
288 | cs_change = 1; | ||
289 | status = 0; | ||
290 | |||
291 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
292 | |||
293 | /* override speed or wordsize? */ | ||
294 | if (t->speed_hz || t->bits_per_word) | ||
295 | do_setup = 1; | ||
296 | |||
297 | /* init (-1) or override (1) transfer params */ | ||
298 | if (do_setup != 0) { | ||
299 | if (bitbang->setup_transfer) { | ||
300 | status = bitbang->setup_transfer(spi, t); | ||
301 | if (status < 0) | ||
302 | break; | ||
303 | } | ||
304 | if (do_setup == -1) | ||
305 | do_setup = 0; | ||
306 | } | ||
307 | |||
308 | /* set up default clock polarity, and activate chip; | ||
309 | * this implicitly updates clock and spi modes as | ||
310 | * previously recorded for this device via setup(). | ||
311 | * (and also deselects any other chip that might be | ||
312 | * selected ...) | ||
313 | */ | ||
314 | if (cs_change) { | ||
315 | bitbang->chipselect(spi, BITBANG_CS_ACTIVE); | ||
316 | ndelay(nsecs); | ||
317 | } | ||
318 | cs_change = t->cs_change; | ||
319 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
320 | status = -EINVAL; | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | /* transfer data. the lower level code handles any | ||
325 | * new dma mappings it needs. our caller always gave | ||
326 | * us dma-safe buffers. | ||
327 | */ | ||
328 | if (t->len) { | ||
329 | /* REVISIT dma API still needs a designated | ||
330 | * DMA_ADDR_INVALID; ~0 might be better. | ||
331 | */ | ||
332 | if (!m->is_dma_mapped) | ||
333 | t->rx_dma = t->tx_dma = 0; | ||
334 | status = bitbang->txrx_bufs(spi, t); | ||
335 | } | ||
336 | if (status > 0) | ||
337 | m->actual_length += status; | ||
338 | if (status != t->len) { | ||
339 | /* always report some kind of error */ | ||
340 | if (status >= 0) | ||
341 | status = -EREMOTEIO; | ||
342 | break; | ||
343 | } | ||
344 | status = 0; | ||
345 | 275 | ||
346 | /* protocol tweaks before next transfer */ | 276 | if (bitbang->setup_transfer) { |
347 | if (t->delay_usecs) | 277 | status = bitbang->setup_transfer(spi, transfer); |
348 | udelay(t->delay_usecs); | 278 | if (status < 0) |
349 | 279 | goto out; | |
350 | if (cs_change && | ||
351 | !list_is_last(&t->transfer_list, &m->transfers)) { | ||
352 | /* sometimes a short mid-message deselect of the chip | ||
353 | * may be needed to terminate a mode or command | ||
354 | */ | ||
355 | ndelay(nsecs); | ||
356 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
357 | ndelay(nsecs); | ||
358 | } | ||
359 | } | 280 | } |
360 | 281 | ||
361 | m->status = status; | 282 | if (transfer->len) |
283 | status = bitbang->txrx_bufs(spi, transfer); | ||
362 | 284 | ||
363 | /* normally deactivate chipselect ... unless no error and | 285 | if (status == transfer->len) |
364 | * cs_change has hinted that the next message will probably | 286 | status = 0; |
365 | * be for this chip too. | 287 | else if (status >= 0) |
366 | */ | 288 | status = -EREMOTEIO; |
367 | if (!(status == 0 && cs_change)) { | ||
368 | ndelay(nsecs); | ||
369 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
370 | ndelay(nsecs); | ||
371 | } | ||
372 | 289 | ||
373 | spi_finalize_current_message(master); | 290 | out: |
291 | spi_finalize_current_transfer(master); | ||
374 | 292 | ||
375 | return status; | 293 | return status; |
376 | } | 294 | } |
@@ -378,17 +296,32 @@ static int spi_bitbang_transfer_one(struct spi_master *master, | |||
378 | static int spi_bitbang_unprepare_hardware(struct spi_master *spi) | 296 | static int spi_bitbang_unprepare_hardware(struct spi_master *spi) |
379 | { | 297 | { |
380 | struct spi_bitbang *bitbang; | 298 | struct spi_bitbang *bitbang; |
381 | unsigned long flags; | ||
382 | 299 | ||
383 | bitbang = spi_master_get_devdata(spi); | 300 | bitbang = spi_master_get_devdata(spi); |
384 | 301 | ||
385 | spin_lock_irqsave(&bitbang->lock, flags); | 302 | mutex_lock(&bitbang->lock); |
386 | bitbang->busy = 0; | 303 | bitbang->busy = 0; |
387 | spin_unlock_irqrestore(&bitbang->lock, flags); | 304 | mutex_unlock(&bitbang->lock); |
388 | 305 | ||
389 | return 0; | 306 | return 0; |
390 | } | 307 | } |
391 | 308 | ||
309 | static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) | ||
310 | { | ||
311 | struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); | ||
312 | |||
313 | /* SPI core provides CS high / low, but bitbang driver | ||
314 | * expects CS active | ||
315 | * spi device driver takes care of handling SPI_CS_HIGH | ||
316 | */ | ||
317 | enable = (!!(spi->mode & SPI_CS_HIGH) == enable); | ||
318 | |||
319 | ndelay(SPI_BITBANG_CS_DELAY); | ||
320 | bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE : | ||
321 | BITBANG_CS_INACTIVE); | ||
322 | ndelay(SPI_BITBANG_CS_DELAY); | ||
323 | } | ||
324 | |||
392 | /*----------------------------------------------------------------------*/ | 325 | /*----------------------------------------------------------------------*/ |
393 | 326 | ||
394 | /** | 327 | /** |
@@ -427,7 +360,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
427 | if (!master || !bitbang->chipselect) | 360 | if (!master || !bitbang->chipselect) |
428 | return -EINVAL; | 361 | return -EINVAL; |
429 | 362 | ||
430 | spin_lock_init(&bitbang->lock); | 363 | mutex_init(&bitbang->lock); |
431 | 364 | ||
432 | if (!master->mode_bits) | 365 | if (!master->mode_bits) |
433 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; | 366 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; |
@@ -437,7 +370,8 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
437 | 370 | ||
438 | master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; | 371 | master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; |
439 | master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; | 372 | master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; |
440 | master->transfer_one_message = spi_bitbang_transfer_one; | 373 | master->transfer_one = spi_bitbang_transfer_one; |
374 | master->set_cs = spi_bitbang_set_cs; | ||
441 | 375 | ||
442 | if (!bitbang->txrx_bufs) { | 376 | if (!bitbang->txrx_bufs) { |
443 | bitbang->use_dma = 0; | 377 | bitbang->use_dma = 0; |
diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 54fb984a3e17..dd3d0a218d8b 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c | |||
@@ -210,12 +210,12 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t) | |||
210 | if (in_8(&hw->regs->cdm) != cdm) | 210 | if (in_8(&hw->regs->cdm) != cdm) |
211 | out_8(&hw->regs->cdm, cdm); | 211 | out_8(&hw->regs->cdm, cdm); |
212 | 212 | ||
213 | spin_lock(&hw->bitbang.lock); | 213 | mutex_lock(&hw->bitbang.lock); |
214 | if (!hw->bitbang.busy) { | 214 | if (!hw->bitbang.busy) { |
215 | hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); | 215 | hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); |
216 | /* Need to ndelay here? */ | 216 | /* Need to ndelay here? */ |
217 | } | 217 | } |
218 | spin_unlock(&hw->bitbang.lock); | 218 | mutex_unlock(&hw->bitbang.lock); |
219 | 219 | ||
220 | return 0; | 220 | return 0; |
221 | } | 221 | } |
diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index f36bc320a807..4e7d1bfed7e6 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c | |||
@@ -198,12 +198,12 @@ static int s3c24xx_spi_setup(struct spi_device *spi) | |||
198 | if (ret) | 198 | if (ret) |
199 | return ret; | 199 | return ret; |
200 | 200 | ||
201 | spin_lock(&hw->bitbang.lock); | 201 | mutex_lock(&hw->bitbang.lock); |
202 | if (!hw->bitbang.busy) { | 202 | if (!hw->bitbang.busy) { |
203 | hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); | 203 | hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); |
204 | /* need to ndelay for 0.5 clocktick ? */ | 204 | /* need to ndelay for 0.5 clocktick ? */ |
205 | } | 205 | } |
206 | spin_unlock(&hw->bitbang.lock); | 206 | mutex_unlock(&hw->bitbang.lock); |
207 | 207 | ||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 85578d4be034..154788ed218c 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/workqueue.h> | 4 | #include <linux/workqueue.h> |
5 | 5 | ||
6 | struct spi_bitbang { | 6 | struct spi_bitbang { |
7 | spinlock_t lock; | 7 | struct mutex lock; |
8 | u8 busy; | 8 | u8 busy; |
9 | u8 use_dma; | 9 | u8 use_dma; |
10 | u8 flags; /* extra spi->mode support */ | 10 | u8 flags; /* extra spi->mode support */ |