All of lore.kernel.org
 help / color / mirror / Atom feed
From: Moritz Fischer <mdf@kernel.org>
To: Lizhi Hou <lizhi.hou@xilinx.com>
Cc: linux-kernel@vger.kernel.org, Lizhi Hou <lizhih@xilinx.com>,
	linux-fpga@vger.kernel.org, maxz@xilinx.com,
	sonal.santan@xilinx.com, michal.simek@xilinx.com,
	stefanos@xilinx.com, devicetree@vger.kernel.org, trix@redhat.com,
	mdf@kernel.org, robh@kernel.org, Max Zhen <max.zhen@xilinx.com>
Subject: Re: [PATCH V3 XRT Alveo 17/18] fpga: xrt: partition isolation platform driver
Date: Sun, 21 Feb 2021 12:36:11 -0800	[thread overview]
Message-ID: <YDLEO6Bg6ySSoupI@archbook> (raw)
In-Reply-To: <20210218064019.29189-18-lizhih@xilinx.com>

On Wed, Feb 17, 2021 at 10:40:18PM -0800, Lizhi Hou wrote:
> Add partition isolation platform driver. partition isolation is
> a hardware function discovered by walking firmware metadata.
> A platform device node will be created for it. Partition isolation
> function isolate the different fpga regions
> 
> Signed-off-by: Sonal Santan <sonal.santan@xilinx.com>
> Signed-off-by: Max Zhen <max.zhen@xilinx.com>
> Signed-off-by: Lizhi Hou <lizhih@xilinx.com>
> ---
>  drivers/fpga/xrt/include/xleaf/axigate.h |  25 ++
>  drivers/fpga/xrt/lib/xleaf/axigate.c     | 298 +++++++++++++++++++++++
>  2 files changed, 323 insertions(+)
>  create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
>  create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c
> 
> diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h b/drivers/fpga/xrt/include/xleaf/axigate.h
> new file mode 100644
> index 000000000000..2cef71e13b30
> --- /dev/null
> +++ b/drivers/fpga/xrt/include/xleaf/axigate.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Header file for XRT Axigate Leaf Driver
> + *
> + * Copyright (C) 2020-2021 Xilinx, Inc.
> + *
> + * Authors:
> + *	Lizhi Hou <Lizhi.Hou@xilinx.com>
> + */
> +
> +#ifndef _XRT_AXIGATE_H_
> +#define _XRT_AXIGATE_H_
> +
> +#include "xleaf.h"
> +#include "metadata.h"
> +
> +/*
> + * AXIGATE driver IOCTL calls.
> + */
> +enum xrt_axigate_ioctl_cmd {
> +	XRT_AXIGATE_FREEZE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
> +	XRT_AXIGATE_FREE,
> +};
> +
> +#endif	/* _XRT_AXIGATE_H_ */
> diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c b/drivers/fpga/xrt/lib/xleaf/axigate.c
> new file mode 100644
> index 000000000000..382969f9925f
> --- /dev/null
> +++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
> @@ -0,0 +1,298 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Xilinx Alveo FPGA AXI Gate Driver
> + *
> + * Copyright (C) 2020-2021 Xilinx, Inc.
> + *
> + * Authors:
> + *      Lizhi Hou<Lizhi.Hou@xilinx.com>
> + */
> +
> +#include <linux/mod_devicetable.h>
> +#include <linux/platform_device.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include "metadata.h"
> +#include "xleaf.h"
> +#include "xleaf/axigate.h"
> +
> +#define XRT_AXIGATE "xrt_axigate"
> +
> +struct axigate_regs {
> +	u32		iag_wr;
> +	u32		iag_rvsd;
> +	u32		iag_rd;
> +} __packed;

