root/drivers/mfd/wm8350-irq.c

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

DEFINITIONS

This source file includes following definitions.
  1. irq_to_wm8350_irq
  2. wm8350_irq
  3. wm8350_irq_lock
  4. wm8350_irq_sync_unlock
  5. wm8350_irq_enable
  6. wm8350_irq_disable
  7. wm8350_irq_init
  8. wm8350_irq_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * wm8350-irq.c  --  IRQ support for Wolfson WM8350
   4  *
   5  * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
   6  *
   7  * Author: Liam Girdwood, Mark Brown
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/bug.h>
  13 #include <linux/device.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/irq.h>
  16 
  17 #include <linux/mfd/wm8350/core.h>
  18 #include <linux/mfd/wm8350/audio.h>
  19 #include <linux/mfd/wm8350/comparator.h>
  20 #include <linux/mfd/wm8350/gpio.h>
  21 #include <linux/mfd/wm8350/pmic.h>
  22 #include <linux/mfd/wm8350/rtc.h>
  23 #include <linux/mfd/wm8350/supply.h>
  24 #include <linux/mfd/wm8350/wdt.h>
  25 
  26 #define WM8350_INT_OFFSET_1                     0
  27 #define WM8350_INT_OFFSET_2                     1
  28 #define WM8350_POWER_UP_INT_OFFSET              2
  29 #define WM8350_UNDER_VOLTAGE_INT_OFFSET         3
  30 #define WM8350_OVER_CURRENT_INT_OFFSET          4
  31 #define WM8350_GPIO_INT_OFFSET                  5
  32 #define WM8350_COMPARATOR_INT_OFFSET            6
  33 
  34 struct wm8350_irq_data {
  35         int primary;
  36         int reg;
  37         int mask;
  38         int primary_only;
  39 };
  40 
  41 static struct wm8350_irq_data wm8350_irqs[] = {
  42         [WM8350_IRQ_OC_LS] = {
  43                 .primary = WM8350_OC_INT,
  44                 .reg = WM8350_OVER_CURRENT_INT_OFFSET,
  45                 .mask = WM8350_OC_LS_EINT,
  46                 .primary_only = 1,
  47         },
  48         [WM8350_IRQ_UV_DC1] = {
  49                 .primary = WM8350_UV_INT,
  50                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  51                 .mask = WM8350_UV_DC1_EINT,
  52         },
  53         [WM8350_IRQ_UV_DC2] = {
  54                 .primary = WM8350_UV_INT,
  55                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  56                 .mask = WM8350_UV_DC2_EINT,
  57         },
  58         [WM8350_IRQ_UV_DC3] = {
  59                 .primary = WM8350_UV_INT,
  60                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  61                 .mask = WM8350_UV_DC3_EINT,
  62         },
  63         [WM8350_IRQ_UV_DC4] = {
  64                 .primary = WM8350_UV_INT,
  65                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  66                 .mask = WM8350_UV_DC4_EINT,
  67         },
  68         [WM8350_IRQ_UV_DC5] = {
  69                 .primary = WM8350_UV_INT,
  70                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  71                 .mask = WM8350_UV_DC5_EINT,
  72         },
  73         [WM8350_IRQ_UV_DC6] = {
  74                 .primary = WM8350_UV_INT,
  75                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  76                 .mask = WM8350_UV_DC6_EINT,
  77         },
  78         [WM8350_IRQ_UV_LDO1] = {
  79                 .primary = WM8350_UV_INT,
  80                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  81                 .mask = WM8350_UV_LDO1_EINT,
  82         },
  83         [WM8350_IRQ_UV_LDO2] = {
  84                 .primary = WM8350_UV_INT,
  85                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  86                 .mask = WM8350_UV_LDO2_EINT,
  87         },
  88         [WM8350_IRQ_UV_LDO3] = {
  89                 .primary = WM8350_UV_INT,
  90                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  91                 .mask = WM8350_UV_LDO3_EINT,
  92         },
  93         [WM8350_IRQ_UV_LDO4] = {
  94                 .primary = WM8350_UV_INT,
  95                 .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
  96                 .mask = WM8350_UV_LDO4_EINT,
  97         },
  98         [WM8350_IRQ_CHG_BAT_HOT] = {
  99                 .primary = WM8350_CHG_INT,
 100                 .reg = WM8350_INT_OFFSET_1,
 101                 .mask = WM8350_CHG_BAT_HOT_EINT,
 102         },
 103         [WM8350_IRQ_CHG_BAT_COLD] = {
 104                 .primary = WM8350_CHG_INT,
 105                 .reg = WM8350_INT_OFFSET_1,
 106                 .mask = WM8350_CHG_BAT_COLD_EINT,
 107         },
 108         [WM8350_IRQ_CHG_BAT_FAIL] = {
 109                 .primary = WM8350_CHG_INT,
 110                 .reg = WM8350_INT_OFFSET_1,
 111                 .mask = WM8350_CHG_BAT_FAIL_EINT,
 112         },
 113         [WM8350_IRQ_CHG_TO] = {
 114                 .primary = WM8350_CHG_INT,
 115                 .reg = WM8350_INT_OFFSET_1,
 116                 .mask = WM8350_CHG_TO_EINT,
 117         },
 118         [WM8350_IRQ_CHG_END] = {
 119                 .primary = WM8350_CHG_INT,
 120                 .reg = WM8350_INT_OFFSET_1,
 121                 .mask = WM8350_CHG_END_EINT,
 122         },
 123         [WM8350_IRQ_CHG_START] = {
 124                 .primary = WM8350_CHG_INT,
 125                 .reg = WM8350_INT_OFFSET_1,
 126                 .mask = WM8350_CHG_START_EINT,
 127         },
 128         [WM8350_IRQ_CHG_FAST_RDY] = {
 129                 .primary = WM8350_CHG_INT,
 130                 .reg = WM8350_INT_OFFSET_1,
 131                 .mask = WM8350_CHG_FAST_RDY_EINT,
 132         },
 133         [WM8350_IRQ_CHG_VBATT_LT_3P9] = {
 134                 .primary = WM8350_CHG_INT,
 135                 .reg = WM8350_INT_OFFSET_1,
 136                 .mask = WM8350_CHG_VBATT_LT_3P9_EINT,
 137         },
 138         [WM8350_IRQ_CHG_VBATT_LT_3P1] = {
 139                 .primary = WM8350_CHG_INT,
 140                 .reg = WM8350_INT_OFFSET_1,
 141                 .mask = WM8350_CHG_VBATT_LT_3P1_EINT,
 142         },
 143         [WM8350_IRQ_CHG_VBATT_LT_2P85] = {
 144                 .primary = WM8350_CHG_INT,
 145                 .reg = WM8350_INT_OFFSET_1,
 146                 .mask = WM8350_CHG_VBATT_LT_2P85_EINT,
 147         },
 148         [WM8350_IRQ_RTC_ALM] = {
 149                 .primary = WM8350_RTC_INT,
 150                 .reg = WM8350_INT_OFFSET_1,
 151                 .mask = WM8350_RTC_ALM_EINT,
 152         },
 153         [WM8350_IRQ_RTC_SEC] = {
 154                 .primary = WM8350_RTC_INT,
 155                 .reg = WM8350_INT_OFFSET_1,
 156                 .mask = WM8350_RTC_SEC_EINT,
 157         },
 158         [WM8350_IRQ_RTC_PER] = {
 159                 .primary = WM8350_RTC_INT,
 160                 .reg = WM8350_INT_OFFSET_1,
 161                 .mask = WM8350_RTC_PER_EINT,
 162         },
 163         [WM8350_IRQ_CS1] = {
 164                 .primary = WM8350_CS_INT,
 165                 .reg = WM8350_INT_OFFSET_2,
 166                 .mask = WM8350_CS1_EINT,
 167         },
 168         [WM8350_IRQ_CS2] = {
 169                 .primary = WM8350_CS_INT,
 170                 .reg = WM8350_INT_OFFSET_2,
 171                 .mask = WM8350_CS2_EINT,
 172         },
 173         [WM8350_IRQ_SYS_HYST_COMP_FAIL] = {
 174                 .primary = WM8350_SYS_INT,
 175                 .reg = WM8350_INT_OFFSET_2,
 176                 .mask = WM8350_SYS_HYST_COMP_FAIL_EINT,
 177         },
 178         [WM8350_IRQ_SYS_CHIP_GT115] = {
 179                 .primary = WM8350_SYS_INT,
 180                 .reg = WM8350_INT_OFFSET_2,
 181                 .mask = WM8350_SYS_CHIP_GT115_EINT,
 182         },
 183         [WM8350_IRQ_SYS_CHIP_GT140] = {
 184                 .primary = WM8350_SYS_INT,
 185                 .reg = WM8350_INT_OFFSET_2,
 186                 .mask = WM8350_SYS_CHIP_GT140_EINT,
 187         },
 188         [WM8350_IRQ_SYS_WDOG_TO] = {
 189                 .primary = WM8350_SYS_INT,
 190                 .reg = WM8350_INT_OFFSET_2,
 191                 .mask = WM8350_SYS_WDOG_TO_EINT,
 192         },
 193         [WM8350_IRQ_AUXADC_DATARDY] = {
 194                 .primary = WM8350_AUXADC_INT,
 195                 .reg = WM8350_INT_OFFSET_2,
 196                 .mask = WM8350_AUXADC_DATARDY_EINT,
 197         },
 198         [WM8350_IRQ_AUXADC_DCOMP4] = {
 199                 .primary = WM8350_AUXADC_INT,
 200                 .reg = WM8350_INT_OFFSET_2,
 201                 .mask = WM8350_AUXADC_DCOMP4_EINT,
 202         },
 203         [WM8350_IRQ_AUXADC_DCOMP3] = {
 204                 .primary = WM8350_AUXADC_INT,
 205                 .reg = WM8350_INT_OFFSET_2,
 206                 .mask = WM8350_AUXADC_DCOMP3_EINT,
 207         },
 208         [WM8350_IRQ_AUXADC_DCOMP2] = {
 209                 .primary = WM8350_AUXADC_INT,
 210                 .reg = WM8350_INT_OFFSET_2,
 211                 .mask = WM8350_AUXADC_DCOMP2_EINT,
 212         },
 213         [WM8350_IRQ_AUXADC_DCOMP1] = {
 214                 .primary = WM8350_AUXADC_INT,
 215                 .reg = WM8350_INT_OFFSET_2,
 216                 .mask = WM8350_AUXADC_DCOMP1_EINT,
 217         },
 218         [WM8350_IRQ_USB_LIMIT] = {
 219                 .primary = WM8350_USB_INT,
 220                 .reg = WM8350_INT_OFFSET_2,
 221                 .mask = WM8350_USB_LIMIT_EINT,
 222                 .primary_only = 1,
 223         },
 224         [WM8350_IRQ_WKUP_OFF_STATE] = {
 225                 .primary = WM8350_WKUP_INT,
 226                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 227                 .mask = WM8350_WKUP_OFF_STATE_EINT,
 228         },
 229         [WM8350_IRQ_WKUP_HIB_STATE] = {
 230                 .primary = WM8350_WKUP_INT,
 231                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 232                 .mask = WM8350_WKUP_HIB_STATE_EINT,
 233         },
 234         [WM8350_IRQ_WKUP_CONV_FAULT] = {
 235                 .primary = WM8350_WKUP_INT,
 236                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 237                 .mask = WM8350_WKUP_CONV_FAULT_EINT,
 238         },
 239         [WM8350_IRQ_WKUP_WDOG_RST] = {
 240                 .primary = WM8350_WKUP_INT,
 241                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 242                 .mask = WM8350_WKUP_WDOG_RST_EINT,
 243         },
 244         [WM8350_IRQ_WKUP_GP_PWR_ON] = {
 245                 .primary = WM8350_WKUP_INT,
 246                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 247                 .mask = WM8350_WKUP_GP_PWR_ON_EINT,
 248         },
 249         [WM8350_IRQ_WKUP_ONKEY] = {
 250                 .primary = WM8350_WKUP_INT,
 251                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 252                 .mask = WM8350_WKUP_ONKEY_EINT,
 253         },
 254         [WM8350_IRQ_WKUP_GP_WAKEUP] = {
 255                 .primary = WM8350_WKUP_INT,
 256                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 257                 .mask = WM8350_WKUP_GP_WAKEUP_EINT,
 258         },
 259         [WM8350_IRQ_CODEC_JCK_DET_L] = {
 260                 .primary = WM8350_CODEC_INT,
 261                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 262                 .mask = WM8350_CODEC_JCK_DET_L_EINT,
 263         },
 264         [WM8350_IRQ_CODEC_JCK_DET_R] = {
 265                 .primary = WM8350_CODEC_INT,
 266                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 267                 .mask = WM8350_CODEC_JCK_DET_R_EINT,
 268         },
 269         [WM8350_IRQ_CODEC_MICSCD] = {
 270                 .primary = WM8350_CODEC_INT,
 271                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 272                 .mask = WM8350_CODEC_MICSCD_EINT,
 273         },
 274         [WM8350_IRQ_CODEC_MICD] = {
 275                 .primary = WM8350_CODEC_INT,
 276                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 277                 .mask = WM8350_CODEC_MICD_EINT,
 278         },
 279         [WM8350_IRQ_EXT_USB_FB] = {
 280                 .primary = WM8350_EXT_INT,
 281                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 282                 .mask = WM8350_EXT_USB_FB_EINT,
 283         },
 284         [WM8350_IRQ_EXT_WALL_FB] = {
 285                 .primary = WM8350_EXT_INT,
 286                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 287                 .mask = WM8350_EXT_WALL_FB_EINT,
 288         },
 289         [WM8350_IRQ_EXT_BAT_FB] = {
 290                 .primary = WM8350_EXT_INT,
 291                 .reg = WM8350_COMPARATOR_INT_OFFSET,
 292                 .mask = WM8350_EXT_BAT_FB_EINT,
 293         },
 294         [WM8350_IRQ_GPIO(0)] = {
 295                 .primary = WM8350_GP_INT,
 296                 .reg = WM8350_GPIO_INT_OFFSET,
 297                 .mask = WM8350_GP0_EINT,
 298         },
 299         [WM8350_IRQ_GPIO(1)] = {
 300                 .primary = WM8350_GP_INT,
 301                 .reg = WM8350_GPIO_INT_OFFSET,
 302                 .mask = WM8350_GP1_EINT,
 303         },
 304         [WM8350_IRQ_GPIO(2)] = {
 305                 .primary = WM8350_GP_INT,
 306                 .reg = WM8350_GPIO_INT_OFFSET,
 307                 .mask = WM8350_GP2_EINT,
 308         },
 309         [WM8350_IRQ_GPIO(3)] = {
 310                 .primary = WM8350_GP_INT,
 311                 .reg = WM8350_GPIO_INT_OFFSET,
 312                 .mask = WM8350_GP3_EINT,
 313         },
 314         [WM8350_IRQ_GPIO(4)] = {
 315                 .primary = WM8350_GP_INT,
 316                 .reg = WM8350_GPIO_INT_OFFSET,
 317                 .mask = WM8350_GP4_EINT,
 318         },
 319         [WM8350_IRQ_GPIO(5)] = {
 320                 .primary = WM8350_GP_INT,
 321                 .reg = WM8350_GPIO_INT_OFFSET,
 322                 .mask = WM8350_GP5_EINT,
 323         },
 324         [WM8350_IRQ_GPIO(6)] = {
 325                 .primary = WM8350_GP_INT,
 326                 .reg = WM8350_GPIO_INT_OFFSET,
 327                 .mask = WM8350_GP6_EINT,
 328         },
 329         [WM8350_IRQ_GPIO(7)] = {
 330                 .primary = WM8350_GP_INT,
 331                 .reg = WM8350_GPIO_INT_OFFSET,
 332                 .mask = WM8350_GP7_EINT,
 333         },
 334         [WM8350_IRQ_GPIO(8)] = {
 335                 .primary = WM8350_GP_INT,
 336                 .reg = WM8350_GPIO_INT_OFFSET,
 337                 .mask = WM8350_GP8_EINT,
 338         },
 339         [WM8350_IRQ_GPIO(9)] = {
 340                 .primary = WM8350_GP_INT,
 341                 .reg = WM8350_GPIO_INT_OFFSET,
 342                 .mask = WM8350_GP9_EINT,
 343         },
 344         [WM8350_IRQ_GPIO(10)] = {
 345                 .primary = WM8350_GP_INT,
 346                 .reg = WM8350_GPIO_INT_OFFSET,
 347                 .mask = WM8350_GP10_EINT,
 348         },
 349         [WM8350_IRQ_GPIO(11)] = {
 350                 .primary = WM8350_GP_INT,
 351                 .reg = WM8350_GPIO_INT_OFFSET,
 352                 .mask = WM8350_GP11_EINT,
 353         },
 354         [WM8350_IRQ_GPIO(12)] = {
 355                 .primary = WM8350_GP_INT,
 356                 .reg = WM8350_GPIO_INT_OFFSET,
 357                 .mask = WM8350_GP12_EINT,
 358         },
 359 };
 360 
 361 static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
 362                                                         int irq)
 363 {
 364         return &wm8350_irqs[irq - wm8350->irq_base];
 365 }
 366 
 367 /*
 368  * This is a threaded IRQ handler so can access I2C/SPI.  Since all
 369  * interrupts are clear on read the IRQ line will be reasserted and
 370  * the physical IRQ will be handled again if another interrupt is
 371  * asserted while we run - in the normal course of events this is a
 372  * rare occurrence so we save I2C/SPI reads.  We're also assuming that
 373  * it's rare to get lots of interrupts firing simultaneously so try to
 374  * minimise I/O.
 375  */
 376 static irqreturn_t wm8350_irq(int irq, void *irq_data)
 377 {
 378         struct wm8350 *wm8350 = irq_data;
 379         u16 level_one;
 380         u16 sub_reg[WM8350_NUM_IRQ_REGS];
 381         int read_done[WM8350_NUM_IRQ_REGS];
 382         struct wm8350_irq_data *data;
 383         int i;
 384 
 385         level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
 386                 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
 387 
 388         if (!level_one)
 389                 return IRQ_NONE;
 390 
 391         memset(&read_done, 0, sizeof(read_done));
 392 
 393         for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) {
 394                 data = &wm8350_irqs[i];
 395 
 396                 if (!(level_one & data->primary))
 397                         continue;
 398 
 399                 if (!read_done[data->reg]) {
 400                         sub_reg[data->reg] =
 401                                 wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
 402                                                 data->reg);
 403                         sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
 404                         read_done[data->reg] = 1;
 405                 }
 406 
 407                 if (sub_reg[data->reg] & data->mask)
 408                         handle_nested_irq(wm8350->irq_base + i);
 409         }
 410 
 411         return IRQ_HANDLED;
 412 }
 413 
 414 static void wm8350_irq_lock(struct irq_data *data)
 415 {
 416         struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
 417 
 418         mutex_lock(&wm8350->irq_lock);
 419 }
 420 
 421 static void wm8350_irq_sync_unlock(struct irq_data *data)
 422 {
 423         struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
 424         int i;
 425 
 426         for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
 427                 /* If there's been a change in the mask write it back
 428                  * to the hardware. */
 429                 WARN_ON(regmap_update_bits(wm8350->regmap,
 430                                            WM8350_INT_STATUS_1_MASK + i,
 431                                            0xffff, wm8350->irq_masks[i]));
 432         }
 433 
 434         mutex_unlock(&wm8350->irq_lock);
 435 }
 436 
 437 static void wm8350_irq_enable(struct irq_data *data)
 438 {
 439         struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
 440         struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
 441                                                              data->irq);
 442 
 443         wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
 444 }
 445 
 446 static void wm8350_irq_disable(struct irq_data *data)
 447 {
 448         struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
 449         struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
 450                                                              data->irq);
 451 
 452         wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
 453 }
 454 
 455 static struct irq_chip wm8350_irq_chip = {
 456         .name                   = "wm8350",
 457         .irq_bus_lock           = wm8350_irq_lock,
 458         .irq_bus_sync_unlock    = wm8350_irq_sync_unlock,
 459         .irq_disable            = wm8350_irq_disable,
 460         .irq_enable             = wm8350_irq_enable,
 461 };
 462 
 463 int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 464                     struct wm8350_platform_data *pdata)
 465 {
 466         int ret, cur_irq, i;
 467         int flags = IRQF_ONESHOT;
 468         int irq_base = -1;
 469 
 470         if (!irq) {
 471                 dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
 472                 return 0;
 473         }
 474 
 475         /* Mask top level interrupts */
 476         wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
 477 
 478         /* Mask all individual interrupts by default and cache the
 479          * masks.  We read the masks back since there are unwritable
 480          * bits in the mask registers. */
 481         for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
 482                 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
 483                                  0xFFFF);
 484                 wm8350->irq_masks[i] =
 485                         wm8350_reg_read(wm8350,
 486                                         WM8350_INT_STATUS_1_MASK + i);
 487         }
 488 
 489         mutex_init(&wm8350->irq_lock);
 490         wm8350->chip_irq = irq;
 491 
 492         if (pdata && pdata->irq_base > 0)
 493                 irq_base = pdata->irq_base;
 494 
 495         wm8350->irq_base =
 496                 irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
 497         if (wm8350->irq_base < 0) {
 498                 dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
 499                         wm8350->irq_base);
 500                 return 0;
 501         }
 502 
 503         if (pdata && pdata->irq_high) {
 504                 flags |= IRQF_TRIGGER_HIGH;
 505 
 506                 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
 507                                 WM8350_IRQ_POL);
 508         } else {
 509                 flags |= IRQF_TRIGGER_LOW;
 510 
 511                 wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
 512                                   WM8350_IRQ_POL);
 513         }
 514 
 515         /* Register with genirq */
 516         for (cur_irq = wm8350->irq_base;
 517              cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
 518              cur_irq++) {
 519                 irq_set_chip_data(cur_irq, wm8350);
 520                 irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip,
 521                                          handle_edge_irq);
 522                 irq_set_nested_thread(cur_irq, 1);
 523 
 524                 irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
 525         }
 526 
 527         ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
 528                                    "wm8350", wm8350);
 529         if (ret != 0)
 530                 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
 531 
 532         /* Allow interrupts to fire */
 533         wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
 534 
 535         return ret;
 536 }
 537 
 538 int wm8350_irq_exit(struct wm8350 *wm8350)
 539 {
 540         free_irq(wm8350->chip_irq, wm8350);
 541         return 0;
 542 }

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