linux/drivers/fpga/socfpga-a10.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * FPGA Manager Driver for Altera Arria10 SoCFPGA
   4 *
   5 * Copyright (C) 2015-2016 Altera Corporation
   6 */
   7#include <linux/clk.h>
   8#include <linux/device.h>
   9#include <linux/delay.h>
  10#include <linux/fpga/fpga-mgr.h>
  11#include <linux/io.h>
  12#include <linux/module.h>
  13#include <linux/of_address.h>
  14#include <linux/regmap.h>
  15
  16#define A10_FPGAMGR_DCLKCNT_OFST                                0x08
  17#define A10_FPGAMGR_DCLKSTAT_OFST                               0x0c
  18#define A10_FPGAMGR_IMGCFG_CTL_00_OFST                          0x70
  19#define A10_FPGAMGR_IMGCFG_CTL_01_OFST                          0x74
  20#define A10_FPGAMGR_IMGCFG_CTL_02_OFST                          0x78
  21#define A10_FPGAMGR_IMGCFG_STAT_OFST                            0x80
  22
  23#define A10_FPGAMGR_DCLKSTAT_DCLKDONE                           BIT(0)
  24
  25#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG           BIT(0)
  26#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS           BIT(1)
  27#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE           BIT(2)
  28#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG                   BIT(8)
  29#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE                BIT(16)
  30#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE                BIT(24)
  31
  32#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG            BIT(0)
  33#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST                BIT(16)
  34#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE                       BIT(24)
  35
  36#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL                   BIT(0)
  37#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK          (BIT(16) | BIT(17))
  38#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT                 16
  39#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH                      BIT(24)
  40#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT                24
  41
  42#define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR                   BIT(0)
  43#define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE              BIT(1)
  44#define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE                    BIT(2)
  45#define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN                 BIT(4)
  46#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN                 BIT(6)
  47#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY                    BIT(9)
  48#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE                     BIT(10)
  49#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR                    BIT(11)
  50#define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN                 BIT(12)
  51#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK   (BIT(16) | BIT(17) | BIT(18))
  52#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT                  16
  53
  54/* FPGA CD Ratio Value */
  55#define CDRATIO_x1                                              0x0
  56#define CDRATIO_x2                                              0x1
  57#define CDRATIO_x4                                              0x2
  58#define CDRATIO_x8                                              0x3
  59
  60/* Configuration width 16/32 bit */
  61#define CFGWDTH_32                                              1
  62#define CFGWDTH_16                                              0
  63
  64/*
  65 * struct a10_fpga_priv - private data for fpga manager
  66 * @regmap: regmap for register access
  67 * @fpga_data_addr: iomap for single address data register to FPGA
  68 * @clk: clock
  69 */
  70struct a10_fpga_priv {
  71        struct regmap *regmap;
  72        void __iomem *fpga_data_addr;
  73        struct clk *clk;
  74};
  75
  76static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg)
  77{
  78        switch (reg) {
  79        case A10_FPGAMGR_DCLKCNT_OFST:
  80        case A10_FPGAMGR_DCLKSTAT_OFST:
  81        case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
  82        case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
  83        case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
  84                return true;
  85        }
  86        return false;
  87}
  88
  89static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg)
  90{
  91        switch (reg) {
  92        case A10_FPGAMGR_DCLKCNT_OFST:
  93        case A10_FPGAMGR_DCLKSTAT_OFST:
  94        case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
  95        case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
  96        case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
  97        case A10_FPGAMGR_IMGCFG_STAT_OFST:
  98                return true;
  99        }
 100        return false;
 101}
 102
 103static const struct regmap_config socfpga_a10_fpga_regmap_config = {
 104        .reg_bits = 32,
 105        .reg_stride = 4,
 106        .val_bits = 32,
 107        .writeable_reg = socfpga_a10_fpga_writeable_reg,
 108        .readable_reg = socfpga_a10_fpga_readable_reg,
 109        .max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
 110        .cache_type = REGCACHE_NONE,
 111};
 112
 113/*
 114 * from the register map description of cdratio in imgcfg_ctrl_02:
 115 *  Normal Configuration    : 32bit Passive Parallel
 116 *  Partial Reconfiguration : 16bit Passive Parallel
 117 */
 118static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
 119                                           int width)
 120{
 121        width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;
 122
 123        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
 124                           A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
 125}
 126
 127static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
 128                                            u32 count)
 129{
 130        u32 val;
 131
 132        /* Clear any existing DONE status. */
 133        regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
 134                     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
 135
 136        /* Issue the DCLK regmap. */
 137        regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);
 138
 139        /* wait till the dclkcnt done */
 140        regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
 141                                 val, 1, 100);
 142
 143        /* Clear DONE status. */
 144        regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
 145                     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
 146}
 147
 148#define RBF_ENCRYPTION_MODE_OFFSET              69
 149#define RBF_DECOMPRESS_OFFSET                   229
 150
 151static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
 152{
 153        if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
 154                return -EINVAL;
 155
 156        /* Is the bitstream encrypted? */
 157        return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
 158}
 159
 160static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size)
 161{
 162        if (buf32_size < RBF_DECOMPRESS_OFFSET + 1)
 163                return -EINVAL;
 164
 165        /* Is the bitstream compressed? */
 166        return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1);
 167}
 168
 169static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width,
 170                                                  bool encrypt, bool compress)
 171{
 172        unsigned int cd_ratio;
 173
 174        /*
 175         * cd ratio is dependent on cfg width and whether the bitstream
 176         * is encrypted and/or compressed.
 177         *
 178         * | width | encr. | compr. | cd ratio |
 179         * |  16   |   0   |   0    |     1    |
 180         * |  16   |   0   |   1    |     4    |
 181         * |  16   |   1   |   0    |     2    |
 182         * |  16   |   1   |   1    |     4    |
 183         * |  32   |   0   |   0    |     1    |
 184         * |  32   |   0   |   1    |     8    |
 185         * |  32   |   1   |   0    |     4    |
 186         * |  32   |   1   |   1    |     8    |
 187         */
 188        if (!compress && !encrypt)
 189                return CDRATIO_x1;
 190
 191        if (compress)
 192                cd_ratio = CDRATIO_x4;
 193        else
 194                cd_ratio = CDRATIO_x2;
 195
 196        /* If 32 bit, double the cd ratio by incrementing the field  */
 197        if (cfg_width == CFGWDTH_32)
 198                cd_ratio += 1;
 199
 200        return cd_ratio;
 201}
 202
 203static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr,
 204                                        unsigned int cfg_width,
 205                                        const char *buf, size_t count)
 206{
 207        struct a10_fpga_priv *priv = mgr->priv;
 208        unsigned int cd_ratio;
 209        int encrypt, compress;
 210
 211        encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4);
 212        if (encrypt < 0)
 213                return -EINVAL;
 214
 215        compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4);
 216        if (compress < 0)
 217                return -EINVAL;
 218
 219        cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress);
 220
 221        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
 222                           A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK,
 223                           cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT);
 224
 225        return 0;
 226}
 227
 228static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv)
 229{
 230        u32 val;
 231
 232        regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val);
 233
 234        return val;
 235}
 236
 237static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv)
 238{
 239        u32 reg, i;
 240
 241        for (i = 0; i < 10 ; i++) {
 242                reg = socfpga_a10_fpga_read_stat(priv);
 243
 244                if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
 245                        return -EINVAL;
 246
 247                if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
 248                        return 0;
 249        }
 250
 251        return -ETIMEDOUT;
 252}
 253
 254static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv)
 255{
 256        u32 reg, i;
 257
 258        for (i = 0; i < 10 ; i++) {
 259                reg = socfpga_a10_fpga_read_stat(priv);
 260
 261                if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
 262                        return -EINVAL;
 263
 264                if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE)
 265                        return 0;
 266        }
 267
 268        return -ETIMEDOUT;
 269}
 270
 271/* Start the FPGA programming by initialize the FPGA Manager */
 272static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
 273                                       struct fpga_image_info *info,
 274                                       const char *buf, size_t count)
 275{
 276        struct a10_fpga_priv *priv = mgr->priv;
 277        unsigned int cfg_width;
 278        u32 msel, stat, mask;
 279        int ret;
 280
 281        if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
 282                cfg_width = CFGWDTH_16;
 283        else
 284                return -EINVAL;
 285
 286        /* Check for passive parallel (msel == 000 or 001) */
 287        msel = socfpga_a10_fpga_read_stat(priv);
 288        msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
 289        msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
 290        if ((msel != 0) && (msel != 1)) {
 291                dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
 292                return -EINVAL;
 293        }
 294
 295        /* Make sure no external devices are interfering */
 296        stat = socfpga_a10_fpga_read_stat(priv);
 297        mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
 298               A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
 299        if ((stat & mask) != mask)
 300                return -EINVAL;
 301
 302        /* Set cfg width */
 303        socfpga_a10_fpga_set_cfg_width(priv, cfg_width);
 304
 305        /* Determine cd ratio from bitstream header and set cd ratio */
 306        ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
 307        if (ret)
 308                return ret;
 309
 310        /*
 311         * Clear s2f_nce to enable chip select.  Leave pr_request
 312         * unasserted and override disabled.
 313         */
 314        regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 315                     A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
 316
 317        /* Set cfg_ctrl to enable s2f dclk and data */
 318        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
 319                           A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
 320                           A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);
 321
 322        /*
 323         * Disable overrides not needed for pr.
 324         * s2f_config==1 leaves reset deasseted.
 325         */
 326        regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
 327                     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
 328                     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
 329                     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
 330                     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);
 331
 332        /* Enable override for data, dclk, nce, and pr_request to CSS */
 333        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 334                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);
 335
 336        /* Send some clocks to clear out any errors */
 337        socfpga_a10_fpga_generate_dclks(priv, 256);
 338
 339        /* Assert pr_request */
 340        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 341                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
 342                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);
 343
 344        /* Provide 2048 DCLKs before starting the config data streaming. */
 345        socfpga_a10_fpga_generate_dclks(priv, 0x7ff);
 346
 347        /* Wait for pr_ready */
 348        return socfpga_a10_fpga_wait_for_pr_ready(priv);
 349}
 350
 351/*
 352 * write data to the FPGA data register
 353 */
 354static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf,
 355                                  size_t count)
 356{
 357        struct a10_fpga_priv *priv = mgr->priv;
 358        u32 *buffer_32 = (u32 *)buf;
 359        size_t i = 0;
 360
 361        if (count <= 0)
 362                return -EINVAL;
 363
 364        /* Write out the complete 32-bit chunks */
 365        while (count >= sizeof(u32)) {
 366                writel(buffer_32[i++], priv->fpga_data_addr);
 367                count -= sizeof(u32);
 368        }
 369
 370        /* Write out remaining non 32-bit chunks */
 371        switch (count) {
 372        case 3:
 373                writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr);
 374                break;
 375        case 2:
 376                writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr);
 377                break;
 378        case 1:
 379                writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr);
 380                break;
 381        case 0:
 382                break;
 383        default:
 384                /* This will never happen */
 385                return -EFAULT;
 386        }
 387
 388        return 0;
 389}
 390
 391static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr,
 392                                           struct fpga_image_info *info)
 393{
 394        struct a10_fpga_priv *priv = mgr->priv;
 395        u32 reg;
 396        int ret;
 397
 398        /* Wait for pr_done */
 399        ret = socfpga_a10_fpga_wait_for_pr_done(priv);
 400
 401        /* Clear pr_request */
 402        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 403                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0);
 404
 405        /* Send some clocks to clear out any errors */
 406        socfpga_a10_fpga_generate_dclks(priv, 256);
 407
 408        /* Disable s2f dclk and data */
 409        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
 410                           A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0);
 411
 412        /* Deassert chip select */
 413        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 414                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE,
 415                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE);
 416
 417        /* Disable data, dclk, nce, and pr_request override to CSS */
 418        regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
 419                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG,
 420                           A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
 421
 422        /* Return any errors regarding pr_done or pr_error */
 423        if (ret)
 424                return ret;
 425
 426        /* Final check */
 427        reg = socfpga_a10_fpga_read_stat(priv);
 428
 429        if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) ||
 430            ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) ||
 431            ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) {
 432                dev_dbg(&mgr->dev,
 433                        "Timeout in final check. Status=%08xf\n", reg);
 434                return -ETIMEDOUT;
 435        }
 436
 437        return 0;
 438}
 439
 440static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
 441{
 442        struct a10_fpga_priv *priv = mgr->priv;
 443        u32 reg = socfpga_a10_fpga_read_stat(priv);
 444
 445        if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)
 446                return FPGA_MGR_STATE_OPERATING;
 447
 448        if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
 449                return FPGA_MGR_STATE_WRITE;
 450
 451        if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR)
 452                return FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
 453
 454        if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)
 455                return FPGA_MGR_STATE_RESET;
 456
 457        return FPGA_MGR_STATE_UNKNOWN;
 458}
 459
 460static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
 461        .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
 462        .state = socfpga_a10_fpga_state,
 463        .write_init = socfpga_a10_fpga_write_init,
 464        .write = socfpga_a10_fpga_write,
 465        .write_complete = socfpga_a10_fpga_write_complete,
 466};
 467
 468static int socfpga_a10_fpga_probe(struct platform_device *pdev)
 469{
 470        struct device *dev = &pdev->dev;
 471        struct a10_fpga_priv *priv;
 472        void __iomem *reg_base;
 473        struct fpga_manager *mgr;
 474        struct resource *res;
 475        int ret;
 476
 477        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 478        if (!priv)
 479                return -ENOMEM;
 480
 481        /* First mmio base is for register access */
 482        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 483        reg_base = devm_ioremap_resource(dev, res);
 484        if (IS_ERR(reg_base))
 485                return PTR_ERR(reg_base);
 486
 487        /* Second mmio base is for writing FPGA image data */
 488        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 489        priv->fpga_data_addr = devm_ioremap_resource(dev, res);
 490        if (IS_ERR(priv->fpga_data_addr))
 491                return PTR_ERR(priv->fpga_data_addr);
 492
 493        /* regmap for register access */
 494        priv->regmap = devm_regmap_init_mmio(dev, reg_base,
 495                                             &socfpga_a10_fpga_regmap_config);
 496        if (IS_ERR(priv->regmap))
 497                return -ENODEV;
 498
 499        priv->clk = devm_clk_get(dev, NULL);
 500        if (IS_ERR(priv->clk)) {
 501                dev_err(dev, "no clock specified\n");
 502                return PTR_ERR(priv->clk);
 503        }
 504
 505        ret = clk_prepare_enable(priv->clk);
 506        if (ret) {
 507                dev_err(dev, "could not enable clock\n");
 508                return -EBUSY;
 509        }
 510
 511        mgr = devm_fpga_mgr_create(dev, "SoCFPGA Arria10 FPGA Manager",
 512                                   &socfpga_a10_fpga_mgr_ops, priv);
 513        if (!mgr)
 514                return -ENOMEM;
 515
 516        platform_set_drvdata(pdev, mgr);
 517
 518        ret = fpga_mgr_register(mgr);
 519        if (ret) {
 520                clk_disable_unprepare(priv->clk);
 521                return ret;
 522        }
 523
 524        return 0;
 525}
 526
 527static int socfpga_a10_fpga_remove(struct platform_device *pdev)
 528{
 529        struct fpga_manager *mgr = platform_get_drvdata(pdev);
 530        struct a10_fpga_priv *priv = mgr->priv;
 531
 532        fpga_mgr_unregister(mgr);
 533        clk_disable_unprepare(priv->clk);
 534
 535        return 0;
 536}
 537
 538static const struct of_device_id socfpga_a10_fpga_of_match[] = {
 539        { .compatible = "altr,socfpga-a10-fpga-mgr", },
 540        {},
 541};
 542
 543MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match);
 544
 545static struct platform_driver socfpga_a10_fpga_driver = {
 546        .probe = socfpga_a10_fpga_probe,
 547        .remove = socfpga_a10_fpga_remove,
 548        .driver = {
 549                .name   = "socfpga_a10_fpga_manager",
 550                .of_match_table = socfpga_a10_fpga_of_match,
 551        },
 552};
 553
 554module_platform_driver(socfpga_a10_fpga_driver);
 555
 556MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
 557MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
 558MODULE_LICENSE("GPL v2");
 559