linux/drivers/misc/xilinx-ai-engine/ai-engine-sysfs-event.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx AI Engine device driver.
   4 *
   5 * Copyright (C) 2021 Xilinx, Inc.
   6 */
   7#include "ai-engine-internal.h"
   8
   9/**
  10 * aie_tile_print_event() - formats events strings from each module into a
  11 *                          single buffer.
  12 * @atile: AI engine tile.
  13 * @buffer: export buffer.
  14 * @core: core module event string
  15 * @mem: memory module event string
  16 * @pl: pl module event string
  17 * @return: length of string copied to buffer.
  18 */
  19static ssize_t aie_tile_print_event(struct aie_tile *atile, char *buffer,
  20                                    char *core, char *mem, char *pl)
  21{
  22        ssize_t len = 0, size = PAGE_SIZE;
  23        u32 ttype;
  24
  25        ttype = atile->apart->adev->ops->get_tile_type(&atile->loc);
  26        if (ttype == AIE_TILE_TYPE_TILE) {
  27                len += scnprintf(&buffer[len], max(0L, size - len),
  28                                 "core: %s\n", core);
  29                len += scnprintf(&buffer[len], max(0L, size - len),
  30                                 "memory: %s\n", mem);
  31        } else {
  32                len += scnprintf(&buffer[len], max(0L, size - len), "pl: %s\n",
  33                                 pl);
  34        }
  35        return len;
  36}
  37
  38/**
  39 * aie_tile_show_event() - exports all active events in a given tile to a
  40 *                         tile level sysfs node.
  41 * @dev: AI engine tile device.
  42 * @attr: sysfs device attribute.
  43 * @buffer: export buffer.
  44 * @return: length of string copied to buffer.
  45 */
  46ssize_t aie_tile_show_event(struct device *dev, struct device_attribute *attr,
  47                            char *buffer)
  48{
  49        struct aie_tile *atile = container_of(dev, struct aie_tile, dev);
  50        struct aie_partition *apart = atile->apart;
  51        ssize_t l = 0;
  52        unsigned long cs[4] = {0}, ms[4] = {0}, ps[4] = {0};
  53        u32 ttype, n;
  54        char core_buf[AIE_SYSFS_EVENT_STS_SIZE],
  55             mem_buf[AIE_SYSFS_EVENT_STS_SIZE],
  56             pl_buf[AIE_SYSFS_EVENT_STS_SIZE];
  57        bool is_delimit_req = false;
  58
  59        if (mutex_lock_interruptible(&apart->mlock)) {
  60                dev_err(&apart->dev,
  61                        "Failed to acquire lock. Process was interrupted by fatal signals\n");
  62                return 0;
  63        }
  64
  65        ttype = apart->adev->ops->get_tile_type(&atile->loc);
  66
  67        if (!aie_part_check_clk_enable_loc(apart, &atile->loc)) {
  68                mutex_unlock(&apart->mlock);
  69                return aie_tile_print_event(atile, buffer, "clock_gated",
  70                                            "clock_gated", "clock_gated");
  71        }
  72
  73        if (ttype == AIE_TILE_TYPE_TILE) {
  74                aie_read_event_status(apart, &atile->loc, AIE_CORE_MOD,
  75                                      (u32 *)cs);
  76                aie_read_event_status(apart, &atile->loc, AIE_MEM_MOD,
  77                                      (u32 *)ms);
  78        } else {
  79                aie_read_event_status(apart, &atile->loc, AIE_PL_MOD,
  80                                      (u32 *)ps);
  81        }
  82
  83        for_each_set_bit(n, cs, 128) {
  84                if (is_delimit_req) {
  85                        l += scnprintf(&core_buf[l],
  86                                       max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
  87                                       DELIMITER_LEVEL0);
  88                }
  89
  90                l += scnprintf(&core_buf[l],
  91                               max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
  92                is_delimit_req = true;
  93        }
  94
  95        l = 0;
  96        is_delimit_req = false;
  97        for_each_set_bit(n, ms, 128) {
  98                if (is_delimit_req) {
  99                        l += scnprintf(&mem_buf[l],
 100                                       max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
 101                                       DELIMITER_LEVEL0);
 102                }
 103
 104                l += scnprintf(&mem_buf[l],
 105                               max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
 106                is_delimit_req = true;
 107        }
 108
 109        l = 0;
 110        is_delimit_req = false;
 111        for_each_set_bit(n, ps, 128) {
 112                if (is_delimit_req) {
 113                        l += scnprintf(&pl_buf[l],
 114                                       max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
 115                                       DELIMITER_LEVEL0);
 116                }
 117
 118                l += scnprintf(&pl_buf[l],
 119                               max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
 120                is_delimit_req = true;
 121        }
 122
 123        mutex_unlock(&apart->mlock);
 124        return aie_tile_print_event(atile, buffer, core_buf, mem_buf, pl_buf);
 125}
 126