diff options
author | Oded Gabbay <ogabbay@kernel.org> | 2021-02-01 21:23:43 +0200 |
---|---|---|
committer | Oded Gabbay <ogabbay@kernel.org> | 2021-02-08 18:20:08 +0200 |
commit | 28bcf1fdc408cd2f7393ae5dcd71c756e1163cdb (patch) | |
tree | a6bd3294d412e9f22339f77e5e33544e77b0f6fb /drivers/misc/habanalabs/common | |
parent | b520ca5d82f69ac28ca3d57f001430c203487cb3 (diff) |
habanalabs: enable F/W events after init done
Only after the initialization of the device is done, the driver is
ready to receive events from the F/W. The driver can't handle events
before that because of races so it will ignore events. In case of
a fatal event, the driver won't know about it and the device will be
operational although it shouldn't be.
Same logic should be applied after hard-reset.
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Diffstat (limited to 'drivers/misc/habanalabs/common')
-rw-r--r-- | drivers/misc/habanalabs/common/device.c | 23 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/habanalabs.h | 9 |
2 files changed, 26 insertions, 6 deletions
diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 59219c862ca0..15fcb5c31c4b 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1159,12 +1159,20 @@ kill_processes: atomic_set(&hdev->in_reset, 0); hdev->needs_reset = false; - if (hard_reset) + dev_notice(hdev->dev, "Successfully finished resetting the device\n"); + + if (hard_reset) { hdev->hard_reset_cnt++; - else - hdev->soft_reset_cnt++; - dev_warn(hdev->dev, "Successfully finished resetting the device\n"); + /* After reset is done, we are ready to receive events from + * the F/W. We can't do it before because we will ignore events + * and if those events are fatal, we won't know about it and + * the device will be operational although it shouldn't be + */ + hdev->asic_funcs->enable_events_from_fw(hdev); + } else { + hdev->soft_reset_cnt++; + } return 0; @@ -1415,6 +1423,13 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) hdev->init_done = true; + /* After initialization is done, we are ready to receive events from + * the F/W. We can't do it before because we will ignore events and if + * those events are fatal, we won't know about it and the device will + * be operational although it shouldn't be + */ + hdev->asic_funcs->enable_events_from_fw(hdev); + return 0; release_ctx: diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 98163317ec43..18ed3a6000b0 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -860,12 +860,16 @@ enum div_select_defs { * and place them in the relevant cs jobs * @collective_wait_create_jobs: allocate collective wait cs jobs * @scramble_addr: Routine to scramble the address prior of mapping it - * in the MMU. + * in the MMU. * @descramble_addr: Routine to de-scramble the address prior of - * showing it to users. + * showing it to users. * @ack_protection_bits_errors: ack and dump all security violations * @get_hw_block_id: retrieve a HW block id to be used by the user to mmap it. * @hw_block_mmap: mmap a HW block with a given id. + * @enable_events_from_fw: send interrupt to firmware to notify them the + * driver is ready to receive asynchronous events. This + * function should be called during the first init and + * after every hard-reset of the device */ struct hl_asic_funcs { int (*early_init)(struct hl_device *hdev); @@ -982,6 +986,7 @@ struct hl_asic_funcs { u32 *block_id); int (*hw_block_mmap)(struct hl_device *hdev, struct vm_area_struct *vma, u32 block_id, u32 block_size); + void (*enable_events_from_fw)(struct hl_device *hdev); }; |