LCOV - code coverage report
Current view: top level - kernel/irq - irqdesc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 133 14.3 %
Date: 2014-04-16 Functions: 6 17 35.3 %
Branches: 15 84 17.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
       3                 :            :  * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
       4                 :            :  *
       5                 :            :  * This file contains the interrupt descriptor management code
       6                 :            :  *
       7                 :            :  * Detailed information is available in Documentation/DocBook/genericirq
       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                 :            : 
      18                 :            : #include "internals.h"
      19                 :            : 
      20                 :            : /*
      21                 :            :  * lockdep: we want to handle all irq_desc locks as a single lock-class:
      22                 :            :  */
      23                 :            : static struct lock_class_key irq_desc_lock_class;
      24                 :            : 
      25                 :            : #if defined(CONFIG_SMP)
      26                 :            : static void __init init_irq_default_affinity(void)
      27                 :            : {
      28                 :            :         alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
      29                 :            :         cpumask_setall(irq_default_affinity);
      30                 :            : }
      31                 :            : #else
      32                 :            : static void __init init_irq_default_affinity(void)
      33                 :            : {
      34                 :            : }
      35                 :            : #endif
      36                 :            : 
      37                 :            : #ifdef CONFIG_SMP
      38                 :            : static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
      39                 :            : {
      40                 :            :         if (!zalloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node))
      41                 :            :                 return -ENOMEM;
      42                 :            : 
      43                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
      44                 :            :         if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
      45                 :            :                 free_cpumask_var(desc->irq_data.affinity);
      46                 :            :                 return -ENOMEM;
      47                 :            :         }
      48                 :            : #endif
      49                 :            :         return 0;
      50                 :            : }
      51                 :            : 
      52                 :            : static void desc_smp_init(struct irq_desc *desc, int node)
      53                 :            : {
      54                 :          0 :         desc->irq_data.node = node;
      55                 :            :         cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
      56                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
      57                 :            :         cpumask_clear(desc->pending_mask);
      58                 :            : #endif
      59                 :            : }
      60                 :            : 
      61                 :            : static inline int desc_node(struct irq_desc *desc)
      62                 :            : {
      63                 :          0 :         return desc->irq_data.node;
      64                 :            : }
      65                 :            : 
      66                 :            : #else
      67                 :            : static inline int
      68                 :            : alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
      69                 :            : static inline void desc_smp_init(struct irq_desc *desc, int node) { }
      70                 :            : static inline int desc_node(struct irq_desc *desc) { return 0; }
      71                 :            : #endif
      72                 :            : 
      73                 :          0 : static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
      74                 :            :                 struct module *owner)
      75                 :            : {
      76                 :            :         int cpu;
      77                 :            : 
      78                 :          0 :         desc->irq_data.irq = irq;
      79                 :          0 :         desc->irq_data.chip = &no_irq_chip;
      80                 :          0 :         desc->irq_data.chip_data = NULL;
      81                 :          0 :         desc->irq_data.handler_data = NULL;
      82                 :          0 :         desc->irq_data.msi_desc = NULL;
      83                 :            :         irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
      84                 :            :         irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
      85                 :          0 :         desc->handle_irq = handle_bad_irq;
      86                 :          0 :         desc->depth = 1;
      87                 :          0 :         desc->irq_count = 0;
      88                 :          0 :         desc->irqs_unhandled = 0;
      89                 :          0 :         desc->name = NULL;
      90                 :          0 :         desc->owner = owner;
      91         [ #  # ]:          0 :         for_each_possible_cpu(cpu)
      92                 :          0 :                 *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
      93                 :            :         desc_smp_init(desc, node);
      94                 :          0 : }
      95                 :            : 
      96                 :            : int nr_irqs = NR_IRQS;
      97                 :            : EXPORT_SYMBOL_GPL(nr_irqs);
      98                 :            : 
      99                 :            : static DEFINE_MUTEX(sparse_irq_lock);
     100                 :            : static DECLARE_BITMAP(allocated_irqs, IRQ_BITMAP_BITS);
     101                 :            : 
     102                 :            : #ifdef CONFIG_SPARSE_IRQ
     103                 :            : 
     104                 :            : static RADIX_TREE(irq_desc_tree, GFP_KERNEL);
     105                 :            : 
     106                 :            : static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
     107                 :            : {
     108                 :          0 :         radix_tree_insert(&irq_desc_tree, irq, desc);
     109                 :            : }
     110                 :            : 
     111                 :          0 : struct irq_desc *irq_to_desc(unsigned int irq)
     112                 :            : {
     113                 :    7118079 :         return radix_tree_lookup(&irq_desc_tree, irq);
     114                 :            : }
     115                 :            : EXPORT_SYMBOL(irq_to_desc);
     116                 :            : 
     117                 :            : static void delete_irq_desc(unsigned int irq)
     118                 :            : {
     119                 :          0 :         radix_tree_delete(&irq_desc_tree, irq);
     120                 :            : }
     121                 :            : 
     122                 :            : #ifdef CONFIG_SMP
     123                 :            : static void free_masks(struct irq_desc *desc)
     124                 :            : {
     125                 :            : #ifdef CONFIG_GENERIC_PENDING_IRQ
     126                 :            :         free_cpumask_var(desc->pending_mask);
     127                 :            : #endif
     128                 :            :         free_cpumask_var(desc->irq_data.affinity);
     129                 :            : }
     130                 :            : #else
     131                 :            : static inline void free_masks(struct irq_desc *desc) { }
     132                 :            : #endif
     133                 :            : 
     134                 :          0 : static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
     135                 :            : {
     136                 :            :         struct irq_desc *desc;
     137                 :            :         gfp_t gfp = GFP_KERNEL;
     138                 :            : 
     139                 :            :         desc = kzalloc_node(sizeof(*desc), gfp, node);
     140         [ #  # ]:          0 :         if (!desc)
     141                 :            :                 return NULL;
     142                 :            :         /* allocate based on nr_cpu_ids */
     143                 :          0 :         desc->kstat_irqs = alloc_percpu(unsigned int);
     144         [ #  # ]:          0 :         if (!desc->kstat_irqs)
     145                 :            :                 goto err_desc;
     146                 :            : 
     147                 :            :         if (alloc_masks(desc, gfp, node))
     148                 :            :                 goto err_kstat;
     149                 :            : 
     150                 :          0 :         raw_spin_lock_init(&desc->lock);
     151                 :            :         lockdep_set_class(&desc->lock, &irq_desc_lock_class);
     152                 :            : 
     153                 :          0 :         desc_set_defaults(irq, desc, node, owner);
     154                 :            : 
     155                 :          0 :         return desc;
     156                 :            : 
     157                 :            : err_kstat:
     158                 :            :         free_percpu(desc->kstat_irqs);
     159                 :            : err_desc:
     160                 :          0 :         kfree(desc);
     161                 :          0 :         return NULL;
     162                 :            : }
     163                 :            : 
     164                 :          0 : static void free_desc(unsigned int irq)
     165                 :            : {
     166                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     167                 :            : 
     168                 :          0 :         unregister_irq_proc(irq, desc);
     169                 :            : 
     170                 :          0 :         mutex_lock(&sparse_irq_lock);
     171                 :            :         delete_irq_desc(irq);
     172                 :          0 :         mutex_unlock(&sparse_irq_lock);
     173                 :            : 
     174                 :            :         free_masks(desc);
     175                 :          0 :         free_percpu(desc->kstat_irqs);
     176                 :          0 :         kfree(desc);
     177                 :          0 : }
     178                 :            : 
     179                 :          0 : static int alloc_descs(unsigned int start, unsigned int cnt, int node,
     180                 :            :                        struct module *owner)
     181                 :            : {
     182                 :            :         struct irq_desc *desc;
     183                 :            :         int i;
     184                 :            : 
     185         [ #  # ]:          0 :         for (i = 0; i < cnt; i++) {
     186                 :          0 :                 desc = alloc_desc(start + i, node, owner);
     187         [ #  # ]:          0 :                 if (!desc)
     188                 :            :                         goto err;
     189                 :          0 :                 mutex_lock(&sparse_irq_lock);
     190                 :            :                 irq_insert_desc(start + i, desc);
     191                 :          0 :                 mutex_unlock(&sparse_irq_lock);
     192                 :            :         }
     193                 :          0 :         return start;
     194                 :            : 
     195                 :            : err:
     196         [ #  # ]:          0 :         for (i--; i >= 0; i--)
     197                 :          0 :                 free_desc(start + i);
     198                 :            : 
     199                 :          0 :         mutex_lock(&sparse_irq_lock);
     200                 :          0 :         bitmap_clear(allocated_irqs, start, cnt);
     201                 :          0 :         mutex_unlock(&sparse_irq_lock);
     202                 :          0 :         return -ENOMEM;
     203                 :            : }
     204                 :            : 
     205                 :            : static int irq_expand_nr_irqs(unsigned int nr)
     206                 :            : {
     207         [ #  # ]:          0 :         if (nr > IRQ_BITMAP_BITS)
     208                 :            :                 return -ENOMEM;
     209                 :          0 :         nr_irqs = nr;
     210                 :            :         return 0;
     211                 :            : }
     212                 :            : 
     213                 :          0 : int __init early_irq_init(void)
     214                 :            : {
     215                 :            :         int i, initcnt, node = first_online_node;
     216                 :            :         struct irq_desc *desc;
     217                 :            : 
     218                 :            :         init_irq_default_affinity();
     219                 :            : 
     220                 :            :         /* Let arch update nr_irqs and return the nr of preallocated irqs */
     221                 :          0 :         initcnt = arch_probe_nr_irqs();
     222                 :          0 :         printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d %d\n", NR_IRQS, nr_irqs, initcnt);
     223                 :            : 
     224 [ #  # ][ #  # ]:          0 :         if (WARN_ON(nr_irqs > IRQ_BITMAP_BITS))
     225                 :          0 :                 nr_irqs = IRQ_BITMAP_BITS;
     226                 :            : 
     227 [ #  # ][ #  # ]:          0 :         if (WARN_ON(initcnt > IRQ_BITMAP_BITS))
     228                 :            :                 initcnt = IRQ_BITMAP_BITS;
     229                 :            : 
     230         [ #  # ]:          0 :         if (initcnt > nr_irqs)
     231                 :          0 :                 nr_irqs = initcnt;
     232                 :            : 
     233         [ #  # ]:          0 :         for (i = 0; i < initcnt; i++) {
     234                 :          0 :                 desc = alloc_desc(i, node, NULL);
     235                 :          0 :                 set_bit(i, allocated_irqs);
     236                 :          0 :                 irq_insert_desc(i, desc);
     237                 :            :         }
     238                 :          0 :         return arch_early_irq_init();
     239                 :            : }
     240                 :            : 
     241                 :            : #else /* !CONFIG_SPARSE_IRQ */
     242                 :            : 
     243                 :            : struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
     244                 :            :         [0 ... NR_IRQS-1] = {
     245                 :            :                 .handle_irq     = handle_bad_irq,
     246                 :            :                 .depth          = 1,
     247                 :            :                 .lock           = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
     248                 :            :         }
     249                 :            : };
     250                 :            : 
     251                 :            : int __init early_irq_init(void)
     252                 :            : {
     253                 :            :         int count, i, node = first_online_node;
     254                 :            :         struct irq_desc *desc;
     255                 :            : 
     256                 :            :         init_irq_default_affinity();
     257                 :            : 
     258                 :            :         printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
     259                 :            : 
     260                 :            :         desc = irq_desc;
     261                 :            :         count = ARRAY_SIZE(irq_desc);
     262                 :            : 
     263                 :            :         for (i = 0; i < count; i++) {
     264                 :            :                 desc[i].kstat_irqs = alloc_percpu(unsigned int);
     265                 :            :                 alloc_masks(&desc[i], GFP_KERNEL, node);
     266                 :            :                 raw_spin_lock_init(&desc[i].lock);
     267                 :            :                 lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
     268                 :            :                 desc_set_defaults(i, &desc[i], node, NULL);
     269                 :            :         }
     270                 :            :         return arch_early_irq_init();
     271                 :            : }
     272                 :            : 
     273                 :            : struct irq_desc *irq_to_desc(unsigned int irq)
     274                 :            : {
     275                 :            :         return (irq < NR_IRQS) ? irq_desc + irq : NULL;
     276                 :            : }
     277                 :            : EXPORT_SYMBOL(irq_to_desc);
     278                 :            : 
     279                 :            : static void free_desc(unsigned int irq)
     280                 :            : {
     281                 :            :         dynamic_irq_cleanup(irq);
     282                 :            : }
     283                 :            : 
     284                 :            : static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
     285                 :            :                               struct module *owner)
     286                 :            : {
     287                 :            :         u32 i;
     288                 :            : 
     289                 :            :         for (i = 0; i < cnt; i++) {
     290                 :            :                 struct irq_desc *desc = irq_to_desc(start + i);
     291                 :            : 
     292                 :            :                 desc->owner = owner;
     293                 :            :         }
     294                 :            :         return start;
     295                 :            : }
     296                 :            : 
     297                 :            : static int irq_expand_nr_irqs(unsigned int nr)
     298                 :            : {
     299                 :            :         return -ENOMEM;
     300                 :            : }
     301                 :            : 
     302                 :            : #endif /* !CONFIG_SPARSE_IRQ */
     303                 :            : 
     304                 :            : /**
     305                 :            :  * generic_handle_irq - Invoke the handler for a particular irq
     306                 :            :  * @irq:        The irq number to handle
     307                 :            :  *
     308                 :            :  */
     309                 :          0 : int generic_handle_irq(unsigned int irq)
     310                 :            : {
     311                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     312                 :            : 
     313         [ +  + ]:    5584482 :         if (!desc)
     314                 :            :                 return -EINVAL;
     315                 :            :         generic_handle_irq_desc(irq, desc);
     316                 :    5633310 :         return 0;
     317                 :            : }
     318                 :            : EXPORT_SYMBOL_GPL(generic_handle_irq);
     319                 :            : 
     320                 :            : /* Dynamic interrupt handling */
     321                 :            : 
     322                 :            : /**
     323                 :            :  * irq_free_descs - free irq descriptors
     324                 :            :  * @from:       Start of descriptor range
     325                 :            :  * @cnt:        Number of consecutive irqs to free
     326                 :            :  */
     327                 :          0 : void irq_free_descs(unsigned int from, unsigned int cnt)
     328                 :            : {
     329                 :            :         int i;
     330                 :            : 
     331 [ #  # ][ #  # ]:          0 :         if (from >= nr_irqs || (from + cnt) > nr_irqs)
     332                 :          0 :                 return;
     333                 :            : 
     334         [ #  # ]:          0 :         for (i = 0; i < cnt; i++)
     335                 :          0 :                 free_desc(from + i);
     336                 :            : 
     337                 :          0 :         mutex_lock(&sparse_irq_lock);
     338                 :          0 :         bitmap_clear(allocated_irqs, from, cnt);
     339                 :          0 :         mutex_unlock(&sparse_irq_lock);
     340                 :            : }
     341                 :            : EXPORT_SYMBOL_GPL(irq_free_descs);
     342                 :            : 
     343                 :            : /**
     344                 :            :  * irq_alloc_descs - allocate and initialize a range of irq descriptors
     345                 :            :  * @irq:        Allocate for specific irq number if irq >= 0
     346                 :            :  * @from:       Start the search from this irq number
     347                 :            :  * @cnt:        Number of consecutive irqs to allocate.
     348                 :            :  * @node:       Preferred node on which the irq descriptor should be allocated
     349                 :            :  * @owner:      Owning module (can be NULL)
     350                 :            :  *
     351                 :            :  * Returns the first irq number or error code
     352                 :            :  */
     353                 :            : int __ref
     354                 :          0 : __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
     355                 :            :                   struct module *owner)
     356                 :            : {
     357                 :            :         int start, ret;
     358                 :            : 
     359         [ #  # ]:          0 :         if (!cnt)
     360                 :            :                 return -EINVAL;
     361                 :            : 
     362         [ #  # ]:          0 :         if (irq >= 0) {
     363         [ #  # ]:          0 :                 if (from > irq)
     364                 :            :                         return -EINVAL;
     365                 :            :                 from = irq;
     366                 :            :         }
     367                 :            : 
     368                 :          0 :         mutex_lock(&sparse_irq_lock);
     369                 :            : 
     370                 :          0 :         start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,
     371                 :            :                                            from, cnt, 0);
     372                 :            :         ret = -EEXIST;
     373         [ #  # ]:          0 :         if (irq >=0 && start != irq)
     374                 :            :                 goto err;
     375                 :            : 
     376         [ #  # ]:          0 :         if (start + cnt > nr_irqs) {
     377                 :            :                 ret = irq_expand_nr_irqs(start + cnt);
     378         [ #  # ]:          0 :                 if (ret)
     379                 :            :                         goto err;
     380                 :            :         }
     381                 :            : 
     382                 :          0 :         bitmap_set(allocated_irqs, start, cnt);
     383                 :          0 :         mutex_unlock(&sparse_irq_lock);
     384                 :          0 :         return alloc_descs(start, cnt, node, owner);
     385                 :            : 
     386                 :            : err:
     387                 :          0 :         mutex_unlock(&sparse_irq_lock);
     388                 :          0 :         return ret;
     389                 :            : }
     390                 :            : EXPORT_SYMBOL_GPL(__irq_alloc_descs);
     391                 :            : 
     392                 :            : /**
     393                 :            :  * irq_reserve_irqs - mark irqs allocated
     394                 :            :  * @from:       mark from irq number
     395                 :            :  * @cnt:        number of irqs to mark
     396                 :            :  *
     397                 :            :  * Returns 0 on success or an appropriate error code
     398                 :            :  */
     399                 :          0 : int irq_reserve_irqs(unsigned int from, unsigned int cnt)
     400                 :            : {
     401                 :            :         unsigned int start;
     402                 :            :         int ret = 0;
     403                 :            : 
     404 [ #  # ][ #  # ]:          0 :         if (!cnt || (from + cnt) > nr_irqs)
     405                 :            :                 return -EINVAL;
     406                 :            : 
     407                 :          0 :         mutex_lock(&sparse_irq_lock);
     408                 :          0 :         start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0);
     409         [ #  # ]:          0 :         if (start == from)
     410                 :          0 :                 bitmap_set(allocated_irqs, start, cnt);
     411                 :            :         else
     412                 :            :                 ret = -EEXIST;
     413                 :          0 :         mutex_unlock(&sparse_irq_lock);
     414                 :          0 :         return ret;
     415                 :            : }
     416                 :            : 
     417                 :            : /**
     418                 :            :  * irq_get_next_irq - get next allocated irq number
     419                 :            :  * @offset:     where to start the search
     420                 :            :  *
     421                 :            :  * Returns next irq number after offset or nr_irqs if none is found.
     422                 :            :  */
     423                 :          0 : unsigned int irq_get_next_irq(unsigned int offset)
     424                 :            : {
     425                 :          0 :         return find_next_bit(allocated_irqs, nr_irqs, offset);
     426                 :            : }
     427                 :            : 
     428                 :            : struct irq_desc *
     429                 :          0 : __irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
     430                 :            :                     unsigned int check)
     431                 :            : {
     432                 :        159 :         struct irq_desc *desc = irq_to_desc(irq);
     433                 :            : 
     434         [ +  - ]:        159 :         if (desc) {
     435         [ +  - ]:        159 :                 if (check & _IRQ_DESC_CHECK) {
     436 [ +  - ][ +  - ]:        159 :                         if ((check & _IRQ_DESC_PERCPU) &&
     437                 :            :                             !irq_settings_is_per_cpu_devid(desc))
     438                 :            :                                 return NULL;
     439                 :            : 
     440 [ -  + ][ #  # ]:        159 :                         if (!(check & _IRQ_DESC_PERCPU) &&
     441                 :            :                             irq_settings_is_per_cpu_devid(desc))
     442                 :            :                                 return NULL;
     443                 :            :                 }
     444                 :            : 
     445         [ -  + ]:        159 :                 if (bus)
     446                 :            :                         chip_bus_lock(desc);
     447                 :        159 :                 raw_spin_lock_irqsave(&desc->lock, *flags);
     448                 :            :         }
     449                 :        159 :         return desc;
     450                 :            : }
     451                 :            : 
     452                 :          0 : void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus)
     453                 :            : {
     454                 :        159 :         raw_spin_unlock_irqrestore(&desc->lock, flags);
     455         [ -  + ]:        159 :         if (bus)
     456                 :            :                 chip_bus_sync_unlock(desc);
     457                 :          0 : }
     458                 :            : 
     459                 :          0 : int irq_set_percpu_devid(unsigned int irq)
     460                 :            : {
     461                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     462                 :            : 
     463         [ #  # ]:          0 :         if (!desc)
     464                 :            :                 return -EINVAL;
     465                 :            : 
     466         [ #  # ]:          0 :         if (desc->percpu_enabled)
     467                 :            :                 return -EINVAL;
     468                 :            : 
     469                 :          0 :         desc->percpu_enabled = kzalloc(sizeof(*desc->percpu_enabled), GFP_KERNEL);
     470                 :            : 
     471         [ #  # ]:          0 :         if (!desc->percpu_enabled)
     472                 :            :                 return -ENOMEM;
     473                 :            : 
     474                 :            :         irq_set_percpu_devid_flags(irq);
     475                 :          0 :         return 0;
     476                 :            : }
     477                 :            : 
     478                 :            : /**
     479                 :            :  * dynamic_irq_cleanup - cleanup a dynamically allocated irq
     480                 :            :  * @irq:        irq number to initialize
     481                 :            :  */
     482                 :          0 : void dynamic_irq_cleanup(unsigned int irq)
     483                 :            : {
     484                 :          0 :         struct irq_desc *desc = irq_to_desc(irq);
     485                 :            :         unsigned long flags;
     486                 :            : 
     487                 :          0 :         raw_spin_lock_irqsave(&desc->lock, flags);
     488                 :          0 :         desc_set_defaults(irq, desc, desc_node(desc), NULL);
     489                 :          0 :         raw_spin_unlock_irqrestore(&desc->lock, flags);
     490                 :          0 : }
     491                 :            : 
     492                 :          0 : unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
     493                 :            : {
     494                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     495                 :            : 
     496         [ +  - ]:       4242 :         return desc && desc->kstat_irqs ?
     497         [ +  - ]:       8484 :                         *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
     498                 :            : }
     499                 :            : 
     500                 :          0 : unsigned int kstat_irqs(unsigned int irq)
     501                 :            : {
     502                 :            :         struct irq_desc *desc = irq_to_desc(irq);
     503                 :            :         int cpu;
     504                 :            :         int sum = 0;
     505                 :            : 
     506 [ +  - ][ +  - ]:       1344 :         if (!desc || !desc->kstat_irqs)
     507                 :            :                 return 0;
     508         [ +  + ]:       9408 :         for_each_possible_cpu(cpu)
     509                 :       6720 :                 sum += *per_cpu_ptr(desc->kstat_irqs, cpu);
     510                 :       1344 :         return sum;
     511                 :            : }

Generated by: LCOV version 1.9