diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-gpio.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0b56cfc71fab..ff7263ce12c7 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -46,6 +46,7 @@ struct spi_gpio { | |||
46 | struct spi_bitbang bitbang; | 46 | struct spi_bitbang bitbang; |
47 | struct spi_gpio_platform_data pdata; | 47 | struct spi_gpio_platform_data pdata; |
48 | struct platform_device *pdev; | 48 | struct platform_device *pdev; |
49 | int cs_gpios[0]; | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /*----------------------------------------------------------------------*/ | 52 | /*----------------------------------------------------------------------*/ |
@@ -89,15 +90,21 @@ struct spi_gpio { | |||
89 | 90 | ||
90 | /*----------------------------------------------------------------------*/ | 91 | /*----------------------------------------------------------------------*/ |
91 | 92 | ||
92 | static inline const struct spi_gpio_platform_data * __pure | 93 | static inline struct spi_gpio * __pure |
93 | spi_to_pdata(const struct spi_device *spi) | 94 | spi_to_spi_gpio(const struct spi_device *spi) |
94 | { | 95 | { |
95 | const struct spi_bitbang *bang; | 96 | const struct spi_bitbang *bang; |
96 | const struct spi_gpio *spi_gpio; | 97 | struct spi_gpio *spi_gpio; |
97 | 98 | ||
98 | bang = spi_master_get_devdata(spi->master); | 99 | bang = spi_master_get_devdata(spi->master); |
99 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); | 100 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); |
100 | return &spi_gpio->pdata; | 101 | return spi_gpio; |
102 | } | ||
103 | |||
104 | static inline struct spi_gpio_platform_data * __pure | ||
105 | spi_to_pdata(const struct spi_device *spi) | ||
106 | { | ||
107 | return &spi_to_spi_gpio(spi)->pdata; | ||
101 | } | 108 | } |
102 | 109 | ||
103 | /* this is #defined to avoid unused-variable warnings when inlining */ | 110 | /* this is #defined to avoid unused-variable warnings when inlining */ |
@@ -210,7 +217,8 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, | |||
210 | 217 | ||
211 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | 218 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) |
212 | { | 219 | { |
213 | unsigned long cs = (unsigned long) spi->controller_data; | 220 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
221 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | ||
214 | 222 | ||
215 | /* set initial clock polarity */ | 223 | /* set initial clock polarity */ |
216 | if (is_active) | 224 | if (is_active) |
@@ -224,8 +232,9 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | |||
224 | 232 | ||
225 | static int spi_gpio_setup(struct spi_device *spi) | 233 | static int spi_gpio_setup(struct spi_device *spi) |
226 | { | 234 | { |
227 | unsigned long cs = (unsigned long) spi->controller_data; | 235 | unsigned int cs = (unsigned int) spi->controller_data; |
228 | int status = 0; | 236 | int status = 0; |
237 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | ||
229 | 238 | ||
230 | if (spi->bits_per_word > 32) | 239 | if (spi->bits_per_word > 32) |
231 | return -EINVAL; | 240 | return -EINVAL; |
@@ -239,8 +248,11 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
239 | !(spi->mode & SPI_CS_HIGH)); | 248 | !(spi->mode & SPI_CS_HIGH)); |
240 | } | 249 | } |
241 | } | 250 | } |
242 | if (!status) | 251 | if (!status) { |
243 | status = spi_bitbang_setup(spi); | 252 | status = spi_bitbang_setup(spi); |
253 | spi_gpio->cs_gpios[spi->chip_select] = cs; | ||
254 | } | ||
255 | |||
244 | if (status) { | 256 | if (status) { |
245 | if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) | 257 | if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) |
246 | gpio_free(cs); | 258 | gpio_free(cs); |
@@ -250,7 +262,8 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
250 | 262 | ||
251 | static void spi_gpio_cleanup(struct spi_device *spi) | 263 | static void spi_gpio_cleanup(struct spi_device *spi) |
252 | { | 264 | { |
253 | unsigned long cs = (unsigned long) spi->controller_data; | 265 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
266 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | ||
254 | 267 | ||
255 | if (cs != SPI_GPIO_NO_CHIPSELECT) | 268 | if (cs != SPI_GPIO_NO_CHIPSELECT) |
256 | gpio_free(cs); | 269 | gpio_free(cs); |
@@ -331,7 +344,8 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev) | |||
331 | if (status < 0) | 344 | if (status < 0) |
332 | return status; | 345 | return status; |
333 | 346 | ||
334 | master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio); | 347 | master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + |
348 | (sizeof(int) * SPI_N_CHIPSEL)); | ||
335 | if (!master) { | 349 | if (!master) { |
336 | status = -ENOMEM; | 350 | status = -ENOMEM; |
337 | goto gpio_free; | 351 | goto gpio_free; |