Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfio: platform: reset: Add Broadcom FlexRM reset module

This patch adds Broadcom FlexRM low-level reset for
VFIO platform.

It will do the following:
1. Disable/Deactivate each FlexRM ring
2. Flush each FlexRM ring

The cleanup sequence for FlexRM rings is adapted from
Broadcom FlexRM mailbox driver.

Signed-off-by: Anup Patel <anup.patel@broadcom.com>
Reviewed-by: Oza Oza <oza.oza@broadcom.com>
Reviewed-by: Scott Branden <scott.branden@broadcom.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Anup Patel and committed by
Alex Williamson
e2588341 79d40370

+123
+9
drivers/vfio/platform/reset/Kconfig
··· 13 13 Enables the VFIO platform driver to handle reset for AMD XGBE 14 14 15 15 If you don't know what to do here, say N. 16 + 17 + config VFIO_PLATFORM_BCMFLEXRM_RESET 18 + tristate "VFIO support for Broadcom FlexRM reset" 19 + depends on VFIO_PLATFORM && (ARCH_BCM_IPROC || COMPILE_TEST) 20 + default ARCH_BCM_IPROC 21 + help 22 + Enables the VFIO platform driver to handle reset for Broadcom FlexRM 23 + 24 + If you don't know what to do here, say N.
+1
drivers/vfio/platform/reset/Makefile
··· 5 5 6 6 obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += vfio-platform-calxedaxgmac.o 7 7 obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o 8 + obj-$(CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET) += vfio_platform_bcmflexrm.o
+113
drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
··· 1 + /* 2 + * Copyright (C) 2017 Broadcom 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License as 6 + * published by the Free Software Foundation version 2. 7 + * 8 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 + * kind, whether express or implied; without even the implied warranty 10 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + /* 15 + * This driver provides reset support for Broadcom FlexRM ring manager 16 + * to VFIO platform. 17 + */ 18 + 19 + #include <linux/delay.h> 20 + #include <linux/device.h> 21 + #include <linux/init.h> 22 + #include <linux/io.h> 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + 26 + #include "vfio_platform_private.h" 27 + 28 + /* FlexRM configuration */ 29 + #define RING_REGS_SIZE 0x10000 30 + #define RING_VER_MAGIC 0x76303031 31 + 32 + /* Per-Ring register offsets */ 33 + #define RING_VER 0x000 34 + #define RING_CONTROL 0x034 35 + #define RING_FLUSH_DONE 0x038 36 + 37 + /* Register RING_CONTROL fields */ 38 + #define CONTROL_FLUSH_SHIFT 5 39 + 40 + /* Register RING_FLUSH_DONE fields */ 41 + #define FLUSH_DONE_MASK 0x1 42 + 43 + static int vfio_platform_bcmflexrm_shutdown(void __iomem *ring) 44 + { 45 + unsigned int timeout; 46 + 47 + /* Disable/inactivate ring */ 48 + writel_relaxed(0x0, ring + RING_CONTROL); 49 + 50 + /* Set ring flush state */ 51 + timeout = 1000; /* timeout of 1s */ 52 + writel_relaxed(BIT(CONTROL_FLUSH_SHIFT), ring + RING_CONTROL); 53 + do { 54 + if (readl_relaxed(ring + RING_FLUSH_DONE) & 55 + FLUSH_DONE_MASK) 56 + break; 57 + mdelay(1); 58 + } while (--timeout); 59 + if (!timeout) 60 + return -ETIMEDOUT; 61 + 62 + /* Clear ring flush state */ 63 + timeout = 1000; /* timeout of 1s */ 64 + writel_relaxed(0x0, ring + RING_CONTROL); 65 + do { 66 + if (!(readl_relaxed(ring + RING_FLUSH_DONE) & 67 + FLUSH_DONE_MASK)) 68 + break; 69 + mdelay(1); 70 + } while (--timeout); 71 + if (!timeout) 72 + return -ETIMEDOUT; 73 + 74 + return 0; 75 + } 76 + 77 + static int vfio_platform_bcmflexrm_reset(struct vfio_platform_device *vdev) 78 + { 79 + void __iomem *ring; 80 + int rc = 0, ret = 0, ring_num = 0; 81 + struct vfio_platform_region *reg = &vdev->regions[0]; 82 + 83 + /* Map FlexRM ring registers if not mapped */ 84 + if (!reg->ioaddr) { 85 + reg->ioaddr = ioremap_nocache(reg->addr, reg->size); 86 + if (!reg->ioaddr) 87 + return -ENOMEM; 88 + } 89 + 90 + /* Discover and shutdown each FlexRM ring */ 91 + for (ring = reg->ioaddr; 92 + ring < (reg->ioaddr + reg->size); ring += RING_REGS_SIZE) { 93 + if (readl_relaxed(ring + RING_VER) == RING_VER_MAGIC) { 94 + rc = vfio_platform_bcmflexrm_shutdown(ring); 95 + if (rc) { 96 + dev_warn(vdev->device, 97 + "FlexRM ring%d shutdown error %d\n", 98 + ring_num, rc); 99 + ret |= rc; 100 + } 101 + ring_num++; 102 + } 103 + } 104 + 105 + return ret; 106 + } 107 + 108 + module_vfio_reset_handler("brcm,iproc-flexrm-mbox", 109 + vfio_platform_bcmflexrm_reset); 110 + 111 + MODULE_LICENSE("GPL v2"); 112 + MODULE_AUTHOR("Anup Patel <anup.patel@broadcom.com>"); 113 + MODULE_DESCRIPTION("Reset support for Broadcom FlexRM VFIO platform device");