File Index
Files and directories
Sign in
FILE

vfio_platform_bcmflexrm.c

File preview with syntax highlighting.

linux-6.19.14/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2017 Broadcom
  4 */
  5
  6/*
  7 * This driver provides reset support for Broadcom FlexRM ring manager
  8 * to VFIO platform.
  9 */
 10
 11#include <linux/delay.h>
 12#include <linux/device.h>
 13#include <linux/init.h>
 14#include <linux/io.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17
 18#include "../vfio_platform_private.h"
 19
 20/* FlexRM configuration */
 21#define RING_REGS_SIZE					0x10000
 22#define RING_VER_MAGIC					0x76303031
 23
 24/* Per-Ring register offsets */
 25#define RING_VER					0x000
 26#define RING_CONTROL					0x034
 27#define RING_FLUSH_DONE					0x038
 28
 29/* Register RING_CONTROL fields */
 30#define CONTROL_FLUSH_SHIFT				5
 31
 32/* Register RING_FLUSH_DONE fields */
 33#define FLUSH_DONE_MASK					0x1
 34
 35static int vfio_platform_bcmflexrm_shutdown(void __iomem *ring)
 36{
 37	unsigned int timeout;
 38
 39	/* Disable/inactivate ring */
 40	writel_relaxed(0x0, ring + RING_CONTROL);
 41
 42	/* Set ring flush state */
 43	timeout = 1000; /* timeout of 1s */
 44	writel_relaxed(BIT(CONTROL_FLUSH_SHIFT), ring + RING_CONTROL);
 45	do {
 46		if (readl_relaxed(ring + RING_FLUSH_DONE) &
 47		    FLUSH_DONE_MASK)
 48			break;
 49		mdelay(1);
 50	} while (--timeout);
 51	if (!timeout)
 52		return -ETIMEDOUT;
 53
 54	/* Clear ring flush state */
 55	timeout = 1000; /* timeout of 1s */
 56	writel_relaxed(0x0, ring + RING_CONTROL);
 57	do {
 58		if (!(readl_relaxed(ring + RING_FLUSH_DONE) &
 59		      FLUSH_DONE_MASK))
 60			break;
 61		mdelay(1);
 62	} while (--timeout);
 63	if (!timeout)
 64		return -ETIMEDOUT;
 65
 66	return 0;
 67}
 68
 69static int vfio_platform_bcmflexrm_reset(struct vfio_platform_device *vdev)
 70{
 71	void __iomem *ring;
 72	int rc = 0, ret = 0, ring_num = 0;
 73	struct vfio_platform_region *reg = &vdev->regions[0];
 74
 75	dev_err_once(vdev->device, "DEPRECATION: VFIO Broadcom FlexRM platform reset is deprecated and will be removed in a future kernel release\n");
 76
 77	/* Map FlexRM ring registers if not mapped */
 78	if (!reg->ioaddr) {
 79		reg->ioaddr = ioremap(reg->addr, reg->size);
 80		if (!reg->ioaddr)
 81			return -ENOMEM;
 82	}
 83
 84	/* Discover and shutdown each FlexRM ring */
 85	for (ring = reg->ioaddr;
 86	     ring < (reg->ioaddr + reg->size); ring += RING_REGS_SIZE) {
 87		if (readl_relaxed(ring + RING_VER) == RING_VER_MAGIC) {
 88			rc = vfio_platform_bcmflexrm_shutdown(ring);
 89			if (rc) {
 90				dev_warn(vdev->device,
 91					 "FlexRM ring%d shutdown error %d\n",
 92					 ring_num, rc);
 93				ret |= rc;
 94			}
 95			ring_num++;
 96		}
 97	}
 98
 99	return ret;
100}
101
102module_vfio_reset_handler("brcm,iproc-flexrm-mbox",
103			  vfio_platform_bcmflexrm_reset);
104
105MODULE_LICENSE("GPL v2");
106MODULE_AUTHOR("Anup Patel <anup.patel@broadcom.com>");
107MODULE_DESCRIPTION("Reset support for Broadcom FlexRM VFIO platform device");
~/ Read-only file preview.