Re: [CI 11/15] drm/i915/huc: track delayed HuC load with a fence

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Hi,

Don't know if this is real or not yet, hit it while running selftests a bit. Something to keep an eye on.

[ 2928.370577] ODEBUG: init destroyed (active state 0) object type: i915_sw_fence hint: sw_fence_dummy_notify+0x0/0x10 [i915]
[ 2928.370903] WARNING: CPU: 2 PID: 1113 at lib/debugobjects.c:502 debug_print_object+0x6b/0x90
[ 2928.370984] Modules linked in: i915(+) drm_display_helper drm_kms_helper netconsole cmac algif_hash algif_skcipher af_alg bnep nls_iso8859_1 snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_intel_dspcfg snd_hda_codec snd_hwdep snd_hda_core snd_pcm intel_tcc_cooling x86_pkg_temp_thermal intel_powerclamp snd_seq_midi snd_seq_midi_event coretemp snd_rawmidi btusb btrtl btbcm kvm_intel btmtk btintel ath10k_pci snd_seq kvm ath10k_core bluetooth snd_timer rapl intel_cstate snd_seq_device input_leds mac80211 ecdh_generic libarc4 ath snd ecc serio_raw intel_wmi_thunderbolt at24 soundcore cfg80211 mei_me intel_xhci_usb_role_switch mei ideapad_laptop intel_pch_thermal platform_profile sparse_keymap acpi_pad sch_fq_codel msr efi_pstore ip_tables x_tables autofs4 crct10dif_pclmul crc32_pclmul ghash_clmulni_intel sha512_ssse3 aesni_intel prime_numbers crypto_simd atkbd drm_buddy cryptd vivaldi_fmap r8169 ttm i2c_i801 i2c_smbus cec realtek xhci_pci syscopyarea ahci
[ 2928.371145]  xhci_pci_renesas sysfillrect sysimgblt libahci fb_sys_fops video wmi [last unloaded: drm_kms_helper]
[ 2928.371489] CPU: 2 PID: 1113 Comm: modprobe Tainted: G     U  W          6.1.0-rc1 #196
[ 2928.371550] Hardware name: LENOVO 80MX/Lenovo E31-80, BIOS DCCN34WW(V2.03) 12/01/2015
[ 2928.371615] RIP: 0010:debug_print_object+0x6b/0x90
[ 2928.371664] Code: 49 89 c1 8b 43 10 83 c2 01 48 c7 c7 e8 be d6 bb 8b 4b 14 89 15 ca be b4 02 4c 8b 45 00 48 8b 14 c5 40 56 a8 bb e8 ec 5b 60 00 <0f> 0b 83 05 28 5a 3e 01 01 48 83 c4 08 5b 5d c3 83 05 1a 5a 3e 01
[ 2928.371782] RSP: 0018:ffff9ed841607a18 EFLAGS: 00010286
[ 2928.371841] RAX: 0000000000000000 RBX: ffff9208116a1d48 RCX: 0000000000000000
[ 2928.371909] RDX: 0000000000000001 RSI: ffffffffbbd277d2 RDI: 00000000ffffffff
[ 2928.372024] RBP: ffffffffc176a540 R08: 0000000000000000 R09: ffffffffbc07a1e0
[ 2928.372128] R10: 0000000000000001 R11: 0000000000000001 R12: ffff9208122da830
[ 2928.372192] R13: ffff92080089b000 R14: ffff9208122da770 R15: 0000000000000000
[ 2928.372259] FS:  00007f53e7617c40(0000) GS:ffff92086e500000(0000) knlGS:0000000000000000
[ 2928.372365] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2928.372425] CR2: 000055cd28b33070 CR3: 0000000110dbd006 CR4: 00000000003706e0
[ 2928.372526] Call Trace:
[ 2928.372568]  <TASK>
[ 2928.372614]  ? intel_guc_hang_check+0xb0/0xb0 [i915]
[ 2928.373001]  __i915_sw_fence_init+0x2b/0x50 [i915]
[ 2928.373374]  intel_huc_init_early+0x75/0xb0 [i915]
[ 2928.373868]  intel_uc_init_early+0x4e/0x210 [i915]
[ 2928.374241]  intel_gt_common_init_early+0x16f/0x180 [i915]
[ 2928.374718]  intel_root_gt_init_early+0x49/0x60 [i915]
[ 2928.375074]  i915_driver_probe+0x917/0xed0 [i915]
[ 2928.375398]  ? drm_privacy_screen_get+0x163/0x1a0
[ 2928.375512]  i915_pci_probe+0xb0/0x230 [i915]
[ 2928.375823]  ? _raw_spin_unlock_irqrestore+0x38/0x50
[ 2928.375896]  pci_device_probe+0xa4/0x140
[ 2928.375930]  really_probe+0xd8/0x380
[ 2928.375992]  ? pm_runtime_barrier+0x50/0x80
[ 2928.376056]  __driver_probe_device+0x78/0x170
[ 2928.376103]  driver_probe_device+0x1e/0x80
[ 2928.376134]  __driver_attach+0x98/0x1e0
[ 2928.376161]  ? __device_attach_driver+0xf0/0xf0
[ 2928.376206]  ? __device_attach_driver+0xf0/0xf0
[ 2928.376237]  bus_for_each_dev+0x78/0xc0
[ 2928.376285]  bus_add_driver+0x1ad/0x200
[ 2928.376315]  driver_register+0x8f/0xe0
[ 2928.376344]  i915_init+0x1a/0x73 [i915]
[ 2928.376715]  ? 0xffffffffc04d0000
[ 2928.376766]  do_one_initcall+0x58/0x300
[ 2928.376824]  ? rcu_read_lock_sched_held+0x3f/0x70
[ 2928.376884]  ? trace_kmalloc+0x2c/0xd0
[ 2928.376951]  ? kmalloc_trace+0x44/0x50
[ 2928.377009]  do_init_module+0x4c/0x1e0
[ 2928.377069]  __do_sys_finit_module+0xb4/0x120
[ 2928.377156]  do_syscall_64+0x56/0x80
[ 2928.377210]  ? do_syscall_64+0x63/0x80
[ 2928.377264]  ? lockdep_hardirqs_on+0x79/0x100
[ 2928.377321]  ? do_syscall_64+0x63/0x80
[ 2928.377389]  ? lockdep_hardirqs_on+0x79/0x100
[ 2928.377464]  ? do_syscall_64+0x63/0x80
[ 2928.377516]  ? do_syscall_64+0x63/0x80
[ 2928.377566]  ? lockdep_hardirqs_on+0x79/0x100
[ 2928.377624]  ? do_syscall_64+0x63/0x80
[ 2928.377673]  ? lockdep_hardirqs_on+0x79/0x100
[ 2928.377728]  ? do_syscall_64+0x63/0x80
[ 2928.377779]  ? do_syscall_64+0x63/0x80
[ 2928.377830]  ? do_syscall_64+0x63/0x80
[ 2928.377882]  ? lockdep_hardirqs_on+0x79/0x100
[ 2928.377939]  entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 2928.378002] RIP: 0033:0x7f53e6d1ea3d
[ 2928.378054] Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c3 a3 0f 00 f7 d8 64 89 01 48
[ 2928.378184] RSP: 002b:00007ffee7d9bc08 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 2928.378260] RAX: ffffffffffffffda RBX: 000055cd28b2cdf0 RCX: 00007f53e6d1ea3d
[ 2928.378327] RDX: 0000000000000000 RSI: 000055cd28b339f0 RDI: 0000000000000005
[ 2928.378392] RBP: 0000000000040000 R08: 0000000000000000 R09: 0000000000000002
[ 2928.378472] R10: 0000000000000005 R11: 0000000000000246 R12: 000055cd28b339f0
[ 2928.378539] R13: 000055cd28b2cf20 R14: 0000000000000000 R15: 000055cd28b33eb0
[ 2928.378634]  </TASK>
[ 2928.378675] irq event stamp: 133143
[ 2928.378738] hardirqs last  enabled at (133153): [<ffffffffbaafef92>] __up_console_sem+0x52/0x60
[ 2928.378833] hardirqs last disabled at (133162): [<ffffffffbaafef77>] __up_console_sem+0x37/0x60
[ 2928.378959] softirqs last  enabled at (132814): [<ffffffffbaa86bc1>] __irq_exit_rcu+0xc1/0x110
[ 2928.379037] softirqs last disabled at (132601): [<ffffffffbaa86bc1>] __irq_exit_rcu+0xc1/0x110
[ 2928.379126] ---[ end trace 0000000000000000 ]---

