Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright 2017 NXP
0003 
0004 /*                     INTMUX Block Diagram
0005  *
0006  *                               ________________
0007  * interrupt source #  0  +---->|                |
0008  *                        |     |                |
0009  * interrupt source #  1  +++-->|                |
0010  *            ...         | |   |   channel # 0  |--------->interrupt out # 0
0011  *            ...         | |   |                |
0012  *            ...         | |   |                |
0013  * interrupt source # X-1 +++-->|________________|
0014  *                        | | |
0015  *                        | | |
0016  *                        | | |  ________________
0017  *                        +---->|                |
0018  *                        | | | |                |
0019  *                        | +-->|                |
0020  *                        | | | |   channel # 1  |--------->interrupt out # 1
0021  *                        | | +>|                |
0022  *                        | | | |                |
0023  *                        | | | |________________|
0024  *                        | | |
0025  *                        | | |
0026  *                        | | |       ...
0027  *                        | | |       ...
0028  *                        | | |
0029  *                        | | |  ________________
0030  *                        +---->|                |
0031  *                          | | |                |
0032  *                          +-->|                |
0033  *                            | |   channel # N  |--------->interrupt out # N
0034  *                            +>|                |
0035  *                              |                |
0036  *                              |________________|
0037  *
0038  *
0039  * N: Interrupt Channel Instance Number (N=7)
0040  * X: Interrupt Source Number for each channel (X=32)
0041  *
0042  * The INTMUX interrupt multiplexer has 8 channels, each channel receives 32
0043  * interrupt sources and generates 1 interrupt output.
0044  *
0045  */
0046 
0047 #include <linux/clk.h>
0048 #include <linux/interrupt.h>
0049 #include <linux/irq.h>
0050 #include <linux/irqchip/chained_irq.h>
0051 #include <linux/irqdomain.h>
0052 #include <linux/kernel.h>
0053 #include <linux/of_irq.h>
0054 #include <linux/of_platform.h>
0055 #include <linux/spinlock.h>
0056 #include <linux/pm_runtime.h>
0057 
0058 #define CHANIER(n)  (0x10 + (0x40 * n))
0059 #define CHANIPR(n)  (0x20 + (0x40 * n))
0060 
0061 #define CHAN_MAX_NUM        0x8
0062 
0063 struct intmux_irqchip_data {
0064     u32         saved_reg;
0065     int         chanidx;
0066     int         irq;
0067     struct irq_domain   *domain;
0068 };
0069 
0070 struct intmux_data {
0071     raw_spinlock_t          lock;
0072     void __iomem            *regs;
0073     struct clk          *ipg_clk;
0074     int             channum;
0075     struct intmux_irqchip_data  irqchip_data[];
0076 };
0077 
0078 static void imx_intmux_irq_mask(struct irq_data *d)
0079 {
0080     struct intmux_irqchip_data *irqchip_data = d->chip_data;
0081     int idx = irqchip_data->chanidx;
0082     struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
0083                         irqchip_data[idx]);
0084     unsigned long flags;
0085     void __iomem *reg;
0086     u32 val;
0087 
0088     raw_spin_lock_irqsave(&data->lock, flags);
0089     reg = data->regs + CHANIER(idx);
0090     val = readl_relaxed(reg);
0091     /* disable the interrupt source of this channel */
0092     val &= ~BIT(d->hwirq);
0093     writel_relaxed(val, reg);
0094     raw_spin_unlock_irqrestore(&data->lock, flags);
0095 }
0096 
0097 static void imx_intmux_irq_unmask(struct irq_data *d)
0098 {
0099     struct intmux_irqchip_data *irqchip_data = d->chip_data;
0100     int idx = irqchip_data->chanidx;
0101     struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
0102                         irqchip_data[idx]);
0103     unsigned long flags;
0104     void __iomem *reg;
0105     u32 val;
0106 
0107     raw_spin_lock_irqsave(&data->lock, flags);
0108     reg = data->regs + CHANIER(idx);
0109     val = readl_relaxed(reg);
0110     /* enable the interrupt source of this channel */
0111     val |= BIT(d->hwirq);
0112     writel_relaxed(val, reg);
0113     raw_spin_unlock_irqrestore(&data->lock, flags);
0114 }
0115 
0116 static struct irq_chip imx_intmux_irq_chip __ro_after_init = {
0117     .name       = "intmux",
0118     .irq_mask   = imx_intmux_irq_mask,
0119     .irq_unmask = imx_intmux_irq_unmask,
0120 };
0121 
0122 static int imx_intmux_irq_map(struct irq_domain *h, unsigned int irq,
0123                   irq_hw_number_t hwirq)
0124 {
0125     struct intmux_irqchip_data *data = h->host_data;
0126 
0127     irq_set_chip_data(irq, data);
0128     irq_set_chip_and_handler(irq, &imx_intmux_irq_chip, handle_level_irq);
0129 
0130     return 0;
0131 }
0132 
0133 static int imx_intmux_irq_xlate(struct irq_domain *d, struct device_node *node,
0134                 const u32 *intspec, unsigned int intsize,
0135                 unsigned long *out_hwirq, unsigned int *out_type)
0136 {
0137     struct intmux_irqchip_data *irqchip_data = d->host_data;
0138     int idx = irqchip_data->chanidx;
0139     struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
0140                         irqchip_data[idx]);
0141 
0142     /*
0143      * two cells needed in interrupt specifier:
0144      * the 1st cell: hw interrupt number
0145      * the 2nd cell: channel index
0146      */
0147     if (WARN_ON(intsize != 2))
0148         return -EINVAL;
0149 
0150     if (WARN_ON(intspec[1] >= data->channum))
0151         return -EINVAL;
0152 
0153     *out_hwirq = intspec[0];
0154     *out_type = IRQ_TYPE_LEVEL_HIGH;
0155 
0156     return 0;
0157 }
0158 
0159 static int imx_intmux_irq_select(struct irq_domain *d, struct irq_fwspec *fwspec,
0160                  enum irq_domain_bus_token bus_token)
0161 {
0162     struct intmux_irqchip_data *irqchip_data = d->host_data;
0163 
0164     /* Not for us */
0165     if (fwspec->fwnode != d->fwnode)
0166         return false;
0167 
0168     return irqchip_data->chanidx == fwspec->param[1];
0169 }
0170 
0171 static const struct irq_domain_ops imx_intmux_domain_ops = {
0172     .map        = imx_intmux_irq_map,
0173     .xlate      = imx_intmux_irq_xlate,
0174     .select     = imx_intmux_irq_select,
0175 };
0176 
0177 static void imx_intmux_irq_handler(struct irq_desc *desc)
0178 {
0179     struct intmux_irqchip_data *irqchip_data = irq_desc_get_handler_data(desc);
0180     int idx = irqchip_data->chanidx;
0181     struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
0182                         irqchip_data[idx]);
0183     unsigned long irqstat;
0184     int pos;
0185 
0186     chained_irq_enter(irq_desc_get_chip(desc), desc);
0187 
0188     /* read the interrupt source pending status of this channel */
0189     irqstat = readl_relaxed(data->regs + CHANIPR(idx));
0190 
0191     for_each_set_bit(pos, &irqstat, 32)
0192         generic_handle_domain_irq(irqchip_data->domain, pos);
0193 
0194     chained_irq_exit(irq_desc_get_chip(desc), desc);
0195 }
0196 
0197 static int imx_intmux_probe(struct platform_device *pdev)
0198 {
0199     struct device_node *np = pdev->dev.of_node;
0200     struct irq_domain *domain;
0201     struct intmux_data *data;
0202     int channum;
0203     int i, ret;
0204 
0205     channum = platform_irq_count(pdev);
0206     if (channum == -EPROBE_DEFER) {
0207         return -EPROBE_DEFER;
0208     } else if (channum > CHAN_MAX_NUM) {
0209         dev_err(&pdev->dev, "supports up to %d multiplex channels\n",
0210             CHAN_MAX_NUM);
0211         return -EINVAL;
0212     }
0213 
0214     data = devm_kzalloc(&pdev->dev, struct_size(data, irqchip_data, channum), GFP_KERNEL);
0215     if (!data)
0216         return -ENOMEM;
0217 
0218     data->regs = devm_platform_ioremap_resource(pdev, 0);
0219     if (IS_ERR(data->regs)) {
0220         dev_err(&pdev->dev, "failed to initialize reg\n");
0221         return PTR_ERR(data->regs);
0222     }
0223 
0224     data->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
0225     if (IS_ERR(data->ipg_clk))
0226         return dev_err_probe(&pdev->dev, PTR_ERR(data->ipg_clk),
0227                      "failed to get ipg clk\n");
0228 
0229     data->channum = channum;
0230     raw_spin_lock_init(&data->lock);
0231 
0232     pm_runtime_get_noresume(&pdev->dev);
0233     pm_runtime_set_active(&pdev->dev);
0234     pm_runtime_enable(&pdev->dev);
0235 
0236     ret = clk_prepare_enable(data->ipg_clk);
0237     if (ret) {
0238         dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret);
0239         return ret;
0240     }
0241 
0242     for (i = 0; i < channum; i++) {
0243         data->irqchip_data[i].chanidx = i;
0244 
0245         data->irqchip_data[i].irq = irq_of_parse_and_map(np, i);
0246         if (data->irqchip_data[i].irq <= 0) {
0247             ret = -EINVAL;
0248             dev_err(&pdev->dev, "failed to get irq\n");
0249             goto out;
0250         }
0251 
0252         domain = irq_domain_add_linear(np, 32, &imx_intmux_domain_ops,
0253                            &data->irqchip_data[i]);
0254         if (!domain) {
0255             ret = -ENOMEM;
0256             dev_err(&pdev->dev, "failed to create IRQ domain\n");
0257             goto out;
0258         }
0259         data->irqchip_data[i].domain = domain;
0260         irq_domain_set_pm_device(domain, &pdev->dev);
0261 
0262         /* disable all interrupt sources of this channel firstly */
0263         writel_relaxed(0, data->regs + CHANIER(i));
0264 
0265         irq_set_chained_handler_and_data(data->irqchip_data[i].irq,
0266                          imx_intmux_irq_handler,
0267                          &data->irqchip_data[i]);
0268     }
0269 
0270     platform_set_drvdata(pdev, data);
0271 
0272     /*
0273      * Let pm_runtime_put() disable clock.
0274      * If CONFIG_PM is not enabled, the clock will stay powered.
0275      */
0276     pm_runtime_put(&pdev->dev);
0277 
0278     return 0;
0279 out:
0280     clk_disable_unprepare(data->ipg_clk);
0281     return ret;
0282 }
0283 
0284 static int imx_intmux_remove(struct platform_device *pdev)
0285 {
0286     struct intmux_data *data = platform_get_drvdata(pdev);
0287     int i;
0288 
0289     for (i = 0; i < data->channum; i++) {
0290         /* disable all interrupt sources of this channel */
0291         writel_relaxed(0, data->regs + CHANIER(i));
0292 
0293         irq_set_chained_handler_and_data(data->irqchip_data[i].irq,
0294                          NULL, NULL);
0295 
0296         irq_domain_remove(data->irqchip_data[i].domain);
0297     }
0298 
0299     pm_runtime_disable(&pdev->dev);
0300 
0301     return 0;
0302 }
0303 
0304 #ifdef CONFIG_PM
0305 static int imx_intmux_runtime_suspend(struct device *dev)
0306 {
0307     struct intmux_data *data = dev_get_drvdata(dev);
0308     struct intmux_irqchip_data *irqchip_data;
0309     int i;
0310 
0311     for (i = 0; i < data->channum; i++) {
0312         irqchip_data = &data->irqchip_data[i];
0313         irqchip_data->saved_reg = readl_relaxed(data->regs + CHANIER(i));
0314     }
0315 
0316     clk_disable_unprepare(data->ipg_clk);
0317 
0318     return 0;
0319 }
0320 
0321 static int imx_intmux_runtime_resume(struct device *dev)
0322 {
0323     struct intmux_data *data = dev_get_drvdata(dev);
0324     struct intmux_irqchip_data *irqchip_data;
0325     int ret, i;
0326 
0327     ret = clk_prepare_enable(data->ipg_clk);
0328     if (ret) {
0329         dev_err(dev, "failed to enable ipg clk: %d\n", ret);
0330         return ret;
0331     }
0332 
0333     for (i = 0; i < data->channum; i++) {
0334         irqchip_data = &data->irqchip_data[i];
0335         writel_relaxed(irqchip_data->saved_reg, data->regs + CHANIER(i));
0336     }
0337 
0338     return 0;
0339 }
0340 #endif
0341 
0342 static const struct dev_pm_ops imx_intmux_pm_ops = {
0343     SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0344                       pm_runtime_force_resume)
0345     SET_RUNTIME_PM_OPS(imx_intmux_runtime_suspend,
0346                imx_intmux_runtime_resume, NULL)
0347 };
0348 
0349 static const struct of_device_id imx_intmux_id[] = {
0350     { .compatible = "fsl,imx-intmux", },
0351     { /* sentinel */ },
0352 };
0353 
0354 static struct platform_driver imx_intmux_driver = {
0355     .driver = {
0356         .name = "imx-intmux",
0357         .of_match_table = imx_intmux_id,
0358         .pm = &imx_intmux_pm_ops,
0359     },
0360     .probe = imx_intmux_probe,
0361     .remove = imx_intmux_remove,
0362 };
0363 builtin_platform_driver(imx_intmux_driver);