xref: /linux/drivers/accel/ivpu/ivpu_hw.c (revision 52ab5be191c42fe1bffac97ee248a237b9712889)
18a27ad81SWachowski, Karol // SPDX-License-Identifier: GPL-2.0-only
28a27ad81SWachowski, Karol /*
38a27ad81SWachowski, Karol  * Copyright (C) 2020 - 2024 Intel Corporation
48a27ad81SWachowski, Karol  */
58a27ad81SWachowski, Karol 
68a27ad81SWachowski, Karol #include "ivpu_drv.h"
78a27ad81SWachowski, Karol #include "ivpu_hw.h"
88a27ad81SWachowski, Karol #include "ivpu_hw_btrs.h"
98a27ad81SWachowski, Karol #include "ivpu_hw_ip.h"
108a27ad81SWachowski, Karol 
118a27ad81SWachowski, Karol #include <linux/dmi.h>
128a27ad81SWachowski, Karol 
138a27ad81SWachowski, Karol static char *platform_to_str(u32 platform)
148a27ad81SWachowski, Karol {
158a27ad81SWachowski, Karol 	switch (platform) {
168a27ad81SWachowski, Karol 	case IVPU_PLATFORM_SILICON:
178a27ad81SWachowski, Karol 		return "SILICON";
188a27ad81SWachowski, Karol 	case IVPU_PLATFORM_SIMICS:
198a27ad81SWachowski, Karol 		return "SIMICS";
208a27ad81SWachowski, Karol 	case IVPU_PLATFORM_FPGA:
218a27ad81SWachowski, Karol 		return "FPGA";
228a27ad81SWachowski, Karol 	default:
238a27ad81SWachowski, Karol 		return "Invalid platform";
248a27ad81SWachowski, Karol 	}
258a27ad81SWachowski, Karol }
268a27ad81SWachowski, Karol 
278a27ad81SWachowski, Karol static const struct dmi_system_id dmi_platform_simulation[] = {
288a27ad81SWachowski, Karol 	{
298a27ad81SWachowski, Karol 		.ident = "Intel Simics",
308a27ad81SWachowski, Karol 		.matches = {
318a27ad81SWachowski, Karol 			DMI_MATCH(DMI_BOARD_NAME, "lnlrvp"),
328a27ad81SWachowski, Karol 			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
338a27ad81SWachowski, Karol 			DMI_MATCH(DMI_BOARD_SERIAL, "123456789"),
348a27ad81SWachowski, Karol 		},
358a27ad81SWachowski, Karol 	},
368a27ad81SWachowski, Karol 	{
378a27ad81SWachowski, Karol 		.ident = "Intel Simics",
388a27ad81SWachowski, Karol 		.matches = {
398a27ad81SWachowski, Karol 			DMI_MATCH(DMI_BOARD_NAME, "Simics"),
408a27ad81SWachowski, Karol 		},
418a27ad81SWachowski, Karol 	},
428a27ad81SWachowski, Karol 	{ }
438a27ad81SWachowski, Karol };
448a27ad81SWachowski, Karol 
458a27ad81SWachowski, Karol static void platform_init(struct ivpu_device *vdev)
468a27ad81SWachowski, Karol {
478a27ad81SWachowski, Karol 	if (dmi_check_system(dmi_platform_simulation))
488a27ad81SWachowski, Karol 		vdev->platform = IVPU_PLATFORM_SIMICS;
498a27ad81SWachowski, Karol 	else
508a27ad81SWachowski, Karol 		vdev->platform = IVPU_PLATFORM_SILICON;
518a27ad81SWachowski, Karol 
528a27ad81SWachowski, Karol 	ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n",
538a27ad81SWachowski, Karol 		 platform_to_str(vdev->platform), vdev->platform);
548a27ad81SWachowski, Karol }
558a27ad81SWachowski, Karol 
568a27ad81SWachowski, Karol static void wa_init(struct ivpu_device *vdev)
578a27ad81SWachowski, Karol {
588a27ad81SWachowski, Karol 	vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
598a27ad81SWachowski, Karol 	vdev->wa.clear_runtime_mem = false;
608a27ad81SWachowski, Karol 
618a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
628a27ad81SWachowski, Karol 		vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);
638a27ad81SWachowski, Karol 
64*52ab5be1SWachowski, Karol 	if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
65*52ab5be1SWachowski, Karol 	    ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0)
668a27ad81SWachowski, Karol 		vdev->wa.disable_clock_relinquish = true;
678a27ad81SWachowski, Karol 
68d9dfc4eaSWachowski, Karol 	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
69d9dfc4eaSWachowski, Karol 		vdev->wa.wp0_during_power_up = true;
70d9dfc4eaSWachowski, Karol 
718a27ad81SWachowski, Karol 	IVPU_PRINT_WA(punit_disabled);
728a27ad81SWachowski, Karol 	IVPU_PRINT_WA(clear_runtime_mem);
738a27ad81SWachowski, Karol 	IVPU_PRINT_WA(interrupt_clear_with_0);
748a27ad81SWachowski, Karol 	IVPU_PRINT_WA(disable_clock_relinquish);
75d9dfc4eaSWachowski, Karol 	IVPU_PRINT_WA(wp0_during_power_up);
768a27ad81SWachowski, Karol }
778a27ad81SWachowski, Karol 
788a27ad81SWachowski, Karol static void timeouts_init(struct ivpu_device *vdev)
798a27ad81SWachowski, Karol {
808a27ad81SWachowski, Karol 	if (ivpu_is_fpga(vdev)) {
818a27ad81SWachowski, Karol 		vdev->timeout.boot = 100000;
828a27ad81SWachowski, Karol 		vdev->timeout.jsm = 50000;
838a27ad81SWachowski, Karol 		vdev->timeout.tdr = 2000000;
848a27ad81SWachowski, Karol 		vdev->timeout.reschedule_suspend = 1000;
858a27ad81SWachowski, Karol 		vdev->timeout.autosuspend = -1;
868a27ad81SWachowski, Karol 		vdev->timeout.d0i3_entry_msg = 500;
878a27ad81SWachowski, Karol 	} else if (ivpu_is_simics(vdev)) {
888a27ad81SWachowski, Karol 		vdev->timeout.boot = 50;
898a27ad81SWachowski, Karol 		vdev->timeout.jsm = 500;
908a27ad81SWachowski, Karol 		vdev->timeout.tdr = 10000;
918a27ad81SWachowski, Karol 		vdev->timeout.reschedule_suspend = 10;
928a27ad81SWachowski, Karol 		vdev->timeout.autosuspend = -1;
938a27ad81SWachowski, Karol 		vdev->timeout.d0i3_entry_msg = 100;
948a27ad81SWachowski, Karol 	} else {
958a27ad81SWachowski, Karol 		vdev->timeout.boot = 1000;
968a27ad81SWachowski, Karol 		vdev->timeout.jsm = 500;
978a27ad81SWachowski, Karol 		vdev->timeout.tdr = 2000;
988a27ad81SWachowski, Karol 		vdev->timeout.reschedule_suspend = 10;
998a27ad81SWachowski, Karol 		vdev->timeout.autosuspend = 10;
1008a27ad81SWachowski, Karol 		vdev->timeout.d0i3_entry_msg = 5;
1018a27ad81SWachowski, Karol 	}
1028a27ad81SWachowski, Karol }
1038a27ad81SWachowski, Karol 
1048a27ad81SWachowski, Karol static void memory_ranges_init(struct ivpu_device *vdev)
1058a27ad81SWachowski, Karol {
1068a27ad81SWachowski, Karol 	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
1078a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
1088a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.user,   0xc0000000, 255 * SZ_1M);
1098a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G);
1108a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.dma,   0x200000000, SZ_8G);
1118a27ad81SWachowski, Karol 	} else {
1128a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
1138a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.user,   0x80000000, SZ_256M);
1148a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.shave,  0x80000000 + SZ_256M, SZ_2G - SZ_256M);
1158a27ad81SWachowski, Karol 		ivpu_hw_range_init(&vdev->hw->ranges.dma,   0x200000000, SZ_8G);
1168a27ad81SWachowski, Karol 	}
1178a27ad81SWachowski, Karol }
1188a27ad81SWachowski, Karol 
1198a27ad81SWachowski, Karol static int wp_enable(struct ivpu_device *vdev)
1208a27ad81SWachowski, Karol {
1218a27ad81SWachowski, Karol 	return ivpu_hw_btrs_wp_drive(vdev, true);
1228a27ad81SWachowski, Karol }
1238a27ad81SWachowski, Karol 
1248a27ad81SWachowski, Karol static int wp_disable(struct ivpu_device *vdev)
1258a27ad81SWachowski, Karol {
1268a27ad81SWachowski, Karol 	return ivpu_hw_btrs_wp_drive(vdev, false);
1278a27ad81SWachowski, Karol }
1288a27ad81SWachowski, Karol 
1298a27ad81SWachowski, Karol int ivpu_hw_power_up(struct ivpu_device *vdev)
1308a27ad81SWachowski, Karol {
1318a27ad81SWachowski, Karol 	int ret;
1328a27ad81SWachowski, Karol 
133d9dfc4eaSWachowski, Karol 	if (IVPU_WA(wp0_during_power_up)) {
134d9dfc4eaSWachowski, Karol 		/* WP requests may fail when powering down, so issue WP 0 here */
135d9dfc4eaSWachowski, Karol 		ret = wp_disable(vdev);
136d9dfc4eaSWachowski, Karol 		if (ret)
137d9dfc4eaSWachowski, Karol 			ivpu_warn(vdev, "Failed to disable workpoint: %d\n", ret);
138d9dfc4eaSWachowski, Karol 	}
139d9dfc4eaSWachowski, Karol 
1408a27ad81SWachowski, Karol 	ret = ivpu_hw_btrs_d0i3_disable(vdev);
1418a27ad81SWachowski, Karol 	if (ret)
1428a27ad81SWachowski, Karol 		ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
1438a27ad81SWachowski, Karol 
1448a27ad81SWachowski, Karol 	ret = wp_enable(vdev);
1458a27ad81SWachowski, Karol 	if (ret) {
1468a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to enable workpoint: %d\n", ret);
1478a27ad81SWachowski, Karol 		return ret;
1488a27ad81SWachowski, Karol 	}
1498a27ad81SWachowski, Karol 
1508a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_gen(vdev) >= IVPU_HW_BTRS_LNL) {
1518a27ad81SWachowski, Karol 		if (IVPU_WA(disable_clock_relinquish))
1528a27ad81SWachowski, Karol 			ivpu_hw_btrs_clock_relinquish_disable_lnl(vdev);
1538a27ad81SWachowski, Karol 		ivpu_hw_btrs_profiling_freq_reg_set_lnl(vdev);
1548a27ad81SWachowski, Karol 		ivpu_hw_btrs_ats_print_lnl(vdev);
1558a27ad81SWachowski, Karol 	}
1568a27ad81SWachowski, Karol 
1578a27ad81SWachowski, Karol 	ret = ivpu_hw_ip_host_ss_configure(vdev);
1588a27ad81SWachowski, Karol 	if (ret) {
1598a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
1608a27ad81SWachowski, Karol 		return ret;
1618a27ad81SWachowski, Karol 	}
1628a27ad81SWachowski, Karol 
1638a27ad81SWachowski, Karol 	ivpu_hw_ip_idle_gen_disable(vdev);
1648a27ad81SWachowski, Karol 
1658a27ad81SWachowski, Karol 	ret = ivpu_hw_btrs_wait_for_clock_res_own_ack(vdev);
1668a27ad81SWachowski, Karol 	if (ret) {
1678a27ad81SWachowski, Karol 		ivpu_err(vdev, "Timed out waiting for clock resource own ACK\n");
1688a27ad81SWachowski, Karol 		return ret;
1698a27ad81SWachowski, Karol 	}
1708a27ad81SWachowski, Karol 
1718a27ad81SWachowski, Karol 	ret = ivpu_hw_ip_pwr_domain_enable(vdev);
1728a27ad81SWachowski, Karol 	if (ret) {
1738a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
1748a27ad81SWachowski, Karol 		return ret;
1758a27ad81SWachowski, Karol 	}
1768a27ad81SWachowski, Karol 
1778a27ad81SWachowski, Karol 	ret = ivpu_hw_ip_host_ss_axi_enable(vdev);
1788a27ad81SWachowski, Karol 	if (ret) {
1798a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
1808a27ad81SWachowski, Karol 		return ret;
1818a27ad81SWachowski, Karol 	}
1828a27ad81SWachowski, Karol 
1838a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_LNL)
1848a27ad81SWachowski, Karol 		ivpu_hw_btrs_set_port_arbitration_weights_lnl(vdev);
1858a27ad81SWachowski, Karol 
1868a27ad81SWachowski, Karol 	ret = ivpu_hw_ip_top_noc_enable(vdev);
1878a27ad81SWachowski, Karol 	if (ret)
1888a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
1898a27ad81SWachowski, Karol 
1908a27ad81SWachowski, Karol 	return ret;
1918a27ad81SWachowski, Karol }
1928a27ad81SWachowski, Karol 
1938a27ad81SWachowski, Karol static void save_d0i3_entry_timestamp(struct ivpu_device *vdev)
1948a27ad81SWachowski, Karol {
1958a27ad81SWachowski, Karol 	vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
1968a27ad81SWachowski, Karol 	vdev->hw->d0i3_entry_vpu_ts = ivpu_hw_ip_read_perf_timer_counter(vdev);
1978a27ad81SWachowski, Karol }
1988a27ad81SWachowski, Karol 
1998a27ad81SWachowski, Karol int ivpu_hw_reset(struct ivpu_device *vdev)
2008a27ad81SWachowski, Karol {
2018a27ad81SWachowski, Karol 	int ret = 0;
2028a27ad81SWachowski, Karol 
2038a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_ip_reset(vdev)) {
2048a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to reset NPU IP\n");
2058a27ad81SWachowski, Karol 		ret = -EIO;
2068a27ad81SWachowski, Karol 	}
2078a27ad81SWachowski, Karol 
2088a27ad81SWachowski, Karol 	if (wp_disable(vdev)) {
2098a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to disable workpoint\n");
2108a27ad81SWachowski, Karol 		ret = -EIO;
2118a27ad81SWachowski, Karol 	}
2128a27ad81SWachowski, Karol 
2138a27ad81SWachowski, Karol 	return ret;
2148a27ad81SWachowski, Karol }
2158a27ad81SWachowski, Karol 
2168a27ad81SWachowski, Karol int ivpu_hw_power_down(struct ivpu_device *vdev)
2178a27ad81SWachowski, Karol {
2188a27ad81SWachowski, Karol 	int ret = 0;
2198a27ad81SWachowski, Karol 
2208a27ad81SWachowski, Karol 	save_d0i3_entry_timestamp(vdev);
2218a27ad81SWachowski, Karol 
2228a27ad81SWachowski, Karol 	if (!ivpu_hw_is_idle(vdev))
2238a27ad81SWachowski, Karol 		ivpu_warn(vdev, "NPU not idle during power down\n");
2248a27ad81SWachowski, Karol 
2258a27ad81SWachowski, Karol 	if (ivpu_hw_reset(vdev)) {
2268a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to reset NPU\n");
2278a27ad81SWachowski, Karol 		ret = -EIO;
2288a27ad81SWachowski, Karol 	}
2298a27ad81SWachowski, Karol 
2308a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_d0i3_enable(vdev)) {
2318a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to enter D0I3\n");
2328a27ad81SWachowski, Karol 		ret = -EIO;
2338a27ad81SWachowski, Karol 	}
2348a27ad81SWachowski, Karol 
2358a27ad81SWachowski, Karol 	return ret;
2368a27ad81SWachowski, Karol }
2378a27ad81SWachowski, Karol 
2388a27ad81SWachowski, Karol int ivpu_hw_init(struct ivpu_device *vdev)
2398a27ad81SWachowski, Karol {
2408a27ad81SWachowski, Karol 	ivpu_hw_btrs_info_init(vdev);
2418a27ad81SWachowski, Karol 	ivpu_hw_btrs_freq_ratios_init(vdev);
2428a27ad81SWachowski, Karol 	memory_ranges_init(vdev);
2438a27ad81SWachowski, Karol 	platform_init(vdev);
2448a27ad81SWachowski, Karol 	wa_init(vdev);
2458a27ad81SWachowski, Karol 	timeouts_init(vdev);
2468a27ad81SWachowski, Karol 
2478a27ad81SWachowski, Karol 	return 0;
2488a27ad81SWachowski, Karol }
2498a27ad81SWachowski, Karol 
2508a27ad81SWachowski, Karol int ivpu_hw_boot_fw(struct ivpu_device *vdev)
2518a27ad81SWachowski, Karol {
2528a27ad81SWachowski, Karol 	int ret;
2538a27ad81SWachowski, Karol 
2548a27ad81SWachowski, Karol 	ivpu_hw_ip_snoop_disable(vdev);
2558a27ad81SWachowski, Karol 	ivpu_hw_ip_tbu_mmu_enable(vdev);
2568a27ad81SWachowski, Karol 	ret = ivpu_hw_ip_soc_cpu_boot(vdev);
2578a27ad81SWachowski, Karol 	if (ret)
2588a27ad81SWachowski, Karol 		ivpu_err(vdev, "Failed to boot SOC CPU: %d\n", ret);
2598a27ad81SWachowski, Karol 
2608a27ad81SWachowski, Karol 	return ret;
2618a27ad81SWachowski, Karol }
2628a27ad81SWachowski, Karol 
2638a27ad81SWachowski, Karol void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
2648a27ad81SWachowski, Karol {
2658a27ad81SWachowski, Karol 	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
2668a27ad81SWachowski, Karol 		vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
2678a27ad81SWachowski, Karol 		return;
2688a27ad81SWachowski, Karol 	}
2698a27ad81SWachowski, Karol 
2708a27ad81SWachowski, Karol 	if (enable)
2718a27ad81SWachowski, Karol 		vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
2728a27ad81SWachowski, Karol 	else
2738a27ad81SWachowski, Karol 		vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
2748a27ad81SWachowski, Karol }
2758a27ad81SWachowski, Karol 
2768a27ad81SWachowski, Karol void ivpu_irq_handlers_init(struct ivpu_device *vdev)
2778a27ad81SWachowski, Karol {
2782f7ffb06SJacek Lawrynowicz 	INIT_KFIFO(vdev->hw->irq.fifo);
2792f7ffb06SJacek Lawrynowicz 
2808a27ad81SWachowski, Karol 	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
2818a27ad81SWachowski, Karol 		vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_37xx;
2828a27ad81SWachowski, Karol 	else
2838a27ad81SWachowski, Karol 		vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_40xx;
2848a27ad81SWachowski, Karol 
2858a27ad81SWachowski, Karol 	if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
2868a27ad81SWachowski, Karol 		vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_mtl;
2878a27ad81SWachowski, Karol 	else
2888a27ad81SWachowski, Karol 		vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_lnl;
2898a27ad81SWachowski, Karol }
2908a27ad81SWachowski, Karol 
2918a27ad81SWachowski, Karol void ivpu_hw_irq_enable(struct ivpu_device *vdev)
2928a27ad81SWachowski, Karol {
2932f7ffb06SJacek Lawrynowicz 	kfifo_reset(&vdev->hw->irq.fifo);
2948a27ad81SWachowski, Karol 	ivpu_hw_ip_irq_enable(vdev);
2958a27ad81SWachowski, Karol 	ivpu_hw_btrs_irq_enable(vdev);
2968a27ad81SWachowski, Karol }
2978a27ad81SWachowski, Karol 
2988a27ad81SWachowski, Karol void ivpu_hw_irq_disable(struct ivpu_device *vdev)
2998a27ad81SWachowski, Karol {
3008a27ad81SWachowski, Karol 	ivpu_hw_btrs_irq_disable(vdev);
3018a27ad81SWachowski, Karol 	ivpu_hw_ip_irq_disable(vdev);
3028a27ad81SWachowski, Karol }
3038a27ad81SWachowski, Karol 
3048a27ad81SWachowski, Karol irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr)
3058a27ad81SWachowski, Karol {
3068a27ad81SWachowski, Karol 	struct ivpu_device *vdev = ptr;
3072f7ffb06SJacek Lawrynowicz 	bool ip_handled, btrs_handled;
3088a27ad81SWachowski, Karol 
3098a27ad81SWachowski, Karol 	ivpu_hw_btrs_global_int_disable(vdev);
3108a27ad81SWachowski, Karol 
3118a27ad81SWachowski, Karol 	btrs_handled = ivpu_hw_btrs_irq_handler(vdev, irq);
3128a27ad81SWachowski, Karol 	if (!ivpu_hw_is_idle((vdev)) || !btrs_handled)
3132f7ffb06SJacek Lawrynowicz 		ip_handled = ivpu_hw_ip_irq_handler(vdev, irq);
3148a27ad81SWachowski, Karol 	else
3158a27ad81SWachowski, Karol 		ip_handled = false;
3168a27ad81SWachowski, Karol 
3178a27ad81SWachowski, Karol 	/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
3188a27ad81SWachowski, Karol 	ivpu_hw_btrs_global_int_enable(vdev);
3198a27ad81SWachowski, Karol 
3202f7ffb06SJacek Lawrynowicz 	if (!kfifo_is_empty(&vdev->hw->irq.fifo))
3218a27ad81SWachowski, Karol 		return IRQ_WAKE_THREAD;
3228a27ad81SWachowski, Karol 	if (ip_handled || btrs_handled)
3238a27ad81SWachowski, Karol 		return IRQ_HANDLED;
3248a27ad81SWachowski, Karol 	return IRQ_NONE;
3258a27ad81SWachowski, Karol }
326