0001
0002
0003
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
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 }