root/drivers/spi/spi-iproc-qspi.c

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

DEFINITIONS

This source file includes following definitions.
  1. bcm_iproc_qspi_get_l2_int_status
  2. bcm_iproc_qspi_int_ack
  3. bcm_iproc_qspi_int_set
  4. bcm_iproc_probe
  5. bcm_iproc_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2016 Broadcom Limited
   4  */
   5 
   6 #include <linux/device.h>
   7 #include <linux/io.h>
   8 #include <linux/ioport.h>
   9 #include <linux/module.h>
  10 #include <linux/of.h>
  11 #include <linux/of_address.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/slab.h>
  14 
  15 #include "spi-bcm-qspi.h"
  16 
  17 #define INTR_BASE_BIT_SHIFT                     0x02
  18 #define INTR_COUNT                              0x07
  19 
  20 struct bcm_iproc_intc {
  21         struct bcm_qspi_soc_intc soc_intc;
  22         struct platform_device *pdev;
  23         void __iomem *int_reg;
  24         void __iomem *int_status_reg;
  25         spinlock_t soclock;
  26         bool big_endian;
  27 };
  28 
  29 static u32 bcm_iproc_qspi_get_l2_int_status(struct bcm_qspi_soc_intc *soc_intc)
  30 {
  31         struct bcm_iproc_intc *priv =
  32                         container_of(soc_intc, struct bcm_iproc_intc, soc_intc);
  33         void __iomem *mmio = priv->int_status_reg;
  34         int i;
  35         u32 val = 0, sts = 0;
  36 
  37         for (i = 0; i < INTR_COUNT; i++) {
  38                 if (bcm_qspi_readl(priv->big_endian, mmio + (i * 4)))
  39                         val |= 1UL << i;
  40         }
  41 
  42         if (val & INTR_MSPI_DONE_MASK)
  43                 sts |= MSPI_DONE;
  44 
  45         if (val & BSPI_LR_INTERRUPTS_ALL)
  46                 sts |= BSPI_DONE;
  47 
  48         if (val & BSPI_LR_INTERRUPTS_ERROR)
  49                 sts |= BSPI_ERR;
  50 
  51         return sts;
  52 }
  53 
  54 static void bcm_iproc_qspi_int_ack(struct bcm_qspi_soc_intc *soc_intc, int type)
  55 {
  56         struct bcm_iproc_intc *priv =
  57                         container_of(soc_intc, struct bcm_iproc_intc, soc_intc);
  58         void __iomem *mmio = priv->int_status_reg;
  59         u32 mask = get_qspi_mask(type);
  60         int i;
  61 
  62         for (i = 0; i < INTR_COUNT; i++) {
  63                 if (mask & (1UL << i))
  64                         bcm_qspi_writel(priv->big_endian, 1, mmio + (i * 4));
  65         }
  66 }
  67 
  68 static void bcm_iproc_qspi_int_set(struct bcm_qspi_soc_intc *soc_intc, int type,
  69                                    bool en)
  70 {
  71         struct bcm_iproc_intc *priv =
  72                         container_of(soc_intc, struct bcm_iproc_intc, soc_intc);
  73         void __iomem *mmio = priv->int_reg;
  74         u32 mask = get_qspi_mask(type);
  75         u32 val;
  76         unsigned long flags;
  77 
  78         spin_lock_irqsave(&priv->soclock, flags);
  79 
  80         val = bcm_qspi_readl(priv->big_endian, mmio);
  81 
  82         if (en)
  83                 val = val | (mask << INTR_BASE_BIT_SHIFT);
  84         else
  85                 val = val & ~(mask << INTR_BASE_BIT_SHIFT);
  86 
  87         bcm_qspi_writel(priv->big_endian, val, mmio);
  88 
  89         spin_unlock_irqrestore(&priv->soclock, flags);
  90 }
  91 
  92 static int bcm_iproc_probe(struct platform_device *pdev)
  93 {
  94         struct device *dev = &pdev->dev;
  95         struct bcm_iproc_intc *priv;
  96         struct bcm_qspi_soc_intc *soc_intc;
  97         struct resource *res;
  98 
  99         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 100         if (!priv)
 101                 return -ENOMEM;
 102         soc_intc = &priv->soc_intc;
 103         priv->pdev = pdev;
 104 
 105         spin_lock_init(&priv->soclock);
 106 
 107         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr_regs");
 108         priv->int_reg = devm_ioremap_resource(dev, res);
 109         if (IS_ERR(priv->int_reg))
 110                 return PTR_ERR(priv->int_reg);
 111 
 112         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 113                                            "intr_status_reg");
 114         priv->int_status_reg = devm_ioremap_resource(dev, res);
 115         if (IS_ERR(priv->int_status_reg))
 116                 return PTR_ERR(priv->int_status_reg);
 117 
 118         priv->big_endian = of_device_is_big_endian(dev->of_node);
 119 
 120         bcm_iproc_qspi_int_ack(soc_intc, MSPI_BSPI_DONE);
 121         bcm_iproc_qspi_int_set(soc_intc, MSPI_BSPI_DONE, false);
 122 
 123         soc_intc->bcm_qspi_int_ack = bcm_iproc_qspi_int_ack;
 124         soc_intc->bcm_qspi_int_set = bcm_iproc_qspi_int_set;
 125         soc_intc->bcm_qspi_get_int_status = bcm_iproc_qspi_get_l2_int_status;
 126 
 127         return bcm_qspi_probe(pdev, soc_intc);
 128 }
 129 
 130 static int bcm_iproc_remove(struct platform_device *pdev)
 131 {
 132         return bcm_qspi_remove(pdev);
 133 }
 134 
 135 static const struct of_device_id bcm_iproc_of_match[] = {
 136         { .compatible = "brcm,spi-nsp-qspi" },
 137         { .compatible = "brcm,spi-ns2-qspi" },
 138         {},
 139 };
 140 MODULE_DEVICE_TABLE(of, bcm_iproc_of_match);
 141 
 142 static struct platform_driver bcm_iproc_driver = {
 143         .probe                  = bcm_iproc_probe,
 144         .remove                 = bcm_iproc_remove,
 145         .driver = {
 146                 .name           = "bcm_iproc",
 147                 .pm             = &bcm_qspi_pm_ops,
 148                 .of_match_table = bcm_iproc_of_match,
 149         }
 150 };
 151 module_platform_driver(bcm_iproc_driver);
 152 
 153 MODULE_LICENSE("GPL v2");
 154 MODULE_AUTHOR("Kamal Dasu");
 155 MODULE_DESCRIPTION("SPI flash driver for Broadcom iProc SoCs");

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