Version:  2.0.40 2.2.26 2.4.37 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8

Linux/drivers/spi/spi-bfin-sport.c

  1 /*
  2  * SPI bus via the Blackfin SPORT peripheral
  3  *
  4  * Enter bugs at http://blackfin.uclinux.org/
  5  *
  6  * Copyright 2009-2011 Analog Devices Inc.
  7  *
  8  * Licensed under the GPL-2 or later.
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/delay.h>
 13 #include <linux/device.h>
 14 #include <linux/gpio.h>
 15 #include <linux/io.h>
 16 #include <linux/ioport.h>
 17 #include <linux/irq.h>
 18 #include <linux/errno.h>
 19 #include <linux/interrupt.h>
 20 #include <linux/platform_device.h>
 21 #include <linux/spi/spi.h>
 22 #include <linux/workqueue.h>
 23 
 24 #include <asm/portmux.h>
 25 #include <asm/bfin5xx_spi.h>
 26 #include <asm/blackfin.h>
 27 #include <asm/bfin_sport.h>
 28 #include <asm/cacheflush.h>
 29 
 30 #define DRV_NAME        "bfin-sport-spi"
 31 #define DRV_DESC        "SPI bus via the Blackfin SPORT"
 32 
 33 MODULE_AUTHOR("Cliff Cai");
 34 MODULE_DESCRIPTION(DRV_DESC);
 35 MODULE_LICENSE("GPL");
 36 MODULE_ALIAS("platform:bfin-sport-spi");
 37 
 38 enum bfin_sport_spi_state {
 39         START_STATE,
 40         RUNNING_STATE,
 41         DONE_STATE,
 42         ERROR_STATE,
 43 };
 44 
 45 struct bfin_sport_spi_master_data;
 46 
 47 struct bfin_sport_transfer_ops {
 48         void (*write) (struct bfin_sport_spi_master_data *);
 49         void (*read) (struct bfin_sport_spi_master_data *);
 50         void (*duplex) (struct bfin_sport_spi_master_data *);
 51 };
 52 
 53 struct bfin_sport_spi_master_data {
 54         /* Driver model hookup */
 55         struct device *dev;
 56 
 57         /* SPI framework hookup */
 58         struct spi_master *master;
 59 
 60         /* Regs base of SPI controller */
 61         struct sport_register __iomem *regs;
 62         int err_irq;
 63 
 64         /* Pin request list */
 65         u16 *pin_req;
 66 
 67         struct work_struct pump_messages;
 68         spinlock_t lock;
 69         struct list_head queue;
 70         int busy;
 71         bool run;
 72 
 73         /* Message Transfer pump */
 74         struct tasklet_struct pump_transfers;
 75 
 76         /* Current message transfer state info */
 77         enum bfin_sport_spi_state state;
 78         struct spi_message *cur_msg;
 79         struct spi_transfer *cur_transfer;
 80         struct bfin_sport_spi_slave_data *cur_chip;
 81         union {
 82                 void *tx;
 83                 u8 *tx8;
 84                 u16 *tx16;
 85         };
 86         void *tx_end;
 87         union {
 88                 void *rx;
 89                 u8 *rx8;
 90                 u16 *rx16;
 91         };
 92         void *rx_end;
 93 
 94         int cs_change;
 95         struct bfin_sport_transfer_ops *ops;
 96 };
 97 
 98 struct bfin_sport_spi_slave_data {
 99         u16 ctl_reg;
100         u16 baud;
101         u16 cs_chg_udelay;      /* Some devices require > 255usec delay */
102         u32 cs_gpio;
103         u16 idle_tx_val;
104         struct bfin_sport_transfer_ops *ops;
105 };
106 
107 static void
108 bfin_sport_spi_enable(struct bfin_sport_spi_master_data *drv_data)
109 {
110         bfin_write_or(&drv_data->regs->tcr1, TSPEN);
111         bfin_write_or(&drv_data->regs->rcr1, TSPEN);
112         SSYNC();
113 }
114 
115 static void
116 bfin_sport_spi_disable(struct bfin_sport_spi_master_data *drv_data)
117 {
118         bfin_write_and(&drv_data->regs->tcr1, ~TSPEN);
119         bfin_write_and(&drv_data->regs->rcr1, ~TSPEN);
120         SSYNC();
121 }
122 
123 /* Caculate the SPI_BAUD register value based on input HZ */
124 static u16
125 bfin_sport_hz_to_spi_baud(u32 speed_hz)
126 {
127         u_long clk, sclk = get_sclk();
128         int div = (sclk / (2 * speed_hz)) - 1;
129 
130         if (div < 0)
131                 div = 0;
132 
133         clk = sclk / (2 * (div + 1));
134 
135         if (clk > speed_hz)
136                 div++;
137 
138         return div;
139 }
140 
141 /* Chip select operation functions for cs_change flag */
142 static void
143 bfin_sport_spi_cs_active(struct bfin_sport_spi_slave_data *chip)
144 {
145         gpio_direction_output(chip->cs_gpio, 0);
146 }
147 
148 static void
149 bfin_sport_spi_cs_deactive(struct bfin_sport_spi_slave_data *chip)
150 {
151         gpio_direction_output(chip->cs_gpio, 1);
152         /* Move delay here for consistency */
153         if (chip->cs_chg_udelay)
154                 udelay(chip->cs_chg_udelay);
155 }
156 
157 static void
158 bfin_sport_spi_stat_poll_complete(struct bfin_sport_spi_master_data *drv_data)
159 {
160         unsigned long timeout = jiffies + HZ;
161         while (!(bfin_read(&drv_data->regs->stat) & RXNE)) {
162                 if (!time_before(jiffies, timeout))
163                         break;
164         }
165 }
166 
167 static void
168 bfin_sport_spi_u8_writer(struct bfin_sport_spi_master_data *drv_data)
169 {
170         u16 dummy;
171 
172         while (drv_data->tx < drv_data->tx_end) {
173                 bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
174                 bfin_sport_spi_stat_poll_complete(drv_data);
175                 dummy = bfin_read(&drv_data->regs->rx16);
176         }
177 }
178 
179 static void
180 bfin_sport_spi_u8_reader(struct bfin_sport_spi_master_data *drv_data)
181 {
182         u16 tx_val = drv_data->cur_chip->idle_tx_val;
183 
184         while (drv_data->rx < drv_data->rx_end) {
185                 bfin_write(&drv_data->regs->tx16, tx_val);
186                 bfin_sport_spi_stat_poll_complete(drv_data);
187                 *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
188         }
189 }
190 
191 static void
192 bfin_sport_spi_u8_duplex(struct bfin_sport_spi_master_data *drv_data)
193 {
194         while (drv_data->rx < drv_data->rx_end) {
195                 bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
196                 bfin_sport_spi_stat_poll_complete(drv_data);
197                 *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
198         }
199 }
200 
201 static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u8 = {
202         .write  = bfin_sport_spi_u8_writer,
203         .read   = bfin_sport_spi_u8_reader,
204         .duplex = bfin_sport_spi_u8_duplex,
205 };
206 
207 static void
208 bfin_sport_spi_u16_writer(struct bfin_sport_spi_master_data *drv_data)
209 {
210         u16 dummy;
211 
212         while (drv_data->tx < drv_data->tx_end) {
213                 bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
214                 bfin_sport_spi_stat_poll_complete(drv_data);
215                 dummy = bfin_read(&drv_data->regs->rx16);
216         }
217 }
218 
219 static void
220 bfin_sport_spi_u16_reader(struct bfin_sport_spi_master_data *drv_data)
221 {
222         u16 tx_val = drv_data->cur_chip->idle_tx_val;
223 
224         while (drv_data->rx < drv_data->rx_end) {
225                 bfin_write(&drv_data->regs->tx16, tx_val);
226                 bfin_sport_spi_stat_poll_complete(drv_data);
227                 *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
228         }
229 }
230 
231 static void
232 bfin_sport_spi_u16_duplex(struct bfin_sport_spi_master_data *drv_data)
233 {
234         while (drv_data->rx < drv_data->rx_end) {
235                 bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
236                 bfin_sport_spi_stat_poll_complete(drv_data);
237                 *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
238         }
239 }
240 
241 static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u16 = {
242         .write  = bfin_sport_spi_u16_writer,
243         .read   = bfin_sport_spi_u16_reader,
244         .duplex = bfin_sport_spi_u16_duplex,
245 };
246 
247 /* stop controller and re-config current chip */
248 static void
249 bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)
250 {
251         struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
252 
253         bfin_sport_spi_disable(drv_data);
254         dev_dbg(drv_data->dev, "restoring spi ctl state\n");
255 
256         bfin_write(&drv_data->regs->tcr1, chip->ctl_reg);
257         bfin_write(&drv_data->regs->tclkdiv, chip->baud);
258         SSYNC();
259 
260         bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS));
261         SSYNC();
262 
263         bfin_sport_spi_cs_active(chip);
264 }
265 
266 /* test if there is more transfer to be done */
267 static enum bfin_sport_spi_state
268 bfin_sport_spi_next_transfer(struct bfin_sport_spi_master_data *drv_data)
269 {
270         struct spi_message *msg = drv_data->cur_msg;
271         struct spi_transfer *trans = drv_data->cur_transfer;
272 
273         /* Move to next transfer */
274         if (trans->transfer_list.next != &msg->transfers) {
275                 drv_data->cur_transfer =
276                     list_entry(trans->transfer_list.next,
277                                struct spi_transfer, transfer_list);
278                 return RUNNING_STATE;
279         }
280 
281         return DONE_STATE;
282 }
283 
284 /*
285  * caller already set message->status;
286  * dma and pio irqs are blocked give finished message back
287  */
288 static void
289 bfin_sport_spi_giveback(struct bfin_sport_spi_master_data *drv_data)
290 {
291         struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
292         unsigned long flags;
293         struct spi_message *msg;
294 
295         spin_lock_irqsave(&drv_data->lock, flags);
296         msg = drv_data->cur_msg;
297         drv_data->state = START_STATE;
298         drv_data->cur_msg = NULL;
299         drv_data->cur_transfer = NULL;
300         drv_data->cur_chip = NULL;
301         schedule_work(&drv_data->pump_messages);
302         spin_unlock_irqrestore(&drv_data->lock, flags);
303 
304         if (!drv_data->cs_change)
305                 bfin_sport_spi_cs_deactive(chip);
306 
307         if (msg->complete)
308                 msg->complete(msg->context);
309 }
310 
311 static irqreturn_t
312 sport_err_handler(int irq, void *dev_id)
313 {
314         struct bfin_sport_spi_master_data *drv_data = dev_id;
315         u16 status;
316 
317         dev_dbg(drv_data->dev, "%s enter\n", __func__);
318         status = bfin_read(&drv_data->regs->stat) & (TOVF | TUVF | ROVF | RUVF);
319 
320         if (status) {
321                 bfin_write(&drv_data->regs->stat, status);
322                 SSYNC();
323 
324                 bfin_sport_spi_disable(drv_data);
325                 dev_err(drv_data->dev, "status error:%s%s%s%s\n",
326                         status & TOVF ? " TOVF" : "",
327                         status & TUVF ? " TUVF" : "",
328                         status & ROVF ? " ROVF" : "",
329                         status & RUVF ? " RUVF" : "");
330         }
331 
332         return IRQ_HANDLED;
333 }
334 
335 static void
336 bfin_sport_spi_pump_transfers(unsigned long data)
337 {
338         struct bfin_sport_spi_master_data *drv_data = (void *)data;
339         struct spi_message *message = NULL;
340         struct spi_transfer *transfer = NULL;
341         struct spi_transfer *previous = NULL;
342         struct bfin_sport_spi_slave_data *chip = NULL;
343         unsigned int bits_per_word;
344         u32 tranf_success = 1;
345         u32 transfer_speed;
346         u8 full_duplex = 0;
347 
348         /* Get current state information */
349         message = drv_data->cur_msg;
350         transfer = drv_data->cur_transfer;
351         chip = drv_data->cur_chip;
352 
353         transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz);
354         bfin_write(&drv_data->regs->tclkdiv, transfer_speed);
355         SSYNC();
356 
357         /*
358          * if msg is error or done, report it back using complete() callback
359          */
360 
361          /* Handle for abort */
362         if (drv_data->state == ERROR_STATE) {
363                 dev_dbg(drv_data->dev, "transfer: we've hit an error\n");
364                 message->status = -EIO;
365                 bfin_sport_spi_giveback(drv_data);
366                 return;
367         }
368 
369         /* Handle end of message */
370         if (drv_data->state == DONE_STATE) {
371                 dev_dbg(drv_data->dev, "transfer: all done!\n");
372                 message->status = 0;
373                 bfin_sport_spi_giveback(drv_data);
374                 return;
375         }
376 
377         /* Delay if requested at end of transfer */
378         if (drv_data->state == RUNNING_STATE) {
379                 dev_dbg(drv_data->dev, "transfer: still running ...\n");
380                 previous = list_entry(transfer->transfer_list.prev,
381                                       struct spi_transfer, transfer_list);
382                 if (previous->delay_usecs)
383                         udelay(previous->delay_usecs);
384         }
385 
386         if (transfer->len == 0) {
387                 /* Move to next transfer of this msg */
388                 drv_data->state = bfin_sport_spi_next_transfer(drv_data);
389                 /* Schedule next transfer tasklet */
390                 tasklet_schedule(&drv_data->pump_transfers);
391         }
392 
393         if (transfer->tx_buf != NULL) {
394                 drv_data->tx = (void *)transfer->tx_buf;
395                 drv_data->tx_end = drv_data->tx + transfer->len;
396                 dev_dbg(drv_data->dev, "tx_buf is %p, tx_end is %p\n",
397                         transfer->tx_buf, drv_data->tx_end);
398         } else
399                 drv_data->tx = NULL;
400 
401         if (transfer->rx_buf != NULL) {
402                 full_duplex = transfer->tx_buf != NULL;
403                 drv_data->rx = transfer->rx_buf;
404                 drv_data->rx_end = drv_data->rx + transfer->len;
405                 dev_dbg(drv_data->dev, "rx_buf is %p, rx_end is %p\n",
406                         transfer->rx_buf, drv_data->rx_end);
407         } else
408                 drv_data->rx = NULL;
409 
410         drv_data->cs_change = transfer->cs_change;
411 
412         /* Bits per word setup */
413         bits_per_word = transfer->bits_per_word;
414         if (bits_per_word == 16)
415                 drv_data->ops = &bfin_sport_transfer_ops_u16;
416         else
417                 drv_data->ops = &bfin_sport_transfer_ops_u8;
418         bfin_write(&drv_data->regs->tcr2, bits_per_word - 1);
419         bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1);
420         bfin_write(&drv_data->regs->rcr2, bits_per_word - 1);
421 
422         drv_data->state = RUNNING_STATE;
423 
424         if (drv_data->cs_change)
425                 bfin_sport_spi_cs_active(chip);
426 
427         dev_dbg(drv_data->dev,
428                 "now pumping a transfer: width is %d, len is %d\n",
429                 bits_per_word, transfer->len);
430 
431         /* PIO mode write then read */
432         dev_dbg(drv_data->dev, "doing IO transfer\n");
433 
434         bfin_sport_spi_enable(drv_data);
435         if (full_duplex) {
436                 /* full duplex mode */
437                 BUG_ON((drv_data->tx_end - drv_data->tx) !=
438                        (drv_data->rx_end - drv_data->rx));
439                 drv_data->ops->duplex(drv_data);
440 
441                 if (drv_data->tx != drv_data->tx_end)
442                         tranf_success = 0;
443         } else if (drv_data->tx != NULL) {
444                 /* write only half duplex */
445 
446                 drv_data->ops->write(drv_data);
447 
448                 if (drv_data->tx != drv_data->tx_end)
449                         tranf_success = 0;
450         } else if (drv_data->rx != NULL) {
451                 /* read only half duplex */
452 
453                 drv_data->ops->read(drv_data);
454                 if (drv_data->rx != drv_data->rx_end)
455                         tranf_success = 0;
456         }
457         bfin_sport_spi_disable(drv_data);
458 
459         if (!tranf_success) {
460                 dev_dbg(drv_data->dev, "IO write error!\n");
461                 drv_data->state = ERROR_STATE;
462         } else {
463                 /* Update total byte transferred */
464                 message->actual_length += transfer->len;
465                 /* Move to next transfer of this msg */
466                 drv_data->state = bfin_sport_spi_next_transfer(drv_data);
467                 if (drv_data->cs_change)
468                         bfin_sport_spi_cs_deactive(chip);
469         }
470 
471         /* Schedule next transfer tasklet */
472         tasklet_schedule(&drv_data->pump_transfers);
473 }
474 
475 /* pop a msg from queue and kick off real transfer */
476 static void
477 bfin_sport_spi_pump_messages(struct work_struct *work)
478 {
479         struct bfin_sport_spi_master_data *drv_data;
480         unsigned long flags;
481         struct spi_message *next_msg;
482 
483         drv_data = container_of(work, struct bfin_sport_spi_master_data, pump_messages);
484 
485         /* Lock queue and check for queue work */
486         spin_lock_irqsave(&drv_data->lock, flags);
487         if (list_empty(&drv_data->queue) || !drv_data->run) {
488                 /* pumper kicked off but no work to do */
489                 drv_data->busy = 0;
490                 spin_unlock_irqrestore(&drv_data->lock, flags);
491                 return;
492         }
493 
494         /* Make sure we are not already running a message */
495         if (drv_data->cur_msg) {
496                 spin_unlock_irqrestore(&drv_data->lock, flags);
497                 return;
498         }
499 
500         /* Extract head of queue */
501         next_msg = list_entry(drv_data->queue.next,
502                 struct spi_message, queue);
503 
504         drv_data->cur_msg = next_msg;
505 
506         /* Setup the SSP using the per chip configuration */
507         drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
508 
509         list_del_init(&drv_data->cur_msg->queue);
510 
511         /* Initialize message state */
512         drv_data->cur_msg->state = START_STATE;
513         drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
514                                             struct spi_transfer, transfer_list);
515         bfin_sport_spi_restore_state(drv_data);
516         dev_dbg(drv_data->dev, "got a message to pump, "
517                 "state is set to: baud %d, cs_gpio %i, ctl 0x%x\n",
518                 drv_data->cur_chip->baud, drv_data->cur_chip->cs_gpio,
519                 drv_data->cur_chip->ctl_reg);
520 
521         dev_dbg(drv_data->dev,
522                 "the first transfer len is %d\n",
523                 drv_data->cur_transfer->len);
524 
525         /* Mark as busy and launch transfers */
526         tasklet_schedule(&drv_data->pump_transfers);
527 
528         drv_data->busy = 1;
529         spin_unlock_irqrestore(&drv_data->lock, flags);
530 }
531 
532 /*
533  * got a msg to transfer, queue it in drv_data->queue.
534  * And kick off message pumper
535  */
536 static int
537 bfin_sport_spi_transfer(struct spi_device *spi, struct spi_message *msg)
538 {
539         struct bfin_sport_spi_master_data *drv_data = spi_master_get_devdata(spi->master);
540         unsigned long flags;
541 
542         spin_lock_irqsave(&drv_data->lock, flags);
543 
544         if (!drv_data->run) {
545                 spin_unlock_irqrestore(&drv_data->lock, flags);
546                 return -ESHUTDOWN;
547         }
548 
549         msg->actual_length = 0;
550         msg->status = -EINPROGRESS;
551         msg->state = START_STATE;
552 
553         dev_dbg(&spi->dev, "adding an msg in transfer()\n");
554         list_add_tail(&msg->queue, &drv_data->queue);
555 
556         if (drv_data->run && !drv_data->busy)
557                 schedule_work(&drv_data->pump_messages);
558 
559         spin_unlock_irqrestore(&drv_data->lock, flags);
560 
561         return 0;
562 }
563 
564 /* Called every time common spi devices change state */
565 static int
566 bfin_sport_spi_setup(struct spi_device *spi)
567 {
568         struct bfin_sport_spi_slave_data *chip, *first = NULL;
569         int ret;
570 
571         /* Only alloc (or use chip_info) on first setup */
572         chip = spi_get_ctldata(spi);
573         if (chip == NULL) {
574                 struct bfin5xx_spi_chip *chip_info;
575 
576                 chip = first = kzalloc(sizeof(*chip), GFP_KERNEL);
577                 if (!chip)
578                         return -ENOMEM;
579 
580                 /* platform chip_info isn't required */
581                 chip_info = spi->controller_data;
582                 if (chip_info) {
583                         /*
584                          * DITFS and TDTYPE are only thing we don't set, but
585                          * they probably shouldn't be changed by people.
586                          */
587                         if (chip_info->ctl_reg || chip_info->enable_dma) {
588                                 ret = -EINVAL;
589                                 dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields\n");
590                                 goto error;
591                         }
592                         chip->cs_chg_udelay = chip_info->cs_chg_udelay;
593                         chip->idle_tx_val = chip_info->idle_tx_val;
594                 }
595         }
596 
597         /* translate common spi framework into our register
598          * following configure contents are same for tx and rx.
599          */
600 
601         if (spi->mode & SPI_CPHA)
602                 chip->ctl_reg &= ~TCKFE;
603         else
604                 chip->ctl_reg |= TCKFE;
605 
606         if (spi->mode & SPI_LSB_FIRST)
607                 chip->ctl_reg |= TLSBIT;
608         else
609                 chip->ctl_reg &= ~TLSBIT;
610 
611         /* Sport in master mode */
612         chip->ctl_reg |= ITCLK | ITFS | TFSR | LATFS | LTFS;
613 
614         chip->baud = bfin_sport_hz_to_spi_baud(spi->max_speed_hz);
615 
616         chip->cs_gpio = spi->chip_select;
617         ret = gpio_request(chip->cs_gpio, spi->modalias);
618         if (ret)
619                 goto error;
620 
621         dev_dbg(&spi->dev, "setup spi chip %s, width is %d\n",
622                         spi->modalias, spi->bits_per_word);
623         dev_dbg(&spi->dev, "ctl_reg is 0x%x, GPIO is %i\n",
624                         chip->ctl_reg, spi->chip_select);
625 
626         spi_set_ctldata(spi, chip);
627 
628         bfin_sport_spi_cs_deactive(chip);
629 
630         return ret;
631 
632  error:
633         kfree(first);
634         return ret;
635 }
636 
637 /*
638  * callback for spi framework.
639  * clean driver specific data
640  */
641 static void
642 bfin_sport_spi_cleanup(struct spi_device *spi)
643 {
644         struct bfin_sport_spi_slave_data *chip = spi_get_ctldata(spi);
645 
646         if (!chip)
647                 return;
648 
649         gpio_free(chip->cs_gpio);
650 
651         kfree(chip);
652 }
653 
654 static int
655 bfin_sport_spi_init_queue(struct bfin_sport_spi_master_data *drv_data)
656 {
657         INIT_LIST_HEAD(&drv_data->queue);
658         spin_lock_init(&drv_data->lock);
659 
660         drv_data->run = false;
661         drv_data->busy = 0;
662 
663         /* init transfer tasklet */
664         tasklet_init(&drv_data->pump_transfers,
665                      bfin_sport_spi_pump_transfers, (unsigned long)drv_data);
666 
667         INIT_WORK(&drv_data->pump_messages, bfin_sport_spi_pump_messages);
668 
669         return 0;
670 }
671 
672 static int
673 bfin_sport_spi_start_queue(struct bfin_sport_spi_master_data *drv_data)
674 {
675         unsigned long flags;
676 
677         spin_lock_irqsave(&drv_data->lock, flags);
678 
679         if (drv_data->run || drv_data->busy) {
680                 spin_unlock_irqrestore(&drv_data->lock, flags);
681                 return -EBUSY;
682         }
683 
684         drv_data->run = true;
685         drv_data->cur_msg = NULL;
686         drv_data->cur_transfer = NULL;
687         drv_data->cur_chip = NULL;
688         spin_unlock_irqrestore(&drv_data->lock, flags);
689 
690         schedule_work(&drv_data->pump_messages);
691 
692         return 0;
693 }
694 
695 static inline int
696 bfin_sport_spi_stop_queue(struct bfin_sport_spi_master_data *drv_data)
697 {
698         unsigned long flags;
699         unsigned limit = 500;
700         int status = 0;
701 
702         spin_lock_irqsave(&drv_data->lock, flags);
703 
704         /*
705          * This is a bit lame, but is optimized for the common execution path.
706          * A wait_queue on the drv_data->busy could be used, but then the common
707          * execution path (pump_messages) would be required to call wake_up or
708          * friends on every SPI message. Do this instead
709          */
710         drv_data->run = false;
711         while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
712                 spin_unlock_irqrestore(&drv_data->lock, flags);
713                 msleep(10);
714                 spin_lock_irqsave(&drv_data->lock, flags);
715         }
716 
717         if (!list_empty(&drv_data->queue) || drv_data->busy)
718                 status = -EBUSY;
719 
720         spin_unlock_irqrestore(&drv_data->lock, flags);
721 
722         return status;
723 }
724 
725 static inline int
726 bfin_sport_spi_destroy_queue(struct bfin_sport_spi_master_data *drv_data)
727 {
728         int status;
729 
730         status = bfin_sport_spi_stop_queue(drv_data);
731         if (status)
732                 return status;
733 
734         flush_work(&drv_data->pump_messages);
735 
736         return 0;
737 }
738 
739 static int bfin_sport_spi_probe(struct platform_device *pdev)
740 {
741         struct device *dev = &pdev->dev;
742         struct bfin5xx_spi_master *platform_info;
743         struct spi_master *master;
744         struct resource *res, *ires;
745         struct bfin_sport_spi_master_data *drv_data;
746         int status;
747 
748         platform_info = dev_get_platdata(dev);
749 
750         /* Allocate master with space for drv_data */
751         master = spi_alloc_master(dev, sizeof(*master) + 16);
752         if (!master) {
753                 dev_err(dev, "cannot alloc spi_master\n");
754                 return -ENOMEM;
755         }
756 
757         drv_data = spi_master_get_devdata(master);
758         drv_data->master = master;
759         drv_data->dev = dev;
760         drv_data->pin_req = platform_info->pin_req;
761 
762         master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
763         master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
764         master->bus_num = pdev->id;
765         master->num_chipselect = platform_info->num_chipselect;
766         master->cleanup = bfin_sport_spi_cleanup;
767         master->setup = bfin_sport_spi_setup;
768         master->transfer = bfin_sport_spi_transfer;
769 
770         /* Find and map our resources */
771         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
772         if (res == NULL) {
773                 dev_err(dev, "cannot get IORESOURCE_MEM\n");
774                 status = -ENOENT;
775                 goto out_error_get_res;
776         }
777 
778         drv_data->regs = ioremap(res->start, resource_size(res));
779         if (drv_data->regs == NULL) {
780                 dev_err(dev, "cannot map registers\n");
781                 status = -ENXIO;
782                 goto out_error_ioremap;
783         }
784 
785         ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
786         if (!ires) {
787                 dev_err(dev, "cannot get IORESOURCE_IRQ\n");
788                 status = -ENODEV;
789                 goto out_error_get_ires;
790         }
791         drv_data->err_irq = ires->start;
792 
793         /* Initial and start queue */
794         status = bfin_sport_spi_init_queue(drv_data);
795         if (status) {
796                 dev_err(dev, "problem initializing queue\n");
797                 goto out_error_queue_alloc;
798         }
799 
800         status = bfin_sport_spi_start_queue(drv_data);
801         if (status) {
802                 dev_err(dev, "problem starting queue\n");
803                 goto out_error_queue_alloc;
804         }
805 
806         status = request_irq(drv_data->err_irq, sport_err_handler,
807                 0, "sport_spi_err", drv_data);
808         if (status) {
809                 dev_err(dev, "unable to request sport err irq\n");
810                 goto out_error_irq;
811         }
812 
813         status = peripheral_request_list(drv_data->pin_req, DRV_NAME);
814         if (status) {
815                 dev_err(dev, "requesting peripherals failed\n");
816                 goto out_error_peripheral;
817         }
818 
819         /* Register with the SPI framework */
820         platform_set_drvdata(pdev, drv_data);
821         status = spi_register_master(master);
822         if (status) {
823                 dev_err(dev, "problem registering spi master\n");
824                 goto out_error_master;
825         }
826 
827         dev_info(dev, "%s, regs_base@%p\n", DRV_DESC, drv_data->regs);
828         return 0;
829 
830  out_error_master:
831         peripheral_free_list(drv_data->pin_req);
832  out_error_peripheral:
833         free_irq(drv_data->err_irq, drv_data);
834  out_error_irq:
835  out_error_queue_alloc:
836         bfin_sport_spi_destroy_queue(drv_data);
837  out_error_get_ires:
838         iounmap(drv_data->regs);
839  out_error_ioremap:
840  out_error_get_res:
841         spi_master_put(master);
842 
843         return status;
844 }
845 
846 /* stop hardware and remove the driver */
847 static int bfin_sport_spi_remove(struct platform_device *pdev)
848 {
849         struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
850         int status = 0;
851 
852         if (!drv_data)
853                 return 0;
854 
855         /* Remove the queue */
856         status = bfin_sport_spi_destroy_queue(drv_data);
857         if (status)
858                 return status;
859 
860         /* Disable the SSP at the peripheral and SOC level */
861         bfin_sport_spi_disable(drv_data);
862 
863         /* Disconnect from the SPI framework */
864         spi_unregister_master(drv_data->master);
865 
866         peripheral_free_list(drv_data->pin_req);
867 
868         return 0;
869 }
870 
871 #ifdef CONFIG_PM_SLEEP
872 static int bfin_sport_spi_suspend(struct device *dev)
873 {
874         struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
875         int status;
876 
877         status = bfin_sport_spi_stop_queue(drv_data);
878         if (status)
879                 return status;
880 
881         /* stop hardware */
882         bfin_sport_spi_disable(drv_data);
883 
884         return status;
885 }
886 
887 static int bfin_sport_spi_resume(struct device *dev)
888 {
889         struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
890         int status;
891 
892         /* Enable the SPI interface */
893         bfin_sport_spi_enable(drv_data);
894 
895         /* Start the queue running */
896         status = bfin_sport_spi_start_queue(drv_data);
897         if (status)
898                 dev_err(drv_data->dev, "problem resuming queue\n");
899 
900         return status;
901 }
902 
903 static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend,
904                         bfin_sport_spi_resume);
905 
906 #define BFIN_SPORT_SPI_PM_OPS           (&bfin_sport_spi_pm_ops)
907 #else
908 #define BFIN_SPORT_SPI_PM_OPS           NULL
909 #endif
910 
911 static struct platform_driver bfin_sport_spi_driver = {
912         .driver = {
913                 .name   = DRV_NAME,
914                 .pm     = BFIN_SPORT_SPI_PM_OPS,
915         },
916         .probe   = bfin_sport_spi_probe,
917         .remove  = bfin_sport_spi_remove,
918 };
919 module_platform_driver(bfin_sport_spi_driver);
920 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us