Regards,

Tvrtko

On 28/09/2022 01:41, Daniele Ceraolo Spurio wrote:
Given that HuC load is delayed on DG2, this patch adds support for a fence
that can be used to wait for load completion. No waiters are added in this
patch (they're coming up in the next one), to keep the focus of the
patch on the tracking logic.

The full HuC loading flow on boot DG2 is as follows:
1) i915 exports the GSC as an aux device;
2) the mei-gsc driver is loaded on the aux device;
3) the mei-pxp component is loaded;
4) mei-pxp calls back into i915 and we load the HuC.

Between steps 1 and 2 there can be several seconds of gap, mainly due to
the kernel doing other work during the boot.
The resume flow is slightly different, because we don't need to
re-expose or re-probe the aux device, so we go directly to step 3 once
i915 and mei-gsc have completed their resume flow.

Here's an example of the boot timing, captured with some logs added to
i915:

[   17.908307] [drm] adding GSC device
[   17.915717] [drm] i915 probe done
[   22.282917] [drm] mei-gsc bound
[   22.938153] [drm] HuC authenticated

Also to note is that if something goes wrong during GSC HW init the
mei-gsc driver will still bind, but steps 3 and 4 will not happen.

The status tracking is done by registering a bus_notifier to receive a
callback when the mei-gsc driver binds, with a large enough timeout to
account for delays. Once mei-gsc is bound, we switch to a smaller
timeout to wait for the mei-pxp component to load.
The fence is signalled on HuC load complete or if anything goes wrong in
any of the tracking steps. Timeout are enforced via hrtimer callbacks.

