1 /*
2  * Copyright (c) 2015 Endless Mobile, Inc.
3  * Author: Carlo Caione <carlo@endlessm.com>
4  * Copyright (c) 2016 BayLibre, SAS.
5  * Author: Jerome Brunet <jbrunet@baylibre.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  * The full GNU General Public License is included in this distribution
19  * in the file called COPYING.
20  */
21 
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 
24 #include <linux/io.h>
25 #include <linux/module.h>
26 #include <linux/irq.h>
27 #include <linux/irqdomain.h>
28 #include <linux/irqchip.h>
29 #include <linux/of.h>
30 #include <linux/of_address.h>
31 
32 #define NUM_CHANNEL 8
33 #define MAX_INPUT_MUX 256
34 
35 #define REG_EDGE_POL	0x00
36 #define REG_PIN_03_SEL	0x04
37 #define REG_PIN_47_SEL	0x08
38 #define REG_FILTER_SEL	0x0c
39 
40 #define REG_EDGE_POL_MASK(x)	(BIT(x) | BIT(16 + (x)))
41 #define REG_EDGE_POL_EDGE(x)	BIT(x)
42 #define REG_EDGE_POL_LOW(x)	BIT(16 + (x))
43 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
44 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
45 
46 struct meson_gpio_irq_params {
47 	unsigned int nr_hwirq;
48 };
49 
50 static const struct meson_gpio_irq_params meson8_params = {
51 	.nr_hwirq = 134,
52 };
53 
54 static const struct meson_gpio_irq_params meson8b_params = {
55 	.nr_hwirq = 119,
56 };
57 
58 static const struct meson_gpio_irq_params gxbb_params = {
59 	.nr_hwirq = 133,
60 };
61 
62 static const struct meson_gpio_irq_params gxl_params = {
63 	.nr_hwirq = 110,
64 };
65 
66 static const struct meson_gpio_irq_params axg_params = {
67 	.nr_hwirq = 100,
68 };
69 
70 static const struct of_device_id meson_irq_gpio_matches[] = {
71 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
72 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
73 	{ .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params },
74 	{ .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params },
75 	{ .compatible = "amlogic,meson-axg-gpio-intc", .data = &axg_params },
76 	{ }
77 };
78 
79 struct meson_gpio_irq_controller {
80 	unsigned int nr_hwirq;
81 	void __iomem *base;
82 	u32 channel_irqs[NUM_CHANNEL];
83 	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
84 	spinlock_t lock;
85 };
86 
87 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
88 				       unsigned int reg, u32 mask, u32 val)
89 {
90 	u32 tmp;
91 
92 	tmp = readl_relaxed(ctl->base + reg);
93 	tmp &= ~mask;
94 	tmp |= val;
95 	writel_relaxed(tmp, ctl->base + reg);
96 }
97 
98 static unsigned int meson_gpio_irq_channel_to_reg(unsigned int channel)
99 {
100 	return (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL;
101 }
102 
103 static int
104 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
105 			       unsigned long  hwirq,
106 			       u32 **channel_hwirq)
107 {
108 	unsigned int reg, idx;
109 
110 	spin_lock(&ctl->lock);
111 
112 	/* Find a free channel */
113 	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
114 	if (idx >= NUM_CHANNEL) {
115 		spin_unlock(&ctl->lock);
116 		pr_err("No channel available\n");
117 		return -ENOSPC;
118 	}
119 
120 	/* Mark the channel as used */
121 	set_bit(idx, ctl->channel_map);
122 
123 	/*
124 	 * Setup the mux of the channel to route the signal of the pad
125 	 * to the appropriate input of the GIC
126 	 */
127 	reg = meson_gpio_irq_channel_to_reg(idx);
128 	meson_gpio_irq_update_bits(ctl, reg,
129 				   0xff << REG_PIN_SEL_SHIFT(idx),
130 				   hwirq << REG_PIN_SEL_SHIFT(idx));
131 
132 	/*
133 	 * Get the hwirq number assigned to this channel through
134 	 * a pointer the channel_irq table. The added benifit of this
135 	 * method is that we can also retrieve the channel index with
136 	 * it, using the table base.
137 	 */
138 	*channel_hwirq = &(ctl->channel_irqs[idx]);
139 
140 	spin_unlock(&ctl->lock);
141 
142 	pr_debug("hwirq %lu assigned to channel %d - irq %u\n",
143 		 hwirq, idx, **channel_hwirq);
144 
145 	return 0;
146 }
147 
148 static unsigned int
149 meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl,
150 			       u32 *channel_hwirq)
151 {
152 	return channel_hwirq - ctl->channel_irqs;
153 }
154 
155 static void
156 meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl,
157 			       u32 *channel_hwirq)
158 {
159 	unsigned int idx;
160 
161 	idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
162 	clear_bit(idx, ctl->channel_map);
163 }
164 
165 static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
166 				     unsigned int type,
167 				     u32 *channel_hwirq)
168 {
169 	u32 val = 0;
170 	unsigned int idx;
171 
172 	idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
173 
174 	/*
175 	 * The controller has a filter block to operate in either LEVEL or
176 	 * EDGE mode, then signal is sent to the GIC. To enable LEVEL_LOW and
177 	 * EDGE_FALLING support (which the GIC does not support), the filter
178 	 * block is also able to invert the input signal it gets before
179 	 * providing it to the GIC.
180 	 */
181 	type &= IRQ_TYPE_SENSE_MASK;
182 
183 	if (type == IRQ_TYPE_EDGE_BOTH)
184 		return -EINVAL;
185 
186 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
187 		val |= REG_EDGE_POL_EDGE(idx);
188 
189 	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
190 		val |= REG_EDGE_POL_LOW(idx);
191 
192 	spin_lock(&ctl->lock);
193 
194 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
195 				   REG_EDGE_POL_MASK(idx), val);
196 
197 	spin_unlock(&ctl->lock);
198 
199 	return 0;
200 }
201 
202 static unsigned int meson_gpio_irq_type_output(unsigned int type)
203 {
204 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
205 
206 	type &= ~IRQ_TYPE_SENSE_MASK;
207 
208 	/*
209 	 * The polarity of the signal provided to the GIC should always
210 	 * be high.
211 	 */
212 	if (sense & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
213 		type |= IRQ_TYPE_LEVEL_HIGH;
214 	else if (sense & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
215 		type |= IRQ_TYPE_EDGE_RISING;
216 
217 	return type;
218 }
219 
220 static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type)
221 {
222 	struct meson_gpio_irq_controller *ctl = data->domain->host_data;
223 	u32 *channel_hwirq = irq_data_get_irq_chip_data(data);
224 	int ret;
225 
226 	ret = meson_gpio_irq_type_setup(ctl, type, channel_hwirq);
227 	if (ret)
228 		return ret;
229 
230 	return irq_chip_set_type_parent(data,
231 					meson_gpio_irq_type_output(type));
232 }
233 
234 static struct irq_chip meson_gpio_irq_chip = {
235 	.name			= "meson-gpio-irqchip",
236 	.irq_mask		= irq_chip_mask_parent,
237 	.irq_unmask		= irq_chip_unmask_parent,
238 	.irq_eoi		= irq_chip_eoi_parent,
239 	.irq_set_type		= meson_gpio_irq_set_type,
240 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
241 #ifdef CONFIG_SMP
242 	.irq_set_affinity	= irq_chip_set_affinity_parent,
243 #endif
244 	.flags			= IRQCHIP_SET_TYPE_MASKED,
245 };
246 
247 static int meson_gpio_irq_domain_translate(struct irq_domain *domain,
248 					   struct irq_fwspec *fwspec,
249 					   unsigned long *hwirq,
250 					   unsigned int *type)
251 {
252 	if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
253 		*hwirq	= fwspec->param[0];
254 		*type	= fwspec->param[1];
255 		return 0;
256 	}
257 
258 	return -EINVAL;
259 }
260 
261 static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain,
262 					   unsigned int virq,
263 					   u32 hwirq,
264 					   unsigned int type)
265 {
266 	struct irq_fwspec fwspec;
267 
268 	fwspec.fwnode = domain->parent->fwnode;
269 	fwspec.param_count = 3;
270 	fwspec.param[0] = 0;	/* SPI */
271 	fwspec.param[1] = hwirq;
272 	fwspec.param[2] = meson_gpio_irq_type_output(type);
273 
274 	return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
275 }
276 
277 static int meson_gpio_irq_domain_alloc(struct irq_domain *domain,
278 				       unsigned int virq,
279 				       unsigned int nr_irqs,
280 				       void *data)
281 {
282 	struct irq_fwspec *fwspec = data;
283 	struct meson_gpio_irq_controller *ctl = domain->host_data;
284 	unsigned long hwirq;
285 	u32 *channel_hwirq;
286 	unsigned int type;
287 	int ret;
288 
289 	if (WARN_ON(nr_irqs != 1))
290 		return -EINVAL;
291 
292 	ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type);
293 	if (ret)
294 		return ret;
295 
296 	ret = meson_gpio_irq_request_channel(ctl, hwirq, &channel_hwirq);
297 	if (ret)
298 		return ret;
299 
300 	ret = meson_gpio_irq_allocate_gic_irq(domain, virq,
301 					      *channel_hwirq, type);
302 	if (ret < 0) {
303 		pr_err("failed to allocate gic irq %u\n", *channel_hwirq);
304 		meson_gpio_irq_release_channel(ctl, channel_hwirq);
305 		return ret;
306 	}
307 
308 	irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
309 				      &meson_gpio_irq_chip, channel_hwirq);
310 
311 	return 0;
312 }
313 
314 static void meson_gpio_irq_domain_free(struct irq_domain *domain,
315 				       unsigned int virq,
316 				       unsigned int nr_irqs)
317 {
318 	struct meson_gpio_irq_controller *ctl = domain->host_data;
319 	struct irq_data *irq_data;
320 	u32 *channel_hwirq;
321 
322 	if (WARN_ON(nr_irqs != 1))
323 		return;
324 
325 	irq_domain_free_irqs_parent(domain, virq, 1);
326 
327 	irq_data = irq_domain_get_irq_data(domain, virq);
328 	channel_hwirq = irq_data_get_irq_chip_data(irq_data);
329 
330 	meson_gpio_irq_release_channel(ctl, channel_hwirq);
331 }
332 
333 static const struct irq_domain_ops meson_gpio_irq_domain_ops = {
334 	.alloc		= meson_gpio_irq_domain_alloc,
335 	.free		= meson_gpio_irq_domain_free,
336 	.translate	= meson_gpio_irq_domain_translate,
337 };
338 
339 static int __init meson_gpio_irq_parse_dt(struct device_node *node,
340 					  struct meson_gpio_irq_controller *ctl)
341 {
342 	const struct of_device_id *match;
343 	const struct meson_gpio_irq_params *params;
344 	int ret;
345 
346 	match = of_match_node(meson_irq_gpio_matches, node);
347 	if (!match)
348 		return -ENODEV;
349 
350 	params = match->data;
351 	ctl->nr_hwirq = params->nr_hwirq;
352 
353 	ret = of_property_read_variable_u32_array(node,
354 						  "amlogic,channel-interrupts",
355 						  ctl->channel_irqs,
356 						  NUM_CHANNEL,
357 						  NUM_CHANNEL);
358 	if (ret < 0) {
359 		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
360 		return ret;
361 	}
362 
363 	return 0;
364 }
365 
366 static int __init meson_gpio_irq_of_init(struct device_node *node,
367 					 struct device_node *parent)
368 {
369 	struct irq_domain *domain, *parent_domain;
370 	struct meson_gpio_irq_controller *ctl;
371 	int ret;
372 
373 	if (!parent) {
374 		pr_err("missing parent interrupt node\n");
375 		return -ENODEV;
376 	}
377 
378 	parent_domain = irq_find_host(parent);
379 	if (!parent_domain) {
380 		pr_err("unable to obtain parent domain\n");
381 		return -ENXIO;
382 	}
383 
384 	ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
385 	if (!ctl)
386 		return -ENOMEM;
387 
388 	spin_lock_init(&ctl->lock);
389 
390 	ctl->base = of_iomap(node, 0);
391 	if (!ctl->base) {
392 		ret = -ENOMEM;
393 		goto free_ctl;
394 	}
395 
396 	ret = meson_gpio_irq_parse_dt(node, ctl);
397 	if (ret)
398 		goto free_channel_irqs;
399 
400 	domain = irq_domain_create_hierarchy(parent_domain, 0, ctl->nr_hwirq,
401 					     of_node_to_fwnode(node),
402 					     &meson_gpio_irq_domain_ops,
403 					     ctl);
404 	if (!domain) {
405 		pr_err("failed to add domain\n");
406 		ret = -ENODEV;
407 		goto free_channel_irqs;
408 	}
409 
410 	pr_info("%d to %d gpio interrupt mux initialized\n",
411 		ctl->nr_hwirq, NUM_CHANNEL);
412 
413 	return 0;
414 
415 free_channel_irqs:
416 	iounmap(ctl->base);
417 free_ctl:
418 	kfree(ctl);
419 
420 	return ret;
421 }
422 
423 IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc",
424 		meson_gpio_irq_of_init);
425