Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0)
0002 /*
0003  * Microchip CoreSPI SPI controller driver
0004  *
0005  * Copyright (c) 2018-2022 Microchip Technology Inc. and its subsidiaries
0006  *
0007  * Author: Daire McNamara <daire.mcnamara@microchip.com>
0008  * Author: Conor Dooley <conor.dooley@microchip.com>
0009  *
0010  */
0011 
0012 #include <linux/clk.h>
0013 #include <linux/delay.h>
0014 #include <linux/err.h>
0015 #include <linux/init.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/io.h>
0018 #include <linux/module.h>
0019 #include <linux/of.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/spi/spi.h>
0022 
0023 #define MAX_LEN             (0xffff)
0024 #define MAX_CS              (8)
0025 #define DEFAULT_FRAMESIZE       (8)
0026 #define FIFO_DEPTH          (32)
0027 #define CLK_GEN_MODE1_MAX       (255)
0028 #define CLK_GEN_MODE0_MAX       (15)
0029 #define CLK_GEN_MIN         (0)
0030 #define MODE_X_MASK_SHIFT       (24)
0031 
0032 #define CONTROL_ENABLE          BIT(0)
0033 #define CONTROL_MASTER          BIT(1)
0034 #define CONTROL_RX_DATA_INT     BIT(4)
0035 #define CONTROL_TX_DATA_INT     BIT(5)
0036 #define CONTROL_RX_OVER_INT     BIT(6)
0037 #define CONTROL_TX_UNDER_INT        BIT(7)
0038 #define CONTROL_SPO         BIT(24)
0039 #define CONTROL_SPH         BIT(25)
0040 #define CONTROL_SPS         BIT(26)
0041 #define CONTROL_FRAMEURUN       BIT(27)
0042 #define CONTROL_CLKMODE         BIT(28)
0043 #define CONTROL_BIGFIFO         BIT(29)
0044 #define CONTROL_OENOFF          BIT(30)
0045 #define CONTROL_RESET           BIT(31)
0046 
0047 #define CONTROL_MODE_MASK       GENMASK(3, 2)
0048 #define  MOTOROLA_MODE          (0)
0049 #define CONTROL_FRAMECNT_MASK       GENMASK(23, 8)
0050 #define CONTROL_FRAMECNT_SHIFT      (8)
0051 
0052 #define STATUS_ACTIVE           BIT(14)
0053 #define STATUS_SSEL         BIT(13)
0054 #define STATUS_FRAMESTART       BIT(12)
0055 #define STATUS_TXFIFO_EMPTY_NEXT_READ   BIT(11)
0056 #define STATUS_TXFIFO_EMPTY     BIT(10)
0057 #define STATUS_TXFIFO_FULL_NEXT_WRITE   BIT(9)
0058 #define STATUS_TXFIFO_FULL      BIT(8)
0059 #define STATUS_RXFIFO_EMPTY_NEXT_READ   BIT(7)
0060 #define STATUS_RXFIFO_EMPTY     BIT(6)
0061 #define STATUS_RXFIFO_FULL_NEXT_WRITE   BIT(5)
0062 #define STATUS_RXFIFO_FULL      BIT(4)
0063 #define STATUS_TX_UNDERRUN      BIT(3)
0064 #define STATUS_RX_OVERFLOW      BIT(2)
0065 #define STATUS_RXDAT_RXED       BIT(1)
0066 #define STATUS_TXDAT_SENT       BIT(0)
0067 
0068 #define INT_TXDONE          BIT(0)
0069 #define INT_RXRDY           BIT(1)
0070 #define INT_RX_CHANNEL_OVERFLOW     BIT(2)
0071 #define INT_TX_CHANNEL_UNDERRUN     BIT(3)
0072 
0073 #define INT_ENABLE_MASK (CONTROL_RX_DATA_INT | CONTROL_TX_DATA_INT | \
0074              CONTROL_RX_OVER_INT | CONTROL_TX_UNDER_INT)
0075 
0076 #define REG_CONTROL     (0x00)
0077 #define REG_FRAME_SIZE      (0x04)
0078 #define REG_STATUS      (0x08)
0079 #define REG_INT_CLEAR       (0x0c)
0080 #define REG_RX_DATA     (0x10)
0081 #define REG_TX_DATA     (0x14)
0082 #define REG_CLK_GEN     (0x18)
0083 #define REG_SLAVE_SELECT    (0x1c)
0084 #define  SSEL_MASK      GENMASK(7, 0)
0085 #define  SSEL_DIRECT        BIT(8)
0086 #define  SSELOUT_SHIFT      9
0087 #define  SSELOUT        BIT(SSELOUT_SHIFT)
0088 #define REG_MIS         (0x20)
0089 #define REG_RIS         (0x24)
0090 #define REG_CONTROL2        (0x28)
0091 #define REG_COMMAND     (0x2c)
0092 #define REG_PKTSIZE     (0x30)
0093 #define REG_CMD_SIZE        (0x34)
0094 #define REG_HWSTATUS        (0x38)
0095 #define REG_STAT8       (0x3c)
0096 #define REG_CTRL2       (0x48)
0097 #define REG_FRAMESUP        (0x50)
0098 
0099 struct mchp_corespi {
0100     void __iomem *regs;
0101     struct clk *clk;
0102     const u8 *tx_buf;
0103     u8 *rx_buf;
0104     u32 clk_gen; /* divider for spi output clock generated by the controller */
0105     u32 clk_mode;
0106     int irq;
0107     int tx_len;
0108     int rx_len;
0109     int pending;
0110 };
0111 
0112 static inline u32 mchp_corespi_read(struct mchp_corespi *spi, unsigned int reg)
0113 {
0114     return readl(spi->regs + reg);
0115 }
0116 
0117 static inline void mchp_corespi_write(struct mchp_corespi *spi, unsigned int reg, u32 val)
0118 {
0119     writel(val, spi->regs + reg);
0120 }
0121 
0122 static inline void mchp_corespi_enable(struct mchp_corespi *spi)
0123 {
0124     u32 control = mchp_corespi_read(spi, REG_CONTROL);
0125 
0126     control |= CONTROL_ENABLE;
0127 
0128     mchp_corespi_write(spi, REG_CONTROL, control);
0129 }
0130 
0131 static inline void mchp_corespi_disable(struct mchp_corespi *spi)
0132 {
0133     u32 control = mchp_corespi_read(spi, REG_CONTROL);
0134 
0135     control &= ~CONTROL_ENABLE;
0136 
0137     mchp_corespi_write(spi, REG_CONTROL, control);
0138 }
0139 
0140 static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi)
0141 {
0142     u8 data;
0143     int fifo_max, i = 0;
0144 
0145     fifo_max = min(spi->rx_len, FIFO_DEPTH);
0146 
0147     while ((i < fifo_max) && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)) {
0148         data = mchp_corespi_read(spi, REG_RX_DATA);
0149 
0150         if (spi->rx_buf)
0151             *spi->rx_buf++ = data;
0152         i++;
0153     }
0154     spi->rx_len -= i;
0155     spi->pending -= i;
0156 }
0157 
0158 static void mchp_corespi_enable_ints(struct mchp_corespi *spi)
0159 {
0160     u32 control, mask = INT_ENABLE_MASK;
0161 
0162     mchp_corespi_disable(spi);
0163 
0164     control = mchp_corespi_read(spi, REG_CONTROL);
0165 
0166     control |= mask;
0167     mchp_corespi_write(spi, REG_CONTROL, control);
0168 
0169     control |= CONTROL_ENABLE;
0170     mchp_corespi_write(spi, REG_CONTROL, control);
0171 }
0172 
0173 static void mchp_corespi_disable_ints(struct mchp_corespi *spi)
0174 {
0175     u32 control, mask = INT_ENABLE_MASK;
0176 
0177     mchp_corespi_disable(spi);
0178 
0179     control = mchp_corespi_read(spi, REG_CONTROL);
0180     control &= ~mask;
0181     mchp_corespi_write(spi, REG_CONTROL, control);
0182 
0183     control |= CONTROL_ENABLE;
0184     mchp_corespi_write(spi, REG_CONTROL, control);
0185 }
0186 
0187 static inline void mchp_corespi_set_xfer_size(struct mchp_corespi *spi, int len)
0188 {
0189     u32 control;
0190     u16 lenpart;
0191 
0192     /*
0193      * Disable the SPI controller. Writes to transfer length have
0194      * no effect when the controller is enabled.
0195      */
0196     mchp_corespi_disable(spi);
0197 
0198     /*
0199      * The lower 16 bits of the frame count are stored in the control reg
0200      * for legacy reasons, but the upper 16 written to a different register:
0201      * FRAMESUP. While both the upper and lower bits can be *READ* from the
0202      * FRAMESUP register, writing to the lower 16 bits is a NOP
0203      */
0204     lenpart = len & 0xffff;
0205 
0206     control = mchp_corespi_read(spi, REG_CONTROL);
0207     control &= ~CONTROL_FRAMECNT_MASK;
0208     control |= lenpart << CONTROL_FRAMECNT_SHIFT;
0209     mchp_corespi_write(spi, REG_CONTROL, control);
0210 
0211     lenpart = len & 0xffff0000;
0212     mchp_corespi_write(spi, REG_FRAMESUP, lenpart);
0213 
0214     control |= CONTROL_ENABLE;
0215     mchp_corespi_write(spi, REG_CONTROL, control);
0216 }
0217 
0218 static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi)
0219 {
0220     u8 byte;
0221     int fifo_max, i = 0;
0222 
0223     fifo_max = min(spi->tx_len, FIFO_DEPTH);
0224     mchp_corespi_set_xfer_size(spi, fifo_max);
0225 
0226     while ((i < fifo_max) && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_TXFIFO_FULL)) {
0227         byte = spi->tx_buf ? *spi->tx_buf++ : 0xaa;
0228         mchp_corespi_write(spi, REG_TX_DATA, byte);
0229         i++;
0230     }
0231 
0232     spi->tx_len -= i;
0233     spi->pending += i;
0234 }
0235 
0236 static inline void mchp_corespi_set_framesize(struct mchp_corespi *spi, int bt)
0237 {
0238     u32 control;
0239 
0240     /*
0241      * Disable the SPI controller. Writes to the frame size have
0242      * no effect when the controller is enabled.
0243      */
0244     mchp_corespi_disable(spi);
0245 
0246     mchp_corespi_write(spi, REG_FRAME_SIZE, bt);
0247 
0248     control = mchp_corespi_read(spi, REG_CONTROL);
0249     control |= CONTROL_ENABLE;
0250     mchp_corespi_write(spi, REG_CONTROL, control);
0251 }
0252 
0253 static void mchp_corespi_set_cs(struct spi_device *spi, bool disable)
0254 {
0255     u32 reg;
0256     struct mchp_corespi *corespi = spi_master_get_devdata(spi->master);
0257 
0258     reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT);
0259     reg &= ~BIT(spi->chip_select);
0260     reg |= !disable << spi->chip_select;
0261 
0262     mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg);
0263 }
0264 
0265 static int mchp_corespi_setup(struct spi_device *spi)
0266 {
0267     struct mchp_corespi *corespi = spi_master_get_devdata(spi->master);
0268     u32 reg;
0269 
0270     /*
0271      * Active high slaves need to be specifically set to their inactive
0272      * states during probe by adding them to the "control group" & thus
0273      * driving their select line low.
0274      */
0275     if (spi->mode & SPI_CS_HIGH) {
0276         reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT);
0277         reg |= BIT(spi->chip_select);
0278         mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg);
0279     }
0280     return 0;
0281 }
0282 
0283 static void mchp_corespi_init(struct spi_master *master, struct mchp_corespi *spi)
0284 {
0285     unsigned long clk_hz;
0286     u32 control = mchp_corespi_read(spi, REG_CONTROL);
0287 
0288     control |= CONTROL_MASTER;
0289 
0290     control &= ~CONTROL_MODE_MASK;
0291     control |= MOTOROLA_MODE;
0292 
0293     mchp_corespi_set_framesize(spi, DEFAULT_FRAMESIZE);
0294 
0295     /* max. possible spi clock rate is the apb clock rate */
0296     clk_hz = clk_get_rate(spi->clk);
0297     master->max_speed_hz = clk_hz;
0298 
0299     /*
0300      * The controller must be configured so that it doesn't remove Chip
0301      * Select until the entire message has been transferred, even if at
0302      * some points TX FIFO becomes empty.
0303      *
0304      * BIGFIFO mode is also enabled, which sets the fifo depth to 32 frames
0305      * for the 8 bit transfers that this driver uses.
0306      */
0307     control = mchp_corespi_read(spi, REG_CONTROL);
0308     control |= CONTROL_SPS | CONTROL_BIGFIFO;
0309 
0310     mchp_corespi_write(spi, REG_CONTROL, control);
0311 
0312     mchp_corespi_enable_ints(spi);
0313 
0314     /*
0315      * It is required to enable direct mode, otherwise control over the chip
0316      * select is relinquished to the hardware. SSELOUT is enabled too so we
0317      * can deal with active high slaves.
0318      */
0319     mchp_corespi_write(spi, REG_SLAVE_SELECT, SSELOUT | SSEL_DIRECT);
0320 
0321     control = mchp_corespi_read(spi, REG_CONTROL);
0322 
0323     control &= ~CONTROL_RESET;
0324     control |= CONTROL_ENABLE;
0325 
0326     mchp_corespi_write(spi, REG_CONTROL, control);
0327 }
0328 
0329 static inline void mchp_corespi_set_clk_gen(struct mchp_corespi *spi)
0330 {
0331     u32 control;
0332 
0333     mchp_corespi_disable(spi);
0334 
0335     control = mchp_corespi_read(spi, REG_CONTROL);
0336     if (spi->clk_mode)
0337         control |= CONTROL_CLKMODE;
0338     else
0339         control &= ~CONTROL_CLKMODE;
0340 
0341     mchp_corespi_write(spi, REG_CLK_GEN, spi->clk_gen);
0342     mchp_corespi_write(spi, REG_CONTROL, control);
0343     mchp_corespi_write(spi, REG_CONTROL, control | CONTROL_ENABLE);
0344 }
0345 
0346 static inline void mchp_corespi_set_mode(struct mchp_corespi *spi, unsigned int mode)
0347 {
0348     u32 control, mode_val;
0349 
0350     switch (mode & SPI_MODE_X_MASK) {
0351     case SPI_MODE_0:
0352         mode_val = 0;
0353         break;
0354     case SPI_MODE_1:
0355         mode_val = CONTROL_SPH;
0356         break;
0357     case SPI_MODE_2:
0358         mode_val = CONTROL_SPO;
0359         break;
0360     case SPI_MODE_3:
0361         mode_val = CONTROL_SPH | CONTROL_SPO;
0362         break;
0363     }
0364 
0365     /*
0366      * Disable the SPI controller. Writes to the frame size have
0367      * no effect when the controller is enabled.
0368      */
0369     mchp_corespi_disable(spi);
0370 
0371     control = mchp_corespi_read(spi, REG_CONTROL);
0372     control &= ~(SPI_MODE_X_MASK << MODE_X_MASK_SHIFT);
0373     control |= mode_val;
0374 
0375     mchp_corespi_write(spi, REG_CONTROL, control);
0376 
0377     control |= CONTROL_ENABLE;
0378     mchp_corespi_write(spi, REG_CONTROL, control);
0379 }
0380 
0381 static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id)
0382 {
0383     struct spi_master *master = dev_id;
0384     struct mchp_corespi *spi = spi_master_get_devdata(master);
0385     u32 intfield = mchp_corespi_read(spi, REG_MIS) & 0xf;
0386     bool finalise = false;
0387 
0388     /* Interrupt line may be shared and not for us at all */
0389     if (intfield == 0)
0390         return IRQ_NONE;
0391 
0392     if (intfield & INT_TXDONE) {
0393         mchp_corespi_write(spi, REG_INT_CLEAR, INT_TXDONE);
0394 
0395         if (spi->rx_len)
0396             mchp_corespi_read_fifo(spi);
0397 
0398         if (spi->tx_len)
0399             mchp_corespi_write_fifo(spi);
0400 
0401         if (!spi->rx_len)
0402             finalise = true;
0403     }
0404 
0405     if (intfield & INT_RXRDY)
0406         mchp_corespi_write(spi, REG_INT_CLEAR, INT_RXRDY);
0407 
0408     if (intfield & INT_RX_CHANNEL_OVERFLOW) {
0409         mchp_corespi_write(spi, REG_INT_CLEAR, INT_RX_CHANNEL_OVERFLOW);
0410         finalise = true;
0411         dev_err(&master->dev,
0412             "%s: RX OVERFLOW: rxlen: %d, txlen: %d\n", __func__,
0413             spi->rx_len, spi->tx_len);
0414     }
0415 
0416     if (intfield & INT_TX_CHANNEL_UNDERRUN) {
0417         mchp_corespi_write(spi, REG_INT_CLEAR, INT_TX_CHANNEL_UNDERRUN);
0418         finalise = true;
0419         dev_err(&master->dev,
0420             "%s: TX UNDERFLOW: rxlen: %d, txlen: %d\n", __func__,
0421             spi->rx_len, spi->tx_len);
0422     }
0423 
0424     if (finalise)
0425         spi_finalize_current_transfer(master);
0426 
0427     return IRQ_HANDLED;
0428 }
0429 
0430 static int mchp_corespi_calculate_clkgen(struct mchp_corespi *spi,
0431                      unsigned long target_hz)
0432 {
0433     unsigned long clk_hz, spi_hz, clk_gen;
0434 
0435     clk_hz = clk_get_rate(spi->clk);
0436     if (!clk_hz)
0437         return -EINVAL;
0438     spi_hz = min(target_hz, clk_hz);
0439 
0440     /*
0441      * There are two possible clock modes for the controller generated
0442      * clock's division ratio:
0443      * CLK_MODE = 0: 1 / (2^(CLK_GEN + 1)) where CLK_GEN = 0 to 15.
0444      * CLK_MODE = 1: 1 / (2 * CLK_GEN + 1) where CLK_GEN = 0 to 255.
0445      * First try mode 1, fall back to 0 and if we have tried both modes and
0446      * we /still/ can't get a good setting, we then throw the toys out of
0447      * the pram and give up
0448      * clk_gen is the register name for the clock divider on MPFS.
0449      */
0450     clk_gen = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1;
0451     if (clk_gen > CLK_GEN_MODE1_MAX || clk_gen <= CLK_GEN_MIN) {
0452         clk_gen = DIV_ROUND_UP(clk_hz, spi_hz);
0453         clk_gen = fls(clk_gen) - 1;
0454 
0455         if (clk_gen > CLK_GEN_MODE0_MAX)
0456             return -EINVAL;
0457 
0458         spi->clk_mode = 0;
0459     } else {
0460         spi->clk_mode = 1;
0461     }
0462 
0463     spi->clk_gen = clk_gen;
0464     return 0;
0465 }
0466 
0467 static int mchp_corespi_transfer_one(struct spi_master *master,
0468                      struct spi_device *spi_dev,
0469                      struct spi_transfer *xfer)
0470 {
0471     struct mchp_corespi *spi = spi_master_get_devdata(master);
0472     int ret;
0473 
0474     ret = mchp_corespi_calculate_clkgen(spi, (unsigned long)xfer->speed_hz);
0475     if (ret) {
0476         dev_err(&master->dev, "failed to set clk_gen for target %u Hz\n", xfer->speed_hz);
0477         return ret;
0478     }
0479 
0480     mchp_corespi_set_clk_gen(spi);
0481 
0482     spi->tx_buf = xfer->tx_buf;
0483     spi->rx_buf = xfer->rx_buf;
0484     spi->tx_len = xfer->len;
0485     spi->rx_len = xfer->len;
0486     spi->pending = 0;
0487 
0488     mchp_corespi_set_xfer_size(spi, (spi->tx_len > FIFO_DEPTH)
0489                    ? FIFO_DEPTH : spi->tx_len);
0490 
0491     if (spi->tx_len)
0492         mchp_corespi_write_fifo(spi);
0493     return 1;
0494 }
0495 
0496 static int mchp_corespi_prepare_message(struct spi_master *master,
0497                     struct spi_message *msg)
0498 {
0499     struct spi_device *spi_dev = msg->spi;
0500     struct mchp_corespi *spi = spi_master_get_devdata(master);
0501 
0502     mchp_corespi_set_framesize(spi, DEFAULT_FRAMESIZE);
0503     mchp_corespi_set_mode(spi, spi_dev->mode);
0504 
0505     return 0;
0506 }
0507 
0508 static int mchp_corespi_probe(struct platform_device *pdev)
0509 {
0510     struct spi_master *master;
0511     struct mchp_corespi *spi;
0512     struct resource *res;
0513     u32 num_cs;
0514     int ret = 0;
0515 
0516     master = devm_spi_alloc_master(&pdev->dev, sizeof(*spi));
0517     if (!master)
0518         return dev_err_probe(&pdev->dev, -ENOMEM,
0519                      "unable to allocate master for SPI controller\n");
0520 
0521     platform_set_drvdata(pdev, master);
0522 
0523     if (of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs))
0524         num_cs = MAX_CS;
0525 
0526     master->num_chipselect = num_cs;
0527     master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
0528     master->setup = mchp_corespi_setup;
0529     master->bits_per_word_mask = SPI_BPW_MASK(8);
0530     master->transfer_one = mchp_corespi_transfer_one;
0531     master->prepare_message = mchp_corespi_prepare_message;
0532     master->set_cs = mchp_corespi_set_cs;
0533     master->dev.of_node = pdev->dev.of_node;
0534 
0535     spi = spi_master_get_devdata(master);
0536 
0537     spi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0538     if (IS_ERR(spi->regs))
0539         return PTR_ERR(spi->regs);
0540 
0541     spi->irq = platform_get_irq(pdev, 0);
0542     if (spi->irq <= 0)
0543         return dev_err_probe(&pdev->dev, -ENXIO,
0544                      "invalid IRQ %d for SPI controller\n",
0545                      spi->irq);
0546 
0547     ret = devm_request_irq(&pdev->dev, spi->irq, mchp_corespi_interrupt,
0548                    IRQF_SHARED, dev_name(&pdev->dev), master);
0549     if (ret)
0550         return dev_err_probe(&pdev->dev, ret,
0551                      "could not request irq: %d\n", ret);
0552 
0553     spi->clk = devm_clk_get(&pdev->dev, NULL);
0554     if (IS_ERR(spi->clk))
0555         return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk),
0556                      "could not get clk: %d\n", ret);
0557 
0558     ret = clk_prepare_enable(spi->clk);
0559     if (ret)
0560         return dev_err_probe(&pdev->dev, ret,
0561                      "failed to enable clock\n");
0562 
0563     mchp_corespi_init(master, spi);
0564 
0565     ret = devm_spi_register_master(&pdev->dev, master);
0566     if (ret) {
0567         mchp_corespi_disable(spi);
0568         clk_disable_unprepare(spi->clk);
0569         return dev_err_probe(&pdev->dev, ret,
0570                      "unable to register master for SPI controller\n");
0571     }
0572 
0573     dev_info(&pdev->dev, "Registered SPI controller %d\n", master->bus_num);
0574 
0575     return 0;
0576 }
0577 
0578 static int mchp_corespi_remove(struct platform_device *pdev)
0579 {
0580     struct spi_master *master  = platform_get_drvdata(pdev);
0581     struct mchp_corespi *spi = spi_master_get_devdata(master);
0582 
0583     mchp_corespi_disable_ints(spi);
0584     clk_disable_unprepare(spi->clk);
0585     mchp_corespi_disable(spi);
0586 
0587     return 0;
0588 }
0589 
0590 #define MICROCHIP_SPI_PM_OPS (NULL)
0591 
0592 /*
0593  * Platform driver data structure
0594  */
0595 
0596 #if defined(CONFIG_OF)
0597 static const struct of_device_id mchp_corespi_dt_ids[] = {
0598     { .compatible = "microchip,mpfs-spi" },
0599     { /* sentinel */ }
0600 };
0601 MODULE_DEVICE_TABLE(of, mchp_corespi_dt_ids);
0602 #endif
0603 
0604 static struct platform_driver mchp_corespi_driver = {
0605     .probe = mchp_corespi_probe,
0606     .driver = {
0607         .name = "microchip-corespi",
0608         .pm = MICROCHIP_SPI_PM_OPS,
0609         .of_match_table = of_match_ptr(mchp_corespi_dt_ids),
0610     },
0611     .remove = mchp_corespi_remove,
0612 };
0613 module_platform_driver(mchp_corespi_driver);
0614 MODULE_DESCRIPTION("Microchip coreSPI SPI controller driver");
0615 MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
0616 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
0617 MODULE_LICENSE("GPL");