0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/clk.h>
0011 #include <linux/io.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/delay.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/spi/spi.h>
0017 #include <linux/completion.h>
0018 #include <linux/err.h>
0019 #include <linux/pm_runtime.h>
0020 #include <linux/of.h>
0021 #include <linux/reset.h>
0022
0023
0024 #define SPI_6348_RSET_SIZE 64
0025 #define SPI_6348_CMD 0x00
0026 #define SPI_6348_INT_STATUS 0x02
0027 #define SPI_6348_INT_MASK_ST 0x03
0028 #define SPI_6348_INT_MASK 0x04
0029 #define SPI_6348_ST 0x05
0030 #define SPI_6348_CLK_CFG 0x06
0031 #define SPI_6348_FILL_BYTE 0x07
0032 #define SPI_6348_MSG_TAIL 0x09
0033 #define SPI_6348_RX_TAIL 0x0b
0034 #define SPI_6348_MSG_CTL 0x40
0035 #define SPI_6348_MSG_CTL_WIDTH 8
0036 #define SPI_6348_MSG_DATA 0x41
0037 #define SPI_6348_MSG_DATA_SIZE 0x3f
0038 #define SPI_6348_RX_DATA 0x80
0039 #define SPI_6348_RX_DATA_SIZE 0x3f
0040
0041
0042 #define SPI_6358_RSET_SIZE 1804
0043 #define SPI_6358_MSG_CTL 0x00
0044 #define SPI_6358_MSG_CTL_WIDTH 16
0045 #define SPI_6358_MSG_DATA 0x02
0046 #define SPI_6358_MSG_DATA_SIZE 0x21e
0047 #define SPI_6358_RX_DATA 0x400
0048 #define SPI_6358_RX_DATA_SIZE 0x220
0049 #define SPI_6358_CMD 0x700
0050 #define SPI_6358_INT_STATUS 0x702
0051 #define SPI_6358_INT_MASK_ST 0x703
0052 #define SPI_6358_INT_MASK 0x704
0053 #define SPI_6358_ST 0x705
0054 #define SPI_6358_CLK_CFG 0x706
0055 #define SPI_6358_FILL_BYTE 0x707
0056 #define SPI_6358_MSG_TAIL 0x709
0057 #define SPI_6358_RX_TAIL 0x70B
0058
0059
0060
0061
0062 #define SPI_FD_RW 0x00
0063 #define SPI_HD_W 0x01
0064 #define SPI_HD_R 0x02
0065 #define SPI_BYTE_CNT_SHIFT 0
0066 #define SPI_6348_MSG_TYPE_SHIFT 6
0067 #define SPI_6358_MSG_TYPE_SHIFT 14
0068
0069
0070 #define SPI_CMD_NOOP 0x00
0071 #define SPI_CMD_SOFT_RESET 0x01
0072 #define SPI_CMD_HARD_RESET 0x02
0073 #define SPI_CMD_START_IMMEDIATE 0x03
0074 #define SPI_CMD_COMMAND_SHIFT 0
0075 #define SPI_CMD_COMMAND_MASK 0x000f
0076 #define SPI_CMD_DEVICE_ID_SHIFT 4
0077 #define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8
0078 #define SPI_CMD_ONE_BYTE_SHIFT 11
0079 #define SPI_CMD_ONE_WIRE_SHIFT 12
0080 #define SPI_DEV_ID_0 0
0081 #define SPI_DEV_ID_1 1
0082 #define SPI_DEV_ID_2 2
0083 #define SPI_DEV_ID_3 3
0084
0085
0086 #define SPI_INTR_CMD_DONE 0x01
0087 #define SPI_INTR_RX_OVERFLOW 0x02
0088 #define SPI_INTR_TX_UNDERFLOW 0x04
0089 #define SPI_INTR_TX_OVERFLOW 0x08
0090 #define SPI_INTR_RX_UNDERFLOW 0x10
0091 #define SPI_INTR_CLEAR_ALL 0x1f
0092
0093
0094 #define SPI_RX_EMPTY 0x02
0095 #define SPI_CMD_BUSY 0x04
0096 #define SPI_SERIAL_BUSY 0x08
0097
0098
0099 #define SPI_CLK_20MHZ 0x00
0100 #define SPI_CLK_0_391MHZ 0x01
0101 #define SPI_CLK_0_781MHZ 0x02
0102 #define SPI_CLK_1_563MHZ 0x03
0103 #define SPI_CLK_3_125MHZ 0x04
0104 #define SPI_CLK_6_250MHZ 0x05
0105 #define SPI_CLK_12_50MHZ 0x06
0106 #define SPI_CLK_MASK 0x07
0107 #define SPI_SSOFFTIME_MASK 0x38
0108 #define SPI_SSOFFTIME_SHIFT 3
0109 #define SPI_BYTE_SWAP 0x80
0110
0111 enum bcm63xx_regs_spi {
0112 SPI_CMD,
0113 SPI_INT_STATUS,
0114 SPI_INT_MASK_ST,
0115 SPI_INT_MASK,
0116 SPI_ST,
0117 SPI_CLK_CFG,
0118 SPI_FILL_BYTE,
0119 SPI_MSG_TAIL,
0120 SPI_RX_TAIL,
0121 SPI_MSG_CTL,
0122 SPI_MSG_DATA,
0123 SPI_RX_DATA,
0124 SPI_MSG_TYPE_SHIFT,
0125 SPI_MSG_CTL_WIDTH,
0126 SPI_MSG_DATA_SIZE,
0127 };
0128
0129 #define BCM63XX_SPI_MAX_PREPEND 15
0130
0131 #define BCM63XX_SPI_MAX_CS 8
0132 #define BCM63XX_SPI_BUS_NUM 0
0133
0134 struct bcm63xx_spi {
0135 struct completion done;
0136
0137 void __iomem *regs;
0138 int irq;
0139
0140
0141 const unsigned long *reg_offsets;
0142 unsigned int fifo_size;
0143 unsigned int msg_type_shift;
0144 unsigned int msg_ctl_width;
0145
0146
0147 u8 __iomem *tx_io;
0148 const u8 __iomem *rx_io;
0149
0150 struct clk *clk;
0151 struct platform_device *pdev;
0152 };
0153
0154 static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
0155 unsigned int offset)
0156 {
0157 return readb(bs->regs + bs->reg_offsets[offset]);
0158 }
0159
0160 static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
0161 unsigned int offset)
0162 {
0163 #ifdef CONFIG_CPU_BIG_ENDIAN
0164 return ioread16be(bs->regs + bs->reg_offsets[offset]);
0165 #else
0166 return readw(bs->regs + bs->reg_offsets[offset]);
0167 #endif
0168 }
0169
0170 static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
0171 u8 value, unsigned int offset)
0172 {
0173 writeb(value, bs->regs + bs->reg_offsets[offset]);
0174 }
0175
0176 static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
0177 u16 value, unsigned int offset)
0178 {
0179 #ifdef CONFIG_CPU_BIG_ENDIAN
0180 iowrite16be(value, bs->regs + bs->reg_offsets[offset]);
0181 #else
0182 writew(value, bs->regs + bs->reg_offsets[offset]);
0183 #endif
0184 }
0185
0186 static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
0187 { 20000000, SPI_CLK_20MHZ },
0188 { 12500000, SPI_CLK_12_50MHZ },
0189 { 6250000, SPI_CLK_6_250MHZ },
0190 { 3125000, SPI_CLK_3_125MHZ },
0191 { 1563000, SPI_CLK_1_563MHZ },
0192 { 781000, SPI_CLK_0_781MHZ },
0193 { 391000, SPI_CLK_0_391MHZ }
0194 };
0195
0196 static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
0197 struct spi_transfer *t)
0198 {
0199 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
0200 u8 clk_cfg, reg;
0201 int i;
0202
0203
0204 clk_cfg = SPI_CLK_0_391MHZ;
0205
0206
0207 for (i = 0; i < SPI_CLK_MASK; i++) {
0208 if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
0209 clk_cfg = bcm63xx_spi_freq_table[i][1];
0210 break;
0211 }
0212 }
0213
0214
0215 reg = bcm_spi_readb(bs, SPI_CLK_CFG);
0216 reg &= ~SPI_CLK_MASK;
0217 reg |= clk_cfg;
0218
0219 bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
0220 dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
0221 clk_cfg, t->speed_hz);
0222 }
0223
0224
0225 #define MODEBITS (SPI_CPOL | SPI_CPHA)
0226
0227 static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
0228 unsigned int num_transfers)
0229 {
0230 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
0231 u16 msg_ctl;
0232 u16 cmd;
0233 unsigned int i, timeout = 0, prepend_len = 0, len = 0;
0234 struct spi_transfer *t = first;
0235 bool do_rx = false;
0236 bool do_tx = false;
0237
0238
0239 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
0240
0241 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
0242 t->tx_buf, t->rx_buf, t->len);
0243
0244 if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
0245 prepend_len = t->len;
0246
0247
0248 for (i = 0; i < num_transfers; i++) {
0249 if (t->tx_buf) {
0250 do_tx = true;
0251 memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
0252
0253
0254 if (t != first)
0255 prepend_len = 0;
0256 }
0257
0258 if (t->rx_buf) {
0259 do_rx = true;
0260
0261 if (t == first)
0262 prepend_len = 0;
0263 }
0264
0265 len += t->len;
0266
0267 t = list_entry(t->transfer_list.next, struct spi_transfer,
0268 transfer_list);
0269 }
0270
0271 reinit_completion(&bs->done);
0272
0273
0274 msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
0275
0276 if (do_rx && do_tx && prepend_len == 0)
0277 msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
0278 else if (do_rx)
0279 msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
0280 else if (do_tx)
0281 msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
0282
0283 switch (bs->msg_ctl_width) {
0284 case 8:
0285 bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
0286 break;
0287 case 16:
0288 bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
0289 break;
0290 }
0291
0292
0293 cmd = SPI_CMD_START_IMMEDIATE;
0294 cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
0295 cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
0296 bcm_spi_writew(bs, cmd, SPI_CMD);
0297
0298
0299 bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
0300
0301 timeout = wait_for_completion_timeout(&bs->done, HZ);
0302 if (!timeout)
0303 return -ETIMEDOUT;
0304
0305 if (!do_rx)
0306 return 0;
0307
0308 len = 0;
0309 t = first;
0310
0311 for (i = 0; i < num_transfers; i++) {
0312 if (t->rx_buf)
0313 memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
0314
0315 if (t != first || prepend_len == 0)
0316 len += t->len;
0317
0318 t = list_entry(t->transfer_list.next, struct spi_transfer,
0319 transfer_list);
0320 }
0321
0322 return 0;
0323 }
0324
0325 static int bcm63xx_spi_transfer_one(struct spi_master *master,
0326 struct spi_message *m)
0327 {
0328 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
0329 struct spi_transfer *t, *first = NULL;
0330 struct spi_device *spi = m->spi;
0331 int status = 0;
0332 unsigned int n_transfers = 0, total_len = 0;
0333 bool can_use_prepend = false;
0334
0335
0336
0337
0338
0339
0340
0341 list_for_each_entry(t, &m->transfers, transfer_list) {
0342 if (!first)
0343 first = t;
0344
0345 n_transfers++;
0346 total_len += t->len;
0347
0348 if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
0349 first->len <= BCM63XX_SPI_MAX_PREPEND)
0350 can_use_prepend = true;
0351 else if (can_use_prepend && t->tx_buf)
0352 can_use_prepend = false;
0353
0354
0355 if ((can_use_prepend &&
0356 total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
0357 (!can_use_prepend && total_len > bs->fifo_size)) {
0358 dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
0359 total_len, bs->fifo_size);
0360 status = -EINVAL;
0361 goto exit;
0362 }
0363
0364
0365 if (t->speed_hz != first->speed_hz) {
0366 dev_err(&spi->dev, "unable to change speed between transfers\n");
0367 status = -EINVAL;
0368 goto exit;
0369 }
0370
0371
0372 if (t->delay.value) {
0373 dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
0374 status = -EINVAL;
0375 goto exit;
0376 }
0377
0378 if (t->cs_change ||
0379 list_is_last(&t->transfer_list, &m->transfers)) {
0380
0381 bcm63xx_spi_setup_transfer(spi, first);
0382
0383
0384 status = bcm63xx_txrx_bufs(spi, first, n_transfers);
0385 if (status)
0386 goto exit;
0387
0388 m->actual_length += total_len;
0389
0390 first = NULL;
0391 n_transfers = 0;
0392 total_len = 0;
0393 can_use_prepend = false;
0394 }
0395 }
0396 exit:
0397 m->status = status;
0398 spi_finalize_current_message(master);
0399
0400 return 0;
0401 }
0402
0403
0404
0405
0406 static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
0407 {
0408 struct spi_master *master = (struct spi_master *)dev_id;
0409 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
0410 u8 intr;
0411
0412
0413 intr = bcm_spi_readb(bs, SPI_INT_STATUS);
0414 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
0415 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
0416
0417
0418 if (intr & SPI_INTR_CMD_DONE)
0419 complete(&bs->done);
0420
0421 return IRQ_HANDLED;
0422 }
0423
0424 static size_t bcm63xx_spi_max_length(struct spi_device *spi)
0425 {
0426 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
0427
0428 return bs->fifo_size;
0429 }
0430
0431 static const unsigned long bcm6348_spi_reg_offsets[] = {
0432 [SPI_CMD] = SPI_6348_CMD,
0433 [SPI_INT_STATUS] = SPI_6348_INT_STATUS,
0434 [SPI_INT_MASK_ST] = SPI_6348_INT_MASK_ST,
0435 [SPI_INT_MASK] = SPI_6348_INT_MASK,
0436 [SPI_ST] = SPI_6348_ST,
0437 [SPI_CLK_CFG] = SPI_6348_CLK_CFG,
0438 [SPI_FILL_BYTE] = SPI_6348_FILL_BYTE,
0439 [SPI_MSG_TAIL] = SPI_6348_MSG_TAIL,
0440 [SPI_RX_TAIL] = SPI_6348_RX_TAIL,
0441 [SPI_MSG_CTL] = SPI_6348_MSG_CTL,
0442 [SPI_MSG_DATA] = SPI_6348_MSG_DATA,
0443 [SPI_RX_DATA] = SPI_6348_RX_DATA,
0444 [SPI_MSG_TYPE_SHIFT] = SPI_6348_MSG_TYPE_SHIFT,
0445 [SPI_MSG_CTL_WIDTH] = SPI_6348_MSG_CTL_WIDTH,
0446 [SPI_MSG_DATA_SIZE] = SPI_6348_MSG_DATA_SIZE,
0447 };
0448
0449 static const unsigned long bcm6358_spi_reg_offsets[] = {
0450 [SPI_CMD] = SPI_6358_CMD,
0451 [SPI_INT_STATUS] = SPI_6358_INT_STATUS,
0452 [SPI_INT_MASK_ST] = SPI_6358_INT_MASK_ST,
0453 [SPI_INT_MASK] = SPI_6358_INT_MASK,
0454 [SPI_ST] = SPI_6358_ST,
0455 [SPI_CLK_CFG] = SPI_6358_CLK_CFG,
0456 [SPI_FILL_BYTE] = SPI_6358_FILL_BYTE,
0457 [SPI_MSG_TAIL] = SPI_6358_MSG_TAIL,
0458 [SPI_RX_TAIL] = SPI_6358_RX_TAIL,
0459 [SPI_MSG_CTL] = SPI_6358_MSG_CTL,
0460 [SPI_MSG_DATA] = SPI_6358_MSG_DATA,
0461 [SPI_RX_DATA] = SPI_6358_RX_DATA,
0462 [SPI_MSG_TYPE_SHIFT] = SPI_6358_MSG_TYPE_SHIFT,
0463 [SPI_MSG_CTL_WIDTH] = SPI_6358_MSG_CTL_WIDTH,
0464 [SPI_MSG_DATA_SIZE] = SPI_6358_MSG_DATA_SIZE,
0465 };
0466
0467 static const struct platform_device_id bcm63xx_spi_dev_match[] = {
0468 {
0469 .name = "bcm6348-spi",
0470 .driver_data = (unsigned long)bcm6348_spi_reg_offsets,
0471 },
0472 {
0473 .name = "bcm6358-spi",
0474 .driver_data = (unsigned long)bcm6358_spi_reg_offsets,
0475 },
0476 {
0477 },
0478 };
0479
0480 static const struct of_device_id bcm63xx_spi_of_match[] = {
0481 { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets },
0482 { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets },
0483 { },
0484 };
0485
0486 static int bcm63xx_spi_probe(struct platform_device *pdev)
0487 {
0488 struct resource *r;
0489 const unsigned long *bcm63xx_spireg;
0490 struct device *dev = &pdev->dev;
0491 int irq, bus_num;
0492 struct spi_master *master;
0493 struct clk *clk;
0494 struct bcm63xx_spi *bs;
0495 int ret;
0496 u32 num_cs = BCM63XX_SPI_MAX_CS;
0497 struct reset_control *reset;
0498
0499 if (dev->of_node) {
0500 const struct of_device_id *match;
0501
0502 match = of_match_node(bcm63xx_spi_of_match, dev->of_node);
0503 if (!match)
0504 return -EINVAL;
0505 bcm63xx_spireg = match->data;
0506
0507 of_property_read_u32(dev->of_node, "num-cs", &num_cs);
0508 if (num_cs > BCM63XX_SPI_MAX_CS) {
0509 dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
0510 num_cs);
0511 num_cs = BCM63XX_SPI_MAX_CS;
0512 }
0513
0514 bus_num = -1;
0515 } else if (pdev->id_entry->driver_data) {
0516 const struct platform_device_id *match = pdev->id_entry;
0517
0518 bcm63xx_spireg = (const unsigned long *)match->driver_data;
0519 bus_num = BCM63XX_SPI_BUS_NUM;
0520 } else {
0521 return -EINVAL;
0522 }
0523
0524 irq = platform_get_irq(pdev, 0);
0525 if (irq < 0)
0526 return irq;
0527
0528 clk = devm_clk_get(dev, "spi");
0529 if (IS_ERR(clk)) {
0530 dev_err(dev, "no clock for device\n");
0531 return PTR_ERR(clk);
0532 }
0533
0534 reset = devm_reset_control_get_optional_exclusive(dev, NULL);
0535 if (IS_ERR(reset))
0536 return PTR_ERR(reset);
0537
0538 master = spi_alloc_master(dev, sizeof(*bs));
0539 if (!master) {
0540 dev_err(dev, "out of memory\n");
0541 return -ENOMEM;
0542 }
0543
0544 bs = spi_master_get_devdata(master);
0545 init_completion(&bs->done);
0546
0547 platform_set_drvdata(pdev, master);
0548 bs->pdev = pdev;
0549
0550 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0551 bs->regs = devm_ioremap_resource(&pdev->dev, r);
0552 if (IS_ERR(bs->regs)) {
0553 ret = PTR_ERR(bs->regs);
0554 goto out_err;
0555 }
0556
0557 bs->irq = irq;
0558 bs->clk = clk;
0559 bs->reg_offsets = bcm63xx_spireg;
0560 bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];
0561
0562 ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
0563 pdev->name, master);
0564 if (ret) {
0565 dev_err(dev, "unable to request irq\n");
0566 goto out_err;
0567 }
0568
0569 master->dev.of_node = dev->of_node;
0570 master->bus_num = bus_num;
0571 master->num_chipselect = num_cs;
0572 master->transfer_one_message = bcm63xx_spi_transfer_one;
0573 master->mode_bits = MODEBITS;
0574 master->bits_per_word_mask = SPI_BPW_MASK(8);
0575 master->max_transfer_size = bcm63xx_spi_max_length;
0576 master->max_message_size = bcm63xx_spi_max_length;
0577 master->auto_runtime_pm = true;
0578 bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT];
0579 bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH];
0580 bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]);
0581 bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]);
0582
0583
0584 ret = clk_prepare_enable(bs->clk);
0585 if (ret)
0586 goto out_err;
0587
0588 ret = reset_control_reset(reset);
0589 if (ret) {
0590 dev_err(dev, "unable to reset device: %d\n", ret);
0591 goto out_clk_disable;
0592 }
0593
0594 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
0595
0596 pm_runtime_enable(&pdev->dev);
0597
0598
0599 ret = devm_spi_register_master(dev, master);
0600 if (ret) {
0601 dev_err(dev, "spi register failed\n");
0602 goto out_pm_disable;
0603 }
0604
0605 dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
0606 r, irq, bs->fifo_size);
0607
0608 return 0;
0609
0610 out_pm_disable:
0611 pm_runtime_disable(&pdev->dev);
0612 out_clk_disable:
0613 clk_disable_unprepare(clk);
0614 out_err:
0615 spi_master_put(master);
0616 return ret;
0617 }
0618
0619 static int bcm63xx_spi_remove(struct platform_device *pdev)
0620 {
0621 struct spi_master *master = platform_get_drvdata(pdev);
0622 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
0623
0624
0625 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
0626
0627
0628 clk_disable_unprepare(bs->clk);
0629
0630 return 0;
0631 }
0632
0633 #ifdef CONFIG_PM_SLEEP
0634 static int bcm63xx_spi_suspend(struct device *dev)
0635 {
0636 struct spi_master *master = dev_get_drvdata(dev);
0637 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
0638
0639 spi_master_suspend(master);
0640
0641 clk_disable_unprepare(bs->clk);
0642
0643 return 0;
0644 }
0645
0646 static int bcm63xx_spi_resume(struct device *dev)
0647 {
0648 struct spi_master *master = dev_get_drvdata(dev);
0649 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
0650 int ret;
0651
0652 ret = clk_prepare_enable(bs->clk);
0653 if (ret)
0654 return ret;
0655
0656 spi_master_resume(master);
0657
0658 return 0;
0659 }
0660 #endif
0661
0662 static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
0663 SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)
0664 };
0665
0666 static struct platform_driver bcm63xx_spi_driver = {
0667 .driver = {
0668 .name = "bcm63xx-spi",
0669 .pm = &bcm63xx_spi_pm_ops,
0670 .of_match_table = bcm63xx_spi_of_match,
0671 },
0672 .id_table = bcm63xx_spi_dev_match,
0673 .probe = bcm63xx_spi_probe,
0674 .remove = bcm63xx_spi_remove,
0675 };
0676
0677 module_platform_driver(bcm63xx_spi_driver);
0678
0679 MODULE_ALIAS("platform:bcm63xx_spi");
0680 MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
0681 MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
0682 MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
0683 MODULE_LICENSE("GPL");