0001
0002
0003
0004
0005 #include <linux/interrupt.h>
0006 #include <linux/mfd/mt6357/core.h>
0007 #include <linux/mfd/mt6357/registers.h>
0008 #include <linux/mfd/mt6358/core.h>
0009 #include <linux/mfd/mt6358/registers.h>
0010 #include <linux/mfd/mt6359/core.h>
0011 #include <linux/mfd/mt6359/registers.h>
0012 #include <linux/mfd/mt6397/core.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_device.h>
0016 #include <linux/of_irq.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regmap.h>
0019
0020 #define MTK_PMIC_REG_WIDTH 16
0021
0022 static const struct irq_top_t mt6357_ints[] = {
0023 MT6357_TOP_GEN(BUCK),
0024 MT6357_TOP_GEN(LDO),
0025 MT6357_TOP_GEN(PSC),
0026 MT6357_TOP_GEN(SCK),
0027 MT6357_TOP_GEN(BM),
0028 MT6357_TOP_GEN(HK),
0029 MT6357_TOP_GEN(AUD),
0030 MT6357_TOP_GEN(MISC),
0031 };
0032
0033 static const struct irq_top_t mt6358_ints[] = {
0034 MT6358_TOP_GEN(BUCK),
0035 MT6358_TOP_GEN(LDO),
0036 MT6358_TOP_GEN(PSC),
0037 MT6358_TOP_GEN(SCK),
0038 MT6358_TOP_GEN(BM),
0039 MT6358_TOP_GEN(HK),
0040 MT6358_TOP_GEN(AUD),
0041 MT6358_TOP_GEN(MISC),
0042 };
0043
0044 static const struct irq_top_t mt6359_ints[] = {
0045 MT6359_TOP_GEN(BUCK),
0046 MT6359_TOP_GEN(LDO),
0047 MT6359_TOP_GEN(PSC),
0048 MT6359_TOP_GEN(SCK),
0049 MT6359_TOP_GEN(BM),
0050 MT6359_TOP_GEN(HK),
0051 MT6359_TOP_GEN(AUD),
0052 MT6359_TOP_GEN(MISC),
0053 };
0054
0055 static struct pmic_irq_data mt6357_irqd = {
0056 .num_top = ARRAY_SIZE(mt6357_ints),
0057 .num_pmic_irqs = MT6357_IRQ_NR,
0058 .top_int_status_reg = MT6357_TOP_INT_STATUS0,
0059 .pmic_ints = mt6357_ints,
0060 };
0061
0062 static struct pmic_irq_data mt6358_irqd = {
0063 .num_top = ARRAY_SIZE(mt6358_ints),
0064 .num_pmic_irqs = MT6358_IRQ_NR,
0065 .top_int_status_reg = MT6358_TOP_INT_STATUS0,
0066 .pmic_ints = mt6358_ints,
0067 };
0068
0069 static struct pmic_irq_data mt6359_irqd = {
0070 .num_top = ARRAY_SIZE(mt6359_ints),
0071 .num_pmic_irqs = MT6359_IRQ_NR,
0072 .top_int_status_reg = MT6359_TOP_INT_STATUS0,
0073 .pmic_ints = mt6359_ints,
0074 };
0075
0076 static void pmic_irq_enable(struct irq_data *data)
0077 {
0078 unsigned int hwirq = irqd_to_hwirq(data);
0079 struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
0080 struct pmic_irq_data *irqd = chip->irq_data;
0081
0082 irqd->enable_hwirq[hwirq] = true;
0083 }
0084
0085 static void pmic_irq_disable(struct irq_data *data)
0086 {
0087 unsigned int hwirq = irqd_to_hwirq(data);
0088 struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
0089 struct pmic_irq_data *irqd = chip->irq_data;
0090
0091 irqd->enable_hwirq[hwirq] = false;
0092 }
0093
0094 static void pmic_irq_lock(struct irq_data *data)
0095 {
0096 struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
0097
0098 mutex_lock(&chip->irqlock);
0099 }
0100
0101 static void pmic_irq_sync_unlock(struct irq_data *data)
0102 {
0103 unsigned int i, top_gp, gp_offset, en_reg, int_regs, shift;
0104 struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
0105 struct pmic_irq_data *irqd = chip->irq_data;
0106
0107 for (i = 0; i < irqd->num_pmic_irqs; i++) {
0108 if (irqd->enable_hwirq[i] == irqd->cache_hwirq[i])
0109 continue;
0110
0111
0112 top_gp = 0;
0113 while ((top_gp + 1) < irqd->num_top &&
0114 i >= irqd->pmic_ints[top_gp + 1].hwirq_base)
0115 top_gp++;
0116
0117
0118 gp_offset = i - irqd->pmic_ints[top_gp].hwirq_base;
0119 int_regs = gp_offset / MTK_PMIC_REG_WIDTH;
0120 shift = gp_offset % MTK_PMIC_REG_WIDTH;
0121 en_reg = irqd->pmic_ints[top_gp].en_reg +
0122 (irqd->pmic_ints[top_gp].en_reg_shift * int_regs);
0123
0124 regmap_update_bits(chip->regmap, en_reg, BIT(shift),
0125 irqd->enable_hwirq[i] << shift);
0126
0127 irqd->cache_hwirq[i] = irqd->enable_hwirq[i];
0128 }
0129 mutex_unlock(&chip->irqlock);
0130 }
0131
0132 static struct irq_chip mt6358_irq_chip = {
0133 .name = "mt6358-irq",
0134 .flags = IRQCHIP_SKIP_SET_WAKE,
0135 .irq_enable = pmic_irq_enable,
0136 .irq_disable = pmic_irq_disable,
0137 .irq_bus_lock = pmic_irq_lock,
0138 .irq_bus_sync_unlock = pmic_irq_sync_unlock,
0139 };
0140
0141 static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
0142 unsigned int top_gp)
0143 {
0144 unsigned int irq_status, sta_reg, status;
0145 unsigned int hwirq, virq;
0146 int i, j, ret;
0147 struct pmic_irq_data *irqd = chip->irq_data;
0148
0149 for (i = 0; i < irqd->pmic_ints[top_gp].num_int_regs; i++) {
0150 sta_reg = irqd->pmic_ints[top_gp].sta_reg +
0151 irqd->pmic_ints[top_gp].sta_reg_shift * i;
0152
0153 ret = regmap_read(chip->regmap, sta_reg, &irq_status);
0154 if (ret) {
0155 dev_err(chip->dev,
0156 "Failed to read IRQ status, ret=%d\n", ret);
0157 return;
0158 }
0159
0160 if (!irq_status)
0161 continue;
0162
0163 status = irq_status;
0164 do {
0165 j = __ffs(status);
0166
0167 hwirq = irqd->pmic_ints[top_gp].hwirq_base +
0168 MTK_PMIC_REG_WIDTH * i + j;
0169
0170 virq = irq_find_mapping(chip->irq_domain, hwirq);
0171 if (virq)
0172 handle_nested_irq(virq);
0173
0174 status &= ~BIT(j);
0175 } while (status);
0176
0177 regmap_write(chip->regmap, sta_reg, irq_status);
0178 }
0179 }
0180
0181 static irqreturn_t mt6358_irq_handler(int irq, void *data)
0182 {
0183 struct mt6397_chip *chip = data;
0184 struct pmic_irq_data *irqd = chip->irq_data;
0185 unsigned int bit, i, top_irq_status = 0;
0186 int ret;
0187
0188 ret = regmap_read(chip->regmap,
0189 irqd->top_int_status_reg,
0190 &top_irq_status);
0191 if (ret) {
0192 dev_err(chip->dev,
0193 "Failed to read status from the device, ret=%d\n", ret);
0194 return IRQ_NONE;
0195 }
0196
0197 for (i = 0; i < irqd->num_top; i++) {
0198 bit = BIT(irqd->pmic_ints[i].top_offset);
0199 if (top_irq_status & bit) {
0200 mt6358_irq_sp_handler(chip, i);
0201 top_irq_status &= ~bit;
0202 if (!top_irq_status)
0203 break;
0204 }
0205 }
0206
0207 return IRQ_HANDLED;
0208 }
0209
0210 static int pmic_irq_domain_map(struct irq_domain *d, unsigned int irq,
0211 irq_hw_number_t hw)
0212 {
0213 struct mt6397_chip *mt6397 = d->host_data;
0214
0215 irq_set_chip_data(irq, mt6397);
0216 irq_set_chip_and_handler(irq, &mt6358_irq_chip, handle_level_irq);
0217 irq_set_nested_thread(irq, 1);
0218 irq_set_noprobe(irq);
0219
0220 return 0;
0221 }
0222
0223 static const struct irq_domain_ops mt6358_irq_domain_ops = {
0224 .map = pmic_irq_domain_map,
0225 .xlate = irq_domain_xlate_twocell,
0226 };
0227
0228 int mt6358_irq_init(struct mt6397_chip *chip)
0229 {
0230 int i, j, ret;
0231 struct pmic_irq_data *irqd;
0232
0233 switch (chip->chip_id) {
0234 case MT6357_CHIP_ID:
0235 chip->irq_data = &mt6357_irqd;
0236 break;
0237
0238 case MT6358_CHIP_ID:
0239 case MT6366_CHIP_ID:
0240 chip->irq_data = &mt6358_irqd;
0241 break;
0242
0243 case MT6359_CHIP_ID:
0244 chip->irq_data = &mt6359_irqd;
0245 break;
0246
0247 default:
0248 dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
0249 return -ENODEV;
0250 }
0251
0252 mutex_init(&chip->irqlock);
0253 irqd = chip->irq_data;
0254 irqd->enable_hwirq = devm_kcalloc(chip->dev,
0255 irqd->num_pmic_irqs,
0256 sizeof(*irqd->enable_hwirq),
0257 GFP_KERNEL);
0258 if (!irqd->enable_hwirq)
0259 return -ENOMEM;
0260
0261 irqd->cache_hwirq = devm_kcalloc(chip->dev,
0262 irqd->num_pmic_irqs,
0263 sizeof(*irqd->cache_hwirq),
0264 GFP_KERNEL);
0265 if (!irqd->cache_hwirq)
0266 return -ENOMEM;
0267
0268
0269 for (i = 0; i < irqd->num_top; i++) {
0270 for (j = 0; j < irqd->pmic_ints[i].num_int_regs; j++)
0271 regmap_write(chip->regmap,
0272 irqd->pmic_ints[i].en_reg +
0273 irqd->pmic_ints[i].en_reg_shift * j, 0);
0274 }
0275
0276 chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
0277 irqd->num_pmic_irqs,
0278 &mt6358_irq_domain_ops, chip);
0279 if (!chip->irq_domain) {
0280 dev_err(chip->dev, "Could not create IRQ domain\n");
0281 return -ENODEV;
0282 }
0283
0284 ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
0285 mt6358_irq_handler, IRQF_ONESHOT,
0286 mt6358_irq_chip.name, chip);
0287 if (ret) {
0288 dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n",
0289 chip->irq, ret);
0290 return ret;
0291 }
0292
0293 enable_irq_wake(chip->irq);
0294 return ret;
0295 }