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