108 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * FPGA Bridge Driver for FPGA Management Engine (FME)4 *5 * Copyright (C) 2017-2018 Intel Corporation, Inc.6 *7 * Authors:8 * Wu Hao <hao.wu@intel.com>9 * Joseph Grecco <joe.grecco@intel.com>10 * Enno Luebbers <enno.luebbers@intel.com>11 * Tim Whisonant <tim.whisonant@intel.com>12 * Ananda Ravuri <ananda.ravuri@intel.com>13 * Henry Mitchel <henry.mitchel@intel.com>14 */15 16#include <linux/module.h>17#include <linux/fpga/fpga-bridge.h>18 19#include "dfl.h"20#include "dfl-fme-pr.h"21 22struct fme_br_priv {23 struct dfl_fme_br_pdata *pdata;24 struct dfl_fpga_port_ops *port_ops;25 struct platform_device *port_pdev;26};27 28static int fme_bridge_enable_set(struct fpga_bridge *bridge, bool enable)29{30 struct fme_br_priv *priv = bridge->priv;31 struct platform_device *port_pdev;32 struct dfl_fpga_port_ops *ops;33 34 if (!priv->port_pdev) {35 port_pdev = dfl_fpga_cdev_find_port(priv->pdata->cdev,36 &priv->pdata->port_id,37 dfl_fpga_check_port_id);38 if (!port_pdev)39 return -ENODEV;40 41 priv->port_pdev = port_pdev;42 }43 44 if (priv->port_pdev && !priv->port_ops) {45 ops = dfl_fpga_port_ops_get(priv->port_pdev);46 if (!ops || !ops->enable_set)47 return -ENOENT;48 49 priv->port_ops = ops;50 }51 52 return priv->port_ops->enable_set(priv->port_pdev, enable);53}54 55static const struct fpga_bridge_ops fme_bridge_ops = {56 .enable_set = fme_bridge_enable_set,57};58 59static int fme_br_probe(struct platform_device *pdev)60{61 struct device *dev = &pdev->dev;62 struct fme_br_priv *priv;63 struct fpga_bridge *br;64 65 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);66 if (!priv)67 return -ENOMEM;68 69 priv->pdata = dev_get_platdata(dev);70 71 br = fpga_bridge_register(dev, "DFL FPGA FME Bridge",72 &fme_bridge_ops, priv);73 if (IS_ERR(br))74 return PTR_ERR(br);75 76 platform_set_drvdata(pdev, br);77 78 return 0;79}80 81static void fme_br_remove(struct platform_device *pdev)82{83 struct fpga_bridge *br = platform_get_drvdata(pdev);84 struct fme_br_priv *priv = br->priv;85 86 fpga_bridge_unregister(br);87 88 if (priv->port_pdev)89 put_device(&priv->port_pdev->dev);90 if (priv->port_ops)91 dfl_fpga_port_ops_put(priv->port_ops);92}93 94static struct platform_driver fme_br_driver = {95 .driver = {96 .name = DFL_FPGA_FME_BRIDGE,97 },98 .probe = fme_br_probe,99 .remove_new = fme_br_remove,100};101 102module_platform_driver(fme_br_driver);103 104MODULE_DESCRIPTION("FPGA Bridge for DFL FPGA Management Engine");105MODULE_AUTHOR("Intel Corporation");106MODULE_LICENSE("GPL v2");107MODULE_ALIAS("platform:dfl-fme-bridge");108