summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/expr.l
diff options
context:
space:
mode:
authorYijie Yang <yijie.yang@oss.qualcomm.com>2026-08-11 16:46:47 +0800
committerRob Herring (Arm) <robh@kernel.org>2026-08-15 15:46:52 -0500
commite1c13aed4a1641550e8c9518c96f016e1d52d09b (patch)
tree61c2297688373db165cc857b7c7adcb147a5c419 /tools/perf/util/expr.l
downloadlinux-stable-e1c13aed4a1641550e8c9518c96f016e1d52d09b.tar.gz
linux-stable-e1c13aed4a1641550e8c9518c96f016e1d52d09b.zip
dt-bindings: interconnect: qcom-bwmon: Add Maili cpu-bwmon compatiblegrafted
Add the Qualcomm Maili SoC compatible string for the CPU bandwidth monitor (BWMONv4). This falls back to the sdm845-bwmon compatible, consistent with the existing pattern used by other recent SoCs such as sm8750 and kaanapali. Signed-off-by: Yijie Yang <yijie.yang@oss.qualcomm.com> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Reviewed-by: Jingyi Wang <jingyi.wang@oss.qualcomm.com> Link: https://patch.msgid.link/20260811-bwmon-v2-1-80f7f150ab9e@oss.qualcomm.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Diffstat (limited to 'tools/perf/util/expr.l')
-rw-r--r--tools/perf/util/expr.l150
1 files changed, 150 insertions, 0 deletions
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
new file mode 100644
index 000000000..f16ccff27
--- /dev/null
+++ b/tools/perf/util/expr.l
@@ -0,0 +1,150 @@
+%option prefix="expr_"
+%option reentrant
+%option bison-bridge
+
+%{
+#include <linux/compiler.h>
+#include "expr.h"
+#include "expr-bison.h"
+#include <math.h>
+
+char *expr_get_text(yyscan_t yyscanner);
+YYSTYPE *expr_get_lval(yyscan_t yyscanner);
+
+static double __value(YYSTYPE *yylval, char *str, int token)
+{
+ double num;
+
+ errno = 0;
+ num = strtod(str, NULL);
+ if (errno)
+ return EXPR_ERROR;
+
+ yylval->num = num;
+ return token;
+}
+
+static int value(yyscan_t scanner)
+{
+ YYSTYPE *yylval = expr_get_lval(scanner);
+ char *text = expr_get_text(scanner);
+
+ return __value(yylval, text, NUMBER);
+}
+
+/*
+ * Allow @ instead of / to be able to specify pmu/event/ without
+ * conflicts with normal division.
+ */
+static char *normalize(char *str, int runtime)
+{
+ char *ret = str;
+ char *dst = str;
+
+ while (*str) {
+ if (*str == '\\') {
+ *dst++ = *++str;
+ if (!*str)
+ break;
+ }
+ else if (*str == '?') {
+ char *paramval;
+ int i = 0;
+ int size = asprintf(&paramval, "%d", runtime);
+
+ if (size < 0)
+ *dst++ = '0';
+ else {
+ while (i < size)
+ *dst++ = paramval[i++];
+ free(paramval);
+ }
+ }
+ else
+ *dst++ = *str;
+ str++;
+ }
+
+ *dst = 0x0;
+ return ret;
+}
+
+static int str(yyscan_t scanner, int token, int runtime)
+{
+ YYSTYPE *yylval = expr_get_lval(scanner);
+ char *text = expr_get_text(scanner);
+
+ yylval->str = normalize(strdup(text), runtime);
+ if (!yylval->str)
+ return EXPR_ERROR;
+
+ yylval->str = normalize(yylval->str, runtime);
+ return token;
+}
+
+static int literal(yyscan_t scanner, const struct expr_scanner_ctx *sctx)
+{
+ YYSTYPE *yylval = expr_get_lval(scanner);
+
+ yylval->num = expr__get_literal(expr_get_text(scanner), sctx);
+ if (isnan(yylval->num)) {
+ if (!sctx->is_test)
+ return EXPR_ERROR;
+ yylval->num = 1;
+ }
+ return LITERAL;
+}
+
+static int nan_value(yyscan_t scanner)
+{
+ YYSTYPE *yylval = expr_get_lval(scanner);
+
+ yylval->num = NAN;
+ return NUMBER;
+}
+%}
+
+number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)?
+
+sch [-,=]
+spec \\{sch}
+sym [0-9a-zA-Z_\.:@?]+
+symbol ({spec}|{sym})+
+literal #[0-9a-zA-Z_\.\-]+
+
+%%
+ struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
+
+d_ratio { return D_RATIO; }
+max { return MAX; }
+min { return MIN; }
+if { return IF; }
+else { return ELSE; }
+source_count { return SOURCE_COUNT; }
+aggr_nr { return AGGR_NR; }
+has_event { return HAS_EVENT; }
+strcmp_cpuid_str { return STRCMP_CPUID_STR; }
+NaN { return nan_value(yyscanner); }
+{literal} { return literal(yyscanner, sctx); }
+{number} { return value(yyscanner); }
+{symbol} { return str(yyscanner, ID, sctx->runtime); }
+"|" { return '|'; }
+"^" { return '^'; }
+"&" { return '&'; }
+"<" { return '<'; }
+">" { return '>'; }
+"-" { return '-'; }
+"+" { return '+'; }
+"*" { return '*'; }
+"/" { return '/'; }
+"%" { return '%'; }
+"(" { return '('; }
+")" { return ')'; }
+"," { return ','; }
+. { }
+%%
+
+int expr_wrap(void *scanner __maybe_unused)
+{
+ return 1;
+}