Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3823154imm; Tue, 17 Jul 2018 10:52:40 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdGp2HmV2EHrfEkT1S1hEfTPk3tKCrumL4hSOqtmaBcW83k2yIM8nBqfAbVmCGJL0v2NTAm X-Received: by 2002:a17:902:1d4a:: with SMTP id u10-v6mr1232625plu.267.1531849960550; Tue, 17 Jul 2018 10:52:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531849960; cv=none; d=google.com; s=arc-20160816; b=LG2Aqi/HZqiSeuE1VVP9t0eV8qVXkBVC1j/aPuACJ/YfHuMv3jtq2c6rTc36z068Em IesiLLViRSGJmOkekES0JJeyr9ZYbc8G0Z5mf+jrsZKPH/9+H8jklzz5lq6hGZBJIzyP LJ5tjFIP0t3B1NqWz67OhmGYs/tXqUwgTRuXL1iysozwbPYUwZzcI5pGhqOiJakb3oCo iLbrkqBhpnq/3rrZtQ9O0NA07cpIs/WxeQz70HSDYfpnFPzGKQbMTBT986aeP5dc8tU7 r6AtaZ/QlxIYTaAE0+TCRHvT9NVirqaEtsVIV38cz/Q9G6lCUCSha02S3Sacr+X98N/f 5+vQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=39h5RXJ5wcXY1dvVCOCrCdUtcb2wenhZGGNL9U4FlQ0=; b=HLpUAYLZb6O2HTCbbG97wUEUH6Ds5ZGCPWG0H6GUMmZXWx753sJf987MIQaPdTRv9t 0jhNXobwwm0J+9mqTXIvIiNJ3UaOpy3JE89qiPsJjsaE5lPfVDsIm+KqG8NPd56HsluE ywFt4hTY6slDee1VkaasrxGP4UDLSx1KP+XxgqFVpJiAAUpcSankbtAhzgWHa0J4nzGO NTFzTz+nNLct+0IJuV4T+1PcTwMMrJY9VimmPB1LhtqgxcfDOHbSSB5EGBXkKJwtsI2/ njX8d+txdXJinRc/3i56t3gOCIZUGtSGN7oc8LRWfci19zNF/+QDVW/b1o9WdcLLye7L 5x7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="W/uxpuH5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i4-v6si1460875pgk.2.2018.07.17.10.52.25; Tue, 17 Jul 2018 10:52:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="W/uxpuH5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731090AbeGQSZB (ORCPT + 99 others); Tue, 17 Jul 2018 14:25:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:53104 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729721AbeGQSZB (ORCPT ); Tue, 17 Jul 2018 14:25:01 -0400 Received: from mail-yb0-f169.google.com (mail-yb0-f169.google.com [209.85.213.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C8F6A20834; Tue, 17 Jul 2018 17:51:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1531849875; bh=+herIqvgXQJ0BE2my7SIvRLORuf5kM6iDM5eS8WhmiQ=; h=In-Reply-To:References:From:Date:Subject:To:Cc:From; b=W/uxpuH5gYyM6vi4AW65nwxzv5VlP0N2TpBR+5US0+kP8kXGhNC9/hmZSqfPHLLHP XRYIZ6sw4cy4cU/PTUd1cdb/S7OgooJTVHgN5m0krpd6pu7XaQidr3x2yNEzbt/Tv/ KSAHBbqHkyMOQP3AAgXQ1KjSOInEwQZHuSfZDxpM= Received: by mail-yb0-f169.google.com with SMTP id s1-v6so761604ybk.3; Tue, 17 Jul 2018 10:51:15 -0700 (PDT) X-Gm-Message-State: AOUpUlEuZcNxFYeF6r4MxOE4Xd6fhkeifi26T91ieOc/797TxuJ0p/3K XyAfdWfpXSDIV9+lHhd0fO6OMA04ZGXaiXX4qMo= X-Received: by 2002:a25:1f0b:: with SMTP id f11-v6mr1505956ybf.100.1531849874994; Tue, 17 Jul 2018 10:51:14 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a25:8182:0:0:0:0:0 with HTTP; Tue, 17 Jul 2018 10:50:34 -0700 (PDT) In-Reply-To: References: <1530629215-26990-1-git-send-email-richard.gong@linux.intel.com> <1530629215-26990-7-git-send-email-richard.gong@linux.intel.com> From: Alan Tull Date: Tue, 17 Jul 2018 12:50:34 -0500 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCHv6 6/8] fpga: add intel stratix10 soc fpga manager driver To: Moritz Fischer Cc: Richard Gong , Catalin Marinas , Will Deacon , Dinh Nguyen , Rob Herring , Mark Rutland , Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , linux-arm-kernel , Linux Kernel Mailing List , Devicetree List , linux-fpga@vger.kernel.org, Linux Doc Mailing List , Yves Vandervennet , Richard Gong Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jul 9, 2018 at 6:05 PM, Moritz Fischer wrote: > Hi Richard + Alan, > > couple of small stuff inline. Sorry for the super late reply. > Hi Moritz, Thanks for the review comments! > On Tue, Jul 3, 2018 at 7:46 AM, wrote: >> From: Alan Tull >> >> Add driver for reconfiguring Intel Stratix10 SoC FPGA devices. >> This driver communicates through the Intel Service Driver which >> does communication with privileged hardware (that does the >> FPGA programming) through a secure mailbox. >> >> Signed-off-by: Alan Tull >> Signed-off-by: Richard Gong ... >> +static int s10_svc_send_msg(struct s10_priv *priv, >> + enum stratix10_svc_command_code command, >> + void *payload, u32 payload_length) >> +{ >> + struct stratix10_svc_chan *chan = priv->chan; >> + struct stratix10_svc_client_msg msg; >> + int ret; >> + >> + pr_debug("%s cmd=%d payload=%p legnth=%d\n", >> + __func__, command, payload, payload_length); > > Can we make those dev_dbg() ? Or do we not have a device available? It's easy to get client dev:and it's worth doing by adding: struct device *dev = priv->client.dev; >> + >> + msg.command = command; >> + msg.payload = payload; >> + msg.payload_length = payload_length; >> + >> + ret = stratix10_svc_send(chan, &msg); >> + pr_debug("stratix10_svc_send returned status %d\n", ret); >> + >> + return ret; >> +} >> + ... >> +/** >> + * s10_ops_write_init >> + * Prepare for FPGA reconfiguration by requesting partial reconfig and >> + * allocating buffers from the service layer. >> + * @mgr: fpga manager >> + * @info: fpga image info >> + * @buf: fpga image buffer >> + * @count: size of buf in bytes >> + */ >> +static int s10_ops_write_init(struct fpga_manager *mgr, >> + struct fpga_image_info *info, >> + const char *buf, size_t count) >> +{ >> + struct s10_priv *priv = mgr->priv; >> + struct device *dev = priv->client.dev; >> + struct stratix10_svc_command_reconfig_payload payload; >> + char *kbuf; >> + uint i; >> + int ret; >> + >> + payload.flags = 0; >> + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { >> + dev_info(dev, "Requesting partial reconfiguration.\n"); > Do we need these to be _info() or can the by _dbg()? The Framework > already prints ("Writing blah.foo to ...") >> + payload.flags |= BIT(COMMAND_RECONFIG_FLAG_PARTIAL); >> + } else { >> + dev_info(dev, "Requesting full reconfiguration.\n"); > Same here. These can go away or be dgb. fpga-mgr.c has dev_info(dev, "writing %s to %s\n", image_name, mgr->name); in fpga_mgr_firmware_load(). Maybe at some point it would be better to have the "Reauesting full/partial reconfiguration" messages as dbg messages in fpga-mgr.c. Some of the fpga manager drivers have one message or the other only because they only handle full or partial, so it's an error message in their case.such as "Partial reconfiguration not supported." >> + } >> + >> + reinit_completion(&priv->status_return_completion); >> + ret = s10_svc_send_msg(priv, COMMAND_RECONFIG, >> + &payload, sizeof(payload)); >> + if (ret < 0) >> + goto init_done; >> + >> + ret = wait_for_completion_interruptible_timeout( >> + &priv->status_return_completion, S10_RECONFIG_TIMEOUT); >> + if (!ret) { >> + dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n"); >> + ret = -ETIMEDOUT; >> + goto init_done; >> + } >> + if (ret < 0) { >> + dev_err(dev, "error (%d) waiting for RECONFIG_REQUEST\n", ret); >> + goto init_done; >> + } >> + >> + ret = 0; >> + if (!test_and_clear_bit(SVC_STATUS_RECONFIG_REQUEST_OK, >> + &priv->status)) { >> + ret = -ETIMEDOUT; >> + goto init_done; >> + } >> + >> + /* Allocate buffers from the service layer's pool. */ >> + for (i = 0; i < NUM_SVC_BUFS; i++) { >> + kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE); >> + if (!kbuf) { >> + s10_free_buffers(mgr); >> + ret = -ENOMEM; >> + goto init_done; >> + } >> + >> + priv->svc_bufs[i].buf = kbuf; >> + priv->svc_bufs[i].lock = 0; >> + } >> + >> +init_done: >> + stratix10_svc_done(priv->chan); >> + return ret; >> +} >> + >> +/** >> + * s10_send_buf >> + * Send a buffer to the service layer queue >> + * @mgr: fpga manager struct >> + * @buf: fpga image buffer >> + * @count: size of buf in bytes >> + * Returns # of bytes transferred or -ENOBUFS if the all the buffers are in use >> + * or if the service queue is full. Never returns 0. >> + */ >> +static int s10_send_buf(struct fpga_manager *mgr, const char *buf, size_t count) >> +{ >> + struct s10_priv *priv = mgr->priv; >> + struct device *dev = priv->client.dev; >> + void *svc_buf; >> + size_t xfer_sz; >> + int ret; >> + uint i; >> + >> + /* get/lock a buffer that that's not being used */ >> + for (i = 0; i < NUM_SVC_BUFS; i++) >> + if (!test_and_set_bit_lock(SVC_BUF_LOCK, >> + &priv->svc_bufs[i].lock)) >> + break; >> + >> + if (i == NUM_SVC_BUFS) >> + return -ENOBUFS; >> + >> + xfer_sz = count < SVC_BUF_SIZE ? count : SVC_BUF_SIZE; >> + >> + svc_buf = priv->svc_bufs[i].buf; >> + memcpy(svc_buf, buf, xfer_sz); >> + ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_DATA_SUBMIT, >> + svc_buf, xfer_sz); >> + if (ret < 0) { >> + dev_err(dev, >> + "Error while sending data to service layer (%d)", ret); >> + return ret; >> + } > Do we need to clean up anything here, or is the buffer unlocked if we fail? Yes, need to unlock buff if s10_svc_send_msg() fails. clear_bit_unlock(SVC_BUF_LOCK, &priv->svc_bufs[i].lock); >> + >> + return xfer_sz; >> +} ... >> +static int s10_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct s10_priv *priv; >> + struct fpga_manager *mgr; >> + int ret; >> + >> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); >> + if (!priv) >> + return -ENOMEM; >> + >> + priv->client.dev = dev; >> + priv->client.receive_cb = s10_receive_callback; >> + priv->client.priv = priv; >> + >> + priv->chan = stratix10_svc_request_channel_byname(&priv->client, >> + SVC_CLIENT_FPGA); >> + if (IS_ERR(priv->chan)) { >> + dev_err(dev, "couldn't get service channel (%s)\n", >> + SVC_CLIENT_FPGA); >> + return PTR_ERR(priv->chan); >> + } >> + >> + init_completion(&priv->status_return_completion); >> + >> + mgr = fpga_mgr_create(dev, "Stratix10 SOC FPGA Manager", >> + &s10_ops, priv); >> + if (!mgr) >> + return -ENOMEM; > Does this release the channel above? We need to call "stratix10_svc_free_channel(priv->chan);" here if fpga_mgr_create() fails. >> + >> + ret = fpga_mgr_register(mgr); >> + if (ret) { >> + dev_err(dev, "unable to register FPGA manager\n"); >> + stratix10_svc_free_channel(priv->chan); >> + fpga_mgr_free(mgr); >> + return ret; >> + } >> + >> + platform_set_drvdata(pdev, mgr); >> + >> + return ret; >> +}