linux/drivers/spi/spi-bcm63xx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Broadcom BCM63xx SPI controller support
   4 *
   5 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
   6 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
   7 */
   8
   9#include <linux/kernel.h>
  10#include <linux/clk.h>
  11#include <linux/io.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include <linux/delay.h>
  15#include <linux/interrupt.h>
  16#include <linux/spi/spi.h>
  17#include <linux/completion.h>
  18#include <linux/err.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/of.h>
  21#include <linux/reset.h>
  22
  23/* BCM 6338/6348 SPI core */
  24#define SPI_6348_RSET_SIZE              64
  25#define SPI_6348_CMD                    0x00    /* 16-bits register */
  26#define SPI_6348_INT_STATUS             0x02
  27#define SPI_6348_INT_MASK_ST            0x03
  28#define SPI_6348_INT_MASK               0x04
  29#define SPI_6348_ST                     0x05
  30#define SPI_6348_CLK_CFG                0x06
  31#define SPI_6348_FILL_BYTE              0x07
  32#define SPI_6348_MSG_TAIL               0x09
  33#define SPI_6348_RX_TAIL                0x0b
  34#define SPI_6348_MSG_CTL                0x40    /* 8-bits register */
  35#define SPI_6348_MSG_CTL_WIDTH          8
  36#define SPI_6348_MSG_DATA               0x41
  37#define SPI_6348_MSG_DATA_SIZE          0x3f
  38#define SPI_6348_RX_DATA                0x80
  39#define SPI_6348_RX_DATA_SIZE           0x3f
  40
  41/* BCM 3368/6358/6262/6368 SPI core */
  42#define SPI_6358_RSET_SIZE              1804
  43#define SPI_6358_MSG_CTL                0x00    /* 16-bits register */
  44#define SPI_6358_MSG_CTL_WIDTH          16
  45#define SPI_6358_MSG_DATA               0x02
  46#define SPI_6358_MSG_DATA_SIZE          0x21e
  47#define SPI_6358_RX_DATA                0x400
  48#define SPI_6358_RX_DATA_SIZE           0x220
  49#define SPI_6358_CMD                    0x700   /* 16-bits register */
  50#define SPI_6358_INT_STATUS             0x702
  51#define SPI_6358_INT_MASK_ST            0x703
  52#define SPI_6358_INT_MASK               0x704
  53#define SPI_6358_ST                     0x705
  54#define SPI_6358_CLK_CFG                0x706
  55#define SPI_6358_FILL_BYTE              0x707
  56#define SPI_6358_MSG_TAIL               0x709
  57#define SPI_6358_RX_TAIL                0x70B
  58
  59/* Shared SPI definitions */
  60
  61/* Message configuration */
  62#define SPI_FD_RW                       0x00
  63#define SPI_HD_W                        0x01
  64#define SPI_HD_R                        0x02
  65#define SPI_BYTE_CNT_SHIFT              0
  66#define SPI_6348_MSG_TYPE_SHIFT         6
  67#define SPI_6358_MSG_TYPE_SHIFT         14
  68
  69/* Command */
  70#define SPI_CMD_NOOP                    0x00
  71#define SPI_CMD_SOFT_RESET              0x01
  72#define SPI_CMD_HARD_RESET              0x02
  73#define SPI_CMD_START_IMMEDIATE         0x03
  74#define SPI_CMD_COMMAND_SHIFT           0
  75#define SPI_CMD_COMMAND_MASK            0x000f
  76#define SPI_CMD_DEVICE_ID_SHIFT         4
  77#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT  8
  78#define SPI_CMD_ONE_BYTE_SHIFT          11
  79#define SPI_CMD_ONE_WIRE_SHIFT          12
  80#define SPI_DEV_ID_0                    0
  81#define SPI_DEV_ID_1                    1
  82#define SPI_DEV_ID_2                    2
  83#define SPI_DEV_ID_3                    3
  84
  85/* Interrupt mask */
  86#define SPI_INTR_CMD_DONE               0x01
  87#define SPI_INTR_RX_OVERFLOW            0x02
  88#define SPI_INTR_TX_UNDERFLOW           0x04
  89#define SPI_INTR_TX_OVERFLOW            0x08
  90#define SPI_INTR_RX_UNDERFLOW           0x10
  91#define SPI_INTR_CLEAR_ALL              0x1f
  92
  93/* Status */
  94#define SPI_RX_EMPTY                    0x02
  95#define SPI_CMD_BUSY                    0x04
  96#define SPI_SERIAL_BUSY                 0x08
  97
  98/* Clock configuration */
  99#define SPI_CLK_20MHZ                   0x00
 100#define SPI_CLK_0_391MHZ                0x01
 101#define SPI_CLK_0_781MHZ                0x02    /* default */
 102#define SPI_CLK_1_563MHZ                0x03
 103#define SPI_CLK_3_125MHZ                0x04
 104#define SPI_CLK_6_250MHZ                0x05
 105#define SPI_CLK_12_50MHZ                0x06
 106#define SPI_CLK_MASK                    0x07
 107#define SPI_SSOFFTIME_MASK              0x38
 108#define SPI_SSOFFTIME_SHIFT             3
 109#define SPI_BYTE_SWAP                   0x80
 110
 111enum bcm63xx_regs_spi {
 112        SPI_CMD,
 113        SPI_INT_STATUS,
 114        SPI_INT_MASK_ST,
 115        SPI_INT_MASK,
 116        SPI_ST,
 117        SPI_CLK_CFG,
 118        SPI_FILL_BYTE,
 119        SPI_MSG_TAIL,
 120        SPI_RX_TAIL,
 121        SPI_MSG_CTL,
 122        SPI_MSG_DATA,
 123        SPI_RX_DATA,
 124        SPI_MSG_TYPE_SHIFT,
 125        SPI_MSG_CTL_WIDTH,
 126        SPI_MSG_DATA_SIZE,
 127};
 128
 129#define BCM63XX_SPI_MAX_PREPEND         15
 130
 131#define BCM63XX_SPI_MAX_CS              8
 132#define BCM63XX_SPI_BUS_NUM             0
 133
 134struct bcm63xx_spi {
 135        struct completion       done;
 136
 137        void __iomem            *regs;
 138        int                     irq;
 139
 140        /* Platform data */
 141        const unsigned long     *reg_offsets;
 142        unsigned int            fifo_size;
 143        unsigned int            msg_type_shift;
 144        unsigned int            msg_ctl_width;
 145
 146        /* data iomem */
 147        u8 __iomem              *tx_io;
 148        const u8 __iomem        *rx_io;
 149
 150        struct clk              *clk;
 151        struct platform_device  *pdev;
 152};
 153
 154static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
 155                               unsigned int offset)
 156{
 157        return readb(bs->regs + bs->reg_offsets[offset]);
 158}
 159
 160static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
 161                                unsigned int offset)
 162{
 163#ifdef CONFIG_CPU_BIG_ENDIAN
 164        return ioread16be(bs->regs + bs->reg_offsets[offset]);
 165#else
 166        return readw(bs->regs + bs->reg_offsets[offset]);
 167#endif
 168}
 169
 170static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
 171                                  u8 value, unsigned int offset)
 172{
 173        writeb(value, bs->regs + bs->reg_offsets[offset]);
 174}
 175
 176static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
 177                                  u16 value, unsigned int offset)
 178{
 179#ifdef CONFIG_CPU_BIG_ENDIAN
 180        iowrite16be(value, bs->regs + bs->reg_offsets[offset]);
 181#else
 182        writew(value, bs->regs + bs->reg_offsets[offset]);
 183#endif
 184}
 185
 186static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
 187        { 20000000, SPI_CLK_20MHZ },
 188        { 12500000, SPI_CLK_12_50MHZ },
 189        {  6250000, SPI_CLK_6_250MHZ },
 190        {  3125000, SPI_CLK_3_125MHZ },
 191        {  1563000, SPI_CLK_1_563MHZ },
 192        {   781000, SPI_CLK_0_781MHZ },
 193        {   391000, SPI_CLK_0_391MHZ }
 194};
 195
 196static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
 197                                      struct spi_transfer *t)
 198{
 199        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 200        u8 clk_cfg, reg;
 201        int i;
 202
 203        /* Default to lowest clock configuration */
 204        clk_cfg = SPI_CLK_0_391MHZ;
 205
 206        /* Find the closest clock configuration */
 207        for (i = 0; i < SPI_CLK_MASK; i++) {
 208                if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
 209                        clk_cfg = bcm63xx_spi_freq_table[i][1];
 210                        break;
 211                }
 212        }
 213
 214        /* clear existing clock configuration bits of the register */
 215        reg = bcm_spi_readb(bs, SPI_CLK_CFG);
 216        reg &= ~SPI_CLK_MASK;
 217        reg |= clk_cfg;
 218
 219        bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
 220        dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
 221                clk_cfg, t->speed_hz);
 222}
 223
 224/* the spi->mode bits understood by this driver: */
 225#define MODEBITS (SPI_CPOL | SPI_CPHA)
 226
 227static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
 228                                unsigned int num_transfers)
 229{
 230        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 231        u16 msg_ctl;
 232        u16 cmd;
 233        unsigned int i, timeout = 0, prepend_len = 0, len = 0;
 234        struct spi_transfer *t = first;
 235        bool do_rx = false;
 236        bool do_tx = false;
 237
 238        /* Disable the CMD_DONE interrupt */
 239        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 240
 241        dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
 242                t->tx_buf, t->rx_buf, t->len);
 243
 244        if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
 245                prepend_len = t->len;
 246
 247        /* prepare the buffer */
 248        for (i = 0; i < num_transfers; i++) {
 249                if (t->tx_buf) {
 250                        do_tx = true;
 251                        memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
 252
 253                        /* don't prepend more than one tx */
 254                        if (t != first)
 255                                prepend_len = 0;
 256                }
 257
 258                if (t->rx_buf) {
 259                        do_rx = true;
 260                        /* prepend is half-duplex write only */
 261                        if (t == first)
 262                                prepend_len = 0;
 263                }
 264
 265                len += t->len;
 266
 267                t = list_entry(t->transfer_list.next, struct spi_transfer,
 268                               transfer_list);
 269        }
 270
 271        reinit_completion(&bs->done);
 272
 273        /* Fill in the Message control register */
 274        msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
 275
 276        if (do_rx && do_tx && prepend_len == 0)
 277                msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
 278        else if (do_rx)
 279                msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
 280        else if (do_tx)
 281                msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
 282
 283        switch (bs->msg_ctl_width) {
 284        case 8:
 285                bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
 286                break;
 287        case 16:
 288                bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
 289                break;
 290        }
 291
 292        /* Issue the transfer */
 293        cmd = SPI_CMD_START_IMMEDIATE;
 294        cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
 295        cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
 296        bcm_spi_writew(bs, cmd, SPI_CMD);
 297
 298        /* Enable the CMD_DONE interrupt */
 299        bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
 300
 301        timeout = wait_for_completion_timeout(&bs->done, HZ);
 302        if (!timeout)
 303                return -ETIMEDOUT;
 304
 305        if (!do_rx)
 306                return 0;
 307
 308        len = 0;
 309        t = first;
 310        /* Read out all the data */
 311        for (i = 0; i < num_transfers; i++) {
 312                if (t->rx_buf)
 313                        memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
 314
 315                if (t != first || prepend_len == 0)
 316                        len += t->len;
 317
 318                t = list_entry(t->transfer_list.next, struct spi_transfer,
 319                               transfer_list);
 320        }
 321
 322        return 0;
 323}
 324
 325static int bcm63xx_spi_transfer_one(struct spi_master *master,
 326                                        struct spi_message *m)
 327{
 328        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 329        struct spi_transfer *t, *first = NULL;
 330        struct spi_device *spi = m->spi;
 331        int status = 0;
 332        unsigned int n_transfers = 0, total_len = 0;
 333        bool can_use_prepend = false;
 334
 335        /*
 336         * This SPI controller does not support keeping CS active after a
 337         * transfer.
 338         * Work around this by merging as many transfers we can into one big
 339         * full-duplex transfers.
 340         */
 341        list_for_each_entry(t, &m->transfers, transfer_list) {
 342                if (!first)
 343                        first = t;
 344
 345                n_transfers++;
 346                total_len += t->len;
 347
 348                if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
 349                    first->len <= BCM63XX_SPI_MAX_PREPEND)
 350                        can_use_prepend = true;
 351                else if (can_use_prepend && t->tx_buf)
 352                        can_use_prepend = false;
 353
 354                /* we can only transfer one fifo worth of data */
 355                if ((can_use_prepend &&
 356                     total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
 357                    (!can_use_prepend && total_len > bs->fifo_size)) {
 358                        dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
 359                                total_len, bs->fifo_size);
 360                        status = -EINVAL;
 361                        goto exit;
 362                }
 363
 364                /* all combined transfers have to have the same speed */
 365                if (t->speed_hz != first->speed_hz) {
 366                        dev_err(&spi->dev, "unable to change speed between transfers\n");
 367                        status = -EINVAL;
 368                        goto exit;
 369                }
 370
 371                /* CS will be deasserted directly after transfer */
 372                if (t->delay_usecs || t->delay.value) {
 373                        dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
 374                        status = -EINVAL;
 375                        goto exit;
 376                }
 377
 378                if (t->cs_change ||
 379                    list_is_last(&t->transfer_list, &m->transfers)) {
 380                        /* configure adapter for a new transfer */
 381                        bcm63xx_spi_setup_transfer(spi, first);
 382
 383                        /* send the data */
 384                        status = bcm63xx_txrx_bufs(spi, first, n_transfers);
 385                        if (status)
 386                                goto exit;
 387
 388                        m->actual_length += total_len;
 389
 390                        first = NULL;
 391                        n_transfers = 0;
 392                        total_len = 0;
 393                        can_use_prepend = false;
 394                }
 395        }
 396exit:
 397        m->status = status;
 398        spi_finalize_current_message(master);
 399
 400        return 0;
 401}
 402
 403/* This driver supports single master mode only. Hence
 404 * CMD_DONE is the only interrupt we care about
 405 */
 406static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
 407{
 408        struct spi_master *master = (struct spi_master *)dev_id;
 409        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 410        u8 intr;
 411
 412        /* Read interupts and clear them immediately */
 413        intr = bcm_spi_readb(bs, SPI_INT_STATUS);
 414        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 415        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 416
 417        /* A transfer completed */
 418        if (intr & SPI_INTR_CMD_DONE)
 419                complete(&bs->done);
 420
 421        return IRQ_HANDLED;
 422}
 423
 424static size_t bcm63xx_spi_max_length(struct spi_device *spi)
 425{
 426        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 427
 428        return bs->fifo_size;
 429}
 430
 431static const unsigned long bcm6348_spi_reg_offsets[] = {
 432        [SPI_CMD]               = SPI_6348_CMD,
 433        [SPI_INT_STATUS]        = SPI_6348_INT_STATUS,
 434        [SPI_INT_MASK_ST]       = SPI_6348_INT_MASK_ST,
 435        [SPI_INT_MASK]          = SPI_6348_INT_MASK,
 436        [SPI_ST]                = SPI_6348_ST,
 437        [SPI_CLK_CFG]           = SPI_6348_CLK_CFG,
 438        [SPI_FILL_BYTE]         = SPI_6348_FILL_BYTE,
 439        [SPI_MSG_TAIL]          = SPI_6348_MSG_TAIL,
 440        [SPI_RX_TAIL]           = SPI_6348_RX_TAIL,
 441        [SPI_MSG_CTL]           = SPI_6348_MSG_CTL,
 442        [SPI_MSG_DATA]          = SPI_6348_MSG_DATA,
 443        [SPI_RX_DATA]           = SPI_6348_RX_DATA,
 444        [SPI_MSG_TYPE_SHIFT]    = SPI_6348_MSG_TYPE_SHIFT,
 445        [SPI_MSG_CTL_WIDTH]     = SPI_6348_MSG_CTL_WIDTH,
 446        [SPI_MSG_DATA_SIZE]     = SPI_6348_MSG_DATA_SIZE,
 447};
 448
 449static const unsigned long bcm6358_spi_reg_offsets[] = {
 450        [SPI_CMD]               = SPI_6358_CMD,
 451        [SPI_INT_STATUS]        = SPI_6358_INT_STATUS,
 452        [SPI_INT_MASK_ST]       = SPI_6358_INT_MASK_ST,
 453        [SPI_INT_MASK]          = SPI_6358_INT_MASK,
 454        [SPI_ST]                = SPI_6358_ST,
 455        [SPI_CLK_CFG]           = SPI_6358_CLK_CFG,
 456        [SPI_FILL_BYTE]         = SPI_6358_FILL_BYTE,
 457        [SPI_MSG_TAIL]          = SPI_6358_MSG_TAIL,
 458        [SPI_RX_TAIL]           = SPI_6358_RX_TAIL,
 459        [SPI_MSG_CTL]           = SPI_6358_MSG_CTL,
 460        [SPI_MSG_DATA]          = SPI_6358_MSG_DATA,
 461        [SPI_RX_DATA]           = SPI_6358_RX_DATA,
 462        [SPI_MSG_TYPE_SHIFT]    = SPI_6358_MSG_TYPE_SHIFT,
 463        [SPI_MSG_CTL_WIDTH]     = SPI_6358_MSG_CTL_WIDTH,
 464        [SPI_MSG_DATA_SIZE]     = SPI_6358_MSG_DATA_SIZE,
 465};
 466
 467static const struct platform_device_id bcm63xx_spi_dev_match[] = {
 468        {
 469                .name = "bcm6348-spi",
 470                .driver_data = (unsigned long)bcm6348_spi_reg_offsets,
 471        },
 472        {
 473                .name = "bcm6358-spi",
 474                .driver_data = (unsigned long)bcm6358_spi_reg_offsets,
 475        },
 476        {
 477        },
 478};
 479
 480static const struct of_device_id bcm63xx_spi_of_match[] = {
 481        { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets },
 482        { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets },
 483        { },
 484};
 485
 486static int bcm63xx_spi_probe(struct platform_device *pdev)
 487{
 488        struct resource *r;
 489        const unsigned long *bcm63xx_spireg;
 490        struct device *dev = &pdev->dev;
 491        int irq, bus_num;
 492        struct spi_master *master;
 493        struct clk *clk;
 494        struct bcm63xx_spi *bs;
 495        int ret;
 496        u32 num_cs = BCM63XX_SPI_MAX_CS;
 497        struct reset_control *reset;
 498
 499        if (dev->of_node) {
 500                const struct of_device_id *match;
 501
 502                match = of_match_node(bcm63xx_spi_of_match, dev->of_node);
 503                if (!match)
 504                        return -EINVAL;
 505                bcm63xx_spireg = match->data;
 506
 507                of_property_read_u32(dev->of_node, "num-cs", &num_cs);
 508                if (num_cs > BCM63XX_SPI_MAX_CS) {
 509                        dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
 510                                 num_cs);
 511                        num_cs = BCM63XX_SPI_MAX_CS;
 512                }
 513
 514                bus_num = -1;
 515        } else if (pdev->id_entry->driver_data) {
 516                const struct platform_device_id *match = pdev->id_entry;
 517
 518                bcm63xx_spireg = (const unsigned long *)match->driver_data;
 519                bus_num = BCM63XX_SPI_BUS_NUM;
 520        } else {
 521                return -EINVAL;
 522        }
 523
 524        irq = platform_get_irq(pdev, 0);
 525        if (irq < 0)
 526                return irq;
 527
 528        clk = devm_clk_get(dev, "spi");
 529        if (IS_ERR(clk)) {
 530                dev_err(dev, "no clock for device\n");
 531                return PTR_ERR(clk);
 532        }
 533
 534        reset = devm_reset_control_get_optional_exclusive(dev, NULL);
 535        if (IS_ERR(reset))
 536                return PTR_ERR(reset);
 537
 538        master = spi_alloc_master(dev, sizeof(*bs));
 539        if (!master) {
 540                dev_err(dev, "out of memory\n");
 541                return -ENOMEM;
 542        }
 543
 544        bs = spi_master_get_devdata(master);
 545        init_completion(&bs->done);
 546
 547        platform_set_drvdata(pdev, master);
 548        bs->pdev = pdev;
 549
 550        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 551        bs->regs = devm_ioremap_resource(&pdev->dev, r);
 552        if (IS_ERR(bs->regs)) {
 553                ret = PTR_ERR(bs->regs);
 554                goto out_err;
 555        }
 556
 557        bs->irq = irq;
 558        bs->clk = clk;
 559        bs->reg_offsets = bcm63xx_spireg;
 560        bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];
 561
 562        ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
 563                                                        pdev->name, master);
 564        if (ret) {
 565                dev_err(dev, "unable to request irq\n");
 566                goto out_err;
 567        }
 568
 569        master->dev.of_node = dev->of_node;
 570        master->bus_num = bus_num;
 571        master->num_chipselect = num_cs;
 572        master->transfer_one_message = bcm63xx_spi_transfer_one;
 573        master->mode_bits = MODEBITS;
 574        master->bits_per_word_mask = SPI_BPW_MASK(8);
 575        master->max_transfer_size = bcm63xx_spi_max_length;
 576        master->max_message_size = bcm63xx_spi_max_length;
 577        master->auto_runtime_pm = true;
 578        bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT];
 579        bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH];
 580        bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]);
 581        bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]);
 582
 583        /* Initialize hardware */
 584        ret = clk_prepare_enable(bs->clk);
 585        if (ret)
 586                goto out_err;
 587
 588        ret = reset_control_reset(reset);
 589        if (ret) {
 590                dev_err(dev, "unable to reset device: %d\n", ret);
 591                goto out_clk_disable;
 592        }
 593
 594        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 595
 596        /* register and we are done */
 597        ret = devm_spi_register_master(dev, master);
 598        if (ret) {
 599                dev_err(dev, "spi register failed\n");
 600                goto out_clk_disable;
 601        }
 602
 603        dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
 604                 r, irq, bs->fifo_size);
 605
 606        return 0;
 607
 608out_clk_disable:
 609        clk_disable_unprepare(clk);
 610out_err:
 611        spi_master_put(master);
 612        return ret;
 613}
 614
 615static int bcm63xx_spi_remove(struct platform_device *pdev)
 616{
 617        struct spi_master *master = platform_get_drvdata(pdev);
 618        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 619
 620        /* reset spi block */
 621        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 622
 623        /* HW shutdown */
 624        clk_disable_unprepare(bs->clk);
 625
 626        return 0;
 627}
 628
 629#ifdef CONFIG_PM_SLEEP
 630static int bcm63xx_spi_suspend(struct device *dev)
 631{
 632        struct spi_master *master = dev_get_drvdata(dev);
 633        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 634
 635        spi_master_suspend(master);
 636
 637        clk_disable_unprepare(bs->clk);
 638
 639        return 0;
 640}
 641
 642static int bcm63xx_spi_resume(struct device *dev)
 643{
 644        struct spi_master *master = dev_get_drvdata(dev);
 645        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 646        int ret;
 647
 648        ret = clk_prepare_enable(bs->clk);
 649        if (ret)
 650                return ret;
 651
 652        spi_master_resume(master);
 653
 654        return 0;
 655}
 656#endif
 657
 658static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
 659        SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)
 660};
 661
 662static struct platform_driver bcm63xx_spi_driver = {
 663        .driver = {
 664                .name   = "bcm63xx-spi",
 665                .pm     = &bcm63xx_spi_pm_ops,
 666                .of_match_table = bcm63xx_spi_of_match,
 667        },
 668        .id_table       = bcm63xx_spi_dev_match,
 669        .probe          = bcm63xx_spi_probe,
 670        .remove         = bcm63xx_spi_remove,
 671};
 672
 673module_platform_driver(bcm63xx_spi_driver);
 674
 675MODULE_ALIAS("platform:bcm63xx_spi");
 676MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 677MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
 678MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
 679MODULE_LICENSE("GPL");
 680