root/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vfio_platform_bcmflexrm_shutdown
  2. vfio_platform_bcmflexrm_reset

   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");

/* [<][>][^][v][top][bottom][index][help] */