Just make them #defines, even more so if there are only 3 of them.
> +
> +struct xrt_axigate {
> +	struct platform_device	*pdev;
> +	void			*base;
> +	struct mutex		gate_lock; /* gate dev lock */
> +
> +	void			*evt_hdl;
> +	const char		*ep_name;
> +
> +	bool			gate_freezed;
> +};
> +
> +/* the ep names are in the order of hardware layers */
> +static const char * const xrt_axigate_epnames[] = {
> +	XRT_MD_NODE_GATE_PLP,
> +	XRT_MD_NODE_GATE_ULP,
> +	NULL
> +};
> +
> +#define reg_rd(g, r)						\
> +	ioread32((void *)(g)->base + offsetof(struct axigate_regs, r))
> +#define reg_wr(g, v, r)						\
> +	iowrite32(v, (void *)(g)->base + offsetof(struct axigate_regs, r))
> +
> +static inline void freeze_gate(struct xrt_axigate *gate)
> +{
> +	reg_wr(gate, 0, iag_wr);
> +	ndelay(500);
> +	reg_rd(gate, iag_rd);
> +}
> +
> +static inline void free_gate(struct xrt_axigate *gate)
> +{
> +	reg_wr(gate, 0x2, iag_wr);
> +	ndelay(500);
Magic constants?
> +	(void)reg_rd(gate, iag_rd);
At the very least add a comment on why? Is this for PCI synchronization
reasons?

> +	reg_wr(gate, 0x3, iag_wr);
> +	ndelay(500);
Magic constants?
> +	reg_rd(gate, iag_rd);
Does it nead a (void) or not? Be consistent, again, why do we read here
at all?
> +}
> +
> +static int xrt_axigate_epname_idx(struct platform_device *pdev)
> +{
> +	int			i;
> +	int			ret;
> +	struct resource		*res;
Nope. Indents:

struct resource *res;
int, i, ret;

> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		xrt_err(pdev, "Empty Resource!");
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; xrt_axigate_epnames[i]; i++) {
> +		ret = strncmp(xrt_axigate_epnames[i], res->name,
> +			      strlen(xrt_axigate_epnames[i]) + 1);
> +		if (!ret)
> +			break;
> +	}
> +
> +	ret = (xrt_axigate_epnames[i]) ? i : -EINVAL;
Why not just:

	if (xrt_axigate_epnames[i])
		return i;

	return -EINVAL;
