forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This creates an example Counter program under tools/counter/* to exemplify the Counter character device interface. Cc: Pavel Machek <[email protected]> Signed-off-by: William Breathitt Gray <[email protected]> Link: https://lore.kernel.org/r/7c0f975ba098952122302d258ec9ffdef04befaf.1632884256.git.vilhelm.gray@gmail.com Signed-off-by: Jonathan Cameron <[email protected]>
- Loading branch information
1 parent
a8a2873
commit 0860998
Showing
5 changed files
with
154 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4805,6 +4805,7 @@ F: Documentation/driver-api/generic-counter.rst | |
F: drivers/counter/ | ||
F: include/linux/counter.h | ||
F: include/uapi/linux/counter.h | ||
F: tools/counter/ | ||
|
||
CP2615 I2C DRIVER | ||
M: Bence Csókás <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
counter_example-y += counter_example.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
include ../scripts/Makefile.include | ||
|
||
bindir ?= /usr/bin | ||
|
||
ifeq ($(srctree),) | ||
srctree := $(patsubst %/,%,$(dir $(CURDIR))) | ||
srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
endif | ||
|
||
# Do not use make's built-in rules | ||
# (this improves performance and avoids hard-to-debug behaviour); | ||
MAKEFLAGS += -r | ||
|
||
override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | ||
|
||
ALL_TARGETS := counter_example | ||
ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) | ||
|
||
all: $(ALL_PROGRAMS) | ||
|
||
export srctree OUTPUT CC LD CFLAGS | ||
include $(srctree)/tools/build/Makefile.include | ||
|
||
# | ||
# We need the following to be outside of kernel tree | ||
# | ||
$(OUTPUT)include/linux/counter.h: ../../include/uapi/linux/counter.h | ||
mkdir -p $(OUTPUT)include/linux 2>&1 || true | ||
ln -sf $(CURDIR)/../../include/uapi/linux/counter.h $@ | ||
|
||
prepare: $(OUTPUT)include/linux/counter.h | ||
|
||
COUNTER_EXAMPLE := $(OUTPUT)counter_example.o | ||
$(COUNTER_EXAMPLE): prepare FORCE | ||
$(Q)$(MAKE) $(build)=counter_example | ||
$(OUTPUT)counter_example: $(COUNTER_EXAMPLE) | ||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ | ||
|
||
clean: | ||
rm -f $(ALL_PROGRAMS) | ||
rm -rf $(OUTPUT)include/linux/counter.h | ||
find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete | ||
|
||
install: $(ALL_PROGRAMS) | ||
install -d -m 755 $(DESTDIR)$(bindir); \ | ||
for program in $(ALL_PROGRAMS); do \ | ||
install $$program $(DESTDIR)$(bindir); \ | ||
done | ||
|
||
FORCE: | ||
|
||
.PHONY: all install clean FORCE prepare |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Counter - example userspace application | ||
* | ||
* The userspace application opens /dev/counter0, configures the | ||
* COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count | ||
* 1 count, and prints out the data as it becomes available on the | ||
* character device node. | ||
* | ||
* Copyright (C) 2021 William Breathitt Gray | ||
*/ | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <linux/counter.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <sys/ioctl.h> | ||
#include <unistd.h> | ||
|
||
static struct counter_watch watches[2] = { | ||
{ | ||
/* Component data: Count 0 count */ | ||
.component.type = COUNTER_COMPONENT_COUNT, | ||
.component.scope = COUNTER_SCOPE_COUNT, | ||
.component.parent = 0, | ||
/* Event type: Index */ | ||
.event = COUNTER_EVENT_INDEX, | ||
/* Device event channel 0 */ | ||
.channel = 0, | ||
}, | ||
{ | ||
/* Component data: Count 1 count */ | ||
.component.type = COUNTER_COMPONENT_COUNT, | ||
.component.scope = COUNTER_SCOPE_COUNT, | ||
.component.parent = 1, | ||
/* Event type: Index */ | ||
.event = COUNTER_EVENT_INDEX, | ||
/* Device event channel 0 */ | ||
.channel = 0, | ||
}, | ||
}; | ||
|
||
int main(void) | ||
{ | ||
int fd; | ||
int ret; | ||
int i; | ||
struct counter_event event_data[2]; | ||
|
||
fd = open("/dev/counter0", O_RDWR); | ||
if (fd == -1) { | ||
perror("Unable to open /dev/counter0"); | ||
return 1; | ||
} | ||
|
||
for (i = 0; i < 2; 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 (;;) { | ||
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 0: %llu\tCount 0: %llu\n" | ||
"Error Message 0: %s\n" | ||
"Timestamp 1: %llu\tCount 1: %llu\n" | ||
"Error Message 1: %s\n", | ||
event_data[0].timestamp, event_data[0].value, | ||
strerror(event_data[0].status), | ||
event_data[1].timestamp, event_data[1].value, | ||
strerror(event_data[1].status)); | ||
} | ||
|
||
return 0; | ||
} |