v2: fix includes (Jani)
v5: gsc_notifier() remove unneeded ()

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx>
Reviewed-by: Alan Previn <alan.previn.teres.alexis@xxxxxxxxx>
---
  drivers/gpu/drm/i915/gt/intel_gsc.c    |  22 ++-
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 199 +++++++++++++++++++++++++
  drivers/gpu/drm/i915/gt/uc/intel_huc.h |  23 +++
  3 files changed, 241 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
index d56f75b605d8..976fdf27e790 100644
--- a/drivers/gpu/drm/i915/gt/intel_gsc.c
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
@@ -143,8 +143,14 @@ static void gsc_destroy_one(struct drm_i915_private *i915,
  	struct intel_gsc_intf *intf = &gsc->intf[intf_id];
if (intf->adev) {
-		auxiliary_device_delete(&intf->adev->aux_dev);
-		auxiliary_device_uninit(&intf->adev->aux_dev);
+		struct auxiliary_device *aux_dev = &intf->adev->aux_dev;
+
+		if (intf_id == 0)
+			intel_huc_unregister_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
+							  aux_dev->dev.bus);
+
+		auxiliary_device_delete(aux_dev);
+		auxiliary_device_uninit(aux_dev);
  		intf->adev = NULL;
  	}
@@ -243,14 +249,24 @@ static void gsc_init_one(struct drm_i915_private *i915, struct intel_gsc *gsc,
  		goto fail;
  	}
