cdx_controller.c (0ea5c948cb64bab5bc7a5516774eb8536f05aa0d) cdx_controller.c (0e439ba38e615e505404b3935585f1898bafaea9)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * CDX host controller driver for AMD versal-net platform.
4 *
5 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
6 */
7
8#include <linux/mod_devicetable.h>
9#include <linux/platform_device.h>
10#include <linux/slab.h>
11#include <linux/cdx/cdx_bus.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * CDX host controller driver for AMD versal-net platform.
4 *
5 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
6 */
7
8#include <linux/mod_devicetable.h>
9#include <linux/platform_device.h>
10#include <linux/slab.h>
11#include <linux/cdx/cdx_bus.h>
12#include <linux/irqdomain.h>
12
13#include "cdx_controller.h"
14#include "../cdx.h"
15#include "mcdi_functions.h"
16#include "mcdi.h"
17
18static unsigned int cdx_mcdi_rpc_timeout(struct cdx_mcdi *cdx, unsigned int cmd)
19{

--- 35 unchanged lines hidden (view full) ---

55 cdx_unregister_controller(cdx);
56 cdx_mcdi_wait_for_quiescence(cdx->priv, MCDI_RPC_TIMEOUT);
57}
58
59static int cdx_configure_device(struct cdx_controller *cdx,
60 u8 bus_num, u8 dev_num,
61 struct cdx_device_config *dev_config)
62{
13
14#include "cdx_controller.h"
15#include "../cdx.h"
16#include "mcdi_functions.h"
17#include "mcdi.h"
18
19static unsigned int cdx_mcdi_rpc_timeout(struct cdx_mcdi *cdx, unsigned int cmd)
20{

--- 35 unchanged lines hidden (view full) ---

56 cdx_unregister_controller(cdx);
57 cdx_mcdi_wait_for_quiescence(cdx->priv, MCDI_RPC_TIMEOUT);
58}
59
60static int cdx_configure_device(struct cdx_controller *cdx,
61 u8 bus_num, u8 dev_num,
62 struct cdx_device_config *dev_config)
63{
64 u16 msi_index;
63 int ret = 0;
65 int ret = 0;
66 u32 data;
67 u64 addr;
64
65 switch (dev_config->type) {
68
69 switch (dev_config->type) {
70 case CDX_DEV_MSI_CONF:
71 msi_index = dev_config->msi.msi_index;
72 data = dev_config->msi.data;
73 addr = dev_config->msi.addr;
74
75 ret = cdx_mcdi_write_msi(cdx->priv, bus_num, dev_num, msi_index, addr, data);
76 break;
66 case CDX_DEV_RESET_CONF:
67 ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
68 break;
69 case CDX_DEV_BUS_MASTER_CONF:
70 ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
71 dev_config->bus_master_enable);
72 break;
77 case CDX_DEV_RESET_CONF:
78 ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
79 break;
80 case CDX_DEV_BUS_MASTER_CONF:
81 ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
82 dev_config->bus_master_enable);
83 break;
84 case CDX_DEV_MSI_ENABLE:
85 ret = cdx_mcdi_msi_enable(cdx->priv, bus_num, dev_num, dev_config->msi_enable);
86 break;
73 default:
74 ret = -EINVAL;
75 }
76
77 return ret;
78}
79
80static int cdx_scan_devices(struct cdx_controller *cdx)

--- 92 unchanged lines hidden (view full) ---

173 goto cdx_alloc_fail;
174 }
175 platform_set_drvdata(pdev, cdx);
176
177 cdx->dev = &pdev->dev;
178 cdx->priv = cdx_mcdi;
179 cdx->ops = &cdx_ops;
180
87 default:
88 ret = -EINVAL;
89 }
90
91 return ret;
92}
93
94static int cdx_scan_devices(struct cdx_controller *cdx)

--- 92 unchanged lines hidden (view full) ---

187 goto cdx_alloc_fail;
188 }
189 platform_set_drvdata(pdev, cdx);
190
191 cdx->dev = &pdev->dev;
192 cdx->priv = cdx_mcdi;
193 cdx->ops = &cdx_ops;
194
195 /* Create MSI domain */
196 cdx->msi_domain = cdx_msi_domain_init(&pdev->dev);
197 if (!cdx->msi_domain) {
198 dev_err(&pdev->dev, "cdx_msi_domain_init() failed");
199 ret = -ENODEV;
200 goto cdx_msi_fail;
201 }
202
181 ret = cdx_setup_rpmsg(pdev);
182 if (ret) {
183 if (ret != -EPROBE_DEFER)
184 dev_err(&pdev->dev, "Failed to register CDX RPMsg transport\n");
185 goto cdx_rpmsg_fail;
186 }
187
188 dev_info(&pdev->dev, "Successfully registered CDX controller with RPMsg as transport\n");
189 return 0;
190
191cdx_rpmsg_fail:
203 ret = cdx_setup_rpmsg(pdev);
204 if (ret) {
205 if (ret != -EPROBE_DEFER)
206 dev_err(&pdev->dev, "Failed to register CDX RPMsg transport\n");
207 goto cdx_rpmsg_fail;
208 }
209
210 dev_info(&pdev->dev, "Successfully registered CDX controller with RPMsg as transport\n");
211 return 0;
212
213cdx_rpmsg_fail:
214 irq_domain_remove(cdx->msi_domain);
215cdx_msi_fail:
192 kfree(cdx);
193cdx_alloc_fail:
194 cdx_mcdi_finish(cdx_mcdi);
195mcdi_init_fail:
196 kfree(cdx_mcdi);
197
198 return ret;
199}
200
201static int xlnx_cdx_remove(struct platform_device *pdev)
202{
203 struct cdx_controller *cdx = platform_get_drvdata(pdev);
204 struct cdx_mcdi *cdx_mcdi = cdx->priv;
205
206 cdx_destroy_rpmsg(pdev);
207
216 kfree(cdx);
217cdx_alloc_fail:
218 cdx_mcdi_finish(cdx_mcdi);
219mcdi_init_fail:
220 kfree(cdx_mcdi);
221
222 return ret;
223}
224
225static int xlnx_cdx_remove(struct platform_device *pdev)
226{
227 struct cdx_controller *cdx = platform_get_drvdata(pdev);
228 struct cdx_mcdi *cdx_mcdi = cdx->priv;
229
230 cdx_destroy_rpmsg(pdev);
231
232 irq_domain_remove(cdx->msi_domain);
208 kfree(cdx);
209
210 cdx_mcdi_finish(cdx_mcdi);
211 kfree(cdx_mcdi);
212
213 return 0;
214}
215

--- 40 unchanged lines hidden ---
233 kfree(cdx);
234
235 cdx_mcdi_finish(cdx_mcdi);
236 kfree(cdx_mcdi);
237
238 return 0;
239}
240

--- 40 unchanged lines hidden ---