LCOV - code coverage report
Current view: top level - kernel/irq - irqdesc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 98 317 30.9 %
Date: 2022-04-01 14:17:54 Functions: 10 34 29.4 %
Branches: 30 150 20.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
       4                 :            :  * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
       5                 :            :  *
       6                 :            :  * This file contains the interrupt descriptor management code. Detailed
       7                 :            :  * information is available in Documentation/core-api/genericirq.rst
       8                 :            :  *
       9                 :            :  */
      10                 :            : #include <linux/irq.h>
      11                 :            : #include <linux/slab.h>
      12                 :            : #include <linux/export.h>
      13                 :            : #include <linux/interrupt.h>
      14                 :            : #include <linux/kernel_stat.h>
      15                 :            : #include <linux/radix-tree.h>
      16                 :            : #include <linux/bitmap.h>
      17                 :            : #include <linux/irqdomain.h>
      18                 :            : #include <linux/sysfs.h>
      19                 :            : 
      20                 :            : #include "internals.h"
      21                 :            : 
      22                 :            : /*
      23                 :            :  * lockdep: we want to handle all irq_desc locks as a single lock-class:
      24                 :            :  */
      25                 :            : static struct lock_class_key irq_desc_lock_class;
      26                 :            : 
      27                 :            : #if defined(CONFIG_SMP)
      28                 :          0 : static int __init irq_affinity_setup(char *str)
      29                 :            : {
      30                 :          0 :         alloc_bootmem_cpumask_var(&irq_default_affinity);
      31                 :          0 :         cpulist_parse(str, irq_default_affinity);
      32                 :            :         /*
      33                 :            :          * Set at least the boot cpu. We don't want to end up with
      34                 :            :          * bugreports caused by random comandline masks
      35                 :            :          */
      36                 :          0 :         cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
      37                 :          0 :         return 1;
      38                 :            : }
      39                 :            : __setup("irqaffinity=", irq_affinity_setup);
      40                 :            : 
      41                 :         11 : static void __init init_irq_default_affinity(void)
      42                 :            : {
      43         [ +  - ]:         11 :         if (!cpumask_available(irq_default_affinity))
      44                 :            :                 zalloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
      45         [ +  - ]:         11 :         if (cpumask_empty(irq_default_affinity))
      46                 :         11 :                 cpumask_setall(irq_default_affinity);
      47                 :         11 : }
      48                 :            : #else
      49                 :            : static void __init init_irq_default_affinity(void)
      50                 :            : {
      51                 :            : }
      52                 :            : #endif
      53                 :            : 
      54                 :            : #ifdef CONFIG_SMP
      55                 :            : static int alloc_masks(struct irq_desc *desc, int node)
      56                 :            : {
      57                 :            :         if (!zalloc_cpumask_var_node(&desc->irq_common_data.affinity,
      58                 :            :                                      GFP_KERNEL, node))
      59                 :            :                 return -ENOMEM;
      60                 :            : 
      61                 :            : #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
      62                 :            :         if (!zalloc_cpumask_var_node(&desc->irq_common_data.effective_affinity,
      63                 :            :                                      GFP_KERNEL, node)) {
      64                 :            :                 free_cpumask_var(desc->irq_common_data.affinity);
      65                 :            :                 return -ENOMEM;
      66                 :            :         }
      67                 :            : #endif
      68                 :            : 
      69                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
      70                 :            :         if (!zalloc_cpumask_var_node(&desc->pending_mask, GFP_KERNEL, node)) {
      71                 :            : #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
      72                 :            :                 free_cpumask_var(desc->irq_common_data.effective_affinity);
      73                 :            : #endif
      74                 :            :                 free_cpumask_var(desc->irq_common_data.affinity);
      75                 :            :                 return -ENOMEM;
      76                 :            :         }
      77                 :            : #endif
      78                 :            :         return 0;
      79                 :            : }
      80                 :            : 
      81                 :        176 : static void desc_smp_init(struct irq_desc *desc, int node,
      82                 :            :                           const struct cpumask *affinity)
      83                 :            : {
      84                 :        176 :         if (!affinity)
      85                 :        176 :                 affinity = irq_default_affinity;
      86                 :        176 :         cpumask_copy(desc->irq_common_data.affinity, affinity);
      87                 :            : 
      88                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
      89                 :        176 :         cpumask_clear(desc->pending_mask);
      90                 :            : #endif
      91                 :            : #ifdef CONFIG_NUMA
      92                 :        176 :         desc->irq_common_data.node = node;
      93                 :            : #endif
      94                 :            : }
      95                 :            : 
      96                 :            : #else
      97                 :            : static inline int
      98                 :            : alloc_masks(struct irq_desc *desc, int node) { return 0; }
      99                 :            : static inline void
     100                 :            : desc_smp_init(struct irq_desc *desc, int node, const struct cpumask *affinity) { }
     101                 :            : #endif
     102                 :            : 
     103                 :        176 : static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
     104                 :            :                               const struct cpumask *affinity, struct module *owner)
     105                 :            : {
     106                 :        176 :         int cpu;
     107                 :            : 
     108                 :        176 :         desc->irq_common_data.handler_data = NULL;
     109                 :        176 :         desc->irq_common_data.msi_desc = NULL;
     110                 :            : 
     111                 :        176 :         desc->irq_data.common = &desc->irq_common_data;
     112                 :        176 :         desc->irq_data.irq = irq;
     113                 :        176 :         desc->irq_data.chip = &no_irq_chip;
     114                 :        176 :         desc->irq_data.chip_data = NULL;
     115                 :        176 :         irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
     116                 :        176 :         irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
     117                 :        176 :         irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
     118                 :        176 :         desc->handle_irq = handle_bad_irq;
     119                 :        176 :         desc->depth = 1;
     120                 :        176 :         desc->irq_count = 0;
     121                 :        176 :         desc->irqs_unhandled = 0;
     122                 :        176 :         desc->tot_count = 0;
     123                 :        176 :         desc->name = NULL;
     124                 :        176 :         desc->owner = owner;
     125         [ +  + ]:        352 :         for_each_possible_cpu(cpu)
     126                 :        176 :                 *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
     127         [ +  - ]:        176 :         desc_smp_init(desc, node, affinity);
     128                 :        176 : }
     129                 :            : 
     130                 :            : int nr_irqs = NR_IRQS;
     131                 :            : EXPORT_SYMBOL_GPL(nr_irqs);
     132                 :            : 
     133                 :            : static DEFINE_MUTEX(sparse_irq_lock);
     134                 :            : static DECLARE_BITMAP(allocated_irqs, IRQ_BITMAP_BITS);
     135                 :            : 
     136                 :            : #ifdef CONFIG_SPARSE_IRQ
     137                 :            : 
     138                 :            : static void irq_kobj_release(struct kobject *kobj);
     139                 :            : 
     140                 :            : #ifdef CONFIG_SYSFS
     141                 :            : static struct kobject *irq_kobj_base;
     142                 :            : 
     143                 :            : #define IRQ_ATTR_RO(_name) \
     144                 :            : static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
     145                 :            : 
     146                 :          0 : static ssize_t per_cpu_count_show(struct kobject *kobj,
     147                 :            :                                   struct kobj_attribute *attr, char *buf)
     148                 :            : {
     149                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     150                 :          0 :         int cpu, irq = desc->irq_data.irq;
     151                 :          0 :         ssize_t ret = 0;
     152                 :          0 :         char *p = "";
     153                 :            : 
     154         [ #  # ]:          0 :         for_each_possible_cpu(cpu) {
     155                 :          0 :                 unsigned int c = kstat_irqs_cpu(irq, cpu);
     156                 :            : 
     157                 :          0 :                 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s%u", p, c);
     158                 :          0 :                 p = ",";
     159                 :            :         }
     160                 :            : 
     161                 :          0 :         ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
     162                 :          0 :         return ret;
     163                 :            : }
     164                 :            : IRQ_ATTR_RO(per_cpu_count);
     165                 :            : 
     166                 :          0 : static ssize_t chip_name_show(struct kobject *kobj,
     167                 :            :                               struct kobj_attribute *attr, char *buf)
     168                 :            : {
     169                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     170                 :          0 :         ssize_t ret = 0;
     171                 :            : 
     172                 :          0 :         raw_spin_lock_irq(&desc->lock);
     173   [ #  #  #  # ]:          0 :         if (desc->irq_data.chip && desc->irq_data.chip->name) {
     174                 :          0 :                 ret = scnprintf(buf, PAGE_SIZE, "%s\n",
     175                 :            :                                 desc->irq_data.chip->name);
     176                 :            :         }
     177                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     178                 :            : 
     179                 :          0 :         return ret;
     180                 :            : }
     181                 :            : IRQ_ATTR_RO(chip_name);
     182                 :            : 
     183                 :          0 : static ssize_t hwirq_show(struct kobject *kobj,
     184                 :            :                           struct kobj_attribute *attr, char *buf)
     185                 :            : {
     186                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     187                 :          0 :         ssize_t ret = 0;
     188                 :            : 
     189                 :          0 :         raw_spin_lock_irq(&desc->lock);
     190         [ #  # ]:          0 :         if (desc->irq_data.domain)
     191                 :          0 :                 ret = sprintf(buf, "%d\n", (int)desc->irq_data.hwirq);
     192                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     193                 :            : 
     194                 :          0 :         return ret;
     195                 :            : }
     196                 :            : IRQ_ATTR_RO(hwirq);
     197                 :            : 
     198                 :          0 : static ssize_t type_show(struct kobject *kobj,
     199                 :            :                          struct kobj_attribute *attr, char *buf)
     200                 :            : {
     201                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     202                 :          0 :         ssize_t ret = 0;
     203                 :            : 
     204                 :          0 :         raw_spin_lock_irq(&desc->lock);
     205                 :          0 :         ret = sprintf(buf, "%s\n",
     206         [ #  # ]:          0 :                       irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
     207                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     208                 :            : 
     209                 :          0 :         return ret;
     210                 :            : 
     211                 :            : }
     212                 :            : IRQ_ATTR_RO(type);
     213                 :            : 
     214                 :          0 : static ssize_t wakeup_show(struct kobject *kobj,
     215                 :            :                            struct kobj_attribute *attr, char *buf)
     216                 :            : {
     217                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     218                 :          0 :         ssize_t ret = 0;
     219                 :            : 
     220                 :          0 :         raw_spin_lock_irq(&desc->lock);
     221                 :          0 :         ret = sprintf(buf, "%s\n",
     222         [ #  # ]:          0 :                       irqd_is_wakeup_set(&desc->irq_data) ? "enabled" : "disabled");
     223                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     224                 :            : 
     225                 :          0 :         return ret;
     226                 :            : 
     227                 :            : }
     228                 :            : IRQ_ATTR_RO(wakeup);
     229                 :            : 
     230                 :          0 : static ssize_t name_show(struct kobject *kobj,
     231                 :            :                          struct kobj_attribute *attr, char *buf)
     232                 :            : {
     233                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     234                 :          0 :         ssize_t ret = 0;
     235                 :            : 
     236                 :          0 :         raw_spin_lock_irq(&desc->lock);
     237         [ #  # ]:          0 :         if (desc->name)
     238                 :          0 :                 ret = scnprintf(buf, PAGE_SIZE, "%s\n", desc->name);
     239                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     240                 :            : 
     241                 :          0 :         return ret;
     242                 :            : }
     243                 :            : IRQ_ATTR_RO(name);
     244                 :            : 
     245                 :          0 : static ssize_t actions_show(struct kobject *kobj,
     246                 :            :                             struct kobj_attribute *attr, char *buf)
     247                 :            : {
     248                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     249                 :          0 :         struct irqaction *action;
     250                 :          0 :         ssize_t ret = 0;
     251                 :          0 :         char *p = "";
     252                 :            : 
     253                 :          0 :         raw_spin_lock_irq(&desc->lock);
     254         [ #  # ]:          0 :         for (action = desc->action; action != NULL; action = action->next) {
     255                 :          0 :                 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s%s",
     256                 :            :                                  p, action->name);
     257                 :          0 :                 p = ",";
     258                 :            :         }
     259                 :          0 :         raw_spin_unlock_irq(&desc->lock);
     260                 :            : 
     261         [ #  # ]:          0 :         if (ret)
     262                 :          0 :                 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
     263                 :            : 
     264                 :          0 :         return ret;
     265                 :            : }
     266                 :            : IRQ_ATTR_RO(actions);
     267                 :            : 
     268                 :            : static struct attribute *irq_attrs[] = {
     269                 :            :         &per_cpu_count_attr.attr,
     270                 :            :         &chip_name_attr.attr,
     271                 :            :         &hwirq_attr.attr,
     272                 :            :         &type_attr.attr,
     273                 :            :         &wakeup_attr.attr,
     274                 :            :         &name_attr.attr,
     275                 :            :         &actions_attr.attr,
     276                 :            :         NULL
     277                 :            : };
     278                 :            : ATTRIBUTE_GROUPS(irq);
     279                 :            : 
     280                 :            : static struct kobj_type irq_kobj_type = {
     281                 :            :         .release        = irq_kobj_release,
     282                 :            :         .sysfs_ops      = &kobj_sysfs_ops,
     283                 :            :         .default_groups = irq_groups,
     284                 :            : };
     285                 :            : 
     286                 :        176 : static void irq_sysfs_add(int irq, struct irq_desc *desc)
     287                 :            : {
     288         [ +  - ]:        176 :         if (irq_kobj_base) {
     289                 :            :                 /*
     290                 :            :                  * Continue even in case of failure as this is nothing
     291                 :            :                  * crucial.
     292                 :            :                  */
     293         [ -  + ]:        176 :                 if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
     294                 :          0 :                         pr_warn("Failed to add kobject for irq %d\n", irq);
     295                 :            :         }
     296                 :        176 : }
     297                 :            : 
     298                 :          0 : static void irq_sysfs_del(struct irq_desc *desc)
     299                 :            : {
     300                 :            :         /*
     301                 :            :          * If irq_sysfs_init() has not yet been invoked (early boot), then
     302                 :            :          * irq_kobj_base is NULL and the descriptor was never added.
     303                 :            :          * kobject_del() complains about a object with no parent, so make
     304                 :            :          * it conditional.
     305                 :            :          */
     306                 :          0 :         if (irq_kobj_base)
     307                 :          0 :                 kobject_del(&desc->kobj);
     308                 :            : }
     309                 :            : 
     310                 :         11 : static int __init irq_sysfs_init(void)
     311                 :            : {
     312                 :         11 :         struct irq_desc *desc;
     313                 :         11 :         int irq;
     314                 :            : 
     315                 :            :         /* Prevent concurrent irq alloc/free */
     316                 :         11 :         irq_lock_sparse();
     317                 :            : 
     318                 :         11 :         irq_kobj_base = kobject_create_and_add("irq", kernel_kobj);
     319         [ -  + ]:         11 :         if (!irq_kobj_base) {
     320                 :          0 :                 irq_unlock_sparse();
     321                 :          0 :                 return -ENOMEM;
     322                 :            :         }
     323                 :            : 
     324                 :            :         /* Add the already allocated interrupts */
     325   [ +  +  +  + ]:       2827 :         for_each_irq_desc(irq, desc)
     326                 :        176 :                 irq_sysfs_add(irq, desc);
     327                 :         11 :         irq_unlock_sparse();
     328                 :            : 
     329                 :         11 :         return 0;
     330                 :            : }
     331                 :            : postcore_initcall(irq_sysfs_init);
     332                 :            : 
     333                 :            : #else /* !CONFIG_SYSFS */
     334                 :            : 
     335                 :            : static struct kobj_type irq_kobj_type = {
     336                 :            :         .release        = irq_kobj_release,
     337                 :            : };
     338                 :            : 
     339                 :            : static void irq_sysfs_add(int irq, struct irq_desc *desc) {}
     340                 :            : static void irq_sysfs_del(struct irq_desc *desc) {}
     341                 :            : 
     342                 :            : #endif /* CONFIG_SYSFS */
     343                 :            : 
     344                 :            : static RADIX_TREE(irq_desc_tree, GFP_KERNEL);
     345                 :            : 
     346                 :        176 : static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
     347                 :            : {
     348                 :        176 :         radix_tree_insert(&irq_desc_tree, irq, desc);
     349                 :            : }
     350                 :            : 
     351                 :       8591 : struct irq_desc *irq_to_desc(unsigned int irq)
     352                 :            : {
     353                 :       7744 :         return radix_tree_lookup(&irq_desc_tree, irq);
     354                 :            : }
     355                 :            : EXPORT_SYMBOL(irq_to_desc);
     356                 :            : 
     357                 :          0 : static void delete_irq_desc(unsigned int irq)
     358                 :            : {
     359                 :          0 :         radix_tree_delete(&irq_desc_tree, irq);
     360                 :            : }
     361                 :            : 
     362                 :            : #ifdef CONFIG_SMP
     363                 :          0 : static void free_masks(struct irq_desc *desc)
     364                 :            : {
     365                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
     366                 :          0 :         free_cpumask_var(desc->pending_mask);
     367                 :            : #endif
     368                 :          0 :         free_cpumask_var(desc->irq_common_data.affinity);
     369                 :            : #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
     370                 :          0 :         free_cpumask_var(desc->irq_common_data.effective_affinity);
     371                 :            : #endif
     372                 :            : }
     373                 :            : #else
     374                 :            : static inline void free_masks(struct irq_desc *desc) { }
     375                 :            : #endif
     376                 :            : 
     377                 :         11 : void irq_lock_sparse(void)
     378                 :            : {
     379                 :         11 :         mutex_lock(&sparse_irq_lock);
     380                 :          0 : }
     381                 :            : 
     382                 :         11 : void irq_unlock_sparse(void)
     383                 :            : {
     384                 :         11 :         mutex_unlock(&sparse_irq_lock);
     385                 :          0 : }
     386                 :            : 
     387                 :        176 : static struct irq_desc *alloc_desc(int irq, int node, unsigned int flags,
     388                 :            :                                    const struct cpumask *affinity,
     389                 :            :                                    struct module *owner)
     390                 :            : {
     391                 :        176 :         struct irq_desc *desc;
     392                 :            : 
     393                 :        176 :         desc = kzalloc_node(sizeof(*desc), GFP_KERNEL, node);
     394         [ +  - ]:        176 :         if (!desc)
     395                 :            :                 return NULL;
     396                 :            :         /* allocate based on nr_cpu_ids */
     397                 :        176 :         desc->kstat_irqs = alloc_percpu(unsigned int);
     398         [ -  + ]:        176 :         if (!desc->kstat_irqs)
     399                 :          0 :                 goto err_desc;
     400                 :            : 
     401         [ -  + ]:        176 :         if (alloc_masks(desc, node))
     402                 :          0 :                 goto err_kstat;
     403                 :            : 
     404                 :        176 :         raw_spin_lock_init(&desc->lock);
     405                 :        176 :         lockdep_set_class(&desc->lock, &irq_desc_lock_class);
     406                 :        176 :         mutex_init(&desc->request_mutex);
     407                 :        176 :         init_rcu_head(&desc->rcu);
     408                 :            : 
     409                 :        176 :         desc_set_defaults(irq, desc, node, affinity, owner);
     410                 :        176 :         irqd_set(&desc->irq_data, flags);
     411                 :        176 :         kobject_init(&desc->kobj, &irq_kobj_type);
     412                 :            : 
     413                 :        176 :         return desc;
     414                 :            : 
     415                 :            : err_kstat:
     416                 :          0 :         free_percpu(desc->kstat_irqs);
     417                 :          0 : err_desc:
     418                 :          0 :         kfree(desc);
     419                 :          0 :         return NULL;
     420                 :            : }
     421                 :            : 
     422                 :          0 : static void irq_kobj_release(struct kobject *kobj)
     423                 :            : {
     424                 :          0 :         struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
     425                 :            : 
     426                 :          0 :         free_masks(desc);
     427                 :          0 :         free_percpu(desc->kstat_irqs);
     428                 :          0 :         kfree(desc);
     429                 :          0 : }
     430                 :            : 
     431                 :          0 : static void delayed_free_desc(struct rcu_head *rhp)
     432                 :            : {
     433                 :          0 :         struct irq_desc *desc = container_of(rhp, struct irq_desc, rcu);
     434                 :            : 
     435                 :          0 :         kobject_put(&desc->kobj);
     436                 :          0 : }
     437                 :            : 
     438                 :          0 : static void free_desc(unsigned int irq)
     439                 :            : {
     440                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     441                 :            : 
     442                 :          0 :         irq_remove_debugfs_entry(desc);
     443                 :          0 :         unregister_irq_proc(irq, desc);
     444                 :            : 
     445                 :            :         /*
     446                 :            :          * sparse_irq_lock protects also show_interrupts() and
     447                 :            :          * kstat_irq_usr(). Once we deleted the descriptor from the
     448                 :            :          * sparse tree we can free it. Access in proc will fail to
     449                 :            :          * lookup the descriptor.
     450                 :            :          *
     451                 :            :          * The sysfs entry must be serialized against a concurrent
     452                 :            :          * irq_sysfs_init() as well.
     453                 :            :          */
     454         [ #  # ]:          0 :         irq_sysfs_del(desc);
     455                 :          0 :         delete_irq_desc(irq);
     456                 :            : 
     457                 :            :         /*
     458                 :            :          * We free the descriptor, masks and stat fields via RCU. That
     459                 :            :          * allows demultiplex interrupts to do rcu based management of
     460                 :            :          * the child interrupts.
     461                 :            :          * This also allows us to use rcu in kstat_irqs_usr().
     462                 :            :          */
     463                 :          0 :         call_rcu(&desc->rcu, delayed_free_desc);
     464                 :          0 : }
     465                 :            : 
     466                 :          0 : static int alloc_descs(unsigned int start, unsigned int cnt, int node,
     467                 :            :                        const struct irq_affinity_desc *affinity,
     468                 :            :                        struct module *owner)
     469                 :            : {
     470                 :          0 :         struct irq_desc *desc;
     471                 :          0 :         int i;
     472                 :            : 
     473                 :            :         /* Validate affinity mask(s) */
     474         [ #  # ]:          0 :         if (affinity) {
     475         [ #  # ]:          0 :                 for (i = 0; i < cnt; i++) {
     476         [ #  # ]:          0 :                         if (cpumask_empty(&affinity[i].mask))
     477                 :            :                                 return -EINVAL;
     478                 :            :                 }
     479                 :            :         }
     480                 :            : 
     481         [ #  # ]:          0 :         for (i = 0; i < cnt; i++) {
     482                 :          0 :                 const struct cpumask *mask = NULL;
     483                 :          0 :                 unsigned int flags = 0;
     484                 :            : 
     485         [ #  # ]:          0 :                 if (affinity) {
     486         [ #  # ]:          0 :                         if (affinity->is_managed) {
     487                 :          0 :                                 flags = IRQD_AFFINITY_MANAGED |
     488                 :            :                                         IRQD_MANAGED_SHUTDOWN;
     489                 :            :                         }
     490                 :          0 :                         mask = &affinity->mask;
     491                 :          0 :                         node = cpu_to_node(cpumask_first(mask));
     492                 :          0 :                         affinity++;
     493                 :            :                 }
     494                 :            : 
     495                 :          0 :                 desc = alloc_desc(start + i, node, flags, mask, owner);
     496         [ #  # ]:          0 :                 if (!desc)
     497                 :          0 :                         goto err;
     498                 :          0 :                 irq_insert_desc(start + i, desc);
     499                 :          0 :                 irq_sysfs_add(start + i, desc);
     500                 :          0 :                 irq_add_debugfs_entry(start + i, desc);
     501                 :            :         }
     502         [ #  # ]:          0 :         bitmap_set(allocated_irqs, start, cnt);
     503                 :          0 :         return start;
     504                 :            : 
     505                 :            : err:
     506         [ #  # ]:          0 :         for (i--; i >= 0; i--)
     507                 :          0 :                 free_desc(start + i);
     508                 :            :         return -ENOMEM;
     509                 :            : }
     510                 :            : 
     511                 :          0 : static int irq_expand_nr_irqs(unsigned int nr)
     512                 :            : {
     513                 :          0 :         if (nr > IRQ_BITMAP_BITS)
     514                 :            :                 return -ENOMEM;
     515                 :          0 :         nr_irqs = nr;
     516                 :          0 :         return 0;
     517                 :            : }
     518                 :            : 
     519                 :         11 : int __init early_irq_init(void)
     520                 :            : {
     521                 :         11 :         int i, initcnt, node = first_online_node;
     522                 :         11 :         struct irq_desc *desc;
     523                 :            : 
     524                 :         11 :         init_irq_default_affinity();
     525                 :            : 
     526                 :            :         /* Let arch update nr_irqs and return the nr of preallocated irqs */
     527                 :         11 :         initcnt = arch_probe_nr_irqs();
     528                 :         11 :         printk(KERN_INFO "NR_IRQS: %d, nr_irqs: %d, preallocated irqs: %d\n",
     529                 :            :                NR_IRQS, nr_irqs, initcnt);
     530                 :            : 
     531   [ -  +  -  + ]:         11 :         if (WARN_ON(nr_irqs > IRQ_BITMAP_BITS))
     532                 :          0 :                 nr_irqs = IRQ_BITMAP_BITS;
     533                 :            : 
     534   [ -  +  -  + ]:         11 :         if (WARN_ON(initcnt > IRQ_BITMAP_BITS))
     535                 :          0 :                 initcnt = IRQ_BITMAP_BITS;
     536                 :            : 
     537         [ -  + ]:         11 :         if (initcnt > nr_irqs)
     538                 :          0 :                 nr_irqs = initcnt;
     539                 :            : 
     540         [ +  + ]:        187 :         for (i = 0; i < initcnt; i++) {
     541                 :        176 :                 desc = alloc_desc(i, node, 0, NULL, NULL);
     542                 :        176 :                 set_bit(i, allocated_irqs);
     543                 :        176 :                 irq_insert_desc(i, desc);
     544                 :            :         }
     545                 :         11 :         return arch_early_irq_init();
     546                 :            : }
     547                 :            : 
     548                 :            : #else /* !CONFIG_SPARSE_IRQ */
     549                 :            : 
     550                 :            : struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
     551                 :            :         [0 ... NR_IRQS-1] = {
     552                 :            :                 .handle_irq     = handle_bad_irq,
     553                 :            :                 .depth          = 1,
     554                 :            :                 .lock           = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
     555                 :            :         }
     556                 :            : };
     557                 :            : 
     558                 :            : int __init early_irq_init(void)
     559                 :            : {
     560                 :            :         int count, i, node = first_online_node;
     561                 :            :         struct irq_desc *desc;
     562                 :            : 
     563                 :            :         init_irq_default_affinity();
     564                 :            : 
     565                 :            :         printk(KERN_INFO "NR_IRQS: %d\n", NR_IRQS);
     566                 :            : 
     567                 :            :         desc = irq_desc;
     568                 :            :         count = ARRAY_SIZE(irq_desc);
     569                 :            : 
     570                 :            :         for (i = 0; i < count; i++) {
     571                 :            :                 desc[i].kstat_irqs = alloc_percpu(unsigned int);
     572                 :            :                 alloc_masks(&desc[i], node);
     573                 :            :                 raw_spin_lock_init(&desc[i].lock);
     574                 :            :                 lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
     575                 :            :                 mutex_init(&desc[i].request_mutex);
     576                 :            :                 desc_set_defaults(i, &desc[i], node, NULL, NULL);
     577                 :            :         }
     578                 :            :         return arch_early_irq_init();
     579                 :            : }
     580                 :            : 
     581                 :            : struct irq_desc *irq_to_desc(unsigned int irq)
     582                 :            : {
     583                 :            :         return (irq < NR_IRQS) ? irq_desc + irq : NULL;
     584                 :            : }
     585                 :            : EXPORT_SYMBOL(irq_to_desc);
     586                 :            : 
     587                 :            : static void free_desc(unsigned int irq)
     588                 :            : {
     589                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     590                 :            :         unsigned long flags;
     591                 :            : 
     592                 :            :         raw_spin_lock_irqsave(&desc->lock, flags);
     593                 :            :         desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
     594                 :            :         raw_spin_unlock_irqrestore(&desc->lock, flags);
     595                 :            : }
     596                 :            : 
     597                 :            : static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
     598                 :            :                               const struct irq_affinity_desc *affinity,
     599                 :            :                               struct module *owner)
     600                 :            : {
     601                 :            :         u32 i;
     602                 :            : 
     603                 :            :         for (i = 0; i < cnt; i++) {
     604                 :            :                 struct irq_desc *desc = irq_to_desc(start + i);
     605                 :            : 
     606                 :            :                 desc->owner = owner;
     607                 :            :         }
     608                 :            :         bitmap_set(allocated_irqs, start, cnt);
     609                 :            :         return start;
     610                 :            : }
     611                 :            : 
     612                 :            : static int irq_expand_nr_irqs(unsigned int nr)
     613                 :            : {
     614                 :            :         return -ENOMEM;
     615                 :            : }
     616                 :            : 
     617                 :            : void irq_mark_irq(unsigned int irq)
     618                 :            : {
     619                 :            :         mutex_lock(&sparse_irq_lock);
     620                 :            :         bitmap_set(allocated_irqs, irq, 1);
     621                 :            :         mutex_unlock(&sparse_irq_lock);
     622                 :            : }
     623                 :            : 
     624                 :            : #ifdef CONFIG_GENERIC_IRQ_LEGACY
     625                 :            : void irq_init_desc(unsigned int irq)
     626                 :            : {
     627                 :            :         free_desc(irq);
     628                 :            : }
     629                 :            : #endif
     630                 :            : 
     631                 :            : #endif /* !CONFIG_SPARSE_IRQ */
     632                 :            : 
     633                 :            : /**
     634                 :            :  * generic_handle_irq - Invoke the handler for a particular irq
     635                 :            :  * @irq:        The irq number to handle
     636                 :            :  *
     637                 :            :  */
     638                 :          0 : int generic_handle_irq(unsigned int irq)
     639                 :            : {
     640                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     641                 :            : 
     642         [ #  # ]:          0 :         if (!desc)
     643                 :            :                 return -EINVAL;
     644                 :          0 :         generic_handle_irq_desc(desc);
     645                 :          0 :         return 0;
     646                 :            : }
     647                 :            : EXPORT_SYMBOL_GPL(generic_handle_irq);
     648                 :            : 
     649                 :            : #ifdef CONFIG_HANDLE_DOMAIN_IRQ
     650                 :            : /**
     651                 :            :  * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain
     652                 :            :  * @domain:     The domain where to perform the lookup
     653                 :            :  * @hwirq:      The HW irq number to convert to a logical one
     654                 :            :  * @lookup:     Whether to perform the domain lookup or not
     655                 :            :  * @regs:       Register file coming from the low-level handling code
     656                 :            :  *
     657                 :            :  * Returns:     0 on success, or -EINVAL if conversion has failed
     658                 :            :  */
     659                 :            : int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
     660                 :            :                         bool lookup, struct pt_regs *regs)
     661                 :            : {
     662                 :            :         struct pt_regs *old_regs = set_irq_regs(regs);
     663                 :            :         unsigned int irq = hwirq;
     664                 :            :         int ret = 0;
     665                 :            : 
     666                 :            :         irq_enter();
     667                 :            : 
     668                 :            : #ifdef CONFIG_IRQ_DOMAIN
     669                 :            :         if (lookup)
     670                 :            :                 irq = irq_find_mapping(domain, hwirq);
     671                 :            : #endif
     672                 :            : 
     673                 :            :         /*
     674                 :            :          * Some hardware gives randomly wrong interrupts.  Rather
     675                 :            :          * than crashing, do something sensible.
     676                 :            :          */
     677                 :            :         if (unlikely(!irq || irq >= nr_irqs)) {
     678                 :            :                 ack_bad_irq(irq);
     679                 :            :                 ret = -EINVAL;
     680                 :            :         } else {
     681                 :            :                 generic_handle_irq(irq);
     682                 :            :         }
     683                 :            : 
     684                 :            :         irq_exit();
     685                 :            :         set_irq_regs(old_regs);
     686                 :            :         return ret;
     687                 :            : }
     688                 :            : 
     689                 :            : #ifdef CONFIG_IRQ_DOMAIN
     690                 :            : /**
     691                 :            :  * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain
     692                 :            :  * @domain:     The domain where to perform the lookup
     693                 :            :  * @hwirq:      The HW irq number to convert to a logical one
     694                 :            :  * @regs:       Register file coming from the low-level handling code
     695                 :            :  *
     696                 :            :  *              This function must be called from an NMI context.
     697                 :            :  *
     698                 :            :  * Returns:     0 on success, or -EINVAL if conversion has failed
     699                 :            :  */
     700                 :            : int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
     701                 :            :                       struct pt_regs *regs)
     702                 :            : {
     703                 :            :         struct pt_regs *old_regs = set_irq_regs(regs);
     704                 :            :         unsigned int irq;
     705                 :            :         int ret = 0;
     706                 :            : 
     707                 :            :         /*
     708                 :            :          * NMI context needs to be setup earlier in order to deal with tracing.
     709                 :            :          */
     710                 :            :         WARN_ON(!in_nmi());
     711                 :            : 
     712                 :            :         irq = irq_find_mapping(domain, hwirq);
     713                 :            : 
     714                 :            :         /*
     715                 :            :          * ack_bad_irq is not NMI-safe, just report
     716                 :            :          * an invalid interrupt.
     717                 :            :          */
     718                 :            :         if (likely(irq))
     719                 :            :                 generic_handle_irq(irq);
     720                 :            :         else
     721                 :            :                 ret = -EINVAL;
     722                 :            : 
     723                 :            :         set_irq_regs(old_regs);
     724                 :            :         return ret;
     725                 :            : }
     726                 :            : #endif
     727                 :            : #endif
     728                 :            : 
     729                 :            : /* Dynamic interrupt handling */
     730                 :            : 
     731                 :            : /**
     732                 :            :  * irq_free_descs - free irq descriptors
     733                 :            :  * @from:       Start of descriptor range
     734                 :            :  * @cnt:        Number of consecutive irqs to free
     735                 :            :  */
     736                 :          0 : void irq_free_descs(unsigned int from, unsigned int cnt)
     737                 :            : {
     738                 :          0 :         int i;
     739                 :            : 
     740   [ #  #  #  # ]:          0 :         if (from >= nr_irqs || (from + cnt) > nr_irqs)
     741                 :            :                 return;
     742                 :            : 
     743                 :          0 :         mutex_lock(&sparse_irq_lock);
     744         [ #  # ]:          0 :         for (i = 0; i < cnt; i++)
     745                 :          0 :                 free_desc(from + i);
     746                 :            : 
     747         [ #  # ]:          0 :         bitmap_clear(allocated_irqs, from, cnt);
     748                 :          0 :         mutex_unlock(&sparse_irq_lock);
     749                 :            : }
     750                 :            : EXPORT_SYMBOL_GPL(irq_free_descs);
     751                 :            : 
     752                 :            : /**
     753                 :            :  * __irq_alloc_descs - allocate and initialize a range of irq descriptors
     754                 :            :  * @irq:        Allocate for specific irq number if irq >= 0
     755                 :            :  * @from:       Start the search from this irq number
     756                 :            :  * @cnt:        Number of consecutive irqs to allocate.
     757                 :            :  * @node:       Preferred node on which the irq descriptor should be allocated
     758                 :            :  * @owner:      Owning module (can be NULL)
     759                 :            :  * @affinity:   Optional pointer to an affinity mask array of size @cnt which
     760                 :            :  *              hints where the irq descriptors should be allocated and which
     761                 :            :  *              default affinities to use
     762                 :            :  *
     763                 :            :  * Returns the first irq number or error code
     764                 :            :  */
     765                 :            : int __ref
     766                 :          0 : __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
     767                 :            :                   struct module *owner, const struct irq_affinity_desc *affinity)
     768                 :            : {
     769                 :          0 :         int start, ret;
     770                 :            : 
     771         [ #  # ]:          0 :         if (!cnt)
     772                 :            :                 return -EINVAL;
     773                 :            : 
     774         [ #  # ]:          0 :         if (irq >= 0) {
     775         [ #  # ]:          0 :                 if (from > irq)
     776                 :            :                         return -EINVAL;
     777                 :            :                 from = irq;
     778                 :            :         } else {
     779                 :            :                 /*
     780                 :            :                  * For interrupts which are freely allocated the
     781                 :            :                  * architecture can force a lower bound to the @from
     782                 :            :                  * argument. x86 uses this to exclude the GSI space.
     783                 :            :                  */
     784                 :          0 :                 from = arch_dynirq_lower_bound(from);
     785                 :            :         }
     786                 :            : 
     787                 :          0 :         mutex_lock(&sparse_irq_lock);
     788                 :            : 
     789                 :          0 :         start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,
     790                 :            :                                            from, cnt, 0);
     791                 :          0 :         ret = -EEXIST;
     792         [ #  # ]:          0 :         if (irq >=0 && start != irq)
     793                 :          0 :                 goto unlock;
     794                 :            : 
     795         [ #  # ]:          0 :         if (start + cnt > nr_irqs) {
     796         [ #  # ]:          0 :                 ret = irq_expand_nr_irqs(start + cnt);
     797                 :          0 :                 if (ret)
     798                 :          0 :                         goto unlock;
     799                 :            :         }
     800                 :          0 :         ret = alloc_descs(start, cnt, node, affinity, owner);
     801                 :          0 : unlock:
     802                 :          0 :         mutex_unlock(&sparse_irq_lock);
     803                 :          0 :         return ret;
     804                 :            : }
     805                 :            : EXPORT_SYMBOL_GPL(__irq_alloc_descs);
     806                 :            : 
     807                 :            : #ifdef CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
     808                 :            : /**
     809                 :            :  * irq_alloc_hwirqs - Allocate an irq descriptor and initialize the hardware
     810                 :            :  * @cnt:        number of interrupts to allocate
     811                 :            :  * @node:       node on which to allocate
     812                 :            :  *
     813                 :            :  * Returns an interrupt number > 0 or 0, if the allocation fails.
     814                 :            :  */
     815                 :            : unsigned int irq_alloc_hwirqs(int cnt, int node)
     816                 :            : {
     817                 :            :         int i, irq = __irq_alloc_descs(-1, 0, cnt, node, NULL, NULL);
     818                 :            : 
     819                 :            :         if (irq < 0)
     820                 :            :                 return 0;
     821                 :            : 
     822                 :            :         for (i = irq; cnt > 0; i++, cnt--) {
     823                 :            :                 if (arch_setup_hwirq(i, node))
     824                 :            :                         goto err;
     825                 :            :                 irq_clear_status_flags(i, _IRQ_NOREQUEST);
     826                 :            :         }
     827                 :            :         return irq;
     828                 :            : 
     829                 :            : err:
     830                 :            :         for (i--; i >= irq; i--) {
     831                 :            :                 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
     832                 :            :                 arch_teardown_hwirq(i);
     833                 :            :         }
     834                 :            :         irq_free_descs(irq, cnt);
     835                 :            :         return 0;
     836                 :            : }
     837                 :            : EXPORT_SYMBOL_GPL(irq_alloc_hwirqs);
     838                 :            : 
     839                 :            : /**
     840                 :            :  * irq_free_hwirqs - Free irq descriptor and cleanup the hardware
     841                 :            :  * @from:       Free from irq number
     842                 :            :  * @cnt:        number of interrupts to free
     843                 :            :  *
     844                 :            :  */
     845                 :            : void irq_free_hwirqs(unsigned int from, int cnt)
     846                 :            : {
     847                 :            :         int i, j;
     848                 :            : 
     849                 :            :         for (i = from, j = cnt; j > 0; i++, j--) {
     850                 :            :                 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
     851                 :            :                 arch_teardown_hwirq(i);
     852                 :            :         }
     853                 :            :         irq_free_descs(from, cnt);
     854                 :            : }
     855                 :            : EXPORT_SYMBOL_GPL(irq_free_hwirqs);
     856                 :            : #endif
     857                 :            : 
     858                 :            : /**
     859                 :            :  * irq_get_next_irq - get next allocated irq number
     860                 :            :  * @offset:     where to start the search
     861                 :            :  *
     862                 :            :  * Returns next irq number after offset or nr_irqs if none is found.
     863                 :            :  */
     864                 :        187 : unsigned int irq_get_next_irq(unsigned int offset)
     865                 :            : {
     866                 :        187 :         return find_next_bit(allocated_irqs, nr_irqs, offset);
     867                 :            : }
     868                 :            : 
     869                 :            : struct irq_desc *
     870                 :        847 : __irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
     871                 :            :                     unsigned int check)
     872                 :            : {
     873                 :        847 :         struct irq_desc *desc = irq_to_desc(irq);
     874                 :            : 
     875         [ +  - ]:        847 :         if (desc) {
     876         [ -  + ]:        847 :                 if (check & _IRQ_DESC_CHECK) {
     877   [ #  #  #  # ]:          0 :                         if ((check & _IRQ_DESC_PERCPU) &&
     878         [ #  # ]:          0 :                             !irq_settings_is_per_cpu_devid(desc))
     879                 :            :                                 return NULL;
     880                 :            : 
     881   [ #  #  #  # ]:          0 :                         if (!(check & _IRQ_DESC_PERCPU) &&
     882         [ #  # ]:          0 :                             irq_settings_is_per_cpu_devid(desc))
     883                 :            :                                 return NULL;
     884                 :            :                 }
     885                 :            : 
     886         [ +  + ]:        847 :                 if (bus)
     887         [ -  + ]:        341 :                         chip_bus_lock(desc);
     888                 :        847 :                 raw_spin_lock_irqsave(&desc->lock, *flags);
     889                 :            :         }
     890                 :            :         return desc;
     891                 :            : }
     892                 :            : 
     893                 :        847 : void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus)
     894                 :            :         __releases(&desc->lock)
     895                 :            : {
     896                 :        847 :         raw_spin_unlock_irqrestore(&desc->lock, flags);
     897         [ +  + ]:        847 :         if (bus)
     898         [ -  + ]:        341 :                 chip_bus_sync_unlock(desc);
     899                 :        847 : }
     900                 :            : 
     901                 :          0 : int irq_set_percpu_devid_partition(unsigned int irq,
     902                 :            :                                    const struct cpumask *affinity)
     903                 :            : {
     904                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     905                 :            : 
     906         [ #  # ]:          0 :         if (!desc)
     907                 :            :                 return -EINVAL;
     908                 :            : 
     909         [ #  # ]:          0 :         if (desc->percpu_enabled)
     910                 :            :                 return -EINVAL;
     911                 :            : 
     912                 :          0 :         desc->percpu_enabled = kzalloc(sizeof(*desc->percpu_enabled), GFP_KERNEL);
     913                 :            : 
     914         [ #  # ]:          0 :         if (!desc->percpu_enabled)
     915                 :            :                 return -ENOMEM;
     916                 :            : 
     917         [ #  # ]:          0 :         if (affinity)
     918                 :          0 :                 desc->percpu_affinity = affinity;
     919                 :            :         else
     920                 :          0 :                 desc->percpu_affinity = cpu_possible_mask;
     921                 :            : 
     922                 :          0 :         irq_set_percpu_devid_flags(irq);
     923                 :          0 :         return 0;
     924                 :            : }
     925                 :            : 
     926                 :          0 : int irq_set_percpu_devid(unsigned int irq)
     927                 :            : {
     928                 :          0 :         return irq_set_percpu_devid_partition(irq, NULL);
     929                 :            : }
     930                 :            : 
     931                 :          0 : int irq_get_percpu_devid_partition(unsigned int irq, struct cpumask *affinity)
     932                 :            : {
     933                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     934                 :            : 
     935   [ #  #  #  # ]:          0 :         if (!desc || !desc->percpu_enabled)
     936                 :            :                 return -EINVAL;
     937                 :            : 
     938         [ #  # ]:          0 :         if (affinity)
     939                 :          0 :                 cpumask_copy(affinity, desc->percpu_affinity);
     940                 :            : 
     941                 :            :         return 0;
     942                 :            : }
     943                 :            : EXPORT_SYMBOL_GPL(irq_get_percpu_devid_partition);
     944                 :            : 
     945                 :          0 : void kstat_incr_irq_this_cpu(unsigned int irq)
     946                 :            : {
     947                 :          0 :         kstat_incr_irqs_this_cpu(irq_to_desc(irq));
     948                 :          0 : }
     949                 :            : 
     950                 :            : /**
     951                 :            :  * kstat_irqs_cpu - Get the statistics for an interrupt on a cpu
     952                 :            :  * @irq:        The interrupt number
     953                 :            :  * @cpu:        The cpu number
     954                 :            :  *
     955                 :            :  * Returns the sum of interrupt counts on @cpu since boot for
     956                 :            :  * @irq. The caller must ensure that the interrupt is not removed
     957                 :            :  * concurrently.
     958                 :            :  */
     959                 :          0 : unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
     960                 :            : {
     961                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     962                 :            : 
     963         [ #  # ]:          0 :         return desc && desc->kstat_irqs ?
     964         [ #  # ]:          0 :                         *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
     965                 :            : }
     966                 :            : 
     967                 :          0 : static bool irq_is_nmi(struct irq_desc *desc)
     968                 :            : {
     969                 :          0 :         return desc->istate & IRQS_NMI;
     970                 :            : }
     971                 :            : 
     972                 :            : /**
     973                 :            :  * kstat_irqs - Get the statistics for an interrupt
     974                 :            :  * @irq:        The interrupt number
     975                 :            :  *
     976                 :            :  * Returns the sum of interrupt counts on all cpus since boot for
     977                 :            :  * @irq. The caller must ensure that the interrupt is not removed
     978                 :            :  * concurrently.
     979                 :            :  */
     980                 :          0 : unsigned int kstat_irqs(unsigned int irq)
     981                 :            : {
     982                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     983                 :          0 :         unsigned int sum = 0;
     984                 :          0 :         int cpu;
     985                 :            : 
     986   [ #  #  #  # ]:          0 :         if (!desc || !desc->kstat_irqs)
     987                 :            :                 return 0;
     988   [ #  #  #  # ]:          0 :         if (!irq_settings_is_per_cpu_devid(desc) &&
     989                 :          0 :             !irq_settings_is_per_cpu(desc) &&
     990         [ #  # ]:          0 :             !irq_is_nmi(desc))
     991                 :          0 :             return desc->tot_count;
     992                 :            : 
     993         [ #  # ]:          0 :         for_each_possible_cpu(cpu)
     994                 :          0 :                 sum += *per_cpu_ptr(desc->kstat_irqs, cpu);
     995                 :            :         return sum;
     996                 :            : }
     997                 :            : 
     998                 :            : /**
     999                 :            :  * kstat_irqs_usr - Get the statistics for an interrupt
    1000                 :            :  * @irq:        The interrupt number
    1001                 :            :  *
    1002                 :            :  * Returns the sum of interrupt counts on all cpus since boot for @irq.
    1003                 :            :  * Contrary to kstat_irqs() this can be called from any context.
    1004                 :            :  * It uses rcu since a concurrent removal of an interrupt descriptor is
    1005                 :            :  * observing an rcu grace period before delayed_free_desc()/irq_kobj_release().
    1006                 :            :  */
    1007                 :          0 : unsigned int kstat_irqs_usr(unsigned int irq)
    1008                 :            : {
    1009                 :          0 :         unsigned int sum;
    1010                 :            : 
    1011                 :          0 :         rcu_read_lock();
    1012                 :          0 :         sum = kstat_irqs(irq);
    1013                 :          0 :         rcu_read_unlock();
    1014                 :          0 :         return sum;
    1015                 :            : }

Generated by: LCOV version 1.14