Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");