Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2019 MediaTek Inc.
0004 
0005 #include <linux/interrupt.h>
0006 #include <linux/module.h>
0007 #include <linux/of.h>
0008 #include <linux/of_device.h>
0009 #include <linux/of_irq.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/regmap.h>
0012 #include <linux/suspend.h>
0013 #include <linux/mfd/mt6323/core.h>
0014 #include <linux/mfd/mt6323/registers.h>
0015 #include <linux/mfd/mt6331/core.h>
0016 #include <linux/mfd/mt6331/registers.h>
0017 #include <linux/mfd/mt6397/core.h>
0018 #include <linux/mfd/mt6397/registers.h>
0019 
0020 static void mt6397_irq_lock(struct irq_data *data)
0021 {
0022     struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
0023 
0024     mutex_lock(&mt6397->irqlock);
0025 }
0026 
0027 static void mt6397_irq_sync_unlock(struct irq_data *data)
0028 {
0029     struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
0030 
0031     regmap_write(mt6397->regmap, mt6397->int_con[0],
0032              mt6397->irq_masks_cur[0]);
0033     regmap_write(mt6397->regmap, mt6397->int_con[1],
0034              mt6397->irq_masks_cur[1]);
0035 
0036     mutex_unlock(&mt6397->irqlock);
0037 }
0038 
0039 static void mt6397_irq_disable(struct irq_data *data)
0040 {
0041     struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
0042     int shift = data->hwirq & 0xf;
0043     int reg = data->hwirq >> 4;
0044 
0045     mt6397->irq_masks_cur[reg] &= ~BIT(shift);
0046 }
0047 
0048 static void mt6397_irq_enable(struct irq_data *data)
0049 {
0050     struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
0051     int shift = data->hwirq & 0xf;
0052     int reg = data->hwirq >> 4;
0053 
0054     mt6397->irq_masks_cur[reg] |= BIT(shift);
0055 }
0056 
0057 #ifdef CONFIG_PM_SLEEP
0058 static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
0059 {
0060     struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
0061     int shift = irq_data->hwirq & 0xf;
0062     int reg = irq_data->hwirq >> 4;
0063 
0064     if (on)
0065         mt6397->wake_mask[reg] |= BIT(shift);
0066     else
0067         mt6397->wake_mask[reg] &= ~BIT(shift);
0068 
0069     return 0;
0070 }
0071 #else
0072 #define mt6397_irq_set_wake NULL
0073 #endif
0074 
0075 static struct irq_chip mt6397_irq_chip = {
0076     .name = "mt6397-irq",
0077     .irq_bus_lock = mt6397_irq_lock,
0078     .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
0079     .irq_enable = mt6397_irq_enable,
0080     .irq_disable = mt6397_irq_disable,
0081     .irq_set_wake = mt6397_irq_set_wake,
0082 };
0083 
0084 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
0085                   int irqbase)
0086 {
0087     unsigned int status = 0;
0088     int i, irq, ret;
0089 
0090     ret = regmap_read(mt6397->regmap, reg, &status);
0091     if (ret) {
0092         dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
0093         return;
0094     }
0095 
0096     for (i = 0; i < 16; i++) {
0097         if (status & BIT(i)) {
0098             irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
0099             if (irq)
0100                 handle_nested_irq(irq);
0101         }
0102     }
0103 
0104     regmap_write(mt6397->regmap, reg, status);
0105 }
0106 
0107 static irqreturn_t mt6397_irq_thread(int irq, void *data)
0108 {
0109     struct mt6397_chip *mt6397 = data;
0110 
0111     mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
0112     mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
0113 
0114     return IRQ_HANDLED;
0115 }
0116 
0117 static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
0118                  irq_hw_number_t hw)
0119 {
0120     struct mt6397_chip *mt6397 = d->host_data;
0121 
0122     irq_set_chip_data(irq, mt6397);
0123     irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
0124     irq_set_nested_thread(irq, 1);
0125     irq_set_noprobe(irq);
0126 
0127     return 0;
0128 }
0129 
0130 static const struct irq_domain_ops mt6397_irq_domain_ops = {
0131     .map = mt6397_irq_domain_map,
0132 };
0133 
0134 static int mt6397_irq_pm_notifier(struct notifier_block *notifier,
0135                   unsigned long pm_event, void *unused)
0136 {
0137     struct mt6397_chip *chip =
0138         container_of(notifier, struct mt6397_chip, pm_nb);
0139 
0140     switch (pm_event) {
0141     case PM_SUSPEND_PREPARE:
0142         regmap_write(chip->regmap,
0143                  chip->int_con[0], chip->wake_mask[0]);
0144         regmap_write(chip->regmap,
0145                  chip->int_con[1], chip->wake_mask[1]);
0146         enable_irq_wake(chip->irq);
0147         break;
0148 
0149     case PM_POST_SUSPEND:
0150         regmap_write(chip->regmap,
0151                  chip->int_con[0], chip->irq_masks_cur[0]);
0152         regmap_write(chip->regmap,
0153                  chip->int_con[1], chip->irq_masks_cur[1]);
0154         disable_irq_wake(chip->irq);
0155         break;
0156 
0157     default:
0158         break;
0159     }
0160 
0161     return NOTIFY_DONE;
0162 }
0163 
0164 int mt6397_irq_init(struct mt6397_chip *chip)
0165 {
0166     int ret;
0167 
0168     mutex_init(&chip->irqlock);
0169 
0170     switch (chip->chip_id) {
0171     case MT6323_CHIP_ID:
0172         chip->int_con[0] = MT6323_INT_CON0;
0173         chip->int_con[1] = MT6323_INT_CON1;
0174         chip->int_status[0] = MT6323_INT_STATUS0;
0175         chip->int_status[1] = MT6323_INT_STATUS1;
0176         break;
0177     case MT6331_CHIP_ID:
0178         chip->int_con[0] = MT6331_INT_CON0;
0179         chip->int_con[1] = MT6331_INT_CON1;
0180         chip->int_status[0] = MT6331_INT_STATUS_CON0;
0181         chip->int_status[1] = MT6331_INT_STATUS_CON1;
0182         break;
0183     case MT6391_CHIP_ID:
0184     case MT6397_CHIP_ID:
0185         chip->int_con[0] = MT6397_INT_CON0;
0186         chip->int_con[1] = MT6397_INT_CON1;
0187         chip->int_status[0] = MT6397_INT_STATUS0;
0188         chip->int_status[1] = MT6397_INT_STATUS1;
0189         break;
0190 
0191     default:
0192         dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
0193         return -ENODEV;
0194     }
0195 
0196     /* Mask all interrupt sources */
0197     regmap_write(chip->regmap, chip->int_con[0], 0x0);
0198     regmap_write(chip->regmap, chip->int_con[1], 0x0);
0199 
0200     chip->pm_nb.notifier_call = mt6397_irq_pm_notifier;
0201     chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
0202                          MT6397_IRQ_NR,
0203                          &mt6397_irq_domain_ops,
0204                          chip);
0205     if (!chip->irq_domain) {
0206         dev_err(chip->dev, "could not create irq domain\n");
0207         return -ENOMEM;
0208     }
0209 
0210     ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
0211                     mt6397_irq_thread, IRQF_ONESHOT,
0212                     "mt6397-pmic", chip);
0213     if (ret) {
0214         dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
0215             chip->irq, ret);
0216         return ret;
0217     }
0218 
0219     register_pm_notifier(&chip->pm_nb);
0220     return 0;
0221 }