1 /*
2  * Copyright 2008 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 
29 /**
30  * DOC: Interrupt Handling
31  *
32  * Interrupts generated within GPU hardware raise interrupt requests that are
33  * passed to amdgpu IRQ handler which is responsible for detecting source and
34  * type of the interrupt and dispatching matching handlers. If handling an
35  * interrupt requires calling kernel functions that may sleep processing is
36  * dispatched to work handlers.
37  *
38  * If MSI functionality is not disabled by module parameter then MSI
39  * support will be enabled.
40  *
41  * For GPU interrupt sources that may be driven by another driver, IRQ domain
42  * support is used (with mapping between virtual and hardware IRQs).
43  */
44 
45 #include <linux/irq.h>
46 #include <linux/pci.h>
47 
48 #include <drm/drm_crtc_helper.h>
49 #include <drm/drm_irq.h>
50 #include <drm/drm_vblank.h>
51 #include <drm/amdgpu_drm.h>
52 #include "amdgpu.h"
53 #include "amdgpu_ih.h"
54 #include "atom.h"
55 #include "amdgpu_connectors.h"
56 #include "amdgpu_trace.h"
57 #include "amdgpu_amdkfd.h"
58 #include "amdgpu_ras.h"
59 
60 #include <linux/pm_runtime.h>
61 
62 #ifdef CONFIG_DRM_AMD_DC
63 #include "amdgpu_dm_irq.h"
64 #endif
65 
66 #define AMDGPU_WAIT_IDLE_TIMEOUT 200
67 
68 const char *soc15_ih_clientid_name[] = {
69 	"IH",
70 	"SDMA2 or ACP",
71 	"ATHUB",
72 	"BIF",
73 	"SDMA3 or DCE",
74 	"SDMA4 or ISP",
75 	"VMC1 or PCIE0",
76 	"RLC",
77 	"SDMA0",
78 	"SDMA1",
79 	"SE0SH",
80 	"SE1SH",
81 	"SE2SH",
82 	"SE3SH",
83 	"VCN1 or UVD1",
84 	"THM",
85 	"VCN or UVD",
86 	"SDMA5 or VCE0",
87 	"VMC",
88 	"SDMA6 or XDMA",
89 	"GRBM_CP",
90 	"ATS",
91 	"ROM_SMUIO",
92 	"DF",
93 	"SDMA7 or VCE1",
94 	"PWR",
95 	"reserved",
96 	"UTCL2",
97 	"EA",
98 	"UTCL2LOG",
99 	"MP0",
100 	"MP1"
101 };
102 
103 /**
104  * amdgpu_hotplug_work_func - work handler for display hotplug event
105  *
106  * @work: work struct pointer
107  *
108  * This is the hotplug event work handler (all ASICs).
109  * The work gets scheduled from the IRQ handler if there
110  * was a hotplug interrupt.  It walks through the connector table
111  * and calls hotplug handler for each connector. After this, it sends
112  * a DRM hotplug event to alert userspace.
113  *
114  * This design approach is required in order to defer hotplug event handling
115  * from the IRQ handler to a work handler because hotplug handler has to use
116  * mutexes which cannot be locked in an IRQ handler (since &mutex_lock may
117  * sleep).
118  */
119 static void amdgpu_hotplug_work_func(struct work_struct *work)
120 {
121 	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
122 						  hotplug_work);
123 	struct drm_device *dev = adev_to_drm(adev);
124 	struct drm_mode_config *mode_config = &dev->mode_config;
125 	struct drm_connector *connector;
126 	struct drm_connector_list_iter iter;
127 
128 	mutex_lock(&mode_config->mutex);
129 	drm_connector_list_iter_begin(dev, &iter);
130 	drm_for_each_connector_iter(connector, &iter)
131 		amdgpu_connector_hotplug(connector);
132 	drm_connector_list_iter_end(&iter);
133 	mutex_unlock(&mode_config->mutex);
134 	/* Just fire off a uevent and let userspace tell us what to do */
135 	drm_helper_hpd_irq_event(dev);
136 }
137 
138 /**
139  * amdgpu_irq_disable_all - disable *all* interrupts
140  *
141  * @adev: amdgpu device pointer
142  *
143  * Disable all types of interrupts from all sources.
144  */
145 void amdgpu_irq_disable_all(struct amdgpu_device *adev)
146 {
147 	unsigned long irqflags;
148 	unsigned i, j, k;
149 	int r;
150 
151 	spin_lock_irqsave(&adev->irq.lock, irqflags);
152 	for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
153 		if (!adev->irq.client[i].sources)
154 			continue;
155 
156 		for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) {
157 			struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
158 
159 			if (!src || !src->funcs->set || !src->num_types)
160 				continue;
161 
162 			for (k = 0; k < src->num_types; ++k) {
163 				atomic_set(&src->enabled_types[k], 0);
164 				r = src->funcs->set(adev, src, k,
165 						    AMDGPU_IRQ_STATE_DISABLE);
166 				if (r)
167 					DRM_ERROR("error disabling interrupt (%d)\n",
168 						  r);
169 			}
170 		}
171 	}
172 	spin_unlock_irqrestore(&adev->irq.lock, irqflags);
173 }
174 
175 /**
176  * amdgpu_irq_handler - IRQ handler
177  *
178  * @irq: IRQ number (unused)
179  * @arg: pointer to DRM device
180  *
181  * IRQ handler for amdgpu driver (all ASICs).
182  *
183  * Returns:
184  * result of handling the IRQ, as defined by &irqreturn_t
185  */
186 irqreturn_t amdgpu_irq_handler(int irq, void *arg)
187 {
188 	struct drm_device *dev = (struct drm_device *) arg;
189 	struct amdgpu_device *adev = drm_to_adev(dev);
190 	irqreturn_t ret;
191 
192 	ret = amdgpu_ih_process(adev, &adev->irq.ih);
193 	if (ret == IRQ_HANDLED)
194 		pm_runtime_mark_last_busy(dev->dev);
195 
196 	/* For the hardware that cannot enable bif ring for both ras_controller_irq
197          * and ras_err_evnet_athub_irq ih cookies, the driver has to poll status
198 	 * register to check whether the interrupt is triggered or not, and properly
199 	 * ack the interrupt if it is there
200 	 */
201 	if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__PCIE_BIF)) {
202 		if (adev->nbio.funcs &&
203 		    adev->nbio.funcs->handle_ras_controller_intr_no_bifring)
204 			adev->nbio.funcs->handle_ras_controller_intr_no_bifring(adev);
205 
206 		if (adev->nbio.funcs &&
207 		    adev->nbio.funcs->handle_ras_err_event_athub_intr_no_bifring)
208 			adev->nbio.funcs->handle_ras_err_event_athub_intr_no_bifring(adev);
209 	}
210 
211 	return ret;
212 }
213 
214 /**
215  * amdgpu_irq_handle_ih1 - kick of processing for IH1
216  *
217  * @work: work structure in struct amdgpu_irq
218  *
219  * Kick of processing IH ring 1.
220  */
221 static void amdgpu_irq_handle_ih1(struct work_struct *work)
222 {
223 	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
224 						  irq.ih1_work);
225 
226 	amdgpu_ih_process(adev, &adev->irq.ih1);
227 }
228 
229 /**
230  * amdgpu_irq_handle_ih2 - kick of processing for IH2
231  *
232  * @work: work structure in struct amdgpu_irq
233  *
234  * Kick of processing IH ring 2.
235  */
236 static void amdgpu_irq_handle_ih2(struct work_struct *work)
237 {
238 	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
239 						  irq.ih2_work);
240 
241 	amdgpu_ih_process(adev, &adev->irq.ih2);
242 }
243 
244 /**
245  * amdgpu_irq_handle_ih_soft - kick of processing for ih_soft
246  *
247  * @work: work structure in struct amdgpu_irq
248  *
249  * Kick of processing IH soft ring.
250  */
251 static void amdgpu_irq_handle_ih_soft(struct work_struct *work)
252 {
253 	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
254 						  irq.ih_soft_work);
255 
256 	amdgpu_ih_process(adev, &adev->irq.ih_soft);
257 }
258 
259 /**
260  * amdgpu_msi_ok - check whether MSI functionality is enabled
261  *
262  * @adev: amdgpu device pointer (unused)
263  *
264  * Checks whether MSI functionality has been disabled via module parameter
265  * (all ASICs).
266  *
267  * Returns:
268  * *true* if MSIs are allowed to be enabled or *false* otherwise
269  */
270 static bool amdgpu_msi_ok(struct amdgpu_device *adev)
271 {
272 	if (amdgpu_msi == 1)
273 		return true;
274 	else if (amdgpu_msi == 0)
275 		return false;
276 
277 	return true;
278 }
279 
280 /**
281  * amdgpu_irq_init - initialize interrupt handling
282  *
283  * @adev: amdgpu device pointer
284  *
285  * Sets up work functions for hotplug and reset interrupts, enables MSI
286  * functionality, initializes vblank, hotplug and reset interrupt handling.
287  *
288  * Returns:
289  * 0 on success or error code on failure
290  */
291 int amdgpu_irq_init(struct amdgpu_device *adev)
292 {
293 	int r = 0;
294 
295 	spin_lock_init(&adev->irq.lock);
296 
297 	/* Enable MSI if not disabled by module parameter */
298 	adev->irq.msi_enabled = false;
299 
300 	if (amdgpu_msi_ok(adev)) {
301 		int nvec = pci_msix_vec_count(adev->pdev);
302 		unsigned int flags;
303 
304 		if (nvec <= 0) {
305 			flags = PCI_IRQ_MSI;
306 		} else {
307 			flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
308 		}
309 		/* we only need one vector */
310 		nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
311 		if (nvec > 0) {
312 			adev->irq.msi_enabled = true;
313 			dev_dbg(adev->dev, "using MSI/MSI-X.\n");
314 		}
315 	}
316 
317 	if (!amdgpu_device_has_dc_support(adev)) {
318 		if (!adev->enable_virtual_display)
319 			/* Disable vblank IRQs aggressively for power-saving */
320 			/* XXX: can this be enabled for DC? */
321 			adev_to_drm(adev)->vblank_disable_immediate = true;
322 
323 		r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc);
324 		if (r)
325 			return r;
326 
327 		/* Pre-DCE11 */
328 		INIT_WORK(&adev->hotplug_work,
329 				amdgpu_hotplug_work_func);
330 	}
331 
332 	INIT_WORK(&adev->irq.ih1_work, amdgpu_irq_handle_ih1);
333 	INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
334 	INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
335 
336 	adev->irq.installed = true;
337 	/* Use vector 0 for MSI-X */
338 	r = drm_irq_install(adev_to_drm(adev), pci_irq_vector(adev->pdev, 0));
339 	if (r) {
340 		adev->irq.installed = false;
341 		if (!amdgpu_device_has_dc_support(adev))
342 			flush_work(&adev->hotplug_work);
343 		return r;
344 	}
345 	adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
346 
347 	DRM_DEBUG("amdgpu: irq initialized.\n");
348 	return 0;
349 }
350 
351 /**
352  * amdgpu_irq_fini - shut down interrupt handling
353  *
354  * @adev: amdgpu device pointer
355  *
356  * Tears down work functions for hotplug and reset interrupts, disables MSI
357  * functionality, shuts down vblank, hotplug and reset interrupt handling,
358  * turns off interrupts from all sources (all ASICs).
359  */
360 void amdgpu_irq_fini(struct amdgpu_device *adev)
361 {
362 	unsigned i, j;
363 
364 	if (adev->irq.installed) {
365 		drm_irq_uninstall(adev_to_drm(adev));
366 		adev->irq.installed = false;
367 		if (adev->irq.msi_enabled)
368 			pci_free_irq_vectors(adev->pdev);
369 		if (!amdgpu_device_has_dc_support(adev))
370 			flush_work(&adev->hotplug_work);
371 	}
372 
373 	for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
374 		if (!adev->irq.client[i].sources)
375 			continue;
376 
377 		for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) {
378 			struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
379 
380 			if (!src)
381 				continue;
382 
383 			kfree(src->enabled_types);
384 			src->enabled_types = NULL;
385 			if (src->data) {
386 				kfree(src->data);
387 				kfree(src);
388 				adev->irq.client[i].sources[j] = NULL;
389 			}
390 		}
391 		kfree(adev->irq.client[i].sources);
392 		adev->irq.client[i].sources = NULL;
393 	}
394 }
395 
396 /**
397  * amdgpu_irq_add_id - register IRQ source
398  *
399  * @adev: amdgpu device pointer
400  * @client_id: client id
401  * @src_id: source id
402  * @source: IRQ source pointer
403  *
404  * Registers IRQ source on a client.
405  *
406  * Returns:
407  * 0 on success or error code otherwise
408  */
409 int amdgpu_irq_add_id(struct amdgpu_device *adev,
410 		      unsigned client_id, unsigned src_id,
411 		      struct amdgpu_irq_src *source)
412 {
413 	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX)
414 		return -EINVAL;
415 
416 	if (src_id >= AMDGPU_MAX_IRQ_SRC_ID)
417 		return -EINVAL;
418 
419 	if (!source->funcs)
420 		return -EINVAL;
421 
422 	if (!adev->irq.client[client_id].sources) {
423 		adev->irq.client[client_id].sources =
424 			kcalloc(AMDGPU_MAX_IRQ_SRC_ID,
425 				sizeof(struct amdgpu_irq_src *),
426 				GFP_KERNEL);
427 		if (!adev->irq.client[client_id].sources)
428 			return -ENOMEM;
429 	}
430 
431 	if (adev->irq.client[client_id].sources[src_id] != NULL)
432 		return -EINVAL;
433 
434 	if (source->num_types && !source->enabled_types) {
435 		atomic_t *types;
436 
437 		types = kcalloc(source->num_types, sizeof(atomic_t),
438 				GFP_KERNEL);
439 		if (!types)
440 			return -ENOMEM;
441 
442 		source->enabled_types = types;
443 	}
444 
445 	adev->irq.client[client_id].sources[src_id] = source;
446 	return 0;
447 }
448 
449 /**
450  * amdgpu_irq_dispatch - dispatch IRQ to IP blocks
451  *
452  * @adev: amdgpu device pointer
453  * @ih: interrupt ring instance
454  *
455  * Dispatches IRQ to IP blocks.
456  */
457 void amdgpu_irq_dispatch(struct amdgpu_device *adev,
458 			 struct amdgpu_ih_ring *ih)
459 {
460 	u32 ring_index = ih->rptr >> 2;
461 	struct amdgpu_iv_entry entry;
462 	unsigned client_id, src_id;
463 	struct amdgpu_irq_src *src;
464 	bool handled = false;
465 	int r;
466 
467 	entry.ih = ih;
468 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
469 	amdgpu_ih_decode_iv(adev, &entry);
470 
471 	trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
472 
473 	client_id = entry.client_id;
474 	src_id = entry.src_id;
475 
476 	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
477 		DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
478 
479 	} else	if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
480 		DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
481 
482 	} else if ((client_id == AMDGPU_IRQ_CLIENTID_LEGACY) &&
483 		   adev->irq.virq[src_id]) {
484 		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
485 
486 	} else if (!adev->irq.client[client_id].sources) {
487 		DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
488 			  client_id, src_id);
489 
490 	} else if ((src = adev->irq.client[client_id].sources[src_id])) {
491 		r = src->funcs->process(adev, src, &entry);
492 		if (r < 0)
493 			DRM_ERROR("error processing interrupt (%d)\n", r);
494 		else if (r)
495 			handled = true;
496 
497 	} else {
498 		DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
499 	}
500 
501 	/* Send it to amdkfd as well if it isn't already handled */
502 	if (!handled)
503 		amdgpu_amdkfd_interrupt(adev, entry.iv_entry);
504 }
505 
506 /**
507  * amdgpu_irq_delegate - delegate IV to soft IH ring
508  *
509  * @adev: amdgpu device pointer
510  * @entry: IV entry
511  * @num_dw: size of IV
512  *
513  * Delegate the IV to the soft IH ring and schedule processing of it. Used
514  * if the hardware delegation to IH1 or IH2 doesn't work for some reason.
515  */
516 void amdgpu_irq_delegate(struct amdgpu_device *adev,
517 			 struct amdgpu_iv_entry *entry,
518 			 unsigned int num_dw)
519 {
520 	amdgpu_ih_ring_write(&adev->irq.ih_soft, entry->iv_entry, num_dw);
521 	schedule_work(&adev->irq.ih_soft_work);
522 }
523 
524 /**
525  * amdgpu_irq_update - update hardware interrupt state
526  *
527  * @adev: amdgpu device pointer
528  * @src: interrupt source pointer
529  * @type: type of interrupt
530  *
531  * Updates interrupt state for the specific source (all ASICs).
532  */
533 int amdgpu_irq_update(struct amdgpu_device *adev,
534 			     struct amdgpu_irq_src *src, unsigned type)
535 {
536 	unsigned long irqflags;
537 	enum amdgpu_interrupt_state state;
538 	int r;
539 
540 	spin_lock_irqsave(&adev->irq.lock, irqflags);
541 
542 	/* We need to determine after taking the lock, otherwise
543 	   we might disable just enabled interrupts again */
544 	if (amdgpu_irq_enabled(adev, src, type))
545 		state = AMDGPU_IRQ_STATE_ENABLE;
546 	else
547 		state = AMDGPU_IRQ_STATE_DISABLE;
548 
549 	r = src->funcs->set(adev, src, type, state);
550 	spin_unlock_irqrestore(&adev->irq.lock, irqflags);
551 	return r;
552 }
553 
554 /**
555  * amdgpu_irq_gpu_reset_resume_helper - update interrupt states on all sources
556  *
557  * @adev: amdgpu device pointer
558  *
559  * Updates state of all types of interrupts on all sources on resume after
560  * reset.
561  */
562 void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
563 {
564 	int i, j, k;
565 
566 	for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
567 		if (!adev->irq.client[i].sources)
568 			continue;
569 
570 		for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) {
571 			struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
572 
573 			if (!src || !src->funcs || !src->funcs->set)
574 				continue;
575 			for (k = 0; k < src->num_types; k++)
576 				amdgpu_irq_update(adev, src, k);
577 		}
578 	}
579 }
580 
581 /**
582  * amdgpu_irq_get - enable interrupt
583  *
584  * @adev: amdgpu device pointer
585  * @src: interrupt source pointer
586  * @type: type of interrupt
587  *
588  * Enables specified type of interrupt on the specified source (all ASICs).
589  *
590  * Returns:
591  * 0 on success or error code otherwise
592  */
593 int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
594 		   unsigned type)
595 {
596 	if (!adev_to_drm(adev)->irq_enabled)
597 		return -ENOENT;
598 
599 	if (type >= src->num_types)
600 		return -EINVAL;
601 
602 	if (!src->enabled_types || !src->funcs->set)
603 		return -EINVAL;
604 
605 	if (atomic_inc_return(&src->enabled_types[type]) == 1)
606 		return amdgpu_irq_update(adev, src, type);
607 
608 	return 0;
609 }
610 
611 /**
612  * amdgpu_irq_put - disable interrupt
613  *
614  * @adev: amdgpu device pointer
615  * @src: interrupt source pointer
616  * @type: type of interrupt
617  *
618  * Enables specified type of interrupt on the specified source (all ASICs).
619  *
620  * Returns:
621  * 0 on success or error code otherwise
622  */
623 int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
624 		   unsigned type)
625 {
626 	if (!adev_to_drm(adev)->irq_enabled)
627 		return -ENOENT;
628 
629 	if (type >= src->num_types)
630 		return -EINVAL;
631 
632 	if (!src->enabled_types || !src->funcs->set)
633 		return -EINVAL;
634 
635 	if (atomic_dec_and_test(&src->enabled_types[type]))
636 		return amdgpu_irq_update(adev, src, type);
637 
638 	return 0;
639 }
640 
641 /**
642  * amdgpu_irq_enabled - check whether interrupt is enabled or not
643  *
644  * @adev: amdgpu device pointer
645  * @src: interrupt source pointer
646  * @type: type of interrupt
647  *
648  * Checks whether the given type of interrupt is enabled on the given source.
649  *
650  * Returns:
651  * *true* if interrupt is enabled, *false* if interrupt is disabled or on
652  * invalid parameters
653  */
654 bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
655 			unsigned type)
656 {
657 	if (!adev_to_drm(adev)->irq_enabled)
658 		return false;
659 
660 	if (type >= src->num_types)
661 		return false;
662 
663 	if (!src->enabled_types || !src->funcs->set)
664 		return false;
665 
666 	return !!atomic_read(&src->enabled_types[type]);
667 }
668 
669 /* XXX: Generic IRQ handling */
670 static void amdgpu_irq_mask(struct irq_data *irqd)
671 {
672 	/* XXX */
673 }
674 
675 static void amdgpu_irq_unmask(struct irq_data *irqd)
676 {
677 	/* XXX */
678 }
679 
680 /* amdgpu hardware interrupt chip descriptor */
681 static struct irq_chip amdgpu_irq_chip = {
682 	.name = "amdgpu-ih",
683 	.irq_mask = amdgpu_irq_mask,
684 	.irq_unmask = amdgpu_irq_unmask,
685 };
686 
687 /**
688  * amdgpu_irqdomain_map - create mapping between virtual and hardware IRQ numbers
689  *
690  * @d: amdgpu IRQ domain pointer (unused)
691  * @irq: virtual IRQ number
692  * @hwirq: hardware irq number
693  *
694  * Current implementation assigns simple interrupt handler to the given virtual
695  * IRQ.
696  *
697  * Returns:
698  * 0 on success or error code otherwise
699  */
700 static int amdgpu_irqdomain_map(struct irq_domain *d,
701 				unsigned int irq, irq_hw_number_t hwirq)
702 {
703 	if (hwirq >= AMDGPU_MAX_IRQ_SRC_ID)
704 		return -EPERM;
705 
706 	irq_set_chip_and_handler(irq,
707 				 &amdgpu_irq_chip, handle_simple_irq);
708 	return 0;
709 }
710 
711 /* Implementation of methods for amdgpu IRQ domain */
712 static const struct irq_domain_ops amdgpu_hw_irqdomain_ops = {
713 	.map = amdgpu_irqdomain_map,
714 };
715 
716 /**
717  * amdgpu_irq_add_domain - create a linear IRQ domain
718  *
719  * @adev: amdgpu device pointer
720  *
721  * Creates an IRQ domain for GPU interrupt sources
722  * that may be driven by another driver (e.g., ACP).
723  *
724  * Returns:
725  * 0 on success or error code otherwise
726  */
727 int amdgpu_irq_add_domain(struct amdgpu_device *adev)
728 {
729 	adev->irq.domain = irq_domain_add_linear(NULL, AMDGPU_MAX_IRQ_SRC_ID,
730 						 &amdgpu_hw_irqdomain_ops, adev);
731 	if (!adev->irq.domain) {
732 		DRM_ERROR("GPU irq add domain failed\n");
733 		return -ENODEV;
734 	}
735 
736 	return 0;
737 }
738 
739 /**
740  * amdgpu_irq_remove_domain - remove the IRQ domain
741  *
742  * @adev: amdgpu device pointer
743  *
744  * Removes the IRQ domain for GPU interrupt sources
745  * that may be driven by another driver (e.g., ACP).
746  */
747 void amdgpu_irq_remove_domain(struct amdgpu_device *adev)
748 {
749 	if (adev->irq.domain) {
750 		irq_domain_remove(adev->irq.domain);
751 		adev->irq.domain = NULL;
752 	}
753 }
754 
755 /**
756  * amdgpu_irq_create_mapping - create mapping between domain Linux IRQs
757  *
758  * @adev: amdgpu device pointer
759  * @src_id: IH source id
760  *
761  * Creates mapping between a domain IRQ (GPU IH src id) and a Linux IRQ
762  * Use this for components that generate a GPU interrupt, but are driven
763  * by a different driver (e.g., ACP).
764  *
765  * Returns:
766  * Linux IRQ
767  */
768 unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id)
769 {
770 	adev->irq.virq[src_id] = irq_create_mapping(adev->irq.domain, src_id);
771 
772 	return adev->irq.virq[src_id];
773 }
774