timings.c (23aa3b9a6b7d5029c1f124426bc5ba4430dcc29c) | timings.c (6aed82de719b424bd5548aa4179e95f34fd779ab) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2// Copyright (C) 2016, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> | 1// SPDX-License-Identifier: GPL-2.0 2// Copyright (C) 2016, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> |
3#define pr_fmt(fmt) "irq_timings: " fmt |
|
3 4#include <linux/kernel.h> 5#include <linux/percpu.h> 6#include <linux/slab.h> 7#include <linux/static_key.h> | 4 5#include <linux/kernel.h> 6#include <linux/percpu.h> 7#include <linux/slab.h> 8#include <linux/static_key.h> |
9#include <linux/init.h> |
|
8#include <linux/interrupt.h> 9#include <linux/idr.h> 10#include <linux/irq.h> 11#include <linux/math64.h> 12#include <linux/log2.h> 13 14#include <trace/events/irq.h> 15 --- 604 unchanged lines hidden (view full) --- 620 621 if (id < 0) { 622 free_percpu(s); 623 return id; 624 } 625 626 return 0; 627} | 10#include <linux/interrupt.h> 11#include <linux/idr.h> 12#include <linux/irq.h> 13#include <linux/math64.h> 14#include <linux/log2.h> 15 16#include <trace/events/irq.h> 17 --- 604 unchanged lines hidden (view full) --- 622 623 if (id < 0) { 624 free_percpu(s); 625 return id; 626 } 627 628 return 0; 629} |
630 631#ifdef CONFIG_TEST_IRQ_TIMINGS 632static int __init irq_timings_test_irqts(struct irq_timings *irqts, 633 unsigned count) 634{ 635 int start = count >= IRQ_TIMINGS_SIZE ? count - IRQ_TIMINGS_SIZE : 0; 636 int i, irq, oirq = 0xBEEF; 637 u64 ots = 0xDEAD, ts; 638 639 /* 640 * Fill the circular buffer by using the dedicated function. 641 */ 642 for (i = 0; i < count; i++) { 643 pr_debug("%d: index=%d, ts=%llX irq=%X\n", 644 i, i & IRQ_TIMINGS_MASK, ots + i, oirq + i); 645 646 irq_timings_push(ots + i, oirq + i); 647 } 648 649 /* 650 * Compute the first elements values after the index wrapped 651 * up or not. 652 */ 653 ots += start; 654 oirq += start; 655 656 /* 657 * Test the circular buffer count is correct. 658 */ 659 pr_debug("---> Checking timings array count (%d) is right\n", count); 660 if (WARN_ON(irqts->count != count)) 661 return -EINVAL; 662 663 /* 664 * Test the macro allowing to browse all the irqts. 665 */ 666 pr_debug("---> Checking the for_each_irqts() macro\n"); 667 for_each_irqts(i, irqts) { 668 669 irq = irq_timing_decode(irqts->values[i], &ts); 670 671 pr_debug("index=%d, ts=%llX / %llX, irq=%X / %X\n", 672 i, ts, ots, irq, oirq); 673 674 if (WARN_ON(ts != ots || irq != oirq)) 675 return -EINVAL; 676 677 ots++; oirq++; 678 } 679 680 /* 681 * The circular buffer should have be flushed when browsed 682 * with for_each_irqts 683 */ 684 pr_debug("---> Checking timings array is empty after browsing it\n"); 685 if (WARN_ON(irqts->count)) 686 return -EINVAL; 687 688 return 0; 689} 690 691static int __init irq_timings_irqts_selftest(void) 692{ 693 struct irq_timings *irqts = this_cpu_ptr(&irq_timings); 694 int i, ret; 695 696 /* 697 * Test the circular buffer with different number of 698 * elements. The purpose is to test at the limits (empty, half 699 * full, full, wrapped with the cursor at the boundaries, 700 * wrapped several times, etc ... 701 */ 702 int count[] = { 0, 703 IRQ_TIMINGS_SIZE >> 1, 704 IRQ_TIMINGS_SIZE, 705 IRQ_TIMINGS_SIZE + (IRQ_TIMINGS_SIZE >> 1), 706 2 * IRQ_TIMINGS_SIZE, 707 (2 * IRQ_TIMINGS_SIZE) + 3, 708 }; 709 710 for (i = 0; i < ARRAY_SIZE(count); i++) { 711 712 pr_info("---> Checking the timings with %d/%d values\n", 713 count[i], IRQ_TIMINGS_SIZE); 714 715 ret = irq_timings_test_irqts(irqts, count[i]); 716 if (ret) 717 break; 718 } 719 720 return ret; 721} 722 723static int __init irq_timings_selftest(void) 724{ 725 int ret; 726 727 pr_info("------------------- selftest start -----------------\n"); 728 729 /* 730 * At this point, we don't except any subsystem to use the irq 731 * timings but us, so it should not be enabled. 732 */ 733 if (static_branch_unlikely(&irq_timing_enabled)) { 734 pr_warn("irq timings already initialized, skipping selftest\n"); 735 return 0; 736 } 737 738 ret = irq_timings_irqts_selftest(); 739 740 pr_info("---------- selftest end with %s -----------\n", 741 ret ? "failure" : "success"); 742 743 return ret; 744} 745early_initcall(irq_timings_selftest); 746#endif |
|