Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2015 Endless Mobile, Inc.
0004  * Author: Carlo Caione <carlo@endlessm.com>
0005  * Copyright (c) 2016 BayLibre, SAS.
0006  * Author: Jerome Brunet <jbrunet@baylibre.com>
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include <linux/io.h>
0012 #include <linux/module.h>
0013 #include <linux/irq.h>
0014 #include <linux/irqdomain.h>
0015 #include <linux/irqchip.h>
0016 #include <linux/of.h>
0017 #include <linux/of_address.h>
0018 
0019 #define MAX_NUM_CHANNEL 64
0020 #define MAX_INPUT_MUX 256
0021 
0022 #define REG_EDGE_POL    0x00
0023 #define REG_PIN_03_SEL  0x04
0024 #define REG_PIN_47_SEL  0x08
0025 #define REG_FILTER_SEL  0x0c
0026 
0027 /* use for A1 like chips */
0028 #define REG_PIN_A1_SEL  0x04
0029 /* Used for s4 chips */
0030 #define REG_EDGE_POL_S4 0x1c
0031 
0032 /*
0033  * Note: The S905X3 datasheet reports that BOTH_EDGE is controlled by
0034  * bits 24 to 31. Tests on the actual HW show that these bits are
0035  * stuck at 0. Bits 8 to 15 are responsive and have the expected
0036  * effect.
0037  */
0038 #define REG_EDGE_POL_EDGE(params, x)    BIT((params)->edge_single_offset + (x))
0039 #define REG_EDGE_POL_LOW(params, x) BIT((params)->pol_low_offset + (x))
0040 #define REG_BOTH_EDGE(params, x)    BIT((params)->edge_both_offset + (x))
0041 #define REG_EDGE_POL_MASK(params, x)    (   \
0042         REG_EDGE_POL_EDGE(params, x) |  \
0043         REG_EDGE_POL_LOW(params, x)  |  \
0044         REG_BOTH_EDGE(params, x))
0045 #define REG_PIN_SEL_SHIFT(x)    (((x) % 4) * 8)
0046 #define REG_FILTER_SEL_SHIFT(x) ((x) * 4)
0047 
0048 struct meson_gpio_irq_controller;
0049 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
0050                     unsigned int channel, unsigned long hwirq);
0051 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl);
0052 static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
0053                       unsigned int channel,
0054                       unsigned long hwirq);
0055 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
0056 static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
0057                     unsigned int type, u32 *channel_hwirq);
0058 static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
0059                       unsigned int type, u32 *channel_hwirq);
0060 
0061 struct irq_ctl_ops {
0062     void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
0063                  unsigned int channel, unsigned long hwirq);
0064     void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
0065     int (*gpio_irq_set_type)(struct meson_gpio_irq_controller *ctl,
0066                  unsigned int type, u32 *channel_hwirq);
0067 };
0068 
0069 struct meson_gpio_irq_params {
0070     unsigned int nr_hwirq;
0071     unsigned int nr_channels;
0072     bool support_edge_both;
0073     unsigned int edge_both_offset;
0074     unsigned int edge_single_offset;
0075     unsigned int pol_low_offset;
0076     unsigned int pin_sel_mask;
0077     struct irq_ctl_ops ops;
0078 };
0079 
0080 #define INIT_MESON_COMMON(irqs, init, sel, type)        \
0081     .nr_hwirq = irqs,                   \
0082     .ops = {                        \
0083         .gpio_irq_init = init,              \
0084         .gpio_irq_sel_pin = sel,            \
0085         .gpio_irq_set_type = type,          \
0086     },
0087 
0088 #define INIT_MESON8_COMMON_DATA(irqs)               \
0089     INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,  \
0090               meson8_gpio_irq_sel_pin,      \
0091               meson8_gpio_irq_set_type)     \
0092     .edge_single_offset = 0,                \
0093     .pol_low_offset = 16,                   \
0094     .pin_sel_mask = 0xff,                   \
0095     .nr_channels = 8,                   \
0096 
0097 #define INIT_MESON_A1_COMMON_DATA(irqs)             \
0098     INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,     \
0099               meson_a1_gpio_irq_sel_pin,        \
0100               meson8_gpio_irq_set_type)     \
0101     .support_edge_both = true,              \
0102     .edge_both_offset = 16,                 \
0103     .edge_single_offset = 8,                \
0104     .pol_low_offset = 0,                    \
0105     .pin_sel_mask = 0x7f,                   \
0106     .nr_channels = 8,                   \
0107 
0108 #define INIT_MESON_S4_COMMON_DATA(irqs)             \
0109     INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,     \
0110               meson_a1_gpio_irq_sel_pin,        \
0111               meson_s4_gpio_irq_set_type)       \
0112     .support_edge_both = true,              \
0113     .edge_both_offset = 0,                  \
0114     .edge_single_offset = 12,               \
0115     .pol_low_offset = 0,                    \
0116     .pin_sel_mask = 0xff,                   \
0117     .nr_channels = 12,                  \
0118 
0119 static const struct meson_gpio_irq_params meson8_params = {
0120     INIT_MESON8_COMMON_DATA(134)
0121 };
0122 
0123 static const struct meson_gpio_irq_params meson8b_params = {
0124     INIT_MESON8_COMMON_DATA(119)
0125 };
0126 
0127 static const struct meson_gpio_irq_params gxbb_params = {
0128     INIT_MESON8_COMMON_DATA(133)
0129 };
0130 
0131 static const struct meson_gpio_irq_params gxl_params = {
0132     INIT_MESON8_COMMON_DATA(110)
0133 };
0134 
0135 static const struct meson_gpio_irq_params axg_params = {
0136     INIT_MESON8_COMMON_DATA(100)
0137 };
0138 
0139 static const struct meson_gpio_irq_params sm1_params = {
0140     INIT_MESON8_COMMON_DATA(100)
0141     .support_edge_both = true,
0142     .edge_both_offset = 8,
0143 };
0144 
0145 static const struct meson_gpio_irq_params a1_params = {
0146     INIT_MESON_A1_COMMON_DATA(62)
0147 };
0148 
0149 static const struct meson_gpio_irq_params s4_params = {
0150     INIT_MESON_S4_COMMON_DATA(82)
0151 };
0152 
0153 static const struct of_device_id meson_irq_gpio_matches[] = {
0154     { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
0155     { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
0156     { .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params },
0157     { .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params },
0158     { .compatible = "amlogic,meson-axg-gpio-intc", .data = &axg_params },
0159     { .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
0160     { .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
0161     { .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
0162     { .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
0163     { }
0164 };
0165 
0166 struct meson_gpio_irq_controller {
0167     const struct meson_gpio_irq_params *params;
0168     void __iomem *base;
0169     u32 channel_irqs[MAX_NUM_CHANNEL];
0170     DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
0171     spinlock_t lock;
0172 };
0173 
0174 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
0175                        unsigned int reg, u32 mask, u32 val)
0176 {
0177     unsigned long flags;
0178     u32 tmp;
0179 
0180     spin_lock_irqsave(&ctl->lock, flags);
0181 
0182     tmp = readl_relaxed(ctl->base + reg);
0183     tmp &= ~mask;
0184     tmp |= val;
0185     writel_relaxed(tmp, ctl->base + reg);
0186 
0187     spin_unlock_irqrestore(&ctl->lock, flags);
0188 }
0189 
0190 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
0191 {
0192 }
0193 
0194 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
0195                     unsigned int channel, unsigned long hwirq)
0196 {
0197     unsigned int reg_offset;
0198     unsigned int bit_offset;
0199 
0200     reg_offset = (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL;
0201     bit_offset = REG_PIN_SEL_SHIFT(channel);
0202 
0203     meson_gpio_irq_update_bits(ctl, reg_offset,
0204                    ctl->params->pin_sel_mask << bit_offset,
0205                    hwirq << bit_offset);
0206 }
0207 
0208 static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
0209                       unsigned int channel,
0210                       unsigned long hwirq)
0211 {
0212     unsigned int reg_offset;
0213     unsigned int bit_offset;
0214 
0215     bit_offset = ((channel % 2) == 0) ? 0 : 16;
0216     reg_offset = REG_PIN_A1_SEL + ((channel / 2) << 2);
0217 
0218     meson_gpio_irq_update_bits(ctl, reg_offset,
0219                    ctl->params->pin_sel_mask << bit_offset,
0220                    hwirq << bit_offset);
0221 }
0222 
0223 /* For a1 or later chips like a1 there is a switch to enable/disable irq */
0224 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
0225 {
0226     meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
0227 }
0228 
0229 static int
0230 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
0231                    unsigned long  hwirq,
0232                    u32 **channel_hwirq)
0233 {
0234     unsigned long flags;
0235     unsigned int idx;
0236 
0237     spin_lock_irqsave(&ctl->lock, flags);
0238 
0239     /* Find a free channel */
0240     idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
0241     if (idx >= ctl->params->nr_channels) {
0242         spin_unlock_irqrestore(&ctl->lock, flags);
0243         pr_err("No channel available\n");
0244         return -ENOSPC;
0245     }
0246 
0247     /* Mark the channel as used */
0248     set_bit(idx, ctl->channel_map);
0249 
0250     spin_unlock_irqrestore(&ctl->lock, flags);
0251 
0252     /*
0253      * Setup the mux of the channel to route the signal of the pad
0254      * to the appropriate input of the GIC
0255      */
0256     ctl->params->ops.gpio_irq_sel_pin(ctl, idx, hwirq);
0257 
0258     /*
0259      * Get the hwirq number assigned to this channel through
0260      * a pointer the channel_irq table. The added benefit of this
0261      * method is that we can also retrieve the channel index with
0262      * it, using the table base.
0263      */
0264     *channel_hwirq = &(ctl->channel_irqs[idx]);
0265 
0266     pr_debug("hwirq %lu assigned to channel %d - irq %u\n",
0267          hwirq, idx, **channel_hwirq);
0268 
0269     return 0;
0270 }
0271 
0272 static unsigned int
0273 meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl,
0274                    u32 *channel_hwirq)
0275 {
0276     return channel_hwirq - ctl->channel_irqs;
0277 }
0278 
0279 static void
0280 meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl,
0281                    u32 *channel_hwirq)
0282 {
0283     unsigned int idx;
0284 
0285     idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
0286     clear_bit(idx, ctl->channel_map);
0287 }
0288 
0289 static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
0290                     unsigned int type, u32 *channel_hwirq)
0291 {
0292     u32 val = 0;
0293     unsigned int idx;
0294     const struct meson_gpio_irq_params *params;
0295 
0296     params = ctl->params;
0297     idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
0298 
0299     /*
0300      * The controller has a filter block to operate in either LEVEL or
0301      * EDGE mode, then signal is sent to the GIC. To enable LEVEL_LOW and
0302      * EDGE_FALLING support (which the GIC does not support), the filter
0303      * block is also able to invert the input signal it gets before
0304      * providing it to the GIC.
0305      */
0306     type &= IRQ_TYPE_SENSE_MASK;
0307 
0308     /*
0309      * New controller support EDGE_BOTH trigger. This setting takes
0310      * precedence over the other edge/polarity settings
0311      */
0312     if (type == IRQ_TYPE_EDGE_BOTH) {
0313         if (!params->support_edge_both)
0314             return -EINVAL;
0315 
0316         val |= REG_BOTH_EDGE(params, idx);
0317     } else {
0318         if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
0319             val |= REG_EDGE_POL_EDGE(params, idx);
0320 
0321         if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
0322             val |= REG_EDGE_POL_LOW(params, idx);
0323     }
0324 
0325     meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
0326                    REG_EDGE_POL_MASK(params, idx), val);
0327 
0328     return 0;
0329 }
0330 
0331 /*
0332  * gpio irq relative registers for s4
0333  * -PADCTRL_GPIO_IRQ_CTRL0
0334  * bit[31]:    enable/disable all the irq lines
0335  * bit[12-23]: single edge trigger
0336  * bit[0-11]:  polarity trigger
0337  *
0338  * -PADCTRL_GPIO_IRQ_CTRL[X]
0339  * bit[0-16]: 7 bits to choose gpio source for irq line 2*[X] - 2
0340  * bit[16-22]:7 bits to choose gpio source for irq line 2*[X] - 1
0341  * where X = 1-6
0342  *
0343  * -PADCTRL_GPIO_IRQ_CTRL[7]
0344  * bit[0-11]: both edge trigger
0345  */
0346 static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
0347                       unsigned int type, u32 *channel_hwirq)
0348 {
0349     u32 val = 0;
0350     unsigned int idx;
0351 
0352     idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
0353 
0354     type &= IRQ_TYPE_SENSE_MASK;
0355 
0356     meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
0357 
0358     if (type == IRQ_TYPE_EDGE_BOTH) {
0359         val |= BIT(ctl->params->edge_both_offset + idx);
0360         meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
0361                        BIT(ctl->params->edge_both_offset + idx), val);
0362         return 0;
0363     }
0364 
0365     if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
0366         val |= BIT(ctl->params->pol_low_offset + idx);
0367 
0368     if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
0369         val |= BIT(ctl->params->edge_single_offset + idx);
0370 
0371     meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
0372                    BIT(idx) | BIT(12 + idx), val);
0373     return 0;
0374 };
0375 
0376 static unsigned int meson_gpio_irq_type_output(unsigned int type)
0377 {
0378     unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
0379 
0380     type &= ~IRQ_TYPE_SENSE_MASK;
0381 
0382     /*
0383      * The polarity of the signal provided to the GIC should always
0384      * be high.
0385      */
0386     if (sense & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
0387         type |= IRQ_TYPE_LEVEL_HIGH;
0388     else
0389         type |= IRQ_TYPE_EDGE_RISING;
0390 
0391     return type;
0392 }
0393 
0394 static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type)
0395 {
0396     struct meson_gpio_irq_controller *ctl = data->domain->host_data;
0397     u32 *channel_hwirq = irq_data_get_irq_chip_data(data);
0398     int ret;
0399 
0400     ret = ctl->params->ops.gpio_irq_set_type(ctl, type, channel_hwirq);
0401     if (ret)
0402         return ret;
0403 
0404     return irq_chip_set_type_parent(data,
0405                     meson_gpio_irq_type_output(type));
0406 }
0407 
0408 static struct irq_chip meson_gpio_irq_chip = {
0409     .name           = "meson-gpio-irqchip",
0410     .irq_mask       = irq_chip_mask_parent,
0411     .irq_unmask     = irq_chip_unmask_parent,
0412     .irq_eoi        = irq_chip_eoi_parent,
0413     .irq_set_type       = meson_gpio_irq_set_type,
0414     .irq_retrigger      = irq_chip_retrigger_hierarchy,
0415 #ifdef CONFIG_SMP
0416     .irq_set_affinity   = irq_chip_set_affinity_parent,
0417 #endif
0418     .flags          = IRQCHIP_SET_TYPE_MASKED,
0419 };
0420 
0421 static int meson_gpio_irq_domain_translate(struct irq_domain *domain,
0422                        struct irq_fwspec *fwspec,
0423                        unsigned long *hwirq,
0424                        unsigned int *type)
0425 {
0426     if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
0427         *hwirq  = fwspec->param[0];
0428         *type   = fwspec->param[1];
0429         return 0;
0430     }
0431 
0432     return -EINVAL;
0433 }
0434 
0435 static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain,
0436                        unsigned int virq,
0437                        u32 hwirq,
0438                        unsigned int type)
0439 {
0440     struct irq_fwspec fwspec;
0441 
0442     fwspec.fwnode = domain->parent->fwnode;
0443     fwspec.param_count = 3;
0444     fwspec.param[0] = 0;    /* SPI */
0445     fwspec.param[1] = hwirq;
0446     fwspec.param[2] = meson_gpio_irq_type_output(type);
0447 
0448     return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
0449 }
0450 
0451 static int meson_gpio_irq_domain_alloc(struct irq_domain *domain,
0452                        unsigned int virq,
0453                        unsigned int nr_irqs,
0454                        void *data)
0455 {
0456     struct irq_fwspec *fwspec = data;
0457     struct meson_gpio_irq_controller *ctl = domain->host_data;
0458     unsigned long hwirq;
0459     u32 *channel_hwirq;
0460     unsigned int type;
0461     int ret;
0462 
0463     if (WARN_ON(nr_irqs != 1))
0464         return -EINVAL;
0465 
0466     ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type);
0467     if (ret)
0468         return ret;
0469 
0470     ret = meson_gpio_irq_request_channel(ctl, hwirq, &channel_hwirq);
0471     if (ret)
0472         return ret;
0473 
0474     ret = meson_gpio_irq_allocate_gic_irq(domain, virq,
0475                           *channel_hwirq, type);
0476     if (ret < 0) {
0477         pr_err("failed to allocate gic irq %u\n", *channel_hwirq);
0478         meson_gpio_irq_release_channel(ctl, channel_hwirq);
0479         return ret;
0480     }
0481 
0482     irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
0483                       &meson_gpio_irq_chip, channel_hwirq);
0484 
0485     return 0;
0486 }
0487 
0488 static void meson_gpio_irq_domain_free(struct irq_domain *domain,
0489                        unsigned int virq,
0490                        unsigned int nr_irqs)
0491 {
0492     struct meson_gpio_irq_controller *ctl = domain->host_data;
0493     struct irq_data *irq_data;
0494     u32 *channel_hwirq;
0495 
0496     if (WARN_ON(nr_irqs != 1))
0497         return;
0498 
0499     irq_domain_free_irqs_parent(domain, virq, 1);
0500 
0501     irq_data = irq_domain_get_irq_data(domain, virq);
0502     channel_hwirq = irq_data_get_irq_chip_data(irq_data);
0503 
0504     meson_gpio_irq_release_channel(ctl, channel_hwirq);
0505 }
0506 
0507 static const struct irq_domain_ops meson_gpio_irq_domain_ops = {
0508     .alloc      = meson_gpio_irq_domain_alloc,
0509     .free       = meson_gpio_irq_domain_free,
0510     .translate  = meson_gpio_irq_domain_translate,
0511 };
0512 
0513 static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_irq_controller *ctl)
0514 {
0515     const struct of_device_id *match;
0516     int ret;
0517 
0518     match = of_match_node(meson_irq_gpio_matches, node);
0519     if (!match)
0520         return -ENODEV;
0521 
0522     ctl->params = match->data;
0523 
0524     ret = of_property_read_variable_u32_array(node,
0525                           "amlogic,channel-interrupts",
0526                           ctl->channel_irqs,
0527                           ctl->params->nr_channels,
0528                           ctl->params->nr_channels);
0529     if (ret < 0) {
0530         pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
0531         return ret;
0532     }
0533 
0534     ctl->params->ops.gpio_irq_init(ctl);
0535 
0536     return 0;
0537 }
0538 
0539 static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *parent)
0540 {
0541     struct irq_domain *domain, *parent_domain;
0542     struct meson_gpio_irq_controller *ctl;
0543     int ret;
0544 
0545     if (!parent) {
0546         pr_err("missing parent interrupt node\n");
0547         return -ENODEV;
0548     }
0549 
0550     parent_domain = irq_find_host(parent);
0551     if (!parent_domain) {
0552         pr_err("unable to obtain parent domain\n");
0553         return -ENXIO;
0554     }
0555 
0556     ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
0557     if (!ctl)
0558         return -ENOMEM;
0559 
0560     spin_lock_init(&ctl->lock);
0561 
0562     ctl->base = of_iomap(node, 0);
0563     if (!ctl->base) {
0564         ret = -ENOMEM;
0565         goto free_ctl;
0566     }
0567 
0568     ret = meson_gpio_irq_parse_dt(node, ctl);
0569     if (ret)
0570         goto free_channel_irqs;
0571 
0572     domain = irq_domain_create_hierarchy(parent_domain, 0,
0573                          ctl->params->nr_hwirq,
0574                          of_node_to_fwnode(node),
0575                          &meson_gpio_irq_domain_ops,
0576                          ctl);
0577     if (!domain) {
0578         pr_err("failed to add domain\n");
0579         ret = -ENODEV;
0580         goto free_channel_irqs;
0581     }
0582 
0583     pr_info("%d to %d gpio interrupt mux initialized\n",
0584         ctl->params->nr_hwirq, ctl->params->nr_channels);
0585 
0586     return 0;
0587 
0588 free_channel_irqs:
0589     iounmap(ctl->base);
0590 free_ctl:
0591     kfree(ctl);
0592 
0593     return ret;
0594 }
0595 
0596 IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc)
0597 IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
0598 IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc)
0599 
0600 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
0601 MODULE_LICENSE("GPL v2");
0602 MODULE_ALIAS("platform:meson-gpio-intc");