LCOV - code coverage report
Current view: top level - drivers/irqchip - irq-gic-common.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 0 60 0.0 %
Date: 2020-09-30 20:25:40 Functions: 0 7 0.0 %
Branches: 0 40 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Copyright (C) 2002 ARM Limited, All Rights Reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <linux/interrupt.h>
       7                 :            : #include <linux/io.h>
       8                 :            : #include <linux/irq.h>
       9                 :            : #include <linux/irqchip/arm-gic.h>
      10                 :            : 
      11                 :            : #include "irq-gic-common.h"
      12                 :            : 
      13                 :            : static DEFINE_RAW_SPINLOCK(irq_controller_lock);
      14                 :            : 
      15                 :            : static const struct gic_kvm_info *gic_kvm_info;
      16                 :            : 
      17                 :          0 : const struct gic_kvm_info *gic_get_kvm_info(void)
      18                 :            : {
      19                 :          0 :         return gic_kvm_info;
      20                 :            : }
      21                 :            : 
      22                 :          0 : void gic_set_kvm_info(const struct gic_kvm_info *info)
      23                 :            : {
      24         [ #  # ]:          0 :         BUG_ON(gic_kvm_info != NULL);
      25                 :          0 :         gic_kvm_info = info;
      26                 :          0 : }
      27                 :            : 
      28                 :          0 : void gic_enable_of_quirks(const struct device_node *np,
      29                 :            :                           const struct gic_quirk *quirks, void *data)
      30                 :            : {
      31         [ #  # ]:          0 :         for (; quirks->desc; quirks++) {
      32         [ #  # ]:          0 :                 if (!of_device_is_compatible(np, quirks->compatible))
      33                 :          0 :                         continue;
      34         [ #  # ]:          0 :                 if (quirks->init(data))
      35                 :          0 :                         pr_info("GIC: enabling workaround for %s\n",
      36                 :            :                                 quirks->desc);
      37                 :            :         }
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
      41                 :            :                 void *data)
      42                 :            : {
      43         [ #  # ]:          0 :         for (; quirks->desc; quirks++) {
      44         [ #  # ]:          0 :                 if (quirks->compatible)
      45                 :          0 :                         continue;
      46         [ #  # ]:          0 :                 if (quirks->iidr != (quirks->mask & iidr))
      47                 :          0 :                         continue;
      48         [ #  # ]:          0 :                 if (quirks->init(data))
      49                 :          0 :                         pr_info("GIC: enabling workaround for %s\n",
      50                 :            :                                 quirks->desc);
      51                 :            :         }
      52                 :          0 : }
      53                 :            : 
      54                 :          0 : int gic_configure_irq(unsigned int irq, unsigned int type,
      55                 :            :                        void __iomem *base, void (*sync_access)(void))
      56                 :            : {
      57                 :          0 :         u32 confmask = 0x2 << ((irq % 16) * 2);
      58                 :          0 :         u32 confoff = (irq / 16) * 4;
      59                 :            :         u32 val, oldval;
      60                 :            :         int ret = 0;
      61                 :            :         unsigned long flags;
      62                 :            : 
      63                 :            :         /*
      64                 :            :          * Read current configuration register, and insert the config
      65                 :            :          * for "irq", depending on "type".
      66                 :            :          */
      67                 :          0 :         raw_spin_lock_irqsave(&irq_controller_lock, flags);
      68                 :          0 :         val = oldval = readl_relaxed(base + confoff);
      69         [ #  # ]:          0 :         if (type & IRQ_TYPE_LEVEL_MASK)
      70                 :          0 :                 val &= ~confmask;
      71         [ #  # ]:          0 :         else if (type & IRQ_TYPE_EDGE_BOTH)
      72                 :          0 :                 val |= confmask;
      73                 :            : 
      74                 :            :         /* If the current configuration is the same, then we are done */
      75         [ #  # ]:          0 :         if (val == oldval) {
      76                 :          0 :                 raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
      77                 :          0 :                 return 0;
      78                 :            :         }
      79                 :            : 
      80                 :            :         /*
      81                 :            :          * Write back the new configuration, and possibly re-enable
      82                 :            :          * the interrupt. If we fail to write a new configuration for
      83                 :            :          * an SPI then WARN and return an error. If we fail to write the
      84                 :            :          * configuration for a PPI this is most likely because the GIC
      85                 :            :          * does not allow us to set the configuration or we are in a
      86                 :            :          * non-secure mode, and hence it may not be catastrophic.
      87                 :            :          */
      88                 :            :         writel_relaxed(val, base + confoff);
      89         [ #  # ]:          0 :         if (readl_relaxed(base + confoff) != val)
      90                 :            :                 ret = -EINVAL;
      91                 :            : 
      92                 :          0 :         raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
      93                 :            : 
      94         [ #  # ]:          0 :         if (sync_access)
      95                 :          0 :                 sync_access();
      96                 :            : 
      97                 :          0 :         return ret;
      98                 :            : }
      99                 :            : 
     100                 :          0 : void gic_dist_config(void __iomem *base, int gic_irqs,
     101                 :            :                      void (*sync_access)(void))
     102                 :            : {
     103                 :            :         unsigned int i;
     104                 :            : 
     105                 :            :         /*
     106                 :            :          * Set all global interrupts to be level triggered, active low.
     107                 :            :          */
     108         [ #  # ]:          0 :         for (i = 32; i < gic_irqs; i += 16)
     109                 :          0 :                 writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
     110                 :            :                                         base + GIC_DIST_CONFIG + i / 4);
     111                 :            : 
     112                 :            :         /*
     113                 :            :          * Set priority on all global interrupts.
     114                 :            :          */
     115         [ #  # ]:          0 :         for (i = 32; i < gic_irqs; i += 4)
     116                 :          0 :                 writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
     117                 :            : 
     118                 :            :         /*
     119                 :            :          * Deactivate and disable all SPIs. Leave the PPI and SGIs
     120                 :            :          * alone as they are in the redistributor registers on GICv3.
     121                 :            :          */
     122         [ #  # ]:          0 :         for (i = 32; i < gic_irqs; i += 32) {
     123                 :          0 :                 writel_relaxed(GICD_INT_EN_CLR_X32,
     124                 :            :                                base + GIC_DIST_ACTIVE_CLEAR + i / 8);
     125                 :          0 :                 writel_relaxed(GICD_INT_EN_CLR_X32,
     126                 :            :                                base + GIC_DIST_ENABLE_CLEAR + i / 8);
     127                 :            :         }
     128                 :            : 
     129         [ #  # ]:          0 :         if (sync_access)
     130                 :          0 :                 sync_access();
     131                 :          0 : }
     132                 :            : 
     133                 :          0 : void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
     134                 :            : {
     135                 :            :         int i;
     136                 :            : 
     137                 :            :         /*
     138                 :            :          * Deal with the banked PPI and SGI interrupts - disable all
     139                 :            :          * private interrupts. Make sure everything is deactivated.
     140                 :            :          */
     141         [ #  # ]:          0 :         for (i = 0; i < nr; i += 32) {
     142                 :          0 :                 writel_relaxed(GICD_INT_EN_CLR_X32,
     143                 :            :                                base + GIC_DIST_ACTIVE_CLEAR + i / 8);
     144                 :          0 :                 writel_relaxed(GICD_INT_EN_CLR_X32,
     145                 :            :                                base + GIC_DIST_ENABLE_CLEAR + i / 8);
     146                 :            :         }
     147                 :            : 
     148                 :            :         /*
     149                 :            :          * Set priority on PPI and SGI interrupts
     150                 :            :          */
     151         [ #  # ]:          0 :         for (i = 0; i < nr; i += 4)
     152                 :          0 :                 writel_relaxed(GICD_INT_DEF_PRI_X4,
     153                 :            :                                         base + GIC_DIST_PRI + i * 4 / 4);
     154                 :            : 
     155                 :            :         /* Ensure all SGI interrupts are now enabled */
     156                 :          0 :         writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
     157                 :            : 
     158         [ #  # ]:          0 :         if (sync_access)
     159                 :          0 :                 sync_access();
     160                 :          0 : }

Generated by: LCOV version 1.14