+ intf->adev = adev; /* needed by the notifier */
+
+	if (intf_id == 0)
+		intel_huc_register_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
+						aux_dev->dev.bus);
+
  	ret = auxiliary_device_add(aux_dev);
  	if (ret < 0) {
  		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
+		if (intf_id == 0)
+			intel_huc_unregister_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
+							  aux_dev->dev.bus);
+		intf->adev = NULL;
+
  		/* adev will be freed with the put_device() and .release sequence */
  		auxiliary_device_uninit(aux_dev);
  		goto fail;
  	}
-	intf->adev = adev;
return;
  fail:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index f0188931d8e4..5f2144c78f8a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -10,6 +10,9 @@
  #include "intel_huc.h"
  #include "i915_drv.h"
+#include <linux/device/bus.h>
+#include <linux/mei_aux.h>
+
  /**
   * DOC: HuC
   *
@@ -42,6 +45,164 @@
   * HuC-specific commands.
   */
+/*
+ * MEI-GSC load is an async process. The probing of the exposed aux device
+ * (see intel_gsc.c) usually happens a few seconds after i915 probe, depending
+ * on when the kernel schedules it. Unless something goes terribly wrong, we're
+ * guaranteed for this to happen during boot, so the big timeout is a safety net
+ * that we never expect to need.
+ * MEI-PXP + HuC load usually takes ~300ms, but if the GSC needs to be resumed
+ * and/or reset, this can take longer.
+ */
+#define GSC_INIT_TIMEOUT_MS 10000
+#define PXP_INIT_TIMEOUT_MS 2000
+
+static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
+				 enum i915_sw_fence_notify state)
+{
+	return NOTIFY_DONE;
+}
+
+static void __delayed_huc_load_complete(struct intel_huc *huc)
+{
+	if (!i915_sw_fence_done(&huc->delayed_load.fence))
+		i915_sw_fence_complete(&huc->delayed_load.fence);
+}
+
+static void delayed_huc_load_complete(struct intel_huc *huc)
+{
+	hrtimer_cancel(&huc->delayed_load.timer);
+	__delayed_huc_load_complete(huc);
+}
+
+static void __gsc_init_error(struct intel_huc *huc)
+{
+	huc->delayed_load.status = INTEL_HUC_DELAYED_LOAD_ERROR;
+	__delayed_huc_load_complete(huc);
+}
+
+static void gsc_init_error(struct intel_huc *huc)
+{
+	hrtimer_cancel(&huc->delayed_load.timer);
+	__gsc_init_error(huc);
+}
+
+static void gsc_init_done(struct intel_huc *huc)
+{
+	hrtimer_cancel(&huc->delayed_load.timer);
+
+	/* MEI-GSC init is done, now we wait for MEI-PXP to bind */
+	huc->delayed_load.status = INTEL_HUC_WAITING_ON_PXP;
+	if (!i915_sw_fence_done(&huc->delayed_load.fence))
+		hrtimer_start(&huc->delayed_load.timer,
+			      ms_to_ktime(PXP_INIT_TIMEOUT_MS),
+			      HRTIMER_MODE_REL);
+}
+
+static enum hrtimer_restart huc_delayed_load_timer_callback(struct hrtimer *hrtimer)
+{
+	struct intel_huc *huc = container_of(hrtimer, struct intel_huc, delayed_load.timer);
+
+	if (!intel_huc_is_authenticated(huc)) {
+		drm_err(&huc_to_gt(huc)->i915->drm,
+			"timed out waiting for GSC init to load HuC\n");
+
+		__gsc_init_error(huc);
+	}
+
+	return HRTIMER_NORESTART;
+}
+
+static void huc_delayed_load_start(struct intel_huc *huc)
+{
+	ktime_t delay;
+
+	GEM_BUG_ON(intel_huc_is_authenticated(huc));
+
+	/*
+	 * On resume we don't have to wait for MEI-GSC to be re-probed, but we
+	 * do need to wait for MEI-PXP to reset & re-bind
+	 */
+	switch (huc->delayed_load.status) {
+	case INTEL_HUC_WAITING_ON_GSC:
+		delay = ms_to_ktime(GSC_INIT_TIMEOUT_MS);
+		break;
+	case INTEL_HUC_WAITING_ON_PXP:
+		delay = ms_to_ktime(PXP_INIT_TIMEOUT_MS);
+		break;
+	default:
+		gsc_init_error(huc);
+		return;
+	}
+
+	/*
+	 * This fence is always complete unless we're waiting for the
+	 * GSC device to come up to load the HuC. We arm the fence here
+	 * and complete it when we confirm that the HuC is loaded from
+	 * the PXP bind callback.
+	 */
+	GEM_BUG_ON(!i915_sw_fence_done(&huc->delayed_load.fence));
+	i915_sw_fence_fini(&huc->delayed_load.fence);
+	i915_sw_fence_reinit(&huc->delayed_load.fence);
+	i915_sw_fence_await(&huc->delayed_load.fence);
+	i915_sw_fence_commit(&huc->delayed_load.fence);
+
+	hrtimer_start(&huc->delayed_load.timer, delay, HRTIMER_MODE_REL);
+}
+
+static int gsc_notifier(struct notifier_block *nb, unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct intel_huc *huc = container_of(nb, struct intel_huc, delayed_load.nb);
+	struct intel_gsc_intf *intf = &huc_to_gt(huc)->gsc.intf[0];
+
+	if (!intf->adev || &intf->adev->aux_dev.dev != dev)
+		return 0;
+
+	switch (action) {
+	case BUS_NOTIFY_BOUND_DRIVER: /* mei driver bound to aux device */
+		gsc_init_done(huc);
+		break;
+
+	case BUS_NOTIFY_DRIVER_NOT_BOUND: /* mei driver fails to be bound */
+	case BUS_NOTIFY_UNBIND_DRIVER: /* mei driver about to be unbound */
+		drm_info(&huc_to_gt(huc)->i915->drm,
+			 "mei driver not bound, disabling HuC load\n");
+		gsc_init_error(huc);
+		break;
+	}
+
+	return 0;
+}
+
+void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus)
+{
+	int ret;
+
+	if (!intel_huc_is_loaded_by_gsc(huc))
+		return;
+
+	huc->delayed_load.nb.notifier_call = gsc_notifier;
+	ret = bus_register_notifier(bus, &huc->delayed_load.nb);
+	if (ret) {
+		drm_err(&huc_to_gt(huc)->i915->drm,
+			"failed to register GSC notifier\n");
+		huc->delayed_load.nb.notifier_call = NULL;
+		gsc_init_error(huc);
+	}
+}
+
+void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus)
+{
+	if (!huc->delayed_load.nb.notifier_call)
+		return;
+
+	delayed_huc_load_complete(huc);
+
+	bus_unregister_notifier(bus, &huc->delayed_load.nb);
+	huc->delayed_load.nb.notifier_call = NULL;
+}
+
  void intel_huc_init_early(struct intel_huc *huc)
  {
  	struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
@@ -57,6 +218,17 @@ void intel_huc_init_early(struct intel_huc *huc)
  		huc->status.mask = HUC_FW_VERIFIED;
  		huc->status.value = HUC_FW_VERIFIED;
  	}
