Lines Matching +full:io +full:- +full:channel +full:- +full:mux
1 // SPDX-License-Identifier: GPL-2.0-only
11 #include <linux/io.h>
36 #define REG_EDGE_POL_EDGE(params, x) BIT((params)->edge_single_offset + (x))
37 #define REG_EDGE_POL_LOW(params, x) BIT((params)->pol_low_offset + (x))
38 #define REG_BOTH_EDGE(params, x) BIT((params)->edge_both_offset + (x))
48 unsigned int channel, unsigned long hwirq);
51 unsigned int channel,
57 unsigned int channel, unsigned long hwirq);
125 { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
126 { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
127 { .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params },
128 { .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params },
129 { .compatible = "amlogic,meson-axg-gpio-intc", .data = &axg_params },
130 { .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
131 { .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
132 { .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
150 spin_lock_irqsave(&ctl->lock, flags); in meson_gpio_irq_update_bits()
152 tmp = readl_relaxed(ctl->base + reg); in meson_gpio_irq_update_bits()
155 writel_relaxed(tmp, ctl->base + reg); in meson_gpio_irq_update_bits()
157 spin_unlock_irqrestore(&ctl->lock, flags); in meson_gpio_irq_update_bits()
165 unsigned int channel, unsigned long hwirq) in meson8_gpio_irq_sel_pin() argument
170 reg_offset = (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL; in meson8_gpio_irq_sel_pin()
171 bit_offset = REG_PIN_SEL_SHIFT(channel); in meson8_gpio_irq_sel_pin()
174 ctl->params->pin_sel_mask << bit_offset, in meson8_gpio_irq_sel_pin()
179 unsigned int channel, in meson_a1_gpio_irq_sel_pin() argument
185 bit_offset = ((channel % 2) == 0) ? 0 : 16; in meson_a1_gpio_irq_sel_pin()
186 reg_offset = REG_PIN_A1_SEL + ((channel / 2) << 2); in meson_a1_gpio_irq_sel_pin()
189 ctl->params->pin_sel_mask << bit_offset, in meson_a1_gpio_irq_sel_pin()
207 spin_lock_irqsave(&ctl->lock, flags); in meson_gpio_irq_request_channel()
209 /* Find a free channel */ in meson_gpio_irq_request_channel()
210 idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL); in meson_gpio_irq_request_channel()
212 spin_unlock_irqrestore(&ctl->lock, flags); in meson_gpio_irq_request_channel()
213 pr_err("No channel available\n"); in meson_gpio_irq_request_channel()
214 return -ENOSPC; in meson_gpio_irq_request_channel()
217 /* Mark the channel as used */ in meson_gpio_irq_request_channel()
218 set_bit(idx, ctl->channel_map); in meson_gpio_irq_request_channel()
220 spin_unlock_irqrestore(&ctl->lock, flags); in meson_gpio_irq_request_channel()
223 * Setup the mux of the channel to route the signal of the pad in meson_gpio_irq_request_channel()
226 ctl->params->ops.gpio_irq_sel_pin(ctl, idx, hwirq); in meson_gpio_irq_request_channel()
229 * Get the hwirq number assigned to this channel through in meson_gpio_irq_request_channel()
231 * method is that we can also retrieve the channel index with in meson_gpio_irq_request_channel()
234 *channel_hwirq = &(ctl->channel_irqs[idx]); in meson_gpio_irq_request_channel()
236 pr_debug("hwirq %lu assigned to channel %d - irq %u\n", in meson_gpio_irq_request_channel()
246 return channel_hwirq - ctl->channel_irqs; in meson_gpio_irq_get_channel_idx()
256 clear_bit(idx, ctl->channel_map); in meson_gpio_irq_release_channel()
267 params = ctl->params; in meson_gpio_irq_type_setup()
284 if (!params->support_edge_both) in meson_gpio_irq_type_setup()
285 return -EINVAL; in meson_gpio_irq_type_setup()
322 struct meson_gpio_irq_controller *ctl = data->domain->host_data; in meson_gpio_irq_set_type()
335 .name = "meson-gpio-irqchip",
352 if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { in meson_gpio_irq_domain_translate()
353 *hwirq = fwspec->param[0]; in meson_gpio_irq_domain_translate()
354 *type = fwspec->param[1]; in meson_gpio_irq_domain_translate()
358 return -EINVAL; in meson_gpio_irq_domain_translate()
368 fwspec.fwnode = domain->parent->fwnode; in meson_gpio_irq_allocate_gic_irq()
383 struct meson_gpio_irq_controller *ctl = domain->host_data; in meson_gpio_irq_domain_alloc()
390 return -EINVAL; in meson_gpio_irq_domain_alloc()
418 struct meson_gpio_irq_controller *ctl = domain->host_data; in meson_gpio_irq_domain_free()
447 return -ENODEV; in meson_gpio_irq_parse_dt()
449 ctl->params = match->data; in meson_gpio_irq_parse_dt()
452 "amlogic,channel-interrupts", in meson_gpio_irq_parse_dt()
453 ctl->channel_irqs, in meson_gpio_irq_parse_dt()
457 pr_err("can't get %d channel interrupts\n", NUM_CHANNEL); in meson_gpio_irq_parse_dt()
461 ctl->params->ops.gpio_irq_init(ctl); in meson_gpio_irq_parse_dt()
475 return -ENODEV; in meson_gpio_irq_of_init()
481 return -ENXIO; in meson_gpio_irq_of_init()
486 return -ENOMEM; in meson_gpio_irq_of_init()
488 spin_lock_init(&ctl->lock); in meson_gpio_irq_of_init()
490 ctl->base = of_iomap(node, 0); in meson_gpio_irq_of_init()
491 if (!ctl->base) { in meson_gpio_irq_of_init()
492 ret = -ENOMEM; in meson_gpio_irq_of_init()
501 ctl->params->nr_hwirq, in meson_gpio_irq_of_init()
507 ret = -ENODEV; in meson_gpio_irq_of_init()
511 pr_info("%d to %d gpio interrupt mux initialized\n", in meson_gpio_irq_of_init()
512 ctl->params->nr_hwirq, NUM_CHANNEL); in meson_gpio_irq_of_init()
517 iounmap(ctl->base); in meson_gpio_irq_of_init()
524 IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc",