LCOV - code coverage report
Current view: top level - drivers/base/regmap - regmap-irq.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 427 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 19 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : //
       3                 :            : // regmap based irq_chip
       4                 :            : //
       5                 :            : // Copyright 2011 Wolfson Microelectronics plc
       6                 :            : //
       7                 :            : // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
       8                 :            : 
       9                 :            : #include <linux/device.h>
      10                 :            : #include <linux/export.h>
      11                 :            : #include <linux/interrupt.h>
      12                 :            : #include <linux/irq.h>
      13                 :            : #include <linux/irqdomain.h>
      14                 :            : #include <linux/pm_runtime.h>
      15                 :            : #include <linux/regmap.h>
      16                 :            : #include <linux/slab.h>
      17                 :            : 
      18                 :            : #include "internal.h"
      19                 :            : 
      20                 :            : struct regmap_irq_chip_data {
      21                 :            :         struct mutex lock;
      22                 :            :         struct irq_chip irq_chip;
      23                 :            : 
      24                 :            :         struct regmap *map;
      25                 :            :         const struct regmap_irq_chip *chip;
      26                 :            : 
      27                 :            :         int irq_base;
      28                 :            :         struct irq_domain *domain;
      29                 :            : 
      30                 :            :         int irq;
      31                 :            :         int wake_count;
      32                 :            : 
      33                 :            :         void *status_reg_buf;
      34                 :            :         unsigned int *main_status_buf;
      35                 :            :         unsigned int *status_buf;
      36                 :            :         unsigned int *mask_buf;
      37                 :            :         unsigned int *mask_buf_def;
      38                 :            :         unsigned int *wake_buf;
      39                 :            :         unsigned int *type_buf;
      40                 :            :         unsigned int *type_buf_def;
      41                 :            : 
      42                 :            :         unsigned int irq_reg_stride;
      43                 :            :         unsigned int type_reg_stride;
      44                 :            : 
      45                 :            :         bool clear_status:1;
      46                 :            : };
      47                 :            : 
      48                 :            : static inline const
      49                 :            : struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data,
      50                 :            :                                      int irq)
      51                 :            : {
      52                 :          0 :         return &data->chip->irqs[irq];
      53                 :            : }
      54                 :            : 
      55                 :          0 : static void regmap_irq_lock(struct irq_data *data)
      56                 :            : {
      57                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
      58                 :            : 
      59                 :          0 :         mutex_lock(&d->lock);
      60                 :          0 : }
      61                 :            : 
      62                 :          0 : static int regmap_irq_update_bits(struct regmap_irq_chip_data *d,
      63                 :            :                                   unsigned int reg, unsigned int mask,
      64                 :            :                                   unsigned int val)
      65                 :            : {
      66                 :          0 :         if (d->chip->mask_writeonly)
      67                 :          0 :                 return regmap_write_bits(d->map, reg, mask, val);
      68                 :            :         else
      69                 :          0 :                 return regmap_update_bits(d->map, reg, mask, val);
      70                 :            : }
      71                 :            : 
      72                 :          0 : static void regmap_irq_sync_unlock(struct irq_data *data)
      73                 :            : {
      74                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
      75                 :          0 :         struct regmap *map = d->map;
      76                 :            :         int i, ret;
      77                 :            :         u32 reg;
      78                 :            :         u32 unmask_offset;
      79                 :            :         u32 val;
      80                 :            : 
      81                 :          0 :         if (d->chip->runtime_pm) {
      82                 :          0 :                 ret = pm_runtime_get_sync(map->dev);
      83                 :          0 :                 if (ret < 0)
      84                 :          0 :                         dev_err(map->dev, "IRQ sync failed to resume: %d\n",
      85                 :            :                                 ret);
      86                 :            :         }
      87                 :            : 
      88                 :          0 :         if (d->clear_status) {
      89                 :          0 :                 for (i = 0; i < d->chip->num_regs; i++) {
      90                 :          0 :                         reg = d->chip->status_base +
      91                 :          0 :                                 (i * map->reg_stride * d->irq_reg_stride);
      92                 :            : 
      93                 :          0 :                         ret = regmap_read(map, reg, &val);
      94                 :          0 :                         if (ret)
      95                 :          0 :                                 dev_err(d->map->dev,
      96                 :            :                                         "Failed to clear the interrupt status bits\n");
      97                 :            :                 }
      98                 :            : 
      99                 :          0 :                 d->clear_status = false;
     100                 :            :         }
     101                 :            : 
     102                 :            :         /*
     103                 :            :          * If there's been a change in the mask write it back to the
     104                 :            :          * hardware.  We rely on the use of the regmap core cache to
     105                 :            :          * suppress pointless writes.
     106                 :            :          */
     107                 :          0 :         for (i = 0; i < d->chip->num_regs; i++) {
     108                 :          0 :                 if (!d->chip->mask_base)
     109                 :          0 :                         continue;
     110                 :            : 
     111                 :          0 :                 reg = d->chip->mask_base +
     112                 :          0 :                         (i * map->reg_stride * d->irq_reg_stride);
     113                 :          0 :                 if (d->chip->mask_invert) {
     114                 :          0 :                         ret = regmap_irq_update_bits(d, reg,
     115                 :          0 :                                          d->mask_buf_def[i], ~d->mask_buf[i]);
     116                 :          0 :                 } else if (d->chip->unmask_base) {
     117                 :            :                         /* set mask with mask_base register */
     118                 :          0 :                         ret = regmap_irq_update_bits(d, reg,
     119                 :          0 :                                         d->mask_buf_def[i], ~d->mask_buf[i]);
     120                 :          0 :                         if (ret < 0)
     121                 :          0 :                                 dev_err(d->map->dev,
     122                 :            :                                         "Failed to sync unmasks in %x\n",
     123                 :            :                                         reg);
     124                 :          0 :                         unmask_offset = d->chip->unmask_base -
     125                 :          0 :                                                         d->chip->mask_base;
     126                 :            :                         /* clear mask with unmask_base register */
     127                 :          0 :                         ret = regmap_irq_update_bits(d,
     128                 :            :                                         reg + unmask_offset,
     129                 :          0 :                                         d->mask_buf_def[i],
     130                 :          0 :                                         d->mask_buf[i]);
     131                 :            :                 } else {
     132                 :          0 :                         ret = regmap_irq_update_bits(d, reg,
     133                 :          0 :                                          d->mask_buf_def[i], d->mask_buf[i]);
     134                 :            :                 }
     135                 :          0 :                 if (ret != 0)
     136                 :          0 :                         dev_err(d->map->dev, "Failed to sync masks in %x\n",
     137                 :            :                                 reg);
     138                 :            : 
     139                 :          0 :                 reg = d->chip->wake_base +
     140                 :          0 :                         (i * map->reg_stride * d->irq_reg_stride);
     141                 :          0 :                 if (d->wake_buf) {
     142                 :          0 :                         if (d->chip->wake_invert)
     143                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     144                 :          0 :                                                          d->mask_buf_def[i],
     145                 :          0 :                                                          ~d->wake_buf[i]);
     146                 :            :                         else
     147                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     148                 :          0 :                                                          d->mask_buf_def[i],
     149                 :          0 :                                                          d->wake_buf[i]);
     150                 :          0 :                         if (ret != 0)
     151                 :          0 :                                 dev_err(d->map->dev,
     152                 :            :                                         "Failed to sync wakes in %x: %d\n",
     153                 :            :                                         reg, ret);
     154                 :            :                 }
     155                 :            : 
     156                 :          0 :                 if (!d->chip->init_ack_masked)
     157                 :          0 :                         continue;
     158                 :            :                 /*
     159                 :            :                  * Ack all the masked interrupts unconditionally,
     160                 :            :                  * OR if there is masked interrupt which hasn't been Acked,
     161                 :            :                  * it'll be ignored in irq handler, then may introduce irq storm
     162                 :            :                  */
     163                 :          0 :                 if (d->mask_buf[i] && (d->chip->ack_base || d->chip->use_ack)) {
     164                 :          0 :                         reg = d->chip->ack_base +
     165                 :          0 :                                 (i * map->reg_stride * d->irq_reg_stride);
     166                 :            :                         /* some chips ack by write 0 */
     167                 :          0 :                         if (d->chip->ack_invert)
     168                 :          0 :                                 ret = regmap_write(map, reg, ~d->mask_buf[i]);
     169                 :            :                         else
     170                 :          0 :                                 ret = regmap_write(map, reg, d->mask_buf[i]);
     171                 :          0 :                         if (ret != 0)
     172                 :          0 :                                 dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
     173                 :            :                                         reg, ret);
     174                 :            :                 }
     175                 :            :         }
     176                 :            : 
     177                 :            :         /* Don't update the type bits if we're using mask bits for irq type. */
     178                 :          0 :         if (!d->chip->type_in_mask) {
     179                 :          0 :                 for (i = 0; i < d->chip->num_type_reg; i++) {
     180                 :          0 :                         if (!d->type_buf_def[i])
     181                 :          0 :                                 continue;
     182                 :          0 :                         reg = d->chip->type_base +
     183                 :          0 :                                 (i * map->reg_stride * d->type_reg_stride);
     184                 :          0 :                         if (d->chip->type_invert)
     185                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     186                 :          0 :                                         d->type_buf_def[i], ~d->type_buf[i]);
     187                 :            :                         else
     188                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     189                 :          0 :                                         d->type_buf_def[i], d->type_buf[i]);
     190                 :          0 :                         if (ret != 0)
     191                 :          0 :                                 dev_err(d->map->dev, "Failed to sync type in %x\n",
     192                 :            :                                         reg);
     193                 :            :                 }
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         if (d->chip->runtime_pm)
     197                 :          0 :                 pm_runtime_put(map->dev);
     198                 :            : 
     199                 :            :         /* If we've changed our wakeup count propagate it to the parent */
     200                 :          0 :         if (d->wake_count < 0)
     201                 :          0 :                 for (i = d->wake_count; i < 0; i++)
     202                 :          0 :                         irq_set_irq_wake(d->irq, 0);
     203                 :          0 :         else if (d->wake_count > 0)
     204                 :          0 :                 for (i = 0; i < d->wake_count; i++)
     205                 :          0 :                         irq_set_irq_wake(d->irq, 1);
     206                 :            : 
     207                 :          0 :         d->wake_count = 0;
     208                 :            : 
     209                 :          0 :         mutex_unlock(&d->lock);
     210                 :          0 : }
     211                 :            : 
     212                 :          0 : static void regmap_irq_enable(struct irq_data *data)
     213                 :            : {
     214                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
     215                 :          0 :         struct regmap *map = d->map;
     216                 :          0 :         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
     217                 :            :         unsigned int mask, type;
     218                 :            : 
     219                 :          0 :         type = irq_data->type.type_falling_val | irq_data->type.type_rising_val;
     220                 :            : 
     221                 :            :         /*
     222                 :            :          * The type_in_mask flag means that the underlying hardware uses
     223                 :            :          * separate mask bits for rising and falling edge interrupts, but
     224                 :            :          * we want to make them into a single virtual interrupt with
     225                 :            :          * configurable edge.
     226                 :            :          *
     227                 :            :          * If the interrupt we're enabling defines the falling or rising
     228                 :            :          * masks then instead of using the regular mask bits for this
     229                 :            :          * interrupt, use the value previously written to the type buffer
     230                 :            :          * at the corresponding offset in regmap_irq_set_type().
     231                 :            :          */
     232                 :          0 :         if (d->chip->type_in_mask && type)
     233                 :          0 :                 mask = d->type_buf[irq_data->reg_offset / map->reg_stride];
     234                 :            :         else
     235                 :          0 :                 mask = irq_data->mask;
     236                 :            : 
     237                 :          0 :         if (d->chip->clear_on_unmask)
     238                 :          0 :                 d->clear_status = true;
     239                 :            : 
     240                 :          0 :         d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~mask;
     241                 :          0 : }
     242                 :            : 
     243                 :          0 : static void regmap_irq_disable(struct irq_data *data)
     244                 :            : {
     245                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
     246                 :          0 :         struct regmap *map = d->map;
     247                 :          0 :         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
     248                 :            : 
     249                 :          0 :         d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask;
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
     253                 :            : {
     254                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
     255                 :          0 :         struct regmap *map = d->map;
     256                 :          0 :         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
     257                 :            :         int reg;
     258                 :            :         const struct regmap_irq_type *t = &irq_data->type;
     259                 :            : 
     260                 :          0 :         if ((t->types_supported & type) != type)
     261                 :            :                 return 0;
     262                 :            : 
     263                 :          0 :         reg = t->type_reg_offset / map->reg_stride;
     264                 :            : 
     265                 :          0 :         if (t->type_reg_mask)
     266                 :          0 :                 d->type_buf[reg] &= ~t->type_reg_mask;
     267                 :            :         else
     268                 :          0 :                 d->type_buf[reg] &= ~(t->type_falling_val |
     269                 :          0 :                                       t->type_rising_val |
     270                 :          0 :                                       t->type_level_low_val |
     271                 :          0 :                                       t->type_level_high_val);
     272                 :          0 :         switch (type) {
     273                 :            :         case IRQ_TYPE_EDGE_FALLING:
     274                 :          0 :                 d->type_buf[reg] |= t->type_falling_val;
     275                 :          0 :                 break;
     276                 :            : 
     277                 :            :         case IRQ_TYPE_EDGE_RISING:
     278                 :          0 :                 d->type_buf[reg] |= t->type_rising_val;
     279                 :          0 :                 break;
     280                 :            : 
     281                 :            :         case IRQ_TYPE_EDGE_BOTH:
     282                 :          0 :                 d->type_buf[reg] |= (t->type_falling_val |
     283                 :          0 :                                         t->type_rising_val);
     284                 :          0 :                 break;
     285                 :            : 
     286                 :            :         case IRQ_TYPE_LEVEL_HIGH:
     287                 :          0 :                 d->type_buf[reg] |= t->type_level_high_val;
     288                 :          0 :                 break;
     289                 :            : 
     290                 :            :         case IRQ_TYPE_LEVEL_LOW:
     291                 :          0 :                 d->type_buf[reg] |= t->type_level_low_val;
     292                 :          0 :                 break;
     293                 :            :         default:
     294                 :            :                 return -EINVAL;
     295                 :            :         }
     296                 :            :         return 0;
     297                 :            : }
     298                 :            : 
     299                 :          0 : static int regmap_irq_set_wake(struct irq_data *data, unsigned int on)
     300                 :            : {
     301                 :            :         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
     302                 :          0 :         struct regmap *map = d->map;
     303                 :          0 :         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
     304                 :            : 
     305                 :          0 :         if (on) {
     306                 :          0 :                 if (d->wake_buf)
     307                 :          0 :                         d->wake_buf[irq_data->reg_offset / map->reg_stride]
     308                 :          0 :                                 &= ~irq_data->mask;
     309                 :          0 :                 d->wake_count++;
     310                 :            :         } else {
     311                 :          0 :                 if (d->wake_buf)
     312                 :          0 :                         d->wake_buf[irq_data->reg_offset / map->reg_stride]
     313                 :          0 :                                 |= irq_data->mask;
     314                 :          0 :                 d->wake_count--;
     315                 :            :         }
     316                 :            : 
     317                 :          0 :         return 0;
     318                 :            : }
     319                 :            : 
     320                 :            : static const struct irq_chip regmap_irq_chip = {
     321                 :            :         .irq_bus_lock           = regmap_irq_lock,
     322                 :            :         .irq_bus_sync_unlock    = regmap_irq_sync_unlock,
     323                 :            :         .irq_disable            = regmap_irq_disable,
     324                 :            :         .irq_enable             = regmap_irq_enable,
     325                 :            :         .irq_set_type           = regmap_irq_set_type,
     326                 :            :         .irq_set_wake           = regmap_irq_set_wake,
     327                 :            : };
     328                 :            : 
     329                 :          0 : static inline int read_sub_irq_data(struct regmap_irq_chip_data *data,
     330                 :            :                                            unsigned int b)
     331                 :            : {
     332                 :          0 :         const struct regmap_irq_chip *chip = data->chip;
     333                 :          0 :         struct regmap *map = data->map;
     334                 :            :         struct regmap_irq_sub_irq_map *subreg;
     335                 :            :         int i, ret = 0;
     336                 :            : 
     337                 :          0 :         if (!chip->sub_reg_offsets) {
     338                 :            :                 /* Assume linear mapping */
     339                 :          0 :                 ret = regmap_read(map, chip->status_base +
     340                 :          0 :                                   (b * map->reg_stride * data->irq_reg_stride),
     341                 :          0 :                                    &data->status_buf[b]);
     342                 :            :         } else {
     343                 :          0 :                 subreg = &chip->sub_reg_offsets[b];
     344                 :          0 :                 for (i = 0; i < subreg->num_regs; i++) {
     345                 :          0 :                         unsigned int offset = subreg->offset[i];
     346                 :            : 
     347                 :          0 :                         ret = regmap_read(map, chip->status_base + offset,
     348                 :          0 :                                           &data->status_buf[offset]);
     349                 :          0 :                         if (ret)
     350                 :            :                                 break;
     351                 :            :                 }
     352                 :            :         }
     353                 :          0 :         return ret;
     354                 :            : }
     355                 :            : 
     356                 :          0 : static irqreturn_t regmap_irq_thread(int irq, void *d)
     357                 :            : {
     358                 :            :         struct regmap_irq_chip_data *data = d;
     359                 :          0 :         const struct regmap_irq_chip *chip = data->chip;
     360                 :          0 :         struct regmap *map = data->map;
     361                 :            :         int ret, i;
     362                 :            :         bool handled = false;
     363                 :            :         u32 reg;
     364                 :            : 
     365                 :          0 :         if (chip->handle_pre_irq)
     366                 :          0 :                 chip->handle_pre_irq(chip->irq_drv_data);
     367                 :            : 
     368                 :          0 :         if (chip->runtime_pm) {
     369                 :          0 :                 ret = pm_runtime_get_sync(map->dev);
     370                 :          0 :                 if (ret < 0) {
     371                 :          0 :                         dev_err(map->dev, "IRQ thread failed to resume: %d\n",
     372                 :            :                                 ret);
     373                 :          0 :                         goto exit;
     374                 :            :                 }
     375                 :            :         }
     376                 :            : 
     377                 :            :         /*
     378                 :            :          * Read only registers with active IRQs if the chip has 'main status
     379                 :            :          * register'. Else read in the statuses, using a single bulk read if
     380                 :            :          * possible in order to reduce the I/O overheads.
     381                 :            :          */
     382                 :            : 
     383                 :          0 :         if (chip->num_main_regs) {
     384                 :            :                 unsigned int max_main_bits;
     385                 :            :                 unsigned long size;
     386                 :            : 
     387                 :          0 :                 size = chip->num_regs * sizeof(unsigned int);
     388                 :            : 
     389                 :          0 :                 max_main_bits = (chip->num_main_status_bits) ?
     390                 :          0 :                                  chip->num_main_status_bits : chip->num_regs;
     391                 :            :                 /* Clear the status buf as we don't read all status regs */
     392                 :          0 :                 memset(data->status_buf, 0, size);
     393                 :            : 
     394                 :            :                 /* We could support bulk read for main status registers
     395                 :            :                  * but I don't expect to see devices with really many main
     396                 :            :                  * status registers so let's only support single reads for the
     397                 :            :                  * sake of simplicity. and add bulk reads only if needed
     398                 :            :                  */
     399                 :          0 :                 for (i = 0; i < chip->num_main_regs; i++) {
     400                 :          0 :                         ret = regmap_read(map, chip->main_status +
     401                 :          0 :                                   (i * map->reg_stride
     402                 :          0 :                                    * data->irq_reg_stride),
     403                 :          0 :                                   &data->main_status_buf[i]);
     404                 :          0 :                         if (ret) {
     405                 :          0 :                                 dev_err(map->dev,
     406                 :            :                                         "Failed to read IRQ status %d\n",
     407                 :            :                                         ret);
     408                 :          0 :                                 goto exit;
     409                 :            :                         }
     410                 :            :                 }
     411                 :            : 
     412                 :            :                 /* Read sub registers with active IRQs */
     413                 :          0 :                 for (i = 0; i < chip->num_main_regs; i++) {
     414                 :            :                         unsigned int b;
     415                 :          0 :                         const unsigned long mreg = data->main_status_buf[i];
     416                 :            : 
     417                 :          0 :                         for_each_set_bit(b, &mreg, map->format.val_bytes * 8) {
     418                 :          0 :                                 if (i * map->format.val_bytes * 8 + b >
     419                 :            :                                     max_main_bits)
     420                 :            :                                         break;
     421                 :          0 :                                 ret = read_sub_irq_data(data, b);
     422                 :            : 
     423                 :          0 :                                 if (ret != 0) {
     424                 :          0 :                                         dev_err(map->dev,
     425                 :            :                                                 "Failed to read IRQ status %d\n",
     426                 :            :                                                 ret);
     427                 :          0 :                                         goto exit;
     428                 :            :                                 }
     429                 :            :                         }
     430                 :            : 
     431                 :            :                 }
     432                 :          0 :         } else if (!map->use_single_read && map->reg_stride == 1 &&
     433                 :          0 :                    data->irq_reg_stride == 1) {
     434                 :            : 
     435                 :          0 :                 u8 *buf8 = data->status_reg_buf;
     436                 :            :                 u16 *buf16 = data->status_reg_buf;
     437                 :            :                 u32 *buf32 = data->status_reg_buf;
     438                 :            : 
     439                 :          0 :                 BUG_ON(!data->status_reg_buf);
     440                 :            : 
     441                 :          0 :                 ret = regmap_bulk_read(map, chip->status_base,
     442                 :            :                                        data->status_reg_buf,
     443                 :          0 :                                        chip->num_regs);
     444                 :          0 :                 if (ret != 0) {
     445                 :          0 :                         dev_err(map->dev, "Failed to read IRQ status: %d\n",
     446                 :            :                                 ret);
     447                 :          0 :                         goto exit;
     448                 :            :                 }
     449                 :            : 
     450                 :          0 :                 for (i = 0; i < data->chip->num_regs; i++) {
     451                 :          0 :                         switch (map->format.val_bytes) {
     452                 :            :                         case 1:
     453                 :          0 :                                 data->status_buf[i] = buf8[i];
     454                 :          0 :                                 break;
     455                 :            :                         case 2:
     456                 :          0 :                                 data->status_buf[i] = buf16[i];
     457                 :          0 :                                 break;
     458                 :            :                         case 4:
     459                 :          0 :                                 data->status_buf[i] = buf32[i];
     460                 :          0 :                                 break;
     461                 :            :                         default:
     462                 :          0 :                                 BUG();
     463                 :            :                                 goto exit;
     464                 :            :                         }
     465                 :            :                 }
     466                 :            : 
     467                 :            :         } else {
     468                 :          0 :                 for (i = 0; i < data->chip->num_regs; i++) {
     469                 :          0 :                         ret = regmap_read(map, chip->status_base +
     470                 :          0 :                                           (i * map->reg_stride
     471                 :          0 :                                            * data->irq_reg_stride),
     472                 :          0 :                                           &data->status_buf[i]);
     473                 :            : 
     474                 :          0 :                         if (ret != 0) {
     475                 :          0 :                                 dev_err(map->dev,
     476                 :            :                                         "Failed to read IRQ status: %d\n",
     477                 :            :                                         ret);
     478                 :          0 :                                 goto exit;
     479                 :            :                         }
     480                 :            :                 }
     481                 :            :         }
     482                 :            : 
     483                 :            :         /*
     484                 :            :          * Ignore masked IRQs and ack if we need to; we ack early so
     485                 :            :          * there is no race between handling and acknowleding the
     486                 :            :          * interrupt.  We assume that typically few of the interrupts
     487                 :            :          * will fire simultaneously so don't worry about overhead from
     488                 :            :          * doing a write per register.
     489                 :            :          */
     490                 :          0 :         for (i = 0; i < data->chip->num_regs; i++) {
     491                 :          0 :                 data->status_buf[i] &= ~data->mask_buf[i];
     492                 :            : 
     493                 :          0 :                 if (data->status_buf[i] && (chip->ack_base || chip->use_ack)) {
     494                 :          0 :                         reg = chip->ack_base +
     495                 :          0 :                                 (i * map->reg_stride * data->irq_reg_stride);
     496                 :          0 :                         ret = regmap_write(map, reg, data->status_buf[i]);
     497                 :          0 :                         if (ret != 0)
     498                 :          0 :                                 dev_err(map->dev, "Failed to ack 0x%x: %d\n",
     499                 :            :                                         reg, ret);
     500                 :            :                 }
     501                 :            :         }
     502                 :            : 
     503                 :          0 :         for (i = 0; i < chip->num_irqs; i++) {
     504                 :          0 :                 if (data->status_buf[chip->irqs[i].reg_offset /
     505                 :          0 :                                      map->reg_stride] & chip->irqs[i].mask) {
     506                 :          0 :                         handle_nested_irq(irq_find_mapping(data->domain, i));
     507                 :            :                         handled = true;
     508                 :            :                 }
     509                 :            :         }
     510                 :            : 
     511                 :            : exit:
     512                 :          0 :         if (chip->runtime_pm)
     513                 :          0 :                 pm_runtime_put(map->dev);
     514                 :            : 
     515                 :          0 :         if (chip->handle_post_irq)
     516                 :          0 :                 chip->handle_post_irq(chip->irq_drv_data);
     517                 :            : 
     518                 :          0 :         if (handled)
     519                 :            :                 return IRQ_HANDLED;
     520                 :            :         else
     521                 :          0 :                 return IRQ_NONE;
     522                 :            : }
     523                 :            : 
     524                 :          0 : static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
     525                 :            :                           irq_hw_number_t hw)
     526                 :            : {
     527                 :          0 :         struct regmap_irq_chip_data *data = h->host_data;
     528                 :            : 
     529                 :          0 :         irq_set_chip_data(virq, data);
     530                 :          0 :         irq_set_chip(virq, &data->irq_chip);
     531                 :          0 :         irq_set_nested_thread(virq, 1);
     532                 :          0 :         irq_set_parent(virq, data->irq);
     533                 :            :         irq_set_noprobe(virq);
     534                 :            : 
     535                 :          0 :         return 0;
     536                 :            : }
     537                 :            : 
     538                 :            : static const struct irq_domain_ops regmap_domain_ops = {
     539                 :            :         .map    = regmap_irq_map,
     540                 :            :         .xlate  = irq_domain_xlate_onetwocell,
     541                 :            : };
     542                 :            : 
     543                 :            : /**
     544                 :            :  * regmap_add_irq_chip() - Use standard regmap IRQ controller handling
     545                 :            :  *
     546                 :            :  * @map: The regmap for the device.
     547                 :            :  * @irq: The IRQ the device uses to signal interrupts.
     548                 :            :  * @irq_flags: The IRQF_ flags to use for the primary interrupt.
     549                 :            :  * @irq_base: Allocate at specific IRQ number if irq_base > 0.
     550                 :            :  * @chip: Configuration for the interrupt controller.
     551                 :            :  * @data: Runtime data structure for the controller, allocated on success.
     552                 :            :  *
     553                 :            :  * Returns 0 on success or an errno on failure.
     554                 :            :  *
     555                 :            :  * In order for this to be efficient the chip really should use a
     556                 :            :  * register cache.  The chip driver is responsible for restoring the
     557                 :            :  * register values used by the IRQ controller over suspend and resume.
     558                 :            :  */
     559                 :          0 : int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
     560                 :            :                         int irq_base, const struct regmap_irq_chip *chip,
     561                 :            :                         struct regmap_irq_chip_data **data)
     562                 :            : {
     563                 :            :         struct regmap_irq_chip_data *d;
     564                 :            :         int i;
     565                 :            :         int ret = -ENOMEM;
     566                 :            :         int num_type_reg;
     567                 :            :         u32 reg;
     568                 :            :         u32 unmask_offset;
     569                 :            : 
     570                 :          0 :         if (chip->num_regs <= 0)
     571                 :            :                 return -EINVAL;
     572                 :            : 
     573                 :          0 :         if (chip->clear_on_unmask && (chip->ack_base || chip->use_ack))
     574                 :            :                 return -EINVAL;
     575                 :            : 
     576                 :          0 :         for (i = 0; i < chip->num_irqs; i++) {
     577                 :          0 :                 if (chip->irqs[i].reg_offset % map->reg_stride)
     578                 :            :                         return -EINVAL;
     579                 :          0 :                 if (chip->irqs[i].reg_offset / map->reg_stride >=
     580                 :            :                     chip->num_regs)
     581                 :            :                         return -EINVAL;
     582                 :            :         }
     583                 :            : 
     584                 :          0 :         if (irq_base) {
     585                 :          0 :                 irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0);
     586                 :          0 :                 if (irq_base < 0) {
     587                 :          0 :                         dev_warn(map->dev, "Failed to allocate IRQs: %d\n",
     588                 :            :                                  irq_base);
     589                 :          0 :                         return irq_base;
     590                 :            :                 }
     591                 :            :         }
     592                 :            : 
     593                 :          0 :         d = kzalloc(sizeof(*d), GFP_KERNEL);
     594                 :          0 :         if (!d)
     595                 :            :                 return -ENOMEM;
     596                 :            : 
     597                 :          0 :         if (chip->num_main_regs) {
     598                 :          0 :                 d->main_status_buf = kcalloc(chip->num_main_regs,
     599                 :            :                                              sizeof(unsigned int),
     600                 :            :                                              GFP_KERNEL);
     601                 :            : 
     602                 :          0 :                 if (!d->main_status_buf)
     603                 :            :                         goto err_alloc;
     604                 :            :         }
     605                 :            : 
     606                 :          0 :         d->status_buf = kcalloc(chip->num_regs, sizeof(unsigned int),
     607                 :            :                                 GFP_KERNEL);
     608                 :          0 :         if (!d->status_buf)
     609                 :            :                 goto err_alloc;
     610                 :            : 
     611                 :          0 :         d->mask_buf = kcalloc(chip->num_regs, sizeof(unsigned int),
     612                 :            :                               GFP_KERNEL);
     613                 :          0 :         if (!d->mask_buf)
     614                 :            :                 goto err_alloc;
     615                 :            : 
     616                 :          0 :         d->mask_buf_def = kcalloc(chip->num_regs, sizeof(unsigned int),
     617                 :            :                                   GFP_KERNEL);
     618                 :          0 :         if (!d->mask_buf_def)
     619                 :            :                 goto err_alloc;
     620                 :            : 
     621                 :          0 :         if (chip->wake_base) {
     622                 :          0 :                 d->wake_buf = kcalloc(chip->num_regs, sizeof(unsigned int),
     623                 :            :                                       GFP_KERNEL);
     624                 :          0 :                 if (!d->wake_buf)
     625                 :            :                         goto err_alloc;
     626                 :            :         }
     627                 :            : 
     628                 :          0 :         num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg;
     629                 :          0 :         if (num_type_reg) {
     630                 :          0 :                 d->type_buf_def = kcalloc(num_type_reg,
     631                 :            :                                           sizeof(unsigned int), GFP_KERNEL);
     632                 :          0 :                 if (!d->type_buf_def)
     633                 :            :                         goto err_alloc;
     634                 :            : 
     635                 :          0 :                 d->type_buf = kcalloc(num_type_reg, sizeof(unsigned int),
     636                 :            :                                       GFP_KERNEL);
     637                 :          0 :                 if (!d->type_buf)
     638                 :            :                         goto err_alloc;
     639                 :            :         }
     640                 :            : 
     641                 :          0 :         d->irq_chip = regmap_irq_chip;
     642                 :          0 :         d->irq_chip.name = chip->name;
     643                 :          0 :         d->irq = irq;
     644                 :          0 :         d->map = map;
     645                 :          0 :         d->chip = chip;
     646                 :          0 :         d->irq_base = irq_base;
     647                 :            : 
     648                 :          0 :         if (chip->irq_reg_stride)
     649                 :          0 :                 d->irq_reg_stride = chip->irq_reg_stride;
     650                 :            :         else
     651                 :          0 :                 d->irq_reg_stride = 1;
     652                 :            : 
     653                 :          0 :         if (chip->type_reg_stride)
     654                 :          0 :                 d->type_reg_stride = chip->type_reg_stride;
     655                 :            :         else
     656                 :          0 :                 d->type_reg_stride = 1;
     657                 :            : 
     658                 :          0 :         if (!map->use_single_read && map->reg_stride == 1 &&
     659                 :          0 :             d->irq_reg_stride == 1) {
     660                 :          0 :                 d->status_reg_buf = kmalloc_array(chip->num_regs,
     661                 :            :                                                   map->format.val_bytes,
     662                 :            :                                                   GFP_KERNEL);
     663                 :          0 :                 if (!d->status_reg_buf)
     664                 :            :                         goto err_alloc;
     665                 :            :         }
     666                 :            : 
     667                 :          0 :         mutex_init(&d->lock);
     668                 :            : 
     669                 :          0 :         for (i = 0; i < chip->num_irqs; i++)
     670                 :          0 :                 d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride]
     671                 :          0 :                         |= chip->irqs[i].mask;
     672                 :            : 
     673                 :            :         /* Mask all the interrupts by default */
     674                 :          0 :         for (i = 0; i < chip->num_regs; i++) {
     675                 :          0 :                 d->mask_buf[i] = d->mask_buf_def[i];
     676                 :          0 :                 if (!chip->mask_base)
     677                 :          0 :                         continue;
     678                 :            : 
     679                 :          0 :                 reg = chip->mask_base +
     680                 :          0 :                         (i * map->reg_stride * d->irq_reg_stride);
     681                 :          0 :                 if (chip->mask_invert)
     682                 :          0 :                         ret = regmap_irq_update_bits(d, reg,
     683                 :          0 :                                          d->mask_buf[i], ~d->mask_buf[i]);
     684                 :          0 :                 else if (d->chip->unmask_base) {
     685                 :          0 :                         unmask_offset = d->chip->unmask_base -
     686                 :          0 :                                         d->chip->mask_base;
     687                 :          0 :                         ret = regmap_irq_update_bits(d,
     688                 :            :                                         reg + unmask_offset,
     689                 :            :                                         d->mask_buf[i],
     690                 :          0 :                                         d->mask_buf[i]);
     691                 :            :                 } else
     692                 :          0 :                         ret = regmap_irq_update_bits(d, reg,
     693                 :          0 :                                          d->mask_buf[i], d->mask_buf[i]);
     694                 :          0 :                 if (ret != 0) {
     695                 :          0 :                         dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
     696                 :            :                                 reg, ret);
     697                 :          0 :                         goto err_alloc;
     698                 :            :                 }
     699                 :            : 
     700                 :          0 :                 if (!chip->init_ack_masked)
     701                 :          0 :                         continue;
     702                 :            : 
     703                 :            :                 /* Ack masked but set interrupts */
     704                 :          0 :                 reg = chip->status_base +
     705                 :          0 :                         (i * map->reg_stride * d->irq_reg_stride);
     706                 :          0 :                 ret = regmap_read(map, reg, &d->status_buf[i]);
     707                 :          0 :                 if (ret != 0) {
     708                 :          0 :                         dev_err(map->dev, "Failed to read IRQ status: %d\n",
     709                 :            :                                 ret);
     710                 :          0 :                         goto err_alloc;
     711                 :            :                 }
     712                 :            : 
     713                 :          0 :                 if (d->status_buf[i] && (chip->ack_base || chip->use_ack)) {
     714                 :          0 :                         reg = chip->ack_base +
     715                 :          0 :                                 (i * map->reg_stride * d->irq_reg_stride);
     716                 :          0 :                         if (chip->ack_invert)
     717                 :          0 :                                 ret = regmap_write(map, reg,
     718                 :          0 :                                         ~(d->status_buf[i] & d->mask_buf[i]));
     719                 :            :                         else
     720                 :          0 :                                 ret = regmap_write(map, reg,
     721                 :          0 :                                         d->status_buf[i] & d->mask_buf[i]);
     722                 :          0 :                         if (ret != 0) {
     723                 :          0 :                                 dev_err(map->dev, "Failed to ack 0x%x: %d\n",
     724                 :            :                                         reg, ret);
     725                 :          0 :                                 goto err_alloc;
     726                 :            :                         }
     727                 :            :                 }
     728                 :            :         }
     729                 :            : 
     730                 :            :         /* Wake is disabled by default */
     731                 :          0 :         if (d->wake_buf) {
     732                 :          0 :                 for (i = 0; i < chip->num_regs; i++) {
     733                 :          0 :                         d->wake_buf[i] = d->mask_buf_def[i];
     734                 :          0 :                         reg = chip->wake_base +
     735                 :          0 :                                 (i * map->reg_stride * d->irq_reg_stride);
     736                 :            : 
     737                 :          0 :                         if (chip->wake_invert)
     738                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     739                 :          0 :                                                          d->mask_buf_def[i],
     740                 :            :                                                          0);
     741                 :            :                         else
     742                 :          0 :                                 ret = regmap_irq_update_bits(d, reg,
     743                 :          0 :                                                          d->mask_buf_def[i],
     744                 :          0 :                                                          d->wake_buf[i]);
     745                 :          0 :                         if (ret != 0) {
     746                 :          0 :                                 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
     747                 :            :                                         reg, ret);
     748                 :          0 :                                 goto err_alloc;
     749                 :            :                         }
     750                 :            :                 }
     751                 :            :         }
     752                 :            : 
     753                 :          0 :         if (chip->num_type_reg && !chip->type_in_mask) {
     754                 :          0 :                 for (i = 0; i < chip->num_type_reg; ++i) {
     755                 :          0 :                         reg = chip->type_base +
     756                 :          0 :                                 (i * map->reg_stride * d->type_reg_stride);
     757                 :            : 
     758                 :          0 :                         ret = regmap_read(map, reg, &d->type_buf_def[i]);
     759                 :            : 
     760                 :          0 :                         if (d->chip->type_invert)
     761                 :          0 :                                 d->type_buf_def[i] = ~d->type_buf_def[i];
     762                 :            : 
     763                 :          0 :                         if (ret) {
     764                 :          0 :                                 dev_err(map->dev, "Failed to get type defaults at 0x%x: %d\n",
     765                 :            :                                         reg, ret);
     766                 :          0 :                                 goto err_alloc;
     767                 :            :                         }
     768                 :            :                 }
     769                 :            :         }
     770                 :            : 
     771                 :          0 :         if (irq_base)
     772                 :          0 :                 d->domain = irq_domain_add_legacy(map->dev->of_node,
     773                 :          0 :                                                   chip->num_irqs, irq_base, 0,
     774                 :            :                                                   &regmap_domain_ops, d);
     775                 :            :         else
     776                 :          0 :                 d->domain = irq_domain_add_linear(map->dev->of_node,
     777                 :          0 :                                                   chip->num_irqs,
     778                 :            :                                                   &regmap_domain_ops, d);
     779                 :          0 :         if (!d->domain) {
     780                 :          0 :                 dev_err(map->dev, "Failed to create IRQ domain\n");
     781                 :            :                 ret = -ENOMEM;
     782                 :          0 :                 goto err_alloc;
     783                 :            :         }
     784                 :            : 
     785                 :          0 :         ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
     786                 :          0 :                                    irq_flags | IRQF_ONESHOT,
     787                 :            :                                    chip->name, d);
     788                 :          0 :         if (ret != 0) {
     789                 :          0 :                 dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n",
     790                 :            :                         irq, chip->name, ret);
     791                 :          0 :                 goto err_domain;
     792                 :            :         }
     793                 :            : 
     794                 :          0 :         *data = d;
     795                 :            : 
     796                 :          0 :         return 0;
     797                 :            : 
     798                 :            : err_domain:
     799                 :            :         /* Should really dispose of the domain but... */
     800                 :            : err_alloc:
     801                 :          0 :         kfree(d->type_buf);
     802                 :          0 :         kfree(d->type_buf_def);
     803                 :          0 :         kfree(d->wake_buf);
     804                 :          0 :         kfree(d->mask_buf_def);
     805                 :          0 :         kfree(d->mask_buf);
     806                 :          0 :         kfree(d->status_buf);
     807                 :          0 :         kfree(d->status_reg_buf);
     808                 :          0 :         kfree(d);
     809                 :          0 :         return ret;
     810                 :            : }
     811                 :            : EXPORT_SYMBOL_GPL(regmap_add_irq_chip);
     812                 :            : 
     813                 :            : /**
     814                 :            :  * regmap_del_irq_chip() - Stop interrupt handling for a regmap IRQ chip
     815                 :            :  *
     816                 :            :  * @irq: Primary IRQ for the device
     817                 :            :  * @d: &regmap_irq_chip_data allocated by regmap_add_irq_chip()
     818                 :            :  *
     819                 :            :  * This function also disposes of all mapped IRQs on the chip.
     820                 :            :  */
     821                 :          0 : void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
     822                 :            : {
     823                 :            :         unsigned int virq;
     824                 :            :         int hwirq;
     825                 :            : 
     826                 :          0 :         if (!d)
     827                 :          0 :                 return;
     828                 :            : 
     829                 :          0 :         free_irq(irq, d);
     830                 :            : 
     831                 :            :         /* Dispose all virtual irq from irq domain before removing it */
     832                 :          0 :         for (hwirq = 0; hwirq < d->chip->num_irqs; hwirq++) {
     833                 :            :                 /* Ignore hwirq if holes in the IRQ list */
     834                 :          0 :                 if (!d->chip->irqs[hwirq].mask)
     835                 :          0 :                         continue;
     836                 :            : 
     837                 :            :                 /*
     838                 :            :                  * Find the virtual irq of hwirq on chip and if it is
     839                 :            :                  * there then dispose it
     840                 :            :                  */
     841                 :          0 :                 virq = irq_find_mapping(d->domain, hwirq);
     842                 :          0 :                 if (virq)
     843                 :          0 :                         irq_dispose_mapping(virq);
     844                 :            :         }
     845                 :            : 
     846                 :          0 :         irq_domain_remove(d->domain);
     847                 :          0 :         kfree(d->type_buf);
     848                 :          0 :         kfree(d->type_buf_def);
     849                 :          0 :         kfree(d->wake_buf);
     850                 :          0 :         kfree(d->mask_buf_def);
     851                 :          0 :         kfree(d->mask_buf);
     852                 :          0 :         kfree(d->status_reg_buf);
     853                 :          0 :         kfree(d->status_buf);
     854                 :          0 :         kfree(d);
     855                 :            : }
     856                 :            : EXPORT_SYMBOL_GPL(regmap_del_irq_chip);
     857                 :            : 
     858                 :          0 : static void devm_regmap_irq_chip_release(struct device *dev, void *res)
     859                 :            : {
     860                 :          0 :         struct regmap_irq_chip_data *d = *(struct regmap_irq_chip_data **)res;
     861                 :            : 
     862                 :          0 :         regmap_del_irq_chip(d->irq, d);
     863                 :          0 : }
     864                 :            : 
     865                 :          0 : static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
     866                 :            : 
     867                 :            : {
     868                 :            :         struct regmap_irq_chip_data **r = res;
     869                 :            : 
     870                 :          0 :         if (!r || !*r) {
     871                 :          0 :                 WARN_ON(!r || !*r);
     872                 :            :                 return 0;
     873                 :            :         }
     874                 :          0 :         return *r == data;
     875                 :            : }
     876                 :            : 
     877                 :            : /**
     878                 :            :  * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
     879                 :            :  *
     880                 :            :  * @dev: The device pointer on which irq_chip belongs to.
     881                 :            :  * @map: The regmap for the device.
     882                 :            :  * @irq: The IRQ the device uses to signal interrupts
     883                 :            :  * @irq_flags: The IRQF_ flags to use for the primary interrupt.
     884                 :            :  * @irq_base: Allocate at specific IRQ number if irq_base > 0.
     885                 :            :  * @chip: Configuration for the interrupt controller.
     886                 :            :  * @data: Runtime data structure for the controller, allocated on success
     887                 :            :  *
     888                 :            :  * Returns 0 on success or an errno on failure.
     889                 :            :  *
     890                 :            :  * The &regmap_irq_chip_data will be automatically released when the device is
     891                 :            :  * unbound.
     892                 :            :  */
     893                 :          0 : int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
     894                 :            :                              int irq_flags, int irq_base,
     895                 :            :                              const struct regmap_irq_chip *chip,
     896                 :            :                              struct regmap_irq_chip_data **data)
     897                 :            : {
     898                 :            :         struct regmap_irq_chip_data **ptr, *d;
     899                 :            :         int ret;
     900                 :            : 
     901                 :            :         ptr = devres_alloc(devm_regmap_irq_chip_release, sizeof(*ptr),
     902                 :            :                            GFP_KERNEL);
     903                 :          0 :         if (!ptr)
     904                 :            :                 return -ENOMEM;
     905                 :            : 
     906                 :          0 :         ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base,
     907                 :            :                                   chip, &d);
     908                 :          0 :         if (ret < 0) {
     909                 :          0 :                 devres_free(ptr);
     910                 :          0 :                 return ret;
     911                 :            :         }
     912                 :            : 
     913                 :          0 :         *ptr = d;
     914                 :          0 :         devres_add(dev, ptr);
     915                 :          0 :         *data = d;
     916                 :          0 :         return 0;
     917                 :            : }
     918                 :            : EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);
     919                 :            : 
     920                 :            : /**
     921                 :            :  * devm_regmap_del_irq_chip() - Resource managed regmap_del_irq_chip()
     922                 :            :  *
     923                 :            :  * @dev: Device for which which resource was allocated.
     924                 :            :  * @irq: Primary IRQ for the device.
     925                 :            :  * @data: &regmap_irq_chip_data allocated by regmap_add_irq_chip().
     926                 :            :  *
     927                 :            :  * A resource managed version of regmap_del_irq_chip().
     928                 :            :  */
     929                 :          0 : void devm_regmap_del_irq_chip(struct device *dev, int irq,
     930                 :            :                               struct regmap_irq_chip_data *data)
     931                 :            : {
     932                 :            :         int rc;
     933                 :            : 
     934                 :          0 :         WARN_ON(irq != data->irq);
     935                 :          0 :         rc = devres_release(dev, devm_regmap_irq_chip_release,
     936                 :            :                             devm_regmap_irq_chip_match, data);
     937                 :            : 
     938                 :          0 :         if (rc != 0)
     939                 :          0 :                 WARN_ON(rc);
     940                 :          0 : }
     941                 :            : EXPORT_SYMBOL_GPL(devm_regmap_del_irq_chip);
     942                 :            : 
     943                 :            : /**
     944                 :            :  * regmap_irq_chip_get_base() - Retrieve interrupt base for a regmap IRQ chip
     945                 :            :  *
     946                 :            :  * @data: regmap irq controller to operate on.
     947                 :            :  *
     948                 :            :  * Useful for drivers to request their own IRQs.
     949                 :            :  */
     950                 :          0 : int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data)
     951                 :            : {
     952                 :          0 :         WARN_ON(!data->irq_base);
     953                 :          0 :         return data->irq_base;
     954                 :            : }
     955                 :            : EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base);
     956                 :            : 
     957                 :            : /**
     958                 :            :  * regmap_irq_get_virq() - Map an interrupt on a chip to a virtual IRQ
     959                 :            :  *
     960                 :            :  * @data: regmap irq controller to operate on.
     961                 :            :  * @irq: index of the interrupt requested in the chip IRQs.
     962                 :            :  *
     963                 :            :  * Useful for drivers to request their own IRQs.
     964                 :            :  */
     965                 :          0 : int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq)
     966                 :            : {
     967                 :            :         /* Handle holes in the IRQ list */
     968                 :          0 :         if (!data->chip->irqs[irq].mask)
     969                 :            :                 return -EINVAL;
     970                 :            : 
     971                 :          0 :         return irq_create_mapping(data->domain, irq);
     972                 :            : }
     973                 :            : EXPORT_SYMBOL_GPL(regmap_irq_get_virq);
     974                 :            : 
     975                 :            : /**
     976                 :            :  * regmap_irq_get_domain() - Retrieve the irq_domain for the chip
     977                 :            :  *
     978                 :            :  * @data: regmap_irq controller to operate on.
     979                 :            :  *
     980                 :            :  * Useful for drivers to request their own IRQs and for integration
     981                 :            :  * with subsystems.  For ease of integration NULL is accepted as a
     982                 :            :  * domain, allowing devices to just call this even if no domain is
     983                 :            :  * allocated.
     984                 :            :  */
     985                 :          0 : struct irq_domain *regmap_irq_get_domain(struct regmap_irq_chip_data *data)
     986                 :            : {
     987                 :          0 :         if (data)
     988                 :          0 :                 return data->domain;
     989                 :            :         else
     990                 :            :                 return NULL;
     991                 :            : }
     992                 :            : EXPORT_SYMBOL_GPL(regmap_irq_get_domain);
    

Generated by: LCOV version 1.14