From patchwork Fri Sep 22 14:39:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143591 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp5799073vqi; Fri, 22 Sep 2023 11:54:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHWCZGPIQ6F2fGeXDTGdc/WeFeMVHCd3MnzHs1RbM9OouWxoDOMR7Gyv7olcSZLoBZyRn6H X-Received: by 2002:a17:902:db11:b0:1c4:486f:5939 with SMTP id m17-20020a170902db1100b001c4486f5939mr475734plx.3.1695408867138; Fri, 22 Sep 2023 11:54:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695408867; cv=none; d=google.com; s=arc-20160816; b=pR+mmabNbkf1IVSZbpei+4xqrv4yBcm9PfbkUwrLfQHIBTWPys8BofmsFi9lcV2ZVn rCFSQR2lGSNpcYYYDQlD3+pucQfoKdMdlv0aq6XCNEupeD0nH1jv+f3NCtT2rr0nDfT5 1w1ZHogmLSDpLCXJQoW9O51OCd3vUl17kk4pt80BaZIKyVuLs+ARPqs1bMQffPkKBDqy rg3nRb+8SdQWDFB0l7FyZBuR2g2LAE1B+tJ6Wg2BP3etCHJ6horgFRZDJaB3D6L+vJen vRTGg+94bKylSsJAzVxKFT4i6i+ZDC/MYF+RjHH1uxvfk+nwrdzKAzieVN3oYKGm3Fvi zo0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jMfp6I+BexJFvXzAqqy60gAJqPrK5cBocD8rJADux+I=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=VXK8T4a0epcdyAgdKpiwddJK0m+AnBADKilZcbTsSpxceG7+c1EYAAQYYj8bCr20DQ ksrkdsto+HDzTSiQTgS5wAZXf0ZHwSDl+rwVl1rgsyhLVKwrct4+OOEzl/jQgipmL1KX XlEEo7hKh7Ae0zsvThz8VZznDftPDTbn95CFNfmFZ26VVginvW8HexAubao5ClZGn1j3 LwSMBcbIPUiKhVwT921soSHopVmkQHklKyzaLLnxYqznQhcKNQnSBO6Ol7I6RaJNDShz 7h/V9BBd83dlBDF4NfhVsPPACo5GijLH85KAg8RizD8Uihf+lwt09l1c/voCqR1vjkoO 3xNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b="ZJtTT2/1"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from pete.vger.email (pete.vger.email. [2620:137:e000::3:6]) by mx.google.com with ESMTPS id q5-20020a170902a3c500b001b89613687bsi4406731plb.439.2023.09.22.11.54.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 11:54:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) client-ip=2620:137:e000::3:6; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b="ZJtTT2/1"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 6D2B38025BF4; Fri, 22 Sep 2023 07:42:03 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231436AbjIVOkT (ORCPT + 29 others); Fri, 22 Sep 2023 10:40:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230132AbjIVOkM (ORCPT ); Fri, 22 Sep 2023 10:40:12 -0400 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C757B195; Fri, 22 Sep 2023 07:40:04 -0700 (PDT) Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9rxEX013779; Fri, 22 Sep 2023 16:39:45 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=jMfp6I+BexJFvXzAqqy60gAJqPrK5cBocD8rJADux+I=; b=ZJ tTT2/1pwtDHeYembLb1gRKxP8V6BUbMzq4pXDdrPGq4prq7E8fhZs00p8IfDKKW1 IgtY/rIa+IAqW8K1YrhJGQooWF45zasSY9OFr+xOTC4Fge03JhjSKlq8zZ8Ny/w0 cCnxhcawiCcokE8VAU2HJOBvhZ6ELU2Zs8NjvEZH1M7nwJM3lFq9vVx1hNHCqHa5 H35GXVwWHqeyF/2IUS1hMm9hNYzUuExR6HP5o5t4k46YsBqgzdL/b7M4gylYK6cb JnEguFAm9+QZwf1Je4Gu9SQjIROOsBWc6wvRyzu5cL/8aSjz9TiD0MprtyKjWUdo vSYfVzp96/rjN0j/AJ7A== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt7kvsw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:39:44 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 73FA5100056; Fri, 22 Sep 2023 16:39:44 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 694B2235F24; Fri, 22 Sep 2023 16:39:44 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:39:44 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 1/6] tools/counter: add a flexible watch events tool Date: Fri, 22 Sep 2023 16:39:15 +0200 Message-ID: <20230922143920.3144249-2-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:42:03 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777765048391665281 X-GMAIL-MSGID: 1777765048391665281 This adds a new counter tool to be able to test various watch events. A flexible watch array can be populated from command line, each field may be tuned with a dedicated command line sub-option in "--watch" string. Several watch events can be defined, each can have specific watch options, by using "--watch --watch ". Watch options is a comma separated list. It also comes with a simple default watch (to monitor overflow/underflow events), used when no watch parameters are provided. It's equivalent to: counter_watch_events -w comp_count,scope_count,evt_ovf_udf The print_usage() routine proposes another example, from the command line, which generates a 2 elements watch array, to monitor: - overflow underflow events - capture events, on channel 3, that reads read captured data by specifying the component id (capture3_component_id being 7 here). Signed-off-by: Fabrice Gasnier --- Changes in v2: Review comments from William: - revisit watch options to be less error prone: add --watch with sub-options to properly define each watch one by one, as a comma separated list - by the way, drop string/array parsing routines, replaced by getsubopt() - Improve command-line interface descriptions, e.g. like "-h, --help" - Makefile: adopt ARRAY_SIZE from tools/include/linux.kernel.h (via CFLAG) - remove reference to counter_example - clarify commit message, code comment: Index/overflow/underflow event - check calloc return value - Makefile: sort count_watch_events in alphabetic order - Makefile: add a clean rule to delete .*.o.cmd files --- tools/counter/Build | 1 + tools/counter/Makefile | 12 +- tools/counter/counter_watch_events.c | 368 +++++++++++++++++++++++++++ 3 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 tools/counter/counter_watch_events.c diff --git a/tools/counter/Build b/tools/counter/Build index 33f4a51d715e..4bbadb7ec93a 100644 --- a/tools/counter/Build +++ b/tools/counter/Build @@ -1 +1,2 @@ counter_example-y += counter_example.o +counter_watch_events-y += counter_watch_events.o diff --git a/tools/counter/Makefile b/tools/counter/Makefile index b2c2946f44c9..d82d35a520f6 100644 --- a/tools/counter/Makefile +++ b/tools/counter/Makefile @@ -12,9 +12,10 @@ endif # (this improves performance and avoids hard-to-debug behaviour); MAKEFLAGS += -r -override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include +override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include \ + -I$(srctree)/tools/include -ALL_TARGETS := counter_example +ALL_TARGETS := counter_example counter_watch_events ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) all: $(ALL_PROGRAMS) @@ -37,12 +38,19 @@ $(COUNTER_EXAMPLE): prepare FORCE $(OUTPUT)counter_example: $(COUNTER_EXAMPLE) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ +COUNTER_WATCH_EVENTS := $(OUTPUT)counter_watch_events.o +$(COUNTER_WATCH_EVENTS): prepare FORCE + $(Q)$(MAKE) $(build)=counter_watch_events +$(OUTPUT)counter_watch_events: $(COUNTER_WATCH_EVENTS) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/linux/counter.h rm -df $(OUTPUT)include/linux rm -df $(OUTPUT)include find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '\.*.o.cmd' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/counter/counter_watch_events.c b/tools/counter/counter_watch_events.c new file mode 100644 index 000000000000..17eae0ab9cef --- /dev/null +++ b/tools/counter/counter_watch_events.c @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Counter Watch Events - Test various counter watch events in a userspace application */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct counter_watch simple_watch[] = { + { + /* Component data: Count 0 count */ + .component.type = COUNTER_COMPONENT_COUNT, + .component.scope = COUNTER_SCOPE_COUNT, + .component.parent = 0, + /* Event type: overflow or underflow */ + .event = COUNTER_EVENT_OVERFLOW_UNDERFLOW, + /* Device event channel 0 */ + .channel = 0, + }, +}; + +static const char * const counter_event_type_name[] = { + "COUNTER_EVENT_OVERFLOW", + "COUNTER_EVENT_UNDERFLOW", + "COUNTER_EVENT_OVERFLOW_UNDERFLOW", + "COUNTER_EVENT_THRESHOLD", + "COUNTER_EVENT_INDEX", + "COUNTER_EVENT_CHANGE_OF_STATE", + "COUNTER_EVENT_CAPTURE", +}; + +static const char * const counter_component_type_name[] = { + "COUNTER_COMPONENT_NONE", + "COUNTER_COMPONENT_SIGNAL", + "COUNTER_COMPONENT_COUNT", + "COUNTER_COMPONENT_FUNCTION", + "COUNTER_COMPONENT_SYNAPSE_ACTION", + "COUNTER_COMPONENT_EXTENSION", +}; + +static const char * const counter_scope_name[] = { + "COUNTER_SCOPE_DEVICE", + "COUNTER_SCOPE_SIGNAL", + "COUNTER_SCOPE_COUNT", +}; + +static void print_watch(struct counter_watch *watch, int nwatch) +{ + int i; + + /* prints the watch array in C-like structure */ + printf("watch[%d] = {\n", nwatch); + for (i = 0; i < nwatch; i++) { + printf(" [%d] =\t{\n" + "\t\t.component.type = %s\n" + "\t\t.component.scope = %s\n" + "\t\t.component.parent = %d\n" + "\t\t.component.id = %d\n" + "\t\t.event = %s\n" + "\t\t.channel = %d\n" + "\t},\n", + i, + counter_component_type_name[watch[i].component.type], + counter_scope_name[watch[i].component.scope], + watch[i].component.parent, + watch[i].component.id, + counter_event_type_name[watch[i].event], + watch[i].channel); + } + printf("};\n"); +} + +static void print_usage(void) +{ + fprintf(stderr, "Usage:\n\n" + "counter_watch_events [options] [-w ]\n" + "counter_watch_events [options] [-w ] [-w ]...\n" + "\n" + "When no --watch option has been provided, simple watch example is used:\n" + "counter_watch_events [options] -w comp_count,scope_count,evt_ovf_udf\n" + "\n" + "Test various watch events for given counter device.\n" + "\n" + "Options:\n" + " -d, --debug Prints debug information\n" + " -h, --help Prints usage\n" + " -n, --device-num Use /dev/counter [default: /dev/counter0]\n" + " -l, --loop Loop for events [default: 0 (forever)]\n" + " -w, --watch comma-separated list of watch options\n" + "\n" + "Watch options:\n" + " scope_device (COUNTER_SCOPE_DEVICE) [default: scope_device]\n" + " scope_signal (COUNTER_SCOPE_SIGNAL)\n" + " scope_count (COUNTER_SCOPE_COUNT)\n" + "\n" + " comp_none (COUNTER_COMPONENT_NONE) [default: comp_none]\n" + " comp_signal (COUNTER_COMPONENT_SIGNAL)\n" + " comp_count (COUNTER_COMPONENT_COUNT)\n" + " comp_function (COUNTER_COMPONENT_FUNCTION)\n" + " comp_synapse_action (COUNTER_COMPONENT_SYNAPSE_ACTION)\n" + " comp_extension (COUNTER_COMPONENT_EXTENSION)\n" + "\n" + " evt_ovf (COUNTER_EVENT_OVERFLOW) [default: evt_ovf]\n" + " evt_udf (COUNTER_EVENT_UNDERFLOW)\n" + " evt_ovf_udf (COUNTER_EVENT_OVERFLOW_UNDERFLOW)\n" + " evt_threshold (COUNTER_EVENT_THRESHOLD)\n" + " evt_index (COUNTER_EVENT_INDEX)\n" + " evt_change_of_state (COUNTER_EVENT_CHANGE_OF_STATE)\n" + " evt_capture (COUNTER_EVENT_CAPTURE)\n" + "\n" + " chan= channel for this watch [default: 0]\n" + " id= componend id for this watch [default: 0]\n" + " parent= componend parent for this watch [default: 0]\n" + "\n" + "Example with two watched events:\n\n" + "counter_watch_events -d \\\n" + "\t-w comp_count,scope_count,evt_ovf_udf \\\n" + "\t-w comp_extension,scope_count,evt_capture,id=7,chan=3\n" + ); +} + +static const struct option longopts[] = { + { "debug", no_argument, 0, 'd' }, + { "help", no_argument, 0, 'h' }, + { "device-num", required_argument, 0, 'n' }, + { "loop", required_argument, 0, 'l' }, + { "watch", required_argument, 0, 'w' }, + { }, +}; + +/* counter watch subopts */ +enum { + WATCH_SCOPE_DEVICE, + WATCH_SCOPE_SIGNAL, + WATCH_SCOPE_COUNT, + WATCH_COMPONENT_NONE, + WATCH_COMPONENT_SIGNAL, + WATCH_COMPONENT_COUNT, + WATCH_COMPONENT_FUNCTION, + WATCH_COMPONENT_SYNAPSE_ACTION, + WATCH_COMPONENT_EXTENSION, + WATCH_EVENT_OVERFLOW, + WATCH_EVENT_UNDERFLOW, + WATCH_EVENT_OVERFLOW_UNDERFLOW, + WATCH_EVENT_THRESHOLD, + WATCH_EVENT_INDEX, + WATCH_EVENT_CHANGE_OF_STATE, + WATCH_EVENT_CAPTURE, + WATCH_CHANNEL, + WATCH_ID, + WATCH_PARENT, + WATCH_SUBOPTS_MAX, +}; + +static char * const counter_watch_subopts[WATCH_SUBOPTS_MAX + 1] = { + /* component.scope */ + [WATCH_SCOPE_DEVICE] = "scope_device", + [WATCH_SCOPE_SIGNAL] = "scope_signal", + [WATCH_SCOPE_COUNT] = "scope_count", + /* component.type */ + [WATCH_COMPONENT_NONE] = "comp_none", + [WATCH_COMPONENT_SIGNAL] = "comp_signal", + [WATCH_COMPONENT_COUNT] = "comp_count", + [WATCH_COMPONENT_FUNCTION] = "comp_function", + [WATCH_COMPONENT_SYNAPSE_ACTION] = "comp_synapse_action", + [WATCH_COMPONENT_EXTENSION] = "comp_extension", + /* event */ + [WATCH_EVENT_OVERFLOW] = "evt_ovf", + [WATCH_EVENT_UNDERFLOW] = "evt_udf", + [WATCH_EVENT_OVERFLOW_UNDERFLOW] = "evt_ovf_udf", + [WATCH_EVENT_THRESHOLD] = "evt_threshold", + [WATCH_EVENT_INDEX] = "evt_index", + [WATCH_EVENT_CHANGE_OF_STATE] = "evt_change_of_state", + [WATCH_EVENT_CAPTURE] = "evt_capture", + /* channel, id, parent */ + [WATCH_CHANNEL] = "chan", + [WATCH_ID] = "id", + [WATCH_PARENT] = "parent", + /* Empty entry ends the opts array */ + NULL +}; + +int main(int argc, char **argv) +{ + int c, fd, i, ret, debug = 0, loop = 0, dev_num = 0, nwatch = 0; + struct counter_event event_data; + char *device_name = NULL, *subopts, *value; + struct counter_watch *watches; + + /* + * 1st pass: + * - list watch events number to allocate the watch array. + * - parse normal options (other than watch options) + */ + while ((c = getopt_long(argc, argv, "dhn:l:w:", longopts, NULL)) != -1) { + switch (c) { + case 'd': + debug = 1; + break; + case 'h': + print_usage(); + return -1; + case 'n': + dev_num = strtoul(optarg, NULL, 10); + if (errno) + return -errno; + break; + case 'l': + loop = strtol(optarg, NULL, 10); + if (errno) + return -errno; + break; + case 'w': + nwatch++; + break; + default: + return -1; + }; + }; + + if (nwatch) { + watches = calloc(nwatch, sizeof(*watches)); + if (!watches) { + perror("Error allocating watches"); + return 1; + } + } else { + /* default to simple watch example */ + watches = simple_watch; + nwatch = ARRAY_SIZE(simple_watch); + } + + /* 2nd pass: parse watch sub-options to fill in watch array */ + optind = 1; + i = 0; + while ((c = getopt_long(argc, argv, "dhn:l:w:", longopts, NULL)) != -1) { + switch (c) { + case 'w': + subopts = optarg; + while (*subopts != '\0') { + ret = getsubopt(&subopts, counter_watch_subopts, &value); + switch (ret) { + case WATCH_SCOPE_DEVICE: + case WATCH_SCOPE_SIGNAL: + case WATCH_SCOPE_COUNT: + /* match with counter_scope */ + watches[i].component.scope = ret; + break; + case WATCH_COMPONENT_NONE: + case WATCH_COMPONENT_SIGNAL: + case WATCH_COMPONENT_COUNT: + case WATCH_COMPONENT_FUNCTION: + case WATCH_COMPONENT_SYNAPSE_ACTION: + case WATCH_COMPONENT_EXTENSION: + /* match counter_component_type: subtract enum value */ + ret -= WATCH_COMPONENT_NONE; + watches[i].component.type = ret; + break; + case WATCH_EVENT_OVERFLOW: + case WATCH_EVENT_UNDERFLOW: + case WATCH_EVENT_OVERFLOW_UNDERFLOW: + case WATCH_EVENT_THRESHOLD: + case WATCH_EVENT_INDEX: + case WATCH_EVENT_CHANGE_OF_STATE: + case WATCH_EVENT_CAPTURE: + /* match counter_event_type: subtract enum value */ + ret -= WATCH_EVENT_OVERFLOW; + watches[i].event = ret; + break; + case WATCH_CHANNEL: + if (!value) { + fprintf(stderr, "Missing chan=\n"); + return -EINVAL; + } + watches[i].channel = strtoul(value, NULL, 10); + if (errno) + return -errno; + break; + case WATCH_ID: + if (!value) { + fprintf(stderr, "Missing id=\n"); + return -EINVAL; + } + watches[i].component.id = strtoul(value, NULL, 10); + if (errno) + return -errno; + break; + case WATCH_PARENT: + if (!value) { + fprintf(stderr, "Missing parent=\n"); + return -EINVAL; + } + watches[i].component.parent = strtoul(value, NULL, 10); + if (errno) + return -errno; + break; + default: + fprintf(stderr, "Unknown suboption '%s'\n", value); + return -EINVAL; + } + } + i++; + break; + } + }; + + if (debug) + print_watch(watches, nwatch); + + ret = asprintf(&device_name, "/dev/counter%d", dev_num); + if (ret < 0) + return -ENOMEM; + + if (debug) + printf("Opening %s\n", device_name); + + fd = open(device_name, O_RDWR); + if (fd == -1) { + perror("Unable to open counter device"); + return 1; + } + + for (i = 0; i < nwatch; i++) { + ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i); + if (ret == -1) { + fprintf(stderr, "Error adding watches[%d]: %s\n", i, + strerror(errno)); + return 1; + } + } + + ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL); + if (ret == -1) { + perror("Error enabling events"); + return 1; + } + + for (i = 0; loop <= 0 || i < loop; i++) { + ret = read(fd, &event_data, sizeof(event_data)); + if (ret == -1) { + perror("Failed to read event data"); + return 1; + } + + if (ret != sizeof(event_data)) { + fprintf(stderr, "Failed to read event data\n"); + return -EIO; + } + + printf("Timestamp: %llu\tData: %llu\t event: %s\tch: %d\n", + event_data.timestamp, event_data.value, + counter_event_type_name[event_data.watch.event], + event_data.watch.channel); + + if (event_data.status) { + fprintf(stderr, "Error %d: %s\n", event_data.status, + strerror(event_data.status)); + } + } + + return 0; +} From patchwork Fri Sep 22 14:39:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143761 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:910f:0:b0:403:3b70:6f57 with SMTP id r15csp17642vqg; Fri, 22 Sep 2023 18:11:32 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG9usXnlDQ26XjUJx16SEs8lWMtvB1zVmXRNDfQj62iipAR3OjDRoQK1g+/qiuz25maFqDP X-Received: by 2002:aca:121a:0:b0:3a9:e8e2:57a7 with SMTP id 26-20020aca121a000000b003a9e8e257a7mr1201404ois.53.1695431492586; Fri, 22 Sep 2023 18:11:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695431492; cv=none; d=google.com; s=arc-20160816; b=Ow/GtLCz0X7pZp3Cp8/DEipPDVsTOKUk3dKYvWvSxAi4FdYO59HkED1hYnI3UPMYeO P2IgLZWqU4iYEXZ8j5ikgErJSH7azZOtKe2da1tpC52argmQkDVCDJIdt0CQIQG/Wqcl zWTiJmFv9Q4zdU5FsOE+0lOUFgEmAf0DJCVD95ERgEyKJ6Tk3uSV/MTkjGlPnyTf3EDx FMvkjP4eA0EGENDFXPJEBSvzgQVNEZB0Lv0PhW/aLRStvuZeVDtYIockEKqN5HnY1kKQ k1wRTJtsxaivZdUF5BVQKRnp5arN7/qmKNGw9hgmTSdEaZkolAdxVlGln++ep7xPHZ/P r9EQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=d0/rsgmO/GK6El7aXTcbV+jmBIbAy5RKIXMeVlFeF38=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=hEAQtbdXyTgoVUI56xmrANzrPlu7suO4uJw0GdEJ9sqvh5DlO3h4yqj/vKD6uDAvNm 3Iy1rRBZYFi+V6PSy1xUKImQxXGRzZulxkUWEtFclBViGW3t0XQ7PRlwSapeGUIwhlW9 OkJ/f1KrawS/ic6dde7r7YP2F7qjO++YeZImkuf1Vy68mrwHU2TMBVeHeXq5wRLC9dXL arSzrQgBB283KEMusWLDn+tXgGsHqLmXScBRi+JJbAxjHoGfNZYHX0ZJlsGo6Sc1Hgfr +S8+SD4jnEk6I4BQgBZOkU5t5I7eiTwOBNLPXvLDUuWonGUHZzNaByRGz9LLeqrQk0NM FthA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=6eZsgOtI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id y5-20020a63ce05000000b00573fc71f6d9si4924343pgf.64.2023.09.22.18.11.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 18:11:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=6eZsgOtI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id AB2A2830591A; Fri, 22 Sep 2023 07:40:45 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231368AbjIVOkP (ORCPT + 29 others); Fri, 22 Sep 2023 10:40:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38114 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231128AbjIVOkK (ORCPT ); Fri, 22 Sep 2023 10:40:10 -0400 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97BFB194; Fri, 22 Sep 2023 07:40:04 -0700 (PDT) Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9gZ87014839; Fri, 22 Sep 2023 16:39:46 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=d0/rsgmO/GK6El7aXTcbV+jmBIbAy5RKIXMeVlFeF38=; b=6e ZsgOtImNHfhtur/DEj4cK8cd6y3wRZ/JshbKRclGJBWAWr/L4lpcOpUcLS3fVwcV kriaDlSsfPl3L7Eb1eLV5F8i9sJ5UXXSfOS8rrYVkTYlU57HUFJEAG9xy2kBV828 v/8ZuAkqDYWWfDwedHFx4786vV1M8GPgccseuN/efB1r9oOlwo4sDut/dqoP2WzA 6gHZCLjInZwNcWU40WQbNCs1S/jr0o/i2y6QkDZfSxBDLwUTmWz8HvC6ZR0btzBg sWtKQ/XW5JcPzNaFcmuPodc7u7tJkRFXBZ9OXewOlUnPz0A+LiWMXhFWM/g7G0EM QClgJmmZt1VAwx+1WJtw== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt03wg2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:39:46 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 8B6B3100056; Fri, 22 Sep 2023 16:39:45 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 84F0D235F24; Fri, 22 Sep 2023 16:39:45 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:39:44 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 2/6] counter: stm32-timer-cnt: rename quadrature signal Date: Fri, 22 Sep 2023 16:39:16 +0200 Message-ID: <20230922143920.3144249-3-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:40:45 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777788772597131758 X-GMAIL-MSGID: 1777788772597131758 Drop the Quadrature convention in the signal name. On stm32-timer: - Quadrature A signal corresponds to timer input ch1, hence "Channel 1" - Quadrature B signal corresponds to timer input ch2, hence "Channel 2". So name these signals after their channel. I suspect it referred to the (unique) quadrature counter support earlier, but the physical input really is CH1/CH2. This will be easier to support other counter modes. Signed-off-by: Fabrice Gasnier --- Changes in v2: - Drop the "Quadrature" convention from the signal name, as suggested by William --- drivers/counter/stm32-timer-cnt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 6206d2dc3d47..36d812ddf162 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -279,11 +279,11 @@ static const struct counter_ops stm32_timer_cnt_ops = { static struct counter_signal stm32_signals[] = { { .id = 0, - .name = "Channel 1 Quadrature A" + .name = "Channel 1" }, { .id = 1, - .name = "Channel 1 Quadrature B" + .name = "Channel 2" } }; From patchwork Fri Sep 22 14:39:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143590 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp5798196vqi; Fri, 22 Sep 2023 11:52:28 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGYGYq+VHTxdQg2qZ3HplNJmURvyvsJgRT38VDJGmESyM2UyKrf2/ccjzhDsLEbz9xQ48mn X-Received: by 2002:a17:902:d4c3:b0:1bd:da96:dc70 with SMTP id o3-20020a170902d4c300b001bdda96dc70mr290770plg.49.1695408748413; Fri, 22 Sep 2023 11:52:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695408748; cv=none; d=google.com; s=arc-20160816; b=zR8aN1O97AiYr9JeePLiEzLd37KbC+7ghPwUxQnE4t0fLNgcBXQJ9nuLbZ7gO1iKEU b7VpMe3aygIZ+iah4xQcooN+3NnEwjYpKwI788mLHjsPg5DrOAA9BvmjRLijvbMMsIre TmeerA92OwDx2lf93TVSWMPKbcnOzjc2aqkkabKP8hGZj+DUdNN9d2ijD7gvbWwBlhzC GBFYJeP7LbPrTgC/kuTHvK1CWUMAFRkn+6uMUhBr8w8c8B0zhU3CKF48Rj7O1Pxd4u9m pDkOu5e1fUHh2DfBUlv3rWGsToPa4dRoOepAHojj82dC60Tq0d+VpEJ32GK7QxD4QlF/ 5qsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=su2Pq6yXzJ+By01elmOLMUH+D+u4lMRIHEYBe4cjT9E=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=G3k9goGrXyQ8wACPgFx4gB4jWO5fjAJ8UbSm876CZaql/iikBZbYJS+ufngCm9Rok8 p7NF3U6tiv3R+pjRuqjoXjuWTstUfKxICReqrojdI5IUX2iWXBRXibaDWHst44dBg0wW QWH/IsM0WsRXkDZR4ojpdybA+Schbpm4OW1XV6Hvmp1zGF8q8eb0d430IVBPHAg2+R5p BVGzQy3aC+FZoVrGQha9LD3h4m+9Nfq7P6evCM4PEwiiIMOEKjudi4YfD/rRTbR1+Zp2 gMInxdvVzAQzhrRJRFuB2asD2eaAJ0X30K8IIxmP4yoYAthWX440qupSHbXxFsmBvs/9 ykrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=o+x9kkY4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id kz4-20020a170902f9c400b001c20db25108si4078347plb.41.2023.09.22.11.52.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 11:52:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=o+x9kkY4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id CD4BB830591E; Fri, 22 Sep 2023 07:40:17 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231193AbjIVOkM (ORCPT + 29 others); Fri, 22 Sep 2023 10:40:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38102 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230451AbjIVOkK (ORCPT ); Fri, 22 Sep 2023 10:40:10 -0400 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 528CD180; Fri, 22 Sep 2023 07:40:04 -0700 (PDT) Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9tQIl013784; Fri, 22 Sep 2023 16:39:46 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=su2Pq6yXzJ+By01elmOLMUH+D+u4lMRIHEYBe4cjT9E=; b=o+ x9kkY4xmDnZK0M+vArZ/C7/UaIDIv6hBxmfSdyH0GqKendyl1sjq3u6G8zbVIVgv BfMGmFF/mZodJ5RFcp1uez6UM8vz6K2DUPWlo9Utj/jXoTuw6ESKyHmkVbM61Roy dVB9PyM2qp7sLQnJ5mm6h6gcsQ02vNpBShHrqA8i0RSB3nQXineZws3QVrOyYMn6 Zlx6gvcGNpWZoOph8mG4Q57YZKuPndGhC89UWHHETcKjSov5DfTqv3fruKCpDPNp GecWZBrevIp6kM/fYgX67ESevH3ugvAW7lg8JVLBomnTPfJ8JeKK1nNnIFHU20c2 g5KQ6DTSJFHogzZ8n4bw== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt7kvsx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:39:45 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 79C07100051; Fri, 22 Sep 2023 16:39:45 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 7117C235F24; Fri, 22 Sep 2023 16:39:45 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:39:45 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 3/6] counter: stm32-timer-cnt: rename counter Date: Fri, 22 Sep 2023 16:39:17 +0200 Message-ID: <20230922143920.3144249-4-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:40:17 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777764923809104272 X-GMAIL-MSGID: 1777764923809104272 The STM32 timer may count on various sources or channels. The counter isn't specifically counting on channe1 1. So rename it to avoid a confusion. Signed-off-by: Fabrice Gasnier --- drivers/counter/stm32-timer-cnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 36d812ddf162..668e9d1061d3 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -302,7 +302,7 @@ static struct counter_synapse stm32_count_synapses[] = { static struct counter_count stm32_counts = { .id = 0, - .name = "Channel 1 Count", + .name = "STM32 Timer Counter", .functions_list = stm32_count_functions, .num_functions = ARRAY_SIZE(stm32_count_functions), .synapses = stm32_count_synapses, From patchwork Fri Sep 22 14:39:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143492 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp5645128vqi; Fri, 22 Sep 2023 08:02:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHbMJO7d8CVbZGkhHiX9f1II8w7ozBBKzUD5YBB2SSDcZborBcNLfylKu4gpkphpU3tiaoo X-Received: by 2002:a05:6a20:5484:b0:137:e595:830f with SMTP id i4-20020a056a20548400b00137e595830fmr10337276pzk.57.1695394934362; Fri, 22 Sep 2023 08:02:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695394934; cv=none; d=google.com; s=arc-20160816; b=VtK5y8xHOKWON5vH2TuFJREswnbpDXRBJCVl2wz1JcplbF2Z+wFZ/I8si4KxFUMtzC uqzV69fKYmGW4iyV2orQpJa7KHbLvT6pfVJv4qTCXBNqtDX2xCJIiPy3ptq4neYHJyAk eg0LpZ3aUKHqVOv6VRIv9c2uzOYHDeHy+j0MxJOsErzdbApcArQ81GBGGxK9pVEShY5/ +cERIG8Rvb6Q5QCmfzoQNO3zOykdMy6wKFLv2nLC0rkXO6AhfzpRK0qXcyYcqAuttSA5 udo/X0Pg0H3XryOBTwKuIW0CuYFe5FmQa2bDfjBHLDUgdbhymcOi3LRBQ+4xU0NidNWy 0XwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=zdlAGz2FQiBBGeAWxNhwr+O+Dy8TEyK7FmQMy9byDuA=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=BGWif3smw2emaYuqbjc9Fn1Cdhx507CamJirCZRE3CG/vkr57YOUOKnNIwT9yZNcDW Pozi+MBEF4+pejpe68NAm02DHcx2dX8q2kh9n5k8yGXFWUfRxqrRA983oY47asE3HsQG wVkxQ09/VpX8VAUFuLvk3CT0CzrDQe6LVMxmaqHdPt+ju67LaTe3qcvm5nt9tVDid25X eGtXIrRarxXV7hLAk28kC27opZzXdG0QyJv8kPsdia/kKfwhcJ2BBCddANLLAFbGZAGU QkPDB81B8hWaFN+V68f5Frl3owoABsX4aw9SkJk8stgCh2AFQEVrdoLKVvhcHv8ZPT68 N14g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=bKgj1Zah; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id b130-20020a633488000000b005775e2a7951si3830009pga.345.2023.09.22.08.02.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 08:02:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=bKgj1Zah; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 0388D8131C11; Fri, 22 Sep 2023 07:42:00 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231520AbjIVOk3 (ORCPT + 29 others); Fri, 22 Sep 2023 10:40:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231318AbjIVOkN (ORCPT ); Fri, 22 Sep 2023 10:40:13 -0400 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D558180; Fri, 22 Sep 2023 07:40:06 -0700 (PDT) Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9kSaU014836; Fri, 22 Sep 2023 16:39:47 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=zdlAGz2FQiBBGeAWxNhwr+O+Dy8TEyK7FmQMy9byDuA=; b=bK gj1Zahqf8hBJpfgVavnicKOHRaLLvhg55NvUXT7TTQJet1/seiV57yPBL7pq3SNp SwBiiO+PaOkMMy3Jhn5L8q/NT9YJELNuSZie6wRd/hqFOiRU+CekeWgUAkGvfN6P cgrZqt4LXUnrBcSPuz2Mj+lgSgwDkXgetS5yfdzmv+9KkOKKpHRfObSzPWewu6l1 b69tYBOloDOeq9KnNaNlypjtBz/Jn3njt2t3j2KZstb/mHzKAIJwjKGDGl2mSk+Q Ez6lmdr4k3v2YtrKYrYLh7U93LGYpwDkcDqFeTjyqFtsHNwwZMl1vc2xMm+WN1R2 PgcKioFQfHNWZbk9gSmw== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt03wg3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:39:47 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 0BA7410005C; Fri, 22 Sep 2023 16:39:46 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id F4222235F24; Fri, 22 Sep 2023 16:39:45 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:39:45 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 4/6] counter: stm32-timer-cnt: introduce clock signal Date: Fri, 22 Sep 2023 16:39:18 +0200 Message-ID: <20230922143920.3144249-5-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:42:00 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777750438794506726 X-GMAIL-MSGID: 1777750438794506726 Introduce the internal clock signal, used to count when in simple rising function. Define signal ids, to improve readability. Also add the "frequency" attribute for the clock signal, and "prescaler" for the counter. Whit this patch, signal action reports consistent state when "increase" function is used, and the counting frequency: $ echo increase > function $ grep -H "" signal*_action signal0_action:rising edge signal1_action:none signal2_action:none $ echo 1 > enable $ cat count 25425 $ cat count 44439 $ cat ../signal0/frequency 208877930 Signed-off-by: Fabrice Gasnier --- drivers/counter/stm32-timer-cnt.c | 84 ++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 668e9d1061d3..11c66876b213 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -21,6 +21,10 @@ #define TIM_CCER_MASK (TIM_CCER_CC1P | TIM_CCER_CC1NP | \ TIM_CCER_CC2P | TIM_CCER_CC2NP) +#define STM32_CLOCK_SIG 0 +#define STM32_CH1_SIG 1 +#define STM32_CH2_SIG 2 + struct stm32_timer_regs { u32 cr1; u32 cnt; @@ -216,11 +220,44 @@ static int stm32_count_enable_write(struct counter_device *counter, return 0; } +static int stm32_count_prescaler_read(struct counter_device *counter, + struct counter_count *count, u64 *prescaler) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + u32 psc; + + regmap_read(priv->regmap, TIM_PSC, &psc); + + *prescaler = psc + 1; + + return 0; +} + +static int stm32_count_prescaler_write(struct counter_device *counter, + struct counter_count *count, u64 prescaler) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + u32 psc; + + if (!prescaler || prescaler > MAX_TIM_PSC + 1) + return -ERANGE; + + psc = prescaler - 1; + + return regmap_write(priv->regmap, TIM_PSC, psc); +} + static struct counter_comp stm32_count_ext[] = { COUNTER_COMP_DIRECTION(stm32_count_direction_read), COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), COUNTER_COMP_CEILING(stm32_count_ceiling_read, stm32_count_ceiling_write), + COUNTER_COMP_COUNT_U64("prescaler", stm32_count_prescaler_read, + stm32_count_prescaler_write), +}; + +static const enum counter_synapse_action stm32_clock_synapse_actions[] = { + COUNTER_SYNAPSE_ACTION_RISING_EDGE, }; static const enum counter_synapse_action stm32_synapse_actions[] = { @@ -243,25 +280,31 @@ static int stm32_action_read(struct counter_device *counter, switch (function) { case COUNTER_FUNCTION_INCREASE: /* counts on internal clock when CEN=1 */ - *action = COUNTER_SYNAPSE_ACTION_NONE; + if (synapse->signal->id == STM32_CLOCK_SIG) + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + else + *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; case COUNTER_FUNCTION_QUADRATURE_X2_A: /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ - if (synapse->signal->id == count->synapses[0].signal->id) + if (synapse->signal->id == STM32_CH1_SIG) *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; else *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; case COUNTER_FUNCTION_QUADRATURE_X2_B: /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ - if (synapse->signal->id == count->synapses[1].signal->id) + if (synapse->signal->id == STM32_CH2_SIG) *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; else *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; case COUNTER_FUNCTION_QUADRATURE_X4: /* counts up/down on both TI1FP1 and TI2FP2 edges */ - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + if (synapse->signal->id == STM32_CH1_SIG || synapse->signal->id == STM32_CH2_SIG) + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + else + *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; default: return -EINVAL; @@ -276,27 +319,52 @@ static const struct counter_ops stm32_timer_cnt_ops = { .action_read = stm32_action_read, }; +static int stm32_count_clk_get_freq(struct counter_device *counter, + struct counter_signal *signal, u64 *freq) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + + *freq = clk_get_rate(priv->clk); + + return 0; +} + +static struct counter_comp stm32_count_clock_ext[] = { + COUNTER_COMP_SIGNAL_U64("frequency", stm32_count_clk_get_freq, NULL), +}; + static struct counter_signal stm32_signals[] = { { - .id = 0, + .id = STM32_CLOCK_SIG, + .name = "Clock Signal", + .ext = stm32_count_clock_ext, + .num_ext = ARRAY_SIZE(stm32_count_clock_ext), + }, + { + .id = STM32_CH1_SIG, .name = "Channel 1" }, { - .id = 1, + .id = STM32_CH2_SIG, .name = "Channel 2" } }; static struct counter_synapse stm32_count_synapses[] = { + { + .actions_list = stm32_clock_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_clock_synapse_actions), + .signal = &stm32_signals[STM32_CLOCK_SIG] + }, { .actions_list = stm32_synapse_actions, .num_actions = ARRAY_SIZE(stm32_synapse_actions), - .signal = &stm32_signals[0] + .signal = &stm32_signals[STM32_CH1_SIG] }, { .actions_list = stm32_synapse_actions, .num_actions = ARRAY_SIZE(stm32_synapse_actions), - .signal = &stm32_signals[1] + .signal = &stm32_signals[STM32_CH2_SIG] } }; From patchwork Fri Sep 22 14:39:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143540 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp5734602vqi; Fri, 22 Sep 2023 10:02:16 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGqiN9klvATgHN7pUEZbpG20FpeyNrMezPZ+T99weRJBzW95Xi9ZCYwjONJ6VwrFNt3mKwy X-Received: by 2002:a05:6a00:178c:b0:690:ca4e:662f with SMTP id s12-20020a056a00178c00b00690ca4e662fmr9412pfg.5.1695402136157; Fri, 22 Sep 2023 10:02:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695402136; cv=none; d=google.com; s=arc-20160816; b=eMtbmAeFJJEObC2QXpFna49tXn+Qaok+baPcWsqkUZJ2aN2IOKDFRXIhyjjhYujUCq BA2YnIs9QaB3trN5tAARC+7Jgup6bVxgdkrfsjlLU36K5NJMZWYpzgQb0Q+u7QDeNbxx vsWfWoigyPtMkOmMemz8M0GVKt7x/kOnUFDGlKMMvAPEZSDav5m1yFCDyLe12A8Qf1UA McI1XY71z/AQ2DWvmFDyr5jp+PrzOS8tm3c7mU0RKJdgellXS9/bBuWYOAltlwPLP5ES 4kPkvU27Y6vdGS+FqfZqTQ9gU8Ml11XnA3trYKNUDzVOgRmEMRhjlgwDhyg7q9yZtorS Eoag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=KawZuSWRVccI0W5CBQPTZeJo7z6FFdlhAulsQVOR4f8=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=fCJHQt+rqvQJ43i3H1ugPw1dqGUWJY9n23OxysqXy1QcGUDWiGHi4GCk6fccWe4ErD UXWkth8UJbuzPAk+7txUuaOAqj2EPaaVmFL2+1ZwcSPRMUKeOOA05WDLTP4bF898AzF1 fcLxKMljUH2Al/nxPdBpKKKHA+7s4jM9/DP9Ud9x5Kk9URSElQOw+QhjO8dSmN3pII0M zuCw983sXBhe/A9vvRgBcM4xfm3qIomQDBVy1VxHBaDdxalsLOBvHTlwbQtYYGhaAkeM NLl8ttQ9qkHv5f5Q4DzMgR2HTCjzxGlEU4ooI4h+qJzEm5gjMEYpDexENNaz+zbs4Dc6 fQXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=oCDZQ18a; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id h69-20020a636c48000000b00564d6ad2746si4023095pgc.452.2023.09.22.10.02.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 10:02:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=oCDZQ18a; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 578D680BD5DE; Fri, 22 Sep 2023 07:41:47 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231365AbjIVOlU (ORCPT + 29 others); Fri, 22 Sep 2023 10:41:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230386AbjIVOlS (ORCPT ); Fri, 22 Sep 2023 10:41:18 -0400 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 063C6100; Fri, 22 Sep 2023 07:41:11 -0700 (PDT) Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9nFDX017250; Fri, 22 Sep 2023 16:40:57 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=KawZuSWRVccI0W5CBQPTZeJo7z6FFdlhAulsQVOR4f8=; b=oC DZQ18aCDYcal9l5X2EKaR6ppRUrDDkKVKL74fXeABBHkn1Io2ogcAxca3srv39i/ 47SJ5hmkdD/bl0szHboglMro5D/B/RDm5U/A/5Tn65JPHFi4K8bjNo58vDt3tKtm /I8dzw0JluSror7oX3r6s5VVymxNpqc8gtBS+tcR9UD49TPk9bpcxCgUTeyh5wAa 7aQhnWP2n0Mo++D2H5uH6boQpJUrde7KUDqOSWnoSv6w3w0sJgusB4kxpjd7B13v lo2yzReRUjE38vi2qGfvuhVEOzwfH+9+iRNvMwJtx3nxjR2p+savPUYgxNxeyVxf 0geiRutQlE+ahKv/4Fog== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt5uwba-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:40:57 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 95433100051; Fri, 22 Sep 2023 16:40:56 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 8B308235F22; Fri, 22 Sep 2023 16:40:56 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:40:56 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 5/6] counter: stm32-timer-cnt: populate capture channels and check encoder Date: Fri, 22 Sep 2023 16:39:19 +0200 Message-ID: <20230922143920.3144249-6-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:41:47 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777757990636903217 X-GMAIL-MSGID: 1777757990636903217 This is a precursor patch to support capture channels on all possible channels and stm32 timer types. Original driver was intended to be used only as quadrature encoder and simple counter on internal clock. So, add ch3 and ch4 definition. Also add a check on encoder capability, so the driver may be probed for timer instances without encoder feature. This way, all timers may be used as simple counter on internal clock, starting from here. Encoder capability is retrieved by using the timer index (originally in stm32-timer-trigger driver and dt-bindings). The need to keep backward compatibility with existing device tree lead to parse aside trigger node. Add diversity as STM32 timers with capture feature may have either 4, 2, 1 or no cc (capture/compare) channels. Signed-off-by: Fabrice Gasnier --- Changes in v2: - rework to simplify since channel names has been updated. --- drivers/counter/stm32-timer-cnt.c | 204 +++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 6 deletions(-) diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 11c66876b213..acde993891f5 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,8 @@ #define STM32_CLOCK_SIG 0 #define STM32_CH1_SIG 1 #define STM32_CH2_SIG 2 +#define STM32_CH3_SIG 3 +#define STM32_CH4_SIG 4 struct stm32_timer_regs { u32 cr1; @@ -38,6 +41,9 @@ struct stm32_timer_cnt { u32 max_arr; bool enabled; struct stm32_timer_regs bak; + bool has_encoder; + u32 idx; + unsigned int nchannels; }; static const enum counter_function stm32_count_functions[] = { @@ -265,6 +271,10 @@ static const enum counter_synapse_action stm32_synapse_actions[] = { COUNTER_SYNAPSE_ACTION_BOTH_EDGES }; +static const enum counter_synapse_action stm32_synapse_ch_actions[] = { + COUNTER_SYNAPSE_ACTION_NONE, +}; + static int stm32_action_read(struct counter_device *counter, struct counter_count *count, struct counter_synapse *synapse, @@ -347,10 +357,19 @@ static struct counter_signal stm32_signals[] = { { .id = STM32_CH2_SIG, .name = "Channel 2" + }, + { + .id = STM32_CH3_SIG, + .name = "Channel 3" + }, + { + .id = STM32_CH4_SIG, + .name = "Channel 4" } }; -static struct counter_synapse stm32_count_synapses[] = { +/* STM32 Timer with 4 capture channels and quadrature encoder */ +static struct counter_synapse stm32_count_synapses_4ch_enc[] = { { .actions_list = stm32_clock_synapse_actions, .num_actions = ARRAY_SIZE(stm32_clock_synapse_actions), @@ -365,20 +384,159 @@ static struct counter_synapse stm32_count_synapses[] = { .actions_list = stm32_synapse_actions, .num_actions = ARRAY_SIZE(stm32_synapse_actions), .signal = &stm32_signals[STM32_CH2_SIG] - } + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH3_SIG] + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH4_SIG] + }, }; -static struct counter_count stm32_counts = { +static struct counter_count stm32_counts_enc_4ch = { .id = 0, .name = "STM32 Timer Counter", .functions_list = stm32_count_functions, .num_functions = ARRAY_SIZE(stm32_count_functions), + .synapses = stm32_count_synapses_4ch_enc, + .num_synapses = ARRAY_SIZE(stm32_count_synapses_4ch_enc), + .ext = stm32_count_ext, + .num_ext = ARRAY_SIZE(stm32_count_ext) +}; + +/* STM32 Timer with up to 4 capture channels */ +static struct counter_synapse stm32_count_synapses[] = { + { + .actions_list = stm32_clock_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_clock_synapse_actions), + .signal = &stm32_signals[STM32_CLOCK_SIG] + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH1_SIG] + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH2_SIG] + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH3_SIG] + }, + { + .actions_list = stm32_synapse_ch_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_ch_actions), + .signal = &stm32_signals[STM32_CH4_SIG] + }, +}; + +static struct counter_count stm32_counts_4ch = { + .id = 0, + .name = "STM32 Timer Counter", + .functions_list = stm32_count_functions, + .num_functions = 1, /* increase */ .synapses = stm32_count_synapses, .num_synapses = ARRAY_SIZE(stm32_count_synapses), .ext = stm32_count_ext, .num_ext = ARRAY_SIZE(stm32_count_ext) }; +static struct counter_count stm32_counts_2ch = { + .id = 0, + .name = "STM32 Timer Counter", + .functions_list = stm32_count_functions, + .num_functions = 1, /* increase */ + .synapses = stm32_count_synapses, + .num_synapses = 3, /* clock, ch1 and ch2 */ + .ext = stm32_count_ext, + .num_ext = ARRAY_SIZE(stm32_count_ext) +}; + +static struct counter_count stm32_counts_1ch = { + .id = 0, + .name = "STM32 Timer Counter", + .functions_list = stm32_count_functions, + .num_functions = 1, /* increase */ + .synapses = stm32_count_synapses, + .num_synapses = 2, /* clock, ch1 */ + .ext = stm32_count_ext, + .num_ext = ARRAY_SIZE(stm32_count_ext) +}; + +static struct counter_count stm32_counts = { + .id = 0, + .name = "STM32 Timer Counter", + .functions_list = stm32_count_functions, + .num_functions = 1, /* increase */ + .synapses = stm32_count_synapses, + .num_synapses = 1, /* clock only */ + .ext = stm32_count_ext, + .num_ext = ARRAY_SIZE(stm32_count_ext) +}; + +static void stm32_timer_cnt_detect_channels(struct platform_device *pdev, + struct stm32_timer_cnt *priv) +{ + u32 ccer, ccer_backup; + + regmap_read(priv->regmap, TIM_CCER, &ccer_backup); + regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_read(priv->regmap, TIM_CCER, &ccer); + regmap_write(priv->regmap, TIM_CCER, ccer_backup); + priv->nchannels = hweight32(ccer & TIM_CCER_CCXE); + + dev_dbg(&pdev->dev, "has %d cc channels\n", priv->nchannels); +} + +/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 */ +#define STM32_TIM_ENCODER_SUPPORTED (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7)) + +static const char * const stm32_timer_trigger_compat[] = { + "st,stm32-timer-trigger", + "st,stm32h7-timer-trigger", +}; + +static int stm32_timer_cnt_probe_encoder(struct platform_device *pdev, + struct stm32_timer_cnt *priv) +{ + struct device *parent = pdev->dev.parent; + struct device_node *tnode = NULL, *pnode = parent->of_node; + int i, ret; + + /* + * Need to retrieve the trigger node index from DT, to be able + * to determine if the counter supports encoder mode. It also + * enforce backward compatibility, and allow to support other + * counter modes in this driver (when the timer doesn't support + * encoder). + */ + for (i = 0; i < ARRAY_SIZE(stm32_timer_trigger_compat) && !tnode; i++) + tnode = of_get_compatible_child(pnode, stm32_timer_trigger_compat[i]); + if (!tnode) { + dev_err(&pdev->dev, "Can't find trigger node\n"); + return -ENODATA; + } + + ret = of_property_read_u32(tnode, "reg", &priv->idx); + if (ret) { + dev_err(&pdev->dev, "Can't get index (%d)\n", ret); + return ret; + } + + priv->has_encoder = !!(STM32_TIM_ENCODER_SUPPORTED & BIT(priv->idx)); + + dev_dbg(&pdev->dev, "encoder support: %s\n", priv->has_encoder ? "yes" : "no"); + + return 0; +} + static int stm32_timer_cnt_probe(struct platform_device *pdev) { struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); @@ -400,13 +558,47 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) priv->clk = ddata->clk; priv->max_arr = ddata->max_arr; + ret = stm32_timer_cnt_probe_encoder(pdev, priv); + if (ret) + return ret; + + stm32_timer_cnt_detect_channels(pdev, priv); + counter->name = dev_name(dev); counter->parent = dev; counter->ops = &stm32_timer_cnt_ops; - counter->counts = &stm32_counts; counter->num_counts = 1; - counter->signals = stm32_signals; - counter->num_signals = ARRAY_SIZE(stm32_signals); + + /* + * Handle diversity for stm32 timers features. For now encoder is found with + * advanced timers or gp timers with 4 channels. Timers with less channels + * doesn't support encoder. + */ + switch (priv->nchannels) { + case 4: + if (priv->has_encoder) + counter->counts = &stm32_counts_enc_4ch; + else + counter->counts = &stm32_counts_4ch; + counter->signals = stm32_signals; + counter->num_signals = ARRAY_SIZE(stm32_signals); + break; + case 2: + counter->counts = &stm32_counts_2ch; + counter->signals = stm32_signals; + counter->num_signals = 3; /* clock, ch1 and ch2 */ + break; + case 1: + counter->counts = &stm32_counts_1ch; + counter->signals = stm32_signals; + counter->num_signals = 2; /* clock, ch1 */ + break; + default: + counter->counts = &stm32_counts; + counter->signals = stm32_signals; + counter->num_signals = 1; /* clock */ + break; + } platform_set_drvdata(pdev, priv); From patchwork Fri Sep 22 14:39:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 143712 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp5919181vqi; Fri, 22 Sep 2023 16:11:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH4ujixz3toF3qb3mT3QK2jFYoHhLVnXZGTBOpX8rCO1ApnBql76ziB6QQFgu7CE9dJSjv4 X-Received: by 2002:a17:90a:a095:b0:268:1355:b03e with SMTP id r21-20020a17090aa09500b002681355b03emr1029385pjp.38.1695424290238; Fri, 22 Sep 2023 16:11:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695424290; cv=none; d=google.com; s=arc-20160816; b=HPAwDEDWrhCOAlgLHP01QAl8ESCY9mGrwuxXh+nSOluYG96Q17dAYI3M8wQWE8AseS qA5LV8OeX+z4RAxyyD2HHmvkC+Fx9RIPumjiX8ScRciCcU7KsWk64iK5nP2hASZaqqaY 4QloOSfqQNJVoBH4CucYj663eqVP+K/JDUoP31DPPQh4Dt6Wny3Ds05tn/SX98+6YNMl s0zJRKA/1kjDgdmUsJD6gmKIvN3fuMtfmqMiDwVN4QBHh+oTJfZfVrlTsYgi5vcSJA9J 3mYFt+BFd2UDhTskw57tp93+eDLIkNvjBixGqz3rVAXPuMpWRFv8J1hIUsP91jf3DYdB p67g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/h97/B4qukxhkFZg0Z5d4Altp8Ugvu3thWH/oppv3tk=; fh=ozwKRq0p8tj2zy4oAJzh3eawPsCHg5fP2FoTNn7f1y4=; b=z4OaG7vrV7xSaElzr55khMyZaXfZEQzV4XHTJuC4/XhVbKVRz9c5i66thVbeZpco93 iCL6loeQDVY8CUbLppGSVCnUSGFj8HbTojHGNkIRP7pH1MUyPlfKIx5aIEgoXoi0aeO2 9AbuFhAa/MKb79YpeuhJnwWnOjLqmZ0gl/r/Oi8r5hOGkvrOs+r43pC0EfKVSoBhP3A3 2/a6GaYcC4xbBiEiXIR5fC9K+HjWd4iWjczt1qrOWLW2WstgdMVQL1E5lto9cHhn+DlQ RAvR16NGgk9fvA/VG9gCMl49qzJGiaOjdfd4eumSEK6L5mMh2iSfIKJ5VOdYFLHtonSb Qi4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=rIi3IdiA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id w9-20020a17090aaf8900b00258996c09e4si6755550pjq.22.2023.09.22.16.11.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Sep 2023 16:11:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=rIi3IdiA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id DD58D8197028; Fri, 22 Sep 2023 07:41:44 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231538AbjIVOlY (ORCPT + 29 others); Fri, 22 Sep 2023 10:41:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231338AbjIVOlU (ORCPT ); Fri, 22 Sep 2023 10:41:20 -0400 Received: from mx08-00178001.pphosted.com (mx08-00178001.pphosted.com [91.207.212.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D5E1194; Fri, 22 Sep 2023 07:41:13 -0700 (PDT) Received: from pps.filterd (m0369457.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 38M9w09J012040; Fri, 22 Sep 2023 16:40:57 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=/h97/B4qukxhkFZg0Z5d4Altp8Ugvu3thWH/oppv3tk=; b=rI i3IdiASUhP9+rGiah8YJ6wNvnlne2uU/o+Teld0WdkkZO1fZVaA7Vt4TmT7DBtQX /wB7sM9p06jZAobEPDFTvJNXesN8i9fH8L4lW03ktsy40HxSF9aOF6Dnw+CosmqN BhsJKCzCyS5EXTYWJ5HePPzrrRleUC+DNW7i2BF/jvJ9K6kZGwKZb95Ujv2kZq5o Kd2M6VRJEruW7RSY3RLqH53dZdSMP1rtjPoc4tSbEqpgW6mA8X2KysdKRuG4vIV1 wsQuNF9odalTbPSsYGTMx0CI27MUNUNa0/aKVY4nsIIlYxS/3Z8kE7kv3WiJ2YFo ixKERJK/ONE9U0qgzyfA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3t8tt43x9g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 22 Sep 2023 16:40:57 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 30F30100056; Fri, 22 Sep 2023 16:40:57 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 28891235F22; Fri, 22 Sep 2023 16:40:57 +0200 (CEST) Received: from localhost (10.252.14.82) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 22 Sep 2023 16:40:56 +0200 From: Fabrice Gasnier To: CC: , , , , , , Subject: [PATCH v2 6/6] counter: stm32-timer-cnt: add support for events Date: Fri, 22 Sep 2023 16:39:20 +0200 Message-ID: <20230922143920.3144249-7-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> References: <20230922143920.3144249-1-fabrice.gasnier@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.14.82] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-22_13,2023-09-21_01,2023-05-22_02 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Fri, 22 Sep 2023 07:41:44 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777781220169957369 X-GMAIL-MSGID: 1777781220169957369 Add support for capture and overflow events. Also add the related validation and configuration. Captured counter value can be retrieved through CCRx register. Register and enable interrupts to push events. Acked-by: Lee Jones Signed-off-by: Fabrice Gasnier --- Changes in v2: - fix warnings (kernel test robot) - fix a typo - add collected ack from Lee --- drivers/counter/stm32-timer-cnt.c | 280 +++++++++++++++++++++++++++++- include/linux/mfd/stm32-timers.h | 15 ++ 2 files changed, 286 insertions(+), 9 deletions(-) diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index acde993891f5..baa6a2c0ccbf 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -8,6 +8,7 @@ * */ #include +#include #include #include #include @@ -37,6 +38,7 @@ struct stm32_timer_regs { struct stm32_timer_cnt { struct regmap *regmap; + atomic_t nb_ovf; struct clk *clk; u32 max_arr; bool enabled; @@ -44,6 +46,8 @@ struct stm32_timer_cnt { bool has_encoder; u32 idx; unsigned int nchannels; + unsigned int nr_irqs; + u32 *irq; }; static const enum counter_function stm32_count_functions[] = { @@ -253,6 +257,60 @@ static int stm32_count_prescaler_write(struct counter_device *counter, return regmap_write(priv->regmap, TIM_PSC, psc); } +static int stm32_count_cap_read(struct counter_device *counter, + struct counter_count *count, + size_t ch, u64 *cap) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + u32 ccrx; + + switch (ch) { + case 0: + regmap_read(priv->regmap, TIM_CCR1, &ccrx); + break; + case 1: + regmap_read(priv->regmap, TIM_CCR2, &ccrx); + break; + case 2: + regmap_read(priv->regmap, TIM_CCR3, &ccrx); + break; + case 3: + regmap_read(priv->regmap, TIM_CCR4, &ccrx); + break; + default: + return -EINVAL; + } + + dev_dbg(counter->parent, "CCR%zu: 0x%08x\n", ch, ccrx); + + *cap = ccrx; + + return 0; +} + +static int stm32_count_nb_ovf_read(struct counter_device *counter, + struct counter_count *count, u64 *val) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + + *val = atomic_read(&priv->nb_ovf); + + return 0; +} + +static int stm32_count_nb_ovf_write(struct counter_device *counter, + struct counter_count *count, u64 val) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + + if (val > U32_MAX) + return -ERANGE; + + atomic_set(&priv->nb_ovf, val); + + return 0; +} + static struct counter_comp stm32_count_ext[] = { COUNTER_COMP_DIRECTION(stm32_count_direction_read), COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), @@ -260,6 +318,43 @@ static struct counter_comp stm32_count_ext[] = { stm32_count_ceiling_write), COUNTER_COMP_COUNT_U64("prescaler", stm32_count_prescaler_read, stm32_count_prescaler_write), + COUNTER_COMP_COUNT_U64("num_overflows", stm32_count_nb_ovf_read, stm32_count_nb_ovf_write), +}; + +static DEFINE_COUNTER_ARRAY_CAPTURE(stm32_count_cap_array_4ch, 4); +static struct counter_comp stm32_count_4ch_ext[] = { + COUNTER_COMP_DIRECTION(stm32_count_direction_read), + COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), + COUNTER_COMP_CEILING(stm32_count_ceiling_read, + stm32_count_ceiling_write), + COUNTER_COMP_COUNT_U64("prescaler", stm32_count_prescaler_read, + stm32_count_prescaler_write), + COUNTER_COMP_ARRAY_CAPTURE(stm32_count_cap_read, NULL, stm32_count_cap_array_4ch), + COUNTER_COMP_COUNT_U64("num_overflows", stm32_count_nb_ovf_read, stm32_count_nb_ovf_write), +}; + +static DEFINE_COUNTER_ARRAY_CAPTURE(stm32_count_cap_array_2ch, 2); +static struct counter_comp stm32_count_2ch_ext[] = { + COUNTER_COMP_DIRECTION(stm32_count_direction_read), + COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), + COUNTER_COMP_CEILING(stm32_count_ceiling_read, + stm32_count_ceiling_write), + COUNTER_COMP_COUNT_U64("prescaler", stm32_count_prescaler_read, + stm32_count_prescaler_write), + COUNTER_COMP_ARRAY_CAPTURE(stm32_count_cap_read, NULL, stm32_count_cap_array_2ch), + COUNTER_COMP_COUNT_U64("num_overflows", stm32_count_nb_ovf_read, stm32_count_nb_ovf_write), +}; + +static DEFINE_COUNTER_ARRAY_CAPTURE(stm32_count_cap_array_1ch, 1); +static struct counter_comp stm32_count_1ch_ext[] = { + COUNTER_COMP_DIRECTION(stm32_count_direction_read), + COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), + COUNTER_COMP_CEILING(stm32_count_ceiling_read, + stm32_count_ceiling_write), + COUNTER_COMP_COUNT_U64("prescaler", stm32_count_prescaler_read, + stm32_count_prescaler_write), + COUNTER_COMP_ARRAY_CAPTURE(stm32_count_cap_read, NULL, stm32_count_cap_array_1ch), + COUNTER_COMP_COUNT_U64("num_overflows", stm32_count_nb_ovf_read, stm32_count_nb_ovf_write), }; static const enum counter_synapse_action stm32_clock_synapse_actions[] = { @@ -321,12 +416,131 @@ static int stm32_action_read(struct counter_device *counter, } } +struct stm32_count_cc_regs { + u32 ccmr_reg; + u32 ccmr_mask; + u32 ccmr_bits; + u32 ccer_bits; +}; + +static const struct stm32_count_cc_regs stm32_cc[] = { + { TIM_CCMR1, TIM_CCMR_CC1S, TIM_CCMR_CC1S_TI1, + TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC1NP }, + { TIM_CCMR1, TIM_CCMR_CC2S, TIM_CCMR_CC2S_TI2, + TIM_CCER_CC2E | TIM_CCER_CC2P | TIM_CCER_CC2NP }, + { TIM_CCMR2, TIM_CCMR_CC3S, TIM_CCMR_CC3S_TI3, + TIM_CCER_CC3E | TIM_CCER_CC3P | TIM_CCER_CC3NP }, + { TIM_CCMR2, TIM_CCMR_CC4S, TIM_CCMR_CC4S_TI4, + TIM_CCER_CC4E | TIM_CCER_CC4P | TIM_CCER_CC4NP }, +}; + +static int stm32_count_capture_configure(struct counter_device *counter, unsigned int ch, + bool enable) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + u32 ccmr, ccer, sr; + + if (ch >= ARRAY_SIZE(stm32_cc)) { + dev_err(counter->parent, "invalid ch: %d\n", ch); + return -EINVAL; + } + + /* + * configure channel in input capture mode, map channel 1 on TI1, channel2 on TI2... + * Select both edges / non-inverted to trigger a capture. + */ + if (enable) { + /* first clear possibly latched capture flag upon enabling */ + regmap_read(priv->regmap, TIM_CCER, &ccer); + if (!(ccer & stm32_cc[ch].ccer_bits)) { + sr = ~TIM_SR_CC_IF(ch); + regmap_write(priv->regmap, TIM_SR, sr); + } + regmap_update_bits(priv->regmap, stm32_cc[ch].ccmr_reg, stm32_cc[ch].ccmr_mask, + stm32_cc[ch].ccmr_bits); + regmap_set_bits(priv->regmap, TIM_CCER, stm32_cc[ch].ccer_bits); + } else { + regmap_clear_bits(priv->regmap, TIM_CCER, stm32_cc[ch].ccer_bits); + regmap_clear_bits(priv->regmap, stm32_cc[ch].ccmr_reg, stm32_cc[ch].ccmr_mask); + } + + regmap_read(priv->regmap, stm32_cc[ch].ccmr_reg, &ccmr); + regmap_read(priv->regmap, TIM_CCER, &ccer); + dev_dbg(counter->parent, "%s(%s) ch%d 0x%08x 0x%08x\n", __func__, enable ? "ena" : "dis", + ch, ccmr, ccer); + + return 0; +} + +static int stm32_count_events_configure(struct counter_device *counter) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + struct counter_event_node *event_node; + int i, ret; + u32 val, dier = 0; + + list_for_each_entry(event_node, &counter->events_list, l) { + switch (event_node->event) { + case COUNTER_EVENT_OVERFLOW_UNDERFLOW: + /* first clear possibly latched UIF before enabling */ + regmap_read(priv->regmap, TIM_DIER, &val); + if (!(val & TIM_DIER_UIE)) + regmap_write(priv->regmap, TIM_SR, (u32)~TIM_SR_UIF); + dier |= TIM_DIER_UIE; + break; + case COUNTER_EVENT_CAPTURE: + ret = stm32_count_capture_configure(counter, event_node->channel, true); + if (ret) + return ret; + dier |= TIM_DIER_CC_IE(event_node->channel); + break; + default: + /* should never reach this path */ + return -EINVAL; + } + } + + regmap_write(priv->regmap, TIM_DIER, dier); + + /* check for disabled capture events */ + for (i = 0 ; i < priv->nchannels; i++) { + if (!(dier & TIM_DIER_CC_IE(i))) { + ret = stm32_count_capture_configure(counter, i, false); + if (ret) + return ret; + } + } + + return 0; +} + +static int stm32_count_watch_validate(struct counter_device *counter, + const struct counter_watch *watch) +{ + struct stm32_timer_cnt *const priv = counter_priv(counter); + + switch (watch->event) { + case COUNTER_EVENT_CAPTURE: + if (watch->channel >= priv->nchannels) { + dev_err(counter->parent, "Invalid channel %d\n", watch->channel); + return -EINVAL; + } + return 0; + case COUNTER_EVENT_OVERFLOW_UNDERFLOW: + return 0; + default: + return -EINVAL; + } +} + static const struct counter_ops stm32_timer_cnt_ops = { .count_read = stm32_count_read, .count_write = stm32_count_write, .function_read = stm32_count_function_read, .function_write = stm32_count_function_write, .action_read = stm32_action_read, + .events_configure = stm32_count_events_configure, + .watch_validate = stm32_count_watch_validate, }; static int stm32_count_clk_get_freq(struct counter_device *counter, @@ -404,8 +618,8 @@ static struct counter_count stm32_counts_enc_4ch = { .num_functions = ARRAY_SIZE(stm32_count_functions), .synapses = stm32_count_synapses_4ch_enc, .num_synapses = ARRAY_SIZE(stm32_count_synapses_4ch_enc), - .ext = stm32_count_ext, - .num_ext = ARRAY_SIZE(stm32_count_ext) + .ext = stm32_count_4ch_ext, + .num_ext = ARRAY_SIZE(stm32_count_4ch_ext) }; /* STM32 Timer with up to 4 capture channels */ @@ -444,8 +658,8 @@ static struct counter_count stm32_counts_4ch = { .num_functions = 1, /* increase */ .synapses = stm32_count_synapses, .num_synapses = ARRAY_SIZE(stm32_count_synapses), - .ext = stm32_count_ext, - .num_ext = ARRAY_SIZE(stm32_count_ext) + .ext = stm32_count_4ch_ext, + .num_ext = ARRAY_SIZE(stm32_count_4ch_ext) }; static struct counter_count stm32_counts_2ch = { @@ -455,8 +669,8 @@ static struct counter_count stm32_counts_2ch = { .num_functions = 1, /* increase */ .synapses = stm32_count_synapses, .num_synapses = 3, /* clock, ch1 and ch2 */ - .ext = stm32_count_ext, - .num_ext = ARRAY_SIZE(stm32_count_ext) + .ext = stm32_count_2ch_ext, + .num_ext = ARRAY_SIZE(stm32_count_2ch_ext) }; static struct counter_count stm32_counts_1ch = { @@ -466,8 +680,8 @@ static struct counter_count stm32_counts_1ch = { .num_functions = 1, /* increase */ .synapses = stm32_count_synapses, .num_synapses = 2, /* clock, ch1 */ - .ext = stm32_count_ext, - .num_ext = ARRAY_SIZE(stm32_count_ext) + .ext = stm32_count_1ch_ext, + .num_ext = ARRAY_SIZE(stm32_count_1ch_ext) }; static struct counter_count stm32_counts = { @@ -481,6 +695,42 @@ static struct counter_count stm32_counts = { .num_ext = ARRAY_SIZE(stm32_count_ext) }; +static irqreturn_t stm32_timer_cnt_isr(int irq, void *ptr) +{ + struct counter_device *counter = ptr; + struct stm32_timer_cnt *const priv = counter_priv(counter); + u32 clr = GENMASK(31, 0); /* SR flags can be cleared by writing 0 (wr 1 has no effect) */ + u32 sr, dier; + int i; + + regmap_read(priv->regmap, TIM_SR, &sr); + regmap_read(priv->regmap, TIM_DIER, &dier); + /* Only take care of enabled IRQs */ + dier &= (TIM_DIER_UIE | TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE); + sr &= dier; + + if (sr & TIM_SR_UIF) { + atomic_inc(&priv->nb_ovf); + counter_push_event(counter, COUNTER_EVENT_OVERFLOW_UNDERFLOW, 0); + dev_dbg(counter->parent, "COUNTER_EVENT_OVERFLOW_UNDERFLOW\n"); + /* SR flags can be cleared by writing 0, only clear relevant flag */ + clr &= ~TIM_SR_UIF; + } + + /* Check capture events */ + for (i = 0 ; i < priv->nchannels; i++) { + if (sr & TIM_SR_CC_IF(i)) { + counter_push_event(counter, COUNTER_EVENT_CAPTURE, i); + clr &= ~TIM_SR_CC_IF(i); + dev_dbg(counter->parent, "COUNTER_EVENT_CAPTURE, %d\n", i); + } + } + + regmap_write(priv->regmap, TIM_SR, clr); + + return IRQ_HANDLED; +}; + static void stm32_timer_cnt_detect_channels(struct platform_device *pdev, struct stm32_timer_cnt *priv) { @@ -543,7 +793,7 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct stm32_timer_cnt *priv; struct counter_device *counter; - int ret; + int i, ret; if (IS_ERR_OR_NULL(ddata)) return -EINVAL; @@ -557,6 +807,8 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) priv->regmap = ddata->regmap; priv->clk = ddata->clk; priv->max_arr = ddata->max_arr; + priv->nr_irqs = ddata->nr_irqs; + priv->irq = ddata->irq; ret = stm32_timer_cnt_probe_encoder(pdev, priv); if (ret) @@ -602,6 +854,16 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); + for (i = 0; i < priv->nr_irqs; i++) { + ret = devm_request_irq(&pdev->dev, priv->irq[i], stm32_timer_cnt_isr, + 0, dev_name(dev), counter); + if (ret) { + dev_err(dev, "Failed to request irq %d (err %d)\n", + priv->irq[i], ret); + return ret; + } + } + /* Reset input selector to its default input */ regmap_write(priv->regmap, TIM_TISEL, 0x0); diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h index ca35af30745f..5291be74fba1 100644 --- a/include/linux/mfd/stm32-timers.h +++ b/include/linux/mfd/stm32-timers.h @@ -41,6 +41,11 @@ #define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */ #define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */ #define TIM_DIER_UIE BIT(0) /* Update interrupt */ +#define TIM_DIER_CC1IE BIT(1) /* CC1 Interrupt Enable */ +#define TIM_DIER_CC2IE BIT(2) /* CC2 Interrupt Enable */ +#define TIM_DIER_CC3IE BIT(3) /* CC3 Interrupt Enable */ +#define TIM_DIER_CC4IE BIT(4) /* CC4 Interrupt Enable */ +#define TIM_DIER_CC_IE(x) BIT((x) + 1) /* CC1, CC2, CC3, CC4 interrupt enable */ #define TIM_DIER_UDE BIT(8) /* Update DMA request Enable */ #define TIM_DIER_CC1DE BIT(9) /* CC1 DMA request Enable */ #define TIM_DIER_CC2DE BIT(10) /* CC2 DMA request Enable */ @@ -49,6 +54,7 @@ #define TIM_DIER_COMDE BIT(13) /* COM DMA request Enable */ #define TIM_DIER_TDE BIT(14) /* Trigger DMA request Enable */ #define TIM_SR_UIF BIT(0) /* Update interrupt flag */ +#define TIM_SR_CC_IF(x) BIT((x) + 1) /* CC1, CC2, CC3, CC4 interrupt flag */ #define TIM_EGR_UG BIT(0) /* Update Generation */ #define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */ #define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */ @@ -60,16 +66,23 @@ #define TIM_CCMR_CC1S_TI2 BIT(1) /* IC1/IC3 selects TI2/TI4 */ #define TIM_CCMR_CC2S_TI2 BIT(8) /* IC2/IC4 selects TI2/TI4 */ #define TIM_CCMR_CC2S_TI1 BIT(9) /* IC2/IC4 selects TI1/TI3 */ +#define TIM_CCMR_CC3S (BIT(0) | BIT(1)) /* Capture/compare 3 sel */ +#define TIM_CCMR_CC4S (BIT(8) | BIT(9)) /* Capture/compare 4 sel */ +#define TIM_CCMR_CC3S_TI3 BIT(0) /* IC3 selects TI3 */ +#define TIM_CCMR_CC4S_TI4 BIT(8) /* IC4 selects TI4 */ #define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */ #define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */ #define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */ #define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */ #define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */ #define TIM_CCER_CC2P BIT(5) /* Capt/Comp 2 Polarity */ +#define TIM_CCER_CC2NP BIT(7) /* Capt/Comp 2N Polarity */ #define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */ #define TIM_CCER_CC3P BIT(9) /* Capt/Comp 3 Polarity */ +#define TIM_CCER_CC3NP BIT(11) /* Capt/Comp 3N Polarity */ #define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */ #define TIM_CCER_CC4P BIT(13) /* Capt/Comp 4 Polarity */ +#define TIM_CCER_CC4NP BIT(15) /* Capt/Comp 4N Polarity */ #define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12)) #define TIM_BDTR_BKE(x) BIT(12 + (x) * 12) /* Break input enable */ #define TIM_BDTR_BKP(x) BIT(13 + (x) * 12) /* Break input polarity */ @@ -91,6 +104,8 @@ #define TIM_BDTR_BKF_MASK 0xF #define TIM_BDTR_BKF_SHIFT(x) (16 + (x) * 4) +#define MAX_TIM_IC_CHANNELS 4 /* Max number of input capture channels */ + enum stm32_timers_dmas { STM32_TIMERS_DMA_CH1, STM32_TIMERS_DMA_CH2,