Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Device driver for irqs in HISI PMIC IC
0004  *
0005  * Copyright (c) 2013 Linaro Ltd.
0006  * Copyright (c) 2011 Hisilicon.
0007  * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd.
0008  */
0009 
0010 #include <linux/bitops.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/irq.h>
0013 #include <linux/module.h>
0014 #include <linux/of_gpio.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/slab.h>
0017 #include <linux/irqdomain.h>
0018 #include <linux/regmap.h>
0019 
0020 struct hi6421v600_irq {
0021     struct device       *dev;
0022     struct irq_domain   *domain;
0023     int         irq;
0024     unsigned int        *irqs;
0025     struct regmap       *regmap;
0026 
0027     /* Protect IRQ mask changes */
0028     spinlock_t      lock;
0029 };
0030 
0031 enum hi6421v600_irq_list {
0032     OTMP = 0,
0033     VBUS_CONNECT,
0034     VBUS_DISCONNECT,
0035     ALARMON_R,
0036     HOLD_6S,
0037     HOLD_1S,
0038     POWERKEY_UP,
0039     POWERKEY_DOWN,
0040     OCP_SCP_R,
0041     COUL_R,
0042     SIM0_HPD_R,
0043     SIM0_HPD_F,
0044     SIM1_HPD_R,
0045     SIM1_HPD_F,
0046 
0047     PMIC_IRQ_LIST_MAX
0048 };
0049 
0050 #define HISI_IRQ_BANK_SIZE      2
0051 
0052 /*
0053  * IRQ number for the power key button and mask for both UP and DOWN IRQs
0054  */
0055 #define HISI_POWERKEY_IRQ_NUM       0
0056 #define HISI_IRQ_POWERKEY_UP_DOWN   (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
0057 
0058 /*
0059  * Registers for IRQ address and IRQ mask bits
0060  *
0061  * Please notice that we need to regmap a larger region, as other
0062  * registers are used by the irqs.
0063  * See drivers/irq/hi6421-irq.c.
0064  */
0065 #define SOC_PMIC_IRQ_MASK_0_ADDR    0x0202
0066 #define SOC_PMIC_IRQ0_ADDR      0x0212
0067 
0068 /*
0069  * The IRQs are mapped as:
0070  *
0071  *  ======================  =============   ============    =====
0072  *  IRQ         MASK REGISTER   IRQ REGISTER    BIT
0073  *  ======================  =============   ============    =====
0074  *  OTMP            0x0202      0x212       bit 0
0075  *  VBUS_CONNECT        0x0202      0x212       bit 1
0076  *  VBUS_DISCONNECT     0x0202      0x212       bit 2
0077  *  ALARMON_R       0x0202      0x212       bit 3
0078  *  HOLD_6S         0x0202      0x212       bit 4
0079  *  HOLD_1S         0x0202      0x212       bit 5
0080  *  POWERKEY_UP     0x0202      0x212       bit 6
0081  *  POWERKEY_DOWN       0x0202      0x212       bit 7
0082  *
0083  *  OCP_SCP_R       0x0203      0x213       bit 0
0084  *  COUL_R          0x0203      0x213       bit 1
0085  *  SIM0_HPD_R      0x0203      0x213       bit 2
0086  *  SIM0_HPD_F      0x0203      0x213       bit 3
0087  *  SIM1_HPD_R      0x0203      0x213       bit 4
0088  *  SIM1_HPD_F      0x0203      0x213       bit 5
0089  *  ======================  =============   ============    =====
0090  *
0091  * Each mask register contains 8 bits. The ancillary macros below
0092  * convert a number from 0 to 14 into a register address and a bit mask
0093  */
0094 #define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
0095                      (irqd_to_hwirq(irq_data) / BITS_PER_BYTE))
0096 #define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1))
0097 #define HISI_8BITS_MASK         0xff
0098 
0099 static irqreturn_t hi6421v600_irq_handler(int irq, void *__priv)
0100 {
0101     struct hi6421v600_irq *priv = __priv;
0102     unsigned long pending;
0103     unsigned int in;
0104     int i, offset;
0105 
0106     for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
0107         regmap_read(priv->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
0108 
0109         /* Mark pending IRQs as handled */
0110         regmap_write(priv->regmap, SOC_PMIC_IRQ0_ADDR + i, in);
0111 
0112         pending = in & HISI_8BITS_MASK;
0113 
0114         if (i == HISI_POWERKEY_IRQ_NUM &&
0115             (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) {
0116             /*
0117              * If both powerkey down and up IRQs are received,
0118              * handle them at the right order
0119              */
0120             generic_handle_irq_safe(priv->irqs[POWERKEY_DOWN]);
0121             generic_handle_irq_safe(priv->irqs[POWERKEY_UP]);
0122             pending &= ~HISI_IRQ_POWERKEY_UP_DOWN;
0123         }
0124 
0125         if (!pending)
0126             continue;
0127 
0128         for_each_set_bit(offset, &pending, BITS_PER_BYTE) {
0129             generic_handle_irq_safe(priv->irqs[offset + i * BITS_PER_BYTE]);
0130         }
0131     }
0132 
0133     return IRQ_HANDLED;
0134 }
0135 
0136 static void hi6421v600_irq_mask(struct irq_data *d)
0137 {
0138     struct hi6421v600_irq *priv = irq_data_get_irq_chip_data(d);
0139     unsigned long flags;
0140     unsigned int data;
0141     u32 offset;
0142 
0143     offset = HISI_IRQ_MASK_REG(d);
0144 
0145     spin_lock_irqsave(&priv->lock, flags);
0146 
0147     regmap_read(priv->regmap, offset, &data);
0148     data |= HISI_IRQ_MASK_BIT(d);
0149     regmap_write(priv->regmap, offset, data);
0150 
0151     spin_unlock_irqrestore(&priv->lock, flags);
0152 }
0153 
0154 static void hi6421v600_irq_unmask(struct irq_data *d)
0155 {
0156     struct hi6421v600_irq *priv = irq_data_get_irq_chip_data(d);
0157     u32 data, offset;
0158     unsigned long flags;
0159 
0160     offset = HISI_IRQ_MASK_REG(d);
0161 
0162     spin_lock_irqsave(&priv->lock, flags);
0163 
0164     regmap_read(priv->regmap, offset, &data);
0165     data &= ~HISI_IRQ_MASK_BIT(d);
0166     regmap_write(priv->regmap, offset, data);
0167 
0168     spin_unlock_irqrestore(&priv->lock, flags);
0169 }
0170 
0171 static struct irq_chip hi6421v600_pmu_irqchip = {
0172     .name       = "hi6421v600-irq",
0173     .irq_mask   = hi6421v600_irq_mask,
0174     .irq_unmask = hi6421v600_irq_unmask,
0175     .irq_disable    = hi6421v600_irq_mask,
0176     .irq_enable = hi6421v600_irq_unmask,
0177 };
0178 
0179 static int hi6421v600_irq_map(struct irq_domain *d, unsigned int virq,
0180                   irq_hw_number_t hw)
0181 {
0182     struct hi6421v600_irq *priv = d->host_data;
0183 
0184     irq_set_chip_and_handler_name(virq, &hi6421v600_pmu_irqchip,
0185                       handle_simple_irq, "hi6421v600");
0186     irq_set_chip_data(virq, priv);
0187     irq_set_irq_type(virq, IRQ_TYPE_NONE);
0188 
0189     return 0;
0190 }
0191 
0192 static const struct irq_domain_ops hi6421v600_domain_ops = {
0193     .map    = hi6421v600_irq_map,
0194     .xlate  = irq_domain_xlate_twocell,
0195 };
0196 
0197 static void hi6421v600_irq_init(struct hi6421v600_irq *priv)
0198 {
0199     int i;
0200     unsigned int pending;
0201 
0202     /* Mask all IRQs */
0203     for (i = 0; i < HISI_IRQ_BANK_SIZE; i++)
0204         regmap_write(priv->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
0205                  HISI_8BITS_MASK);
0206 
0207     /* Mark all IRQs as handled */
0208     for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
0209         regmap_read(priv->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
0210         regmap_write(priv->regmap, SOC_PMIC_IRQ0_ADDR + i,
0211                  HISI_8BITS_MASK);
0212     }
0213 }
0214 
0215 static int hi6421v600_irq_probe(struct platform_device *pdev)
0216 {
0217     struct device *pmic_dev = pdev->dev.parent;
0218     struct device_node *np = pmic_dev->of_node;
0219     struct platform_device *pmic_pdev;
0220     struct device *dev = &pdev->dev;
0221     struct hi6421v600_irq *priv;
0222     struct regmap *regmap;
0223     unsigned int virq;
0224     int i, ret;
0225 
0226     /*
0227      * This driver is meant to be called by hi6421-spmi-core,
0228      * which should first set drvdata. If this doesn't happen, hit
0229      * a warn on and return.
0230      */
0231     regmap = dev_get_drvdata(pmic_dev);
0232     if (WARN_ON(!regmap))
0233         return -ENODEV;
0234 
0235     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0236     if (!priv)
0237         return -ENOMEM;
0238 
0239     priv->dev = dev;
0240     priv->regmap = regmap;
0241 
0242     spin_lock_init(&priv->lock);
0243 
0244     pmic_pdev = container_of(pmic_dev, struct platform_device, dev);
0245 
0246     priv->irq = platform_get_irq(pmic_pdev, 0);
0247     if (priv->irq < 0) {
0248         dev_err(dev, "Error %d when getting IRQs\n", priv->irq);
0249         return priv->irq;
0250     }
0251 
0252     platform_set_drvdata(pdev, priv);
0253 
0254     hi6421v600_irq_init(priv);
0255 
0256     priv->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL);
0257     if (!priv->irqs)
0258         return -ENOMEM;
0259 
0260     priv->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0,
0261                          &hi6421v600_domain_ops, priv);
0262     if (!priv->domain) {
0263         dev_err(dev, "Failed to create IRQ domain\n");
0264         return -ENODEV;
0265     }
0266 
0267     for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) {
0268         virq = irq_create_mapping(priv->domain, i);
0269         if (!virq) {
0270             dev_err(dev, "Failed to map H/W IRQ\n");
0271             return -ENODEV;
0272         }
0273         priv->irqs[i] = virq;
0274     }
0275 
0276     ret = devm_request_threaded_irq(dev,
0277                     priv->irq, hi6421v600_irq_handler,
0278                     NULL,
0279                     IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
0280                     "pmic", priv);
0281     if (ret < 0) {
0282         dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
0283             ret);
0284         return ret;
0285     }
0286 
0287     return 0;
0288 }
0289 
0290 static const struct platform_device_id hi6421v600_irq_table[] = {
0291     { .name = "hi6421v600-irq" },
0292     {},
0293 };
0294 MODULE_DEVICE_TABLE(platform, hi6421v600_irq_table);
0295 
0296 static struct platform_driver hi6421v600_irq_driver = {
0297     .id_table = hi6421v600_irq_table,
0298     .driver = {
0299         .name = "hi6421v600-irq",
0300     },
0301     .probe  = hi6421v600_irq_probe,
0302 };
0303 module_platform_driver(hi6421v600_irq_driver);
0304 
0305 MODULE_DESCRIPTION("HiSilicon Hi6421v600 IRQ driver");
0306 MODULE_LICENSE("GPL v2");