linux/drivers/spi/spi-orion.c
<<
>>
Prefs
   1/*
   2 * Marvell Orion SPI controller driver
   3 *
   4 * Author: Shadi Ammouri <shadi@marvell.com>
   5 * Copyright (C) 2007-2008 Marvell Ltd.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/interrupt.h>
  13#include <linux/delay.h>
  14#include <linux/platform_device.h>
  15#include <linux/err.h>
  16#include <linux/io.h>
  17#include <linux/spi/spi.h>
  18#include <linux/module.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/of.h>
  21#include <linux/of_device.h>
  22#include <linux/clk.h>
  23#include <linux/sizes.h>
  24#include <asm/unaligned.h>
  25
  26#define DRIVER_NAME                     "orion_spi"
  27
  28/* Runtime PM autosuspend timeout: PM is fairly light on this driver */
  29#define SPI_AUTOSUSPEND_TIMEOUT         200
  30
  31/* Some SoCs using this driver support up to 8 chip selects.
  32 * It is up to the implementer to only use the chip selects
  33 * that are available.
  34 */
  35#define ORION_NUM_CHIPSELECTS           8
  36
  37#define ORION_SPI_WAIT_RDY_MAX_LOOP     2000 /* in usec */
  38
  39#define ORION_SPI_IF_CTRL_REG           0x00
  40#define ORION_SPI_IF_CONFIG_REG         0x04
  41#define ORION_SPI_DATA_OUT_REG          0x08
  42#define ORION_SPI_DATA_IN_REG           0x0c
  43#define ORION_SPI_INT_CAUSE_REG         0x10
  44#define ORION_SPI_TIMING_PARAMS_REG     0x18
  45
  46#define ORION_SPI_TMISO_SAMPLE_MASK     (0x3 << 6)
  47#define ORION_SPI_TMISO_SAMPLE_1        (1 << 6)
  48#define ORION_SPI_TMISO_SAMPLE_2        (2 << 6)
  49
  50#define ORION_SPI_MODE_CPOL             (1 << 11)
  51#define ORION_SPI_MODE_CPHA             (1 << 12)
  52#define ORION_SPI_IF_8_16_BIT_MODE      (1 << 5)
  53#define ORION_SPI_CLK_PRESCALE_MASK     0x1F
  54#define ARMADA_SPI_CLK_PRESCALE_MASK    0xDF
  55#define ORION_SPI_MODE_MASK             (ORION_SPI_MODE_CPOL | \
  56                                         ORION_SPI_MODE_CPHA)
  57#define ORION_SPI_CS_MASK       0x1C
  58#define ORION_SPI_CS_SHIFT      2
  59#define ORION_SPI_CS(cs)        ((cs << ORION_SPI_CS_SHIFT) & \
  60                                        ORION_SPI_CS_MASK)
  61
  62enum orion_spi_type {
  63        ORION_SPI,
  64        ARMADA_SPI,
  65};
  66
  67struct orion_spi_dev {
  68        enum orion_spi_type     typ;
  69        /*
  70         * min_divisor and max_hz should be exclusive, the only we can
  71         * have both is for managing the armada-370-spi case with old
  72         * device tree
  73         */
  74        unsigned long           max_hz;
  75        unsigned int            min_divisor;
  76        unsigned int            max_divisor;
  77        u32                     prescale_mask;
  78        bool                    is_errata_50mhz_ac;
  79};
  80
  81struct orion_spi {
  82        struct spi_master       *master;
  83        void __iomem            *base;
  84        struct clk              *clk;
  85        const struct orion_spi_dev *devdata;
  86};
  87
  88static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
  89{
  90        return orion_spi->base + reg;
  91}
  92
  93static inline void
  94orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
  95{
  96        void __iomem *reg_addr = spi_reg(orion_spi, reg);
  97        u32 val;
  98
  99        val = readl(reg_addr);
 100        val |= mask;
 101        writel(val, reg_addr);
 102}
 103
 104static inline void
 105orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
 106{
 107        void __iomem *reg_addr = spi_reg(orion_spi, reg);
 108        u32 val;
 109
 110        val = readl(reg_addr);
 111        val &= ~mask;
 112        writel(val, reg_addr);
 113}
 114
 115static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
 116{
 117        u32 tclk_hz;
 118        u32 rate;
 119        u32 prescale;
 120        u32 reg;
 121        struct orion_spi *orion_spi;
 122        const struct orion_spi_dev *devdata;
 123
 124        orion_spi = spi_master_get_devdata(spi->master);
 125        devdata = orion_spi->devdata;
 126
 127        tclk_hz = clk_get_rate(orion_spi->clk);
 128
 129        if (devdata->typ == ARMADA_SPI) {
 130                unsigned int clk, spr, sppr, sppr2, err;
 131                unsigned int best_spr, best_sppr, best_err;
 132
 133                best_err = speed;
 134                best_spr = 0;
 135                best_sppr = 0;
 136
 137                /* Iterate over the valid range looking for best fit */
 138                for (sppr = 0; sppr < 8; sppr++) {
 139                        sppr2 = 0x1 << sppr;
 140
 141                        spr = tclk_hz / sppr2;
 142                        spr = DIV_ROUND_UP(spr, speed);
 143                        if ((spr == 0) || (spr > 15))
 144                                continue;
 145
 146                        clk = tclk_hz / (spr * sppr2);
 147                        err = speed - clk;
 148
 149                        if (err < best_err) {
 150                                best_spr = spr;
 151                                best_sppr = sppr;
 152                                best_err = err;
 153                        }
 154                }
 155
 156                if ((best_sppr == 0) && (best_spr == 0))
 157                        return -EINVAL;
 158
 159                prescale = ((best_sppr & 0x6) << 5) |
 160                        ((best_sppr & 0x1) << 4) | best_spr;
 161        } else {
 162                /*
 163                 * the supported rates are: 4,6,8...30
 164                 * round up as we look for equal or less speed
 165                 */
 166                rate = DIV_ROUND_UP(tclk_hz, speed);
 167                rate = roundup(rate, 2);
 168
 169                /* check if requested speed is too small */
 170                if (rate > 30)
 171                        return -EINVAL;
 172
 173                if (rate < 4)
 174                        rate = 4;
 175
 176                /* Convert the rate to SPI clock divisor value. */
 177                prescale = 0x10 + rate/2;
 178        }
 179
 180        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 181        reg = ((reg & ~devdata->prescale_mask) | prescale);
 182        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 183
 184        return 0;
 185}
 186
 187static void
 188orion_spi_mode_set(struct spi_device *spi)
 189{
 190        u32 reg;
 191        struct orion_spi *orion_spi;
 192
 193        orion_spi = spi_master_get_devdata(spi->master);
 194
 195        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 196        reg &= ~ORION_SPI_MODE_MASK;
 197        if (spi->mode & SPI_CPOL)
 198                reg |= ORION_SPI_MODE_CPOL;
 199        if (spi->mode & SPI_CPHA)
 200                reg |= ORION_SPI_MODE_CPHA;
 201        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 202}
 203
 204static void
 205orion_spi_50mhz_ac_timing_erratum(struct spi_device *spi, unsigned int speed)
 206{
 207        u32 reg;
 208        struct orion_spi *orion_spi;
 209
 210        orion_spi = spi_master_get_devdata(spi->master);
 211
 212        /*
 213         * Erratum description: (Erratum NO. FE-9144572) The device
 214         * SPI interface supports frequencies of up to 50 MHz.
 215         * However, due to this erratum, when the device core clock is
 216         * 250 MHz and the SPI interfaces is configured for 50MHz SPI
 217         * clock and CPOL=CPHA=1 there might occur data corruption on
 218         * reads from the SPI device.
 219         * Erratum Workaround:
 220         * Work in one of the following configurations:
 221         * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration
 222         * Register".
 223         * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1
 224         * Register" before setting the interface.
 225         */
 226        reg = readl(spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
 227        reg &= ~ORION_SPI_TMISO_SAMPLE_MASK;
 228
 229        if (clk_get_rate(orion_spi->clk) == 250000000 &&
 230                        speed == 50000000 && spi->mode & SPI_CPOL &&
 231                        spi->mode & SPI_CPHA)
 232                reg |= ORION_SPI_TMISO_SAMPLE_2;
 233        else
 234                reg |= ORION_SPI_TMISO_SAMPLE_1; /* This is the default value */
 235
 236        writel(reg, spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
 237}
 238
 239/*
 240 * called only when no transfer is active on the bus
 241 */
 242static int
 243orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 244{
 245        struct orion_spi *orion_spi;
 246        unsigned int speed = spi->max_speed_hz;
 247        unsigned int bits_per_word = spi->bits_per_word;
 248        int     rc;
 249
 250        orion_spi = spi_master_get_devdata(spi->master);
 251
 252        if ((t != NULL) && t->speed_hz)
 253                speed = t->speed_hz;
 254
 255        if ((t != NULL) && t->bits_per_word)
 256                bits_per_word = t->bits_per_word;
 257
 258        orion_spi_mode_set(spi);
 259
 260        if (orion_spi->devdata->is_errata_50mhz_ac)
 261                orion_spi_50mhz_ac_timing_erratum(spi, speed);
 262
 263        rc = orion_spi_baudrate_set(spi, speed);
 264        if (rc)
 265                return rc;
 266
 267        if (bits_per_word == 16)
 268                orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
 269                                  ORION_SPI_IF_8_16_BIT_MODE);
 270        else
 271                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
 272                                  ORION_SPI_IF_8_16_BIT_MODE);
 273
 274        return 0;
 275}
 276
 277static void orion_spi_set_cs(struct spi_device *spi, bool enable)
 278{
 279        struct orion_spi *orion_spi;
 280
 281        orion_spi = spi_master_get_devdata(spi->master);
 282
 283        orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
 284        orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
 285                                ORION_SPI_CS(spi->chip_select));
 286
 287        /* Chip select logic is inverted from spi_set_cs */
 288        if (!enable)
 289                orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 290        else
 291                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 292}
 293
 294static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
 295{
 296        int i;
 297
 298        for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
 299                if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
 300                        return 1;
 301
 302                udelay(1);
 303        }
 304
 305        return -1;
 306}
 307
 308static inline int
 309orion_spi_write_read_8bit(struct spi_device *spi,
 310                          const u8 **tx_buf, u8 **rx_buf)
 311{
 312        void __iomem *tx_reg, *rx_reg, *int_reg;
 313        struct orion_spi *orion_spi;
 314
 315        orion_spi = spi_master_get_devdata(spi->master);
 316        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 317        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 318        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 319
 320        /* clear the interrupt cause register */
 321        writel(0x0, int_reg);
 322
 323        if (tx_buf && *tx_buf)
 324                writel(*(*tx_buf)++, tx_reg);
 325        else
 326                writel(0, tx_reg);
 327
 328        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 329                dev_err(&spi->dev, "TXS timed out\n");
 330                return -1;
 331        }
 332
 333        if (rx_buf && *rx_buf)
 334                *(*rx_buf)++ = readl(rx_reg);
 335
 336        return 1;
 337}
 338
 339static inline int
 340orion_spi_write_read_16bit(struct spi_device *spi,
 341                           const u16 **tx_buf, u16 **rx_buf)
 342{
 343        void __iomem *tx_reg, *rx_reg, *int_reg;
 344        struct orion_spi *orion_spi;
 345
 346        orion_spi = spi_master_get_devdata(spi->master);
 347        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 348        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 349        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 350
 351        /* clear the interrupt cause register */
 352        writel(0x0, int_reg);
 353
 354        if (tx_buf && *tx_buf)
 355                writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg);
 356        else
 357                writel(0, tx_reg);
 358
 359        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 360                dev_err(&spi->dev, "TXS timed out\n");
 361                return -1;
 362        }
 363
 364        if (rx_buf && *rx_buf)
 365                put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++);
 366
 367        return 1;
 368}
 369
 370static unsigned int
 371orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
 372{
 373        unsigned int count;
 374        int word_len;
 375
 376        word_len = spi->bits_per_word;
 377        count = xfer->len;
 378
 379        if (word_len == 8) {
 380                const u8 *tx = xfer->tx_buf;
 381                u8 *rx = xfer->rx_buf;
 382
 383                do {
 384                        if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
 385                                goto out;
 386                        count--;
 387                } while (count);
 388        } else if (word_len == 16) {
 389                const u16 *tx = xfer->tx_buf;
 390                u16 *rx = xfer->rx_buf;
 391
 392                do {
 393                        if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
 394                                goto out;
 395                        count -= 2;
 396                } while (count);
 397        }
 398
 399out:
 400        return xfer->len - count;
 401}
 402
 403static int orion_spi_transfer_one(struct spi_master *master,
 404                                        struct spi_device *spi,
 405                                        struct spi_transfer *t)
 406{
 407        int status = 0;
 408
 409        status = orion_spi_setup_transfer(spi, t);
 410        if (status < 0)
 411                return status;
 412
 413        if (t->len)
 414                orion_spi_write_read(spi, t);
 415
 416        return status;
 417}
 418
 419static int orion_spi_setup(struct spi_device *spi)
 420{
 421        return orion_spi_setup_transfer(spi, NULL);
 422}
 423
 424static int orion_spi_reset(struct orion_spi *orion_spi)
 425{
 426        /* Verify that the CS is deasserted */
 427        orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 428        return 0;
 429}
 430
 431static const struct orion_spi_dev orion_spi_dev_data = {
 432        .typ = ORION_SPI,
 433        .min_divisor = 4,
 434        .max_divisor = 30,
 435        .prescale_mask = ORION_SPI_CLK_PRESCALE_MASK,
 436};
 437
 438static const struct orion_spi_dev armada_370_spi_dev_data = {
 439        .typ = ARMADA_SPI,
 440        .min_divisor = 4,
 441        .max_divisor = 1920,
 442        .max_hz = 50000000,
 443        .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
 444};
 445
 446static const struct orion_spi_dev armada_xp_spi_dev_data = {
 447        .typ = ARMADA_SPI,
 448        .max_hz = 50000000,
 449        .max_divisor = 1920,
 450        .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
 451};
 452
 453static const struct orion_spi_dev armada_375_spi_dev_data = {
 454        .typ = ARMADA_SPI,
 455        .min_divisor = 15,
 456        .max_divisor = 1920,
 457        .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
 458};
 459
 460static const struct orion_spi_dev armada_380_spi_dev_data = {
 461        .typ = ARMADA_SPI,
 462        .max_hz = 50000000,
 463        .max_divisor = 1920,
 464        .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
 465        .is_errata_50mhz_ac = true,
 466};
 467
 468static const struct of_device_id orion_spi_of_match_table[] = {
 469        {
 470                .compatible = "marvell,orion-spi",
 471                .data = &orion_spi_dev_data,
 472        },
 473        {
 474                .compatible = "marvell,armada-370-spi",
 475                .data = &armada_370_spi_dev_data,
 476        },
 477        {
 478                .compatible = "marvell,armada-375-spi",
 479                .data = &armada_375_spi_dev_data,
 480        },
 481        {
 482                .compatible = "marvell,armada-380-spi",
 483                .data = &armada_380_spi_dev_data,
 484        },
 485        {
 486                .compatible = "marvell,armada-390-spi",
 487                .data = &armada_xp_spi_dev_data,
 488        },
 489        {
 490                .compatible = "marvell,armada-xp-spi",
 491                .data = &armada_xp_spi_dev_data,
 492        },
 493
 494        {}
 495};
 496MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
 497
 498static int orion_spi_probe(struct platform_device *pdev)
 499{
 500        const struct of_device_id *of_id;
 501        const struct orion_spi_dev *devdata;
 502        struct spi_master *master;
 503        struct orion_spi *spi;
 504        struct resource *r;
 505        unsigned long tclk_hz;
 506        int status = 0;
 507
 508        master = spi_alloc_master(&pdev->dev, sizeof(*spi));
 509        if (master == NULL) {
 510                dev_dbg(&pdev->dev, "master allocation failed\n");
 511                return -ENOMEM;
 512        }
 513
 514        if (pdev->id != -1)
 515                master->bus_num = pdev->id;
 516        if (pdev->dev.of_node) {
 517                u32 cell_index;
 518
 519                if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
 520                                          &cell_index))
 521                        master->bus_num = cell_index;
 522        }
 523
 524        /* we support only mode 0, and no options */
 525        master->mode_bits = SPI_CPHA | SPI_CPOL;
 526        master->set_cs = orion_spi_set_cs;
 527        master->transfer_one = orion_spi_transfer_one;
 528        master->num_chipselect = ORION_NUM_CHIPSELECTS;
 529        master->setup = orion_spi_setup;
 530        master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 531        master->auto_runtime_pm = true;
 532
 533        platform_set_drvdata(pdev, master);
 534
 535        spi = spi_master_get_devdata(master);
 536        spi->master = master;
 537
 538        of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
 539        devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
 540        spi->devdata = devdata;
 541
 542        spi->clk = devm_clk_get(&pdev->dev, NULL);
 543        if (IS_ERR(spi->clk)) {
 544                status = PTR_ERR(spi->clk);
 545                goto out;
 546        }
 547
 548        status = clk_prepare_enable(spi->clk);
 549        if (status)
 550                goto out;
 551
 552        tclk_hz = clk_get_rate(spi->clk);
 553
 554        /*
 555         * With old device tree, armada-370-spi could be used with
 556         * Armada XP, however for this SoC the maximum frequency is
 557         * 50MHz instead of tclk/4. On Armada 370, tclk cannot be
 558         * higher than 200MHz. So, in order to be able to handle both
 559         * SoCs, we can take the minimum of 50MHz and tclk/4.
 560         */
 561        if (of_device_is_compatible(pdev->dev.of_node,
 562                                        "marvell,armada-370-spi"))
 563                master->max_speed_hz = min(devdata->max_hz,
 564                                DIV_ROUND_UP(tclk_hz, devdata->min_divisor));
 565        else if (devdata->min_divisor)
 566                master->max_speed_hz =
 567                        DIV_ROUND_UP(tclk_hz, devdata->min_divisor);
 568        else
 569                master->max_speed_hz = devdata->max_hz;
 570        master->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor);
 571
 572        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 573        spi->base = devm_ioremap_resource(&pdev->dev, r);
 574        if (IS_ERR(spi->base)) {
 575                status = PTR_ERR(spi->base);
 576                goto out_rel_clk;
 577        }
 578
 579        pm_runtime_set_active(&pdev->dev);
 580        pm_runtime_use_autosuspend(&pdev->dev);
 581        pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
 582        pm_runtime_enable(&pdev->dev);
 583
 584        status = orion_spi_reset(spi);
 585        if (status < 0)
 586                goto out_rel_pm;
 587
 588        pm_runtime_mark_last_busy(&pdev->dev);
 589        pm_runtime_put_autosuspend(&pdev->dev);
 590
 591        master->dev.of_node = pdev->dev.of_node;
 592        status = spi_register_master(master);
 593        if (status < 0)
 594                goto out_rel_pm;
 595
 596        return status;
 597
 598out_rel_pm:
 599        pm_runtime_disable(&pdev->dev);
 600out_rel_clk:
 601        clk_disable_unprepare(spi->clk);
 602out:
 603        spi_master_put(master);
 604        return status;
 605}
 606
 607
 608static int orion_spi_remove(struct platform_device *pdev)
 609{
 610        struct spi_master *master = platform_get_drvdata(pdev);
 611        struct orion_spi *spi = spi_master_get_devdata(master);
 612
 613        pm_runtime_get_sync(&pdev->dev);
 614        clk_disable_unprepare(spi->clk);
 615
 616        spi_unregister_master(master);
 617        pm_runtime_disable(&pdev->dev);
 618
 619        return 0;
 620}
 621
 622MODULE_ALIAS("platform:" DRIVER_NAME);
 623
 624#ifdef CONFIG_PM
 625static int orion_spi_runtime_suspend(struct device *dev)
 626{
 627        struct spi_master *master = dev_get_drvdata(dev);
 628        struct orion_spi *spi = spi_master_get_devdata(master);
 629
 630        clk_disable_unprepare(spi->clk);
 631        return 0;
 632}
 633
 634static int orion_spi_runtime_resume(struct device *dev)
 635{
 636        struct spi_master *master = dev_get_drvdata(dev);
 637        struct orion_spi *spi = spi_master_get_devdata(master);
 638
 639        return clk_prepare_enable(spi->clk);
 640}
 641#endif
 642
 643static const struct dev_pm_ops orion_spi_pm_ops = {
 644        SET_RUNTIME_PM_OPS(orion_spi_runtime_suspend,
 645                           orion_spi_runtime_resume,
 646                           NULL)
 647};
 648
 649static struct platform_driver orion_spi_driver = {
 650        .driver = {
 651                .name   = DRIVER_NAME,
 652                .pm     = &orion_spi_pm_ops,
 653                .of_match_table = of_match_ptr(orion_spi_of_match_table),
 654        },
 655        .probe          = orion_spi_probe,
 656        .remove         = orion_spi_remove,
 657};
 658
 659module_platform_driver(orion_spi_driver);
 660
 661MODULE_DESCRIPTION("Orion SPI driver");
 662MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>");
 663MODULE_LICENSE("GPL");
 664