> +	return ret;
> +}
> +
> +static void xrt_axigate_freeze(struct platform_device *pdev)
> +{
> +	struct xrt_axigate	*gate;
> +	u32			freeze = 0;
Indents. Fix everywhere.
> +
> +	gate = platform_get_drvdata(pdev);
> +
> +	mutex_lock(&gate->gate_lock);
> +	freeze = reg_rd(gate, iag_rd);
> +	if (freeze) {		/* gate is opened */
> +		xleaf_broadcast_event(pdev, XRT_EVENT_PRE_GATE_CLOSE, false);
> +		freeze_gate(gate);
> +	}
> +
> +	gate->gate_freezed = true;
s/freezed/frozen
> +	mutex_unlock(&gate->gate_lock);
> +
> +	xrt_info(pdev, "freeze gate %s", gate->ep_name);
debug?
> +}
> +
> +static void xrt_axigate_free(struct platform_device *pdev)
> +{
> +	struct xrt_axigate	*gate;
> +	u32			freeze;
> +
> +	gate = platform_get_drvdata(pdev);
> +
> +	mutex_lock(&gate->gate_lock);
> +	freeze = reg_rd(gate, iag_rd);
> +	if (!freeze) {		/* gate is closed */
> +		free_gate(gate);
> +		xleaf_broadcast_event(pdev, XRT_EVENT_POST_GATE_OPEN, true);
> +		/* xrt_axigate_free() could be called in event cb, thus
> +		 * we can not wait for the completes
> +		 */
> +	}
> +
> +	gate->gate_freezed = false;
> +	mutex_unlock(&gate->gate_lock);
> +
> +	xrt_info(pdev, "free gate %s", gate->ep_name);
> +}
> +
> +static void xrt_axigate_event_cb(struct platform_device *pdev, void *arg)
> +{
> +	struct platform_device *leaf;
> +	struct xrt_event *evt = (struct xrt_event *)arg;
> +	enum xrt_events e = evt->xe_evt;
> +	enum xrt_subdev_id id = evt->xe_subdev.xevt_subdev_id;
> +	int instance = evt->xe_subdev.xevt_subdev_instance;
> +	struct xrt_axigate *gate = platform_get_drvdata(pdev);
> +	struct resource	*res;
Reverse x-mas tree;
xxxxxxxxxx
xxxxxxxxx
xxxxxxxx
xxxxxx
> +
> +	switch (e) {
> +	case XRT_EVENT_POST_CREATION:
> +		break;
> +	default:
> +		return;
> +	}
> +
> +	if (id != XRT_SUBDEV_AXIGATE)
> +		return;
> +
> +	leaf = xleaf_get_leaf_by_id(pdev, id, instance);
> +	if (!leaf)
> +		return;
> +
> +	res = platform_get_resource(leaf, IORESOURCE_MEM, 0);
> +	if (!res || !strncmp(res->name, gate->ep_name, strlen(res->name) + 1)) {
> +		(void)xleaf_put_leaf(pdev, leaf);
> +		return;
> +	}
> +
> +	/*
> +	 * higher level axigate instance created,
> +	 * make sure the gate is openned. This covers 1RP flow which
> +	 * has plp gate as well.
> +	 */
> +	if (xrt_axigate_epname_idx(leaf) > xrt_axigate_epname_idx(pdev))
> +		xrt_axigate_free(pdev);
> +	else
> +		xleaf_ioctl(leaf, XRT_AXIGATE_FREE, NULL);
> +
> +	(void)xleaf_put_leaf(pdev, leaf);
> +}
> +
> +static int
> +xrt_axigate_leaf_ioctl(struct platform_device *pdev, u32 cmd, void *arg)
> +{
> +	switch (cmd) {
> +	case XRT_XLEAF_EVENT:
> +		xrt_axigate_event_cb(pdev, arg);
> +		break;
> +	case XRT_AXIGATE_FREEZE:
> +		xrt_axigate_freeze(pdev);
> +		break;
> +	case XRT_AXIGATE_FREE:
> +		xrt_axigate_free(pdev);
> +		break;
> +	default:
> +		xrt_err(pdev, "unsupported cmd %d", cmd);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int xrt_axigate_remove(struct platform_device *pdev)
> +{
> +	struct xrt_axigate	*gate;
> +
> +	gate = platform_get_drvdata(pdev);
> +
> +	if (gate->base)
> +		iounmap(gate->base);
> +
> +	platform_set_drvdata(pdev, NULL);
> +	devm_kfree(&pdev->dev, gate);
No! The point of using devres is so cleanup happens on removal.
While you're at it, if you move the ioremap to a devres version, this
function can basically go away entirely.
> +
> +	return 0;
> +}
> +
> +static int xrt_axigate_probe(struct platform_device *pdev)
> +{
> +	struct xrt_axigate	*gate;
> +	struct resource		*res;
> +	int			ret;
> +
> +	gate = devm_kzalloc(&pdev->dev, sizeof(*gate), GFP_KERNEL);
> +	if (!gate)
> +		return -ENOMEM;
> +
> +	gate->pdev = pdev;
> +	platform_set_drvdata(pdev, gate);
> +
> +	xrt_info(pdev, "probing...");
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		xrt_err(pdev, "Empty resource 0");
> +		ret = -EINVAL;
> +		goto failed;
> +	}
> +
> +	gate->base = ioremap(res->start, res->end - res->start + 1);
> +	if (!gate->base) {
> +		xrt_err(pdev, "map base iomem failed");
> +		ret = -EFAULT;
> +		goto failed;
> +	}
> +
> +	gate->ep_name = res->name;
> +
> +	mutex_init(&gate->gate_lock);
> +
> +	return 0;
> +
> +failed:
> +	xrt_axigate_remove(pdev);
> +	return ret;
> +}
> +
> +static struct xrt_subdev_endpoints xrt_axigate_endpoints[] = {
> +	{
> +		.xse_names = (struct xrt_subdev_ep_names[]) {
> +			{ .ep_name = "ep_pr_isolate_ulp_00" },
> +			{ NULL },
> +		},
> +		.xse_min_ep = 1,
> +	},
> +	{
> +		.xse_names = (struct xrt_subdev_ep_names[]) {
> +			{ .ep_name = "ep_pr_isolate_plp_00" },
> +			{ NULL },
> +		},
> +		.xse_min_ep = 1,
> +	},
> +	{ 0 },
> +};
> +
> +static struct xrt_subdev_drvdata xrt_axigate_data = {
> +	.xsd_dev_ops = {
> +		.xsd_ioctl = xrt_axigate_leaf_ioctl,
> +	},
> +};
> +
> +static const struct platform_device_id xrt_axigate_table[] = {
> +	{ XRT_AXIGATE, (kernel_ulong_t)&xrt_axigate_data },
> +	{ },
> +};
> +
> +static struct platform_driver xrt_axigate_driver = {
> +	.driver = {
> +		.name = XRT_AXIGATE,
> +	},
> +	.probe = xrt_axigate_probe,
> +	.remove = xrt_axigate_remove,
> +	.id_table = xrt_axigate_table,
> +};
> +
> +void axigate_leaf_init_fini(bool init)
> +{
> +	if (init) {
> +		xleaf_register_driver(XRT_SUBDEV_AXIGATE,
> +				      &xrt_axigate_driver, xrt_axigate_endpoints);
> +	} else {
> +		xleaf_unregister_driver(XRT_SUBDEV_AXIGATE);
> +	}
> +}

This thing is duplicated in every file, maybe a macro would be an idea.
> -- 
> 2.18.4
> 

- Moritz

  reply	other threads:[~2021-02-21 20:37 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-18  6:40 [PATCH V3 XRT Alveo 00/18] XRT Alveo driver overview Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 01/18] Documentation: fpga: Add a document describing XRT Alveo drivers Lizhi Hou
2021-02-19 22:26   ` Tom Rix
2021-03-01  6:48     ` Sonal Santan
2021-03-06 17:19       ` Moritz Fischer
2021-03-08 20:12         ` Sonal Santan
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 02/18] fpga: xrt: driver metadata helper functions Lizhi Hou
2021-02-20 17:07   ` Tom Rix
2021-02-23  6:05     ` Lizhi Hou
2021-02-23  1:23   ` Fernando Pacheco
2021-02-25 20:27     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file " Lizhi Hou
2021-02-21 17:12   ` Tom Rix
2021-02-21 18:33     ` Moritz Fischer
2021-03-06  1:13       ` Lizhi Hou
2021-02-26 21:23     ` Lizhi Hou
2021-02-28 16:54       ` Tom Rix
2021-03-02  0:25         ` Lizhi Hou
2021-03-02 15:14           ` Moritz Fischer
2021-03-04 18:53             ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 04/18] fpga: xrt: xrt-lib platform driver manager Lizhi Hou
2021-02-21 20:39   ` Moritz Fischer
2021-03-01 20:34     ` Max Zhen
2021-02-22 15:05   ` Tom Rix
2021-02-23  3:35     ` Moritz Fischer
2021-03-03 17:20     ` Max Zhen
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 05/18] fpga: xrt: group platform driver Lizhi Hou
2021-02-22 18:50   ` Tom Rix
2021-02-26 21:57     ` Max Zhen
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 06/18] fpga: xrt: platform driver infrastructure Lizhi Hou
2021-02-25 21:59   ` Tom Rix
     [not found]     ` <13e9a311-2d04-ba65-3ed2-f9f1834c37de@xilinx.com>
2021-03-08 20:36       ` Max Zhen
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 07/18] fpga: xrt: management physical function driver (root) Lizhi Hou
2021-02-26 15:01   ` Tom Rix
2021-02-26 17:56     ` Moritz Fischer
2021-03-16 20:29     ` Max Zhen
2021-03-17 21:08       ` Tom Rix
2021-03-18  0:44         ` Max Zhen
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 08/18] fpga: xrt: main platform driver for management function device Lizhi Hou
2021-02-26 17:22   ` Tom Rix
2021-03-16 21:23     ` Lizhi Hou
2021-03-17 21:12       ` Tom Rix
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 09/18] fpga: xrt: fpga-mgr and region implementation for xclbin download Lizhi Hou
2021-02-28 16:36   ` Tom Rix
2021-03-04 17:50     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 10/18] fpga: xrt: VSEC platform driver Lizhi Hou
2021-03-01 19:01   ` Tom Rix
2021-03-05 19:58     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 11/18] fpga: xrt: UCS " Lizhi Hou
2021-03-02 16:09   ` Tom Rix
2021-03-10 20:24     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 12/18] fpga: xrt: ICAP " Lizhi Hou
2021-02-21 20:24   ` Moritz Fischer
2021-03-02 18:26     ` Lizhi Hou
2021-03-03 15:12   ` Tom Rix
2021-03-17 20:56     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 13/18] fpga: xrt: devctl " Lizhi Hou
2021-03-04 13:39   ` Tom Rix
2021-03-16 23:54     ` Lizhi Hou
2021-03-17 21:16       ` Tom Rix
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 14/18] fpga: xrt: clock " Lizhi Hou
2021-03-05 15:23   ` Tom Rix
2021-03-11  0:12     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 15/18] fpga: xrt: clock frequence counter " Lizhi Hou
2021-03-06 15:25   ` Tom Rix
2021-03-12 23:43     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 16/18] fpga: xrt: DDR calibration " Lizhi Hou
2021-02-21 20:21   ` Moritz Fischer
2021-03-06 15:34   ` Tom Rix
2021-03-13  0:45     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 17/18] fpga: xrt: partition isolation " Lizhi Hou
2021-02-21 20:36   ` Moritz Fischer [this message]
2021-03-16 20:38     ` Lizhi Hou
2021-03-06 15:54   ` Tom Rix
2021-03-13  6:53     ` Lizhi Hou
2021-02-18  6:40 ` [PATCH V3 XRT Alveo 18/18] fpga: xrt: Kconfig and Makefile updates for XRT drivers Lizhi Hou
2021-02-18  9:02   ` kernel test robot
2021-02-18  9:02     ` kernel test robot
2021-02-18 19:50   ` kernel test robot
2021-02-18 19:50     ` kernel test robot
2021-02-21 14:57   ` Tom Rix
2021-02-21 18:39     ` Moritz Fischer
2021-02-28 20:52       ` Sonal Santan
2021-02-18 13:52 ` [PATCH V3 XRT Alveo 00/18] XRT Alveo driver overview Tom Rix
2021-02-19  5:15   ` Lizhi Hou
2021-02-21 20:43 ` Moritz Fischer
2021-03-01 18:29   ` Lizhi Hou
2021-03-03  6:49   ` Joe Perches
2021-03-03 23:15     ` Moritz Fischer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YDLEO6Bg6ySSoupI@archbook \
    --to=mdf@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-fpga@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizhi.hou@xilinx.com \
    --cc=lizhih@xilinx.com \
    --cc=max.zhen@xilinx.com \
    --cc=maxz@xilinx.com \
    --cc=michal.simek@xilinx.com \
    --cc=robh@kernel.org \
    --cc=sonal.santan@xilinx.com \
    --cc=stefanos@xilinx.com \
    --cc=trix@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.