+
+	/*
+	 * Initialize fence to be complete as this is expected to be complete
+	 * unless there is a delayed HuC reload in progress.
+	 */
+	i915_sw_fence_init(&huc->delayed_load.fence,
+			   sw_fence_dummy_notify);
+	i915_sw_fence_commit(&huc->delayed_load.fence);
+
+	hrtimer_init(&huc->delayed_load.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	huc->delayed_load.timer.function = huc_delayed_load_timer_callback;
  }
#define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
@@ -122,9 +294,25 @@ void intel_huc_fini(struct intel_huc *huc)
  	if (!intel_uc_fw_is_loadable(&huc->fw))
  		return;
+ delayed_huc_load_complete(huc);
+
+	i915_sw_fence_fini(&huc->delayed_load.fence);
  	intel_uc_fw_fini(&huc->fw);
  }
+void intel_huc_suspend(struct intel_huc *huc)
+{
+	if (!intel_uc_fw_is_loadable(&huc->fw))
+		return;
+
+	/*
+	 * in the unlikely case that we're suspending before the GSC has
+	 * completed its loading sequence, just stop waiting. We'll restart
+	 * on resume.
+	 */
+	delayed_huc_load_complete(huc);
+}
+
  int intel_huc_wait_for_auth_complete(struct intel_huc *huc)
  {
  	struct intel_gt *gt = huc_to_gt(huc);
@@ -136,6 +324,9 @@ int intel_huc_wait_for_auth_complete(struct intel_huc *huc)
  					huc->status.value,
  					2, 50, NULL);
