^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * FPGA Manager Driver for Intel Stratix10 SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/fpga/fpga-mgr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/firmware/intel/stratix10-svc-client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * FPGA programming requires a higher level of privilege (EL3), per the SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * design.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define NUM_SVC_BUFS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define SVC_BUF_SIZE SZ_512K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* Indicates buffer is in use if set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SVC_BUF_LOCK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define S10_BUFFER_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_BUFFER_TIMEOUT_MS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define S10_RECONFIG_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_REQUEST_TIMEOUT_MS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * struct s10_svc_buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * buf: virtual address of buf provided by service layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * lock: locked if buffer is in use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct s10_svc_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned long lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct s10_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct stratix10_svc_chan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct stratix10_svc_client client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct completion status_return_completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct s10_svc_buf svc_bufs[NUM_SVC_BUFS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned long status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int s10_svc_send_msg(struct s10_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum stratix10_svc_command_code command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void *payload, u32 payload_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct stratix10_svc_chan *chan = priv->chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device *dev = priv->client.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct stratix10_svc_client_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) dev_dbg(dev, "%s cmd=%d payload=%p length=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __func__, command, payload, payload_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) msg.command = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) msg.payload = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) msg.payload_length = payload_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ret = stratix10_svc_send(chan, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dev_dbg(dev, "stratix10_svc_send returned status %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * Free buffers allocated from the service layer's pool that are not in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Return true when all buffers are freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static bool s10_free_buffers(struct fpga_manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) uint num_free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) for (i = 0; i < NUM_SVC_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!priv->svc_bufs[i].buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) num_free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!test_and_set_bit_lock(SVC_BUF_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) &priv->svc_bufs[i].lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) stratix10_svc_free_memory(priv->chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) priv->svc_bufs[i].buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) priv->svc_bufs[i].buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) num_free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return num_free == NUM_SVC_BUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Returns count of how many buffers are not in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static uint s10_free_buffer_count(struct fpga_manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) uint num_free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) for (i = 0; i < NUM_SVC_BUFS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!priv->svc_bufs[i].buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) num_free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return num_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * s10_unlock_bufs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Given the returned buffer address, match that address to our buffer struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * and unlock that buffer. This marks it as available to be refilled and sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * (or freed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * priv: private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * kaddr: kernel address of buffer that was returned from service layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void s10_unlock_bufs(struct s10_priv *priv, void *kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for (i = 0; i < NUM_SVC_BUFS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (priv->svc_bufs[i].buf == kaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) clear_bit_unlock(SVC_BUF_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) &priv->svc_bufs[i].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) WARN(1, "Unknown buffer returned from service layer %p\n", kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * s10_receive_callback - callback for service layer to use to provide client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * (this driver) messages received through the mailbox.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * client: service layer client struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * data: message from service layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void s10_receive_callback(struct stratix10_svc_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct stratix10_svc_cb_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct s10_priv *priv = client->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) WARN_ONCE(!data, "%s: stratix10_svc_rc_data = NULL", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) status = data->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Here we set status bits as we receive them. Elsewhere, we always use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * test_and_clear_bit() to check status in priv->status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) for (i = 0; i <= SVC_STATUS_ERROR; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (status & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) set_bit(i, &priv->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (status & BIT(SVC_STATUS_BUFFER_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) s10_unlock_bufs(priv, data->kaddr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) s10_unlock_bufs(priv, data->kaddr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) s10_unlock_bufs(priv, data->kaddr3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) complete(&priv->status_return_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * s10_ops_write_init - prepare for FPGA reconfiguration by requesting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * partial reconfig and allocating buffers from the service layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int s10_ops_write_init(struct fpga_manager *mgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct fpga_image_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct device *dev = priv->client.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct stratix10_svc_command_config_type ctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) char *kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ctype.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dev_dbg(dev, "Requesting partial reconfiguration.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ctype.flags |= BIT(COMMAND_RECONFIG_FLAG_PARTIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_dbg(dev, "Requesting full reconfiguration.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) reinit_completion(&priv->status_return_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = s10_svc_send_msg(priv, COMMAND_RECONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) &ctype, sizeof(ctype));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto init_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = wait_for_completion_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) &priv->status_return_completion, S10_RECONFIG_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto init_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!test_and_clear_bit(SVC_STATUS_OK, &priv->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto init_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* Allocate buffers from the service layer's pool. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) for (i = 0; i < NUM_SVC_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!kbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) s10_free_buffers(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) goto init_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) priv->svc_bufs[i].buf = kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) priv->svc_bufs[i].lock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) init_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) stratix10_svc_done(priv->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * s10_send_buf - send a buffer to the service layer queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * mgr: fpga manager struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * buf: fpga image buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * count: size of buf in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Returns # of bytes transferred or -ENOBUFS if the all the buffers are in use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * or if the service queue is full. Never returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int s10_send_buf(struct fpga_manager *mgr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct device *dev = priv->client.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void *svc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) size_t xfer_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* get/lock a buffer that that's not being used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) for (i = 0; i < NUM_SVC_BUFS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!test_and_set_bit_lock(SVC_BUF_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) &priv->svc_bufs[i].lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (i == NUM_SVC_BUFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) xfer_sz = count < SVC_BUF_SIZE ? count : SVC_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) svc_buf = priv->svc_bufs[i].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) memcpy(svc_buf, buf, xfer_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_DATA_SUBMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) svc_buf, xfer_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) "Error while sending data to service layer (%d)", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) clear_bit_unlock(SVC_BUF_LOCK, &priv->svc_bufs[i].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return xfer_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Send a FPGA image to privileged layers to write to the FPGA. When done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * sending, free all service layer buffers we allocated in write_init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int s10_ops_write(struct fpga_manager *mgr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct device *dev = priv->client.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) long wait_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Loop waiting for buffers to be returned. When a buffer is returned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * reuse it to send more data or free if if all data has been sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) while (count > 0 || s10_free_buffer_count(mgr) != NUM_SVC_BUFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) reinit_completion(&priv->status_return_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sent = s10_send_buf(mgr, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (sent < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) count -= sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) buf += sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (s10_free_buffers(mgr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = s10_svc_send_msg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) priv, COMMAND_RECONFIG_DATA_CLAIM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * If callback hasn't already happened, wait for buffers to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * returned from service layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) wait_status = 1; /* not timed out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!priv->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) wait_status = wait_for_completion_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) &priv->status_return_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) S10_BUFFER_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (test_and_clear_bit(SVC_STATUS_BUFFER_DONE, &priv->status) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) test_and_clear_bit(SVC_STATUS_BUFFER_SUBMITTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) &priv->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!wait_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err(dev, "timeout waiting for svc layer buffers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!s10_free_buffers(mgr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dev_err(dev, "%s not all buffers were freed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int s10_ops_write_complete(struct fpga_manager *mgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct fpga_image_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct device *dev = priv->client.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) timeout = usecs_to_jiffies(info->config_complete_timeout_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) reinit_completion(&priv->status_return_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_STATUS, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ret = wait_for_completion_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) &priv->status_return_completion, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) "timeout waiting for RECONFIG_COMPLETED\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Not error or timeout, so ret is # of jiffies until timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) timeout = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (test_and_clear_bit(SVC_STATUS_COMPLETED, &priv->status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) stratix10_svc_done(priv->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static enum fpga_mgr_states s10_ops_state(struct fpga_manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return FPGA_MGR_STATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static const struct fpga_manager_ops s10_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .state = s10_ops_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .write_init = s10_ops_write_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .write = s10_ops_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .write_complete = s10_ops_write_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int s10_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct s10_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct fpga_manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) priv->client.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) priv->client.receive_cb = s10_receive_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) priv->client.priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) priv->chan = stratix10_svc_request_channel_byname(&priv->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) SVC_CLIENT_FPGA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (IS_ERR(priv->chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dev_err(dev, "couldn't get service channel (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) SVC_CLIENT_FPGA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return PTR_ERR(priv->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) init_completion(&priv->status_return_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mgr = fpga_mgr_create(dev, "Stratix10 SOC FPGA Manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) &s10_ops, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!mgr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) dev_err(dev, "unable to create FPGA manager\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto probe_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = fpga_mgr_register(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dev_err(dev, "unable to register FPGA manager\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) fpga_mgr_free(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto probe_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) platform_set_drvdata(pdev, mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) probe_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) stratix10_svc_free_channel(priv->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int s10_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct fpga_manager *mgr = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct s10_priv *priv = mgr->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fpga_mgr_unregister(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fpga_mgr_free(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) stratix10_svc_free_channel(priv->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static const struct of_device_id s10_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {.compatible = "intel,stratix10-soc-fpga-mgr"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {.compatible = "intel,agilex-soc-fpga-mgr"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) MODULE_DEVICE_TABLE(of, s10_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static struct platform_driver s10_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .probe = s10_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .remove = s10_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .name = "Stratix10 SoC FPGA manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .of_match_table = of_match_ptr(s10_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static int __init s10_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct device_node *fw_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) fw_np = of_find_node_by_name(NULL, "svc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!fw_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) of_node_get(fw_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) np = of_find_matching_node(fw_np, s10_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) of_node_put(fw_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) of_node_put(fw_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return platform_driver_register(&s10_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static void __exit s10_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return platform_driver_unregister(&s10_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) module_init(s10_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) module_exit(s10_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) MODULE_DESCRIPTION("Intel Stratix 10 SOC FPGA Manager");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) MODULE_LICENSE("GPL v2");