Files
linux/drivers/accel/habanalabs/common/decoder.c
Linus Torvalds bf4afc53b7 Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
This was done entirely with mindless brute force, using

    git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
        xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21 17:09:51 -08:00

142 lines
3.6 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2022 HabanaLabs, Ltd.
* All Rights Reserved.
*/
#include "habanalabs.h"
#define VCMD_CONTROL_OFFSET 0x40 /* SWREG16 */
#define VCMD_IRQ_STATUS_OFFSET 0x44 /* SWREG17 */
#define VCMD_IRQ_STATUS_ENDCMD_MASK 0x1
#define VCMD_IRQ_STATUS_BUSERR_MASK 0x2
#define VCMD_IRQ_STATUS_TIMEOUT_MASK 0x4
#define VCMD_IRQ_STATUS_CMDERR_MASK 0x8
#define VCMD_IRQ_STATUS_ABORT_MASK 0x10
#define VCMD_IRQ_STATUS_RESET_MASK 0x20
static void dec_print_abnrm_intr_source(struct hl_device *hdev, u32 irq_status)
{
const char *format = "abnormal interrupt source:%s%s%s%s%s%s\n";
char *intr_source[6] = {"Unknown", "", "", "", "", ""};
int i = 0;
if (!irq_status)
return;
if (irq_status & VCMD_IRQ_STATUS_ENDCMD_MASK)
intr_source[i++] = " ENDCMD";
if (irq_status & VCMD_IRQ_STATUS_BUSERR_MASK)
intr_source[i++] = " BUSERR";
if (irq_status & VCMD_IRQ_STATUS_TIMEOUT_MASK)
intr_source[i++] = " TIMEOUT";
if (irq_status & VCMD_IRQ_STATUS_CMDERR_MASK)
intr_source[i++] = " CMDERR";
if (irq_status & VCMD_IRQ_STATUS_ABORT_MASK)
intr_source[i++] = " ABORT";
if (irq_status & VCMD_IRQ_STATUS_RESET_MASK)
intr_source[i++] = " RESET";
dev_err(hdev->dev, format, intr_source[0], intr_source[1],
intr_source[2], intr_source[3], intr_source[4], intr_source[5]);
}
static void dec_abnrm_intr_work(struct work_struct *work)
{
struct hl_dec *dec = container_of(work, struct hl_dec, abnrm_intr_work);
struct hl_device *hdev = dec->hdev;
u32 irq_status, event_mask = 0;
bool reset_required = false;
irq_status = RREG32(dec->base_addr + VCMD_IRQ_STATUS_OFFSET);
dev_err(hdev->dev, "Decoder abnormal interrupt %#x, core %d\n", irq_status, dec->core_id);
dec_print_abnrm_intr_source(hdev, irq_status);
/* Clear the interrupt */
WREG32(dec->base_addr + VCMD_IRQ_STATUS_OFFSET, irq_status);
/* Flush the interrupt clear */
RREG32(dec->base_addr + VCMD_IRQ_STATUS_OFFSET);
if (irq_status & VCMD_IRQ_STATUS_TIMEOUT_MASK) {
reset_required = true;
event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR;
}
if (irq_status & VCMD_IRQ_STATUS_CMDERR_MASK)
event_mask |= HL_NOTIFIER_EVENT_UNDEFINED_OPCODE;
if (irq_status & (VCMD_IRQ_STATUS_ENDCMD_MASK |
VCMD_IRQ_STATUS_BUSERR_MASK |
VCMD_IRQ_STATUS_ABORT_MASK))
event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR;
if (reset_required) {
event_mask |= HL_NOTIFIER_EVENT_DEVICE_RESET;
hl_device_cond_reset(hdev, 0, event_mask);
} else if (event_mask) {
hl_notifier_event_send_all(hdev, event_mask);
}
}
void hl_dec_fini(struct hl_device *hdev)
{
kfree(hdev->dec);
}
int hl_dec_init(struct hl_device *hdev)
{
struct asic_fixed_properties *prop = &hdev->asic_prop;
struct hl_dec *dec;
int rc, j;
/* if max core is 0, nothing to do*/
if (!prop->max_dec)
return 0;
hdev->dec = kzalloc_objs(struct hl_dec, prop->max_dec);
if (!hdev->dec)
return -ENOMEM;
for (j = 0 ; j < prop->max_dec ; j++) {
dec = hdev->dec + j;
dec->hdev = hdev;
INIT_WORK(&dec->abnrm_intr_work, dec_abnrm_intr_work);
dec->core_id = j;
dec->base_addr = hdev->asic_funcs->get_dec_base_addr(hdev, j);
if (!dec->base_addr) {
dev_err(hdev->dev, "Invalid base address of decoder %d\n", j);
rc = -EINVAL;
goto err_dec_fini;
}
}
return 0;
err_dec_fini:
hl_dec_fini(hdev);
return rc;
}
void hl_dec_ctx_fini(struct hl_ctx *ctx)
{
struct hl_device *hdev = ctx->hdev;
struct asic_fixed_properties *prop = &hdev->asic_prop;
struct hl_dec *dec;
int j;
for (j = 0 ; j < prop->max_dec ; j++) {
if (!!(prop->decoder_enabled_mask & BIT(j))) {
dec = hdev->dec + j;
/* Stop the decoder */
WREG32(dec->base_addr + VCMD_CONTROL_OFFSET, 0);
}
}
}