+ /* mark the load process as complete even if the wait failed */
+	delayed_huc_load_complete(huc);
+
  	if (ret) {
  		drm_err(&gt->i915->drm, "HuC: Firmware not verified %d\n", ret);
  		intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
@@ -239,6 +430,12 @@ int intel_huc_check_status(struct intel_huc *huc)
  	return intel_huc_is_authenticated(huc);
  }
+static bool huc_has_delayed_load(struct intel_huc *huc)
+{
+	return intel_huc_is_loaded_by_gsc(huc) &&
+	       (huc->delayed_load.status != INTEL_HUC_DELAYED_LOAD_ERROR);
+}
+
  void intel_huc_update_auth_status(struct intel_huc *huc)
  {
  	if (!intel_uc_fw_is_loadable(&huc->fw))
@@ -247,6 +444,8 @@ void intel_huc_update_auth_status(struct intel_huc *huc)
  	if (intel_huc_is_authenticated(huc))
  		intel_uc_fw_change_status(&huc->fw,
  					  INTEL_UC_FIRMWARE_RUNNING);
+	else if (huc_has_delayed_load(huc))
+		huc_delayed_load_start(huc);
  }
/**
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index 51f9d96a3ca3..915d281c1c72 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -7,9 +7,21 @@
  #define _INTEL_HUC_H_
#include "i915_reg_defs.h"
+#include "i915_sw_fence.h"
  #include "intel_uc_fw.h"
  #include "intel_huc_fw.h"
+#include <linux/notifier.h>
+#include <linux/hrtimer.h>
+
+struct bus_type;
+
+enum intel_huc_delayed_load_status {
+	INTEL_HUC_WAITING_ON_GSC = 0,
+	INTEL_HUC_WAITING_ON_PXP,
+	INTEL_HUC_DELAYED_LOAD_ERROR,
+};
+
  struct intel_huc {
  	/* Generic uC firmware management */
  	struct intel_uc_fw fw;
@@ -20,17 +32,28 @@ struct intel_huc {
  		u32 mask;
  		u32 value;
  	} status;
+
+	struct {
+		struct i915_sw_fence fence;
+		struct hrtimer timer;
+		struct notifier_block nb;
+		enum intel_huc_delayed_load_status status;
+	} delayed_load;
  };
void intel_huc_init_early(struct intel_huc *huc);
  int intel_huc_init(struct intel_huc *huc);
  void intel_huc_fini(struct intel_huc *huc);
+void intel_huc_suspend(struct intel_huc *huc);
  int intel_huc_auth(struct intel_huc *huc);
  int intel_huc_wait_for_auth_complete(struct intel_huc *huc);
  int intel_huc_check_status(struct intel_huc *huc);
  void intel_huc_update_auth_status(struct intel_huc *huc);
  bool intel_huc_is_authenticated(struct intel_huc *huc);
+void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
+void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
+
  static inline int intel_huc_sanitize(struct intel_huc *huc)
  {
  	intel_uc_fw_sanitize(&huc->fw);




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux