12c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim/* 22c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * Interrupt controller support for MAX8998 32c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * 42c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * Copyright (C) 2010 Samsung Electronics Co.Ltd 52c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * Author: Joonyoung Shim <jy0922.shim@samsung.com> 62c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * 72c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * This program is free software; you can redistribute it and/or modify it 82c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * under the terms of the GNU General Public License as published by the 92c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * Free Software Foundation; either version 2 of the License, or (at your 102c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * option) any later version. 112c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * 122c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim */ 132c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 142c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#include <linux/device.h> 152c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#include <linux/interrupt.h> 162c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#include <linux/irq.h> 172c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#include <linux/mfd/max8998-private.h> 182c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 192c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimstruct max8998_irq_data { 202c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int reg; 212c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int mask; 222c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim}; 232c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 242c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimstatic struct max8998_irq_data max8998_irqs[] = { 252c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_DCINF] = { 262c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 272c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_DCINF_MASK, 282c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 292c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_DCINR] = { 302c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 312c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_DCINR_MASK, 322c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 332c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_JIGF] = { 342c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 352c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_JIGF_MASK, 362c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 372c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_JIGR] = { 382c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 392c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_JIGR_MASK, 402c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 412c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_PWRONF] = { 422c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 432c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_PWRONF_MASK, 442c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 452c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_PWRONR] = { 462c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 1, 472c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_PWRONR_MASK, 482c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 492c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_WTSREVNT] = { 502c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 2, 512c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_WTSREVNT_MASK, 522c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 532c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_SMPLEVNT] = { 542c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 2, 552c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_SMPLEVNT_MASK, 562c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 572c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_ALARM1] = { 582c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 2, 592c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_ALARM1_MASK, 602c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 612c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_ALARM0] = { 622c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 2, 632c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_ALARM0_MASK, 642c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 652c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_ONKEY1S] = { 662c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 672c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_ONKEY1S_MASK, 682c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 692c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_TOPOFFR] = { 702c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 712c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_TOPOFFR_MASK, 722c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 732c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_DCINOVPR] = { 742c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 752c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_DCINOVPR_MASK, 762c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 772c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_CHGRSTF] = { 782c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 792c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_CHGRSTF_MASK, 802c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 812c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_DONER] = { 822c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 832c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_DONER_MASK, 842c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 852c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_CHGFAULT] = { 862c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 3, 872c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_CHGFAULT_MASK, 882c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 892c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_LOBAT1] = { 902c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 4, 912c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_LOBAT1_MASK, 922c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 932c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim [MAX8998_IRQ_LOBAT2] = { 942c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .reg = 4, 952c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .mask = MAX8998_IRQ_LOBAT2_MASK, 962c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim }, 972c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim}; 982c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 992c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimstatic inline struct max8998_irq_data * 1002c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimirq_to_max8998_irq(struct max8998_dev *max8998, int irq) 1012c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1022c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return &max8998_irqs[irq - max8998->irq_base]; 1032c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1042c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1052898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brownstatic void max8998_irq_lock(struct irq_data *data) 1062c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1072898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); 1082c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1092c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim mutex_lock(&max8998->irqlock); 1102c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1112c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1122898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brownstatic void max8998_irq_sync_unlock(struct irq_data *data) 1132c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1142898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); 1152c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int i; 1162c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1172c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { 1182c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim /* 1192c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * If there's been a change in the mask write it back 1202c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim * to the hardware. 1212c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim */ 1222c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (max8998->irq_masks_cur[i] != max8998->irq_masks_cache[i]) { 1232c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cache[i] = max8998->irq_masks_cur[i]; 1242c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 1252c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cur[i]); 1262c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 1272c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 1282c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1292c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim mutex_unlock(&max8998->irqlock); 1302c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1312c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1322898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brownstatic void max8998_irq_unmask(struct irq_data *data) 1332c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1342898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); 1352898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, 1362898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown data->irq); 1372c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1382c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 1392c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1402c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1412898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brownstatic void max8998_irq_mask(struct irq_data *data) 1422c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1432898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); 1442898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, 1452898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown data->irq); 1462c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1472c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 1482c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1492c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1502c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimstatic struct irq_chip max8998_irq_chip = { 1512c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim .name = "max8998", 1522898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown .irq_bus_lock = max8998_irq_lock, 1532898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown .irq_bus_sync_unlock = max8998_irq_sync_unlock, 1542898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown .irq_mask = max8998_irq_mask, 1552898577e160c7d60d2b11cb3b1c3b55d0e1468dbMark Brown .irq_unmask = max8998_irq_unmask, 1562c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim}; 1572c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1582c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimstatic irqreturn_t max8998_irq_thread(int irq, void *data) 1592c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1602c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim struct max8998_dev *max8998 = data; 1612c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim u8 irq_reg[MAX8998_NUM_IRQ_REGS]; 1622c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int ret; 1632c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int i; 1642c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1652c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim ret = max8998_bulk_read(max8998->i2c, MAX8998_REG_IRQ1, 1662c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim MAX8998_NUM_IRQ_REGS, irq_reg); 1672c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (ret < 0) { 1682c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim dev_err(max8998->dev, "Failed to read interrupt register: %d\n", 1692c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim ret); 1702c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return IRQ_NONE; 1712c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 1722c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1732c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim /* Apply masking */ 1742c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) 1752c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim irq_reg[i] &= ~max8998->irq_masks_cur[i]; 1762c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1772c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim /* Report */ 1782c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim for (i = 0; i < MAX8998_IRQ_NR; i++) { 1792c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) 1802c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim handle_nested_irq(max8998->irq_base + i); 1812c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 1822c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1832c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return IRQ_HANDLED; 1842c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 1852c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 186cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Hamint max8998_irq_resume(struct max8998_dev *max8998) 187cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham{ 188cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham if (max8998->irq && max8998->irq_base) 189cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham max8998_irq_thread(max8998->irq_base, max8998); 190cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham return 0; 191cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham} 192cdd137c9c86c201ddb7f42ec978d2da45e7b7a17MyungJoo Ham 1932c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimint max8998_irq_init(struct max8998_dev *max8998) 1942c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 1952c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int i; 1962c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int cur_irq; 1972c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim int ret; 1982c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 1992c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (!max8998->irq) { 2002c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim dev_warn(max8998->dev, 2012c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim "No interrupt specified, no interrupts\n"); 2022c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_base = 0; 2032c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return 0; 2042c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 2052c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2062c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (!max8998->irq_base) { 2072c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim dev_err(max8998->dev, 2082c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim "No interrupt base specified, no interrupts\n"); 2092c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return 0; 2102c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 2112c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2122c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim mutex_init(&max8998->irqlock); 2132c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2142c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim /* Mask the individual interrupt sources */ 2152c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) { 2162c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cur[i] = 0xff; 2172c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq_masks_cache[i] = 0xff; 2182c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 0xff); 2192c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 2202c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2212c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff); 2222c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff); 2232c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2242c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim /* register with genirq */ 2252c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim for (i = 0; i < MAX8998_IRQ_NR; i++) { 2262c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim cur_irq = i + max8998->irq_base; 227d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner irq_set_chip_data(cur_irq, max8998); 228d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, 2292c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim handle_edge_irq); 230d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner irq_set_nested_thread(cur_irq, 1); 2312c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#ifdef CONFIG_ARM 2322c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim set_irq_flags(cur_irq, IRQF_VALID); 2332c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#else 234d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner irq_set_noprobe(cur_irq); 2352c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim#endif 2362c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 2372c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2382c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread, 2392c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2402c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim "max8998-irq", max8998); 2412c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (ret) { 2422c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim dev_err(max8998->dev, "Failed to request IRQ %d: %d\n", 2432c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->irq, ret); 2442c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return ret; 2452c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim } 2462c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2472c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (!max8998->ono) 2482c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return 0; 2492c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2502c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim ret = request_threaded_irq(max8998->ono, NULL, max8998_irq_thread, 2512c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | 2522c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim IRQF_ONESHOT, "max8998-ono", max8998); 2532c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (ret) 2542c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim dev_err(max8998->dev, "Failed to request IRQ %d: %d\n", 2552c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim max8998->ono, ret); 2562c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2572c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim return 0; 2582c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 2592c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim 2602c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shimvoid max8998_irq_exit(struct max8998_dev *max8998) 2612c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim{ 2621558b51eb7c813b3d90bdd68057403f7cac191faAxel Lin if (max8998->ono) 2631558b51eb7c813b3d90bdd68057403f7cac191faAxel Lin free_irq(max8998->ono, max8998); 2641558b51eb7c813b3d90bdd68057403f7cac191faAxel Lin 2652c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim if (max8998->irq) 2662c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim free_irq(max8998->irq, max8998); 2672c7e6f5797140b33ec2b967ff28941e1c7eff4b2Joonyoung Shim} 268