Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2020 MediaTek Inc.
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         /* Find out the IRQ group */
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         /* Find the IRQ registers */
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     /* Disable all interrupts for initializing */
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 }