1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
23eb8057bSDavid S. Miller /* pcr.c: Generic sparc64 performance counter infrastructure.
33eb8057bSDavid S. Miller *
43eb8057bSDavid S. Miller * Copyright (C) 2009 David S. Miller (davem@davemloft.net)
53eb8057bSDavid S. Miller */
63eb8057bSDavid S. Miller #include <linux/kernel.h>
7066bcacaSPaul Gortmaker #include <linux/export.h>
83eb8057bSDavid S. Miller #include <linux/init.h>
93eb8057bSDavid S. Miller #include <linux/irq.h>
103eb8057bSDavid S. Miller
11e360adbeSPeter Zijlstra #include <linux/irq_work.h>
129960e9e8SDavid S. Miller #include <linux/ftrace.h>
135686f9c3SDavid S. Miller
143eb8057bSDavid S. Miller #include <asm/pil.h>
153eb8057bSDavid S. Miller #include <asm/pcr.h>
16e5553a6dSDavid S. Miller #include <asm/nmi.h>
176faaeb8eSDavid S. Miller #include <asm/asi.h>
18c2068dabSPaul Gortmaker #include <asm/spitfire.h>
193eb8057bSDavid S. Miller
203eb8057bSDavid S. Miller /* This code is shared between various users of the performance
213eb8057bSDavid S. Miller * counters. Users will be oprofile, pseudo-NMI watchdog, and the
22cdd6c482SIngo Molnar * perf_event support layer.
233eb8057bSDavid S. Miller */
243eb8057bSDavid S. Miller
253eb8057bSDavid S. Miller /* Performance counter interrupts run unmasked at PIL level 15.
263eb8057bSDavid S. Miller * Therefore we can't do things like wakeups and other work
273eb8057bSDavid S. Miller * that expects IRQ disabling to be adhered to in locking etc.
283eb8057bSDavid S. Miller *
293eb8057bSDavid S. Miller * Therefore in such situations we defer the work by signalling
303eb8057bSDavid S. Miller * a lower level cpu IRQ.
313eb8057bSDavid S. Miller */
deferred_pcr_work_irq(int irq,struct pt_regs * regs)329960e9e8SDavid S. Miller void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
333eb8057bSDavid S. Miller {
345686f9c3SDavid S. Miller struct pt_regs *old_regs;
355686f9c3SDavid S. Miller
363eb8057bSDavid S. Miller clear_softint(1 << PIL_DEFERRED_PCR_WORK);
375686f9c3SDavid S. Miller
385686f9c3SDavid S. Miller old_regs = set_irq_regs(regs);
395686f9c3SDavid S. Miller irq_enter();
40e360adbeSPeter Zijlstra #ifdef CONFIG_IRQ_WORK
41e360adbeSPeter Zijlstra irq_work_run();
425686f9c3SDavid S. Miller #endif
435686f9c3SDavid S. Miller irq_exit();
445686f9c3SDavid S. Miller set_irq_regs(old_regs);
453eb8057bSDavid S. Miller }
463eb8057bSDavid S. Miller
arch_irq_work_raise(void)47e360adbeSPeter Zijlstra void arch_irq_work_raise(void)
483eb8057bSDavid S. Miller {
493eb8057bSDavid S. Miller set_softint(1 << PIL_DEFERRED_PCR_WORK);
503eb8057bSDavid S. Miller }
513eb8057bSDavid S. Miller
523eb8057bSDavid S. Miller const struct pcr_ops *pcr_ops;
533eb8057bSDavid S. Miller EXPORT_SYMBOL_GPL(pcr_ops);
543eb8057bSDavid S. Miller
direct_pcr_read(unsigned long reg_num)550bab20baSDavid S. Miller static u64 direct_pcr_read(unsigned long reg_num)
563eb8057bSDavid S. Miller {
573eb8057bSDavid S. Miller u64 val;
583eb8057bSDavid S. Miller
590bab20baSDavid S. Miller WARN_ON_ONCE(reg_num != 0);
6009d053c7SDavid S. Miller __asm__ __volatile__("rd %%pcr, %0" : "=r" (val));
613eb8057bSDavid S. Miller return val;
623eb8057bSDavid S. Miller }
633eb8057bSDavid S. Miller
direct_pcr_write(unsigned long reg_num,u64 val)640bab20baSDavid S. Miller static void direct_pcr_write(unsigned long reg_num, u64 val)
653eb8057bSDavid S. Miller {
660bab20baSDavid S. Miller WARN_ON_ONCE(reg_num != 0);
6709d053c7SDavid S. Miller __asm__ __volatile__("wr %0, 0x0, %%pcr" : : "r" (val));
6809d053c7SDavid S. Miller }
6909d053c7SDavid S. Miller
direct_pic_read(unsigned long reg_num)7009d053c7SDavid S. Miller static u64 direct_pic_read(unsigned long reg_num)
7109d053c7SDavid S. Miller {
7209d053c7SDavid S. Miller u64 val;
7309d053c7SDavid S. Miller
7409d053c7SDavid S. Miller WARN_ON_ONCE(reg_num != 0);
7509d053c7SDavid S. Miller __asm__ __volatile__("rd %%pic, %0" : "=r" (val));
7609d053c7SDavid S. Miller return val;
7709d053c7SDavid S. Miller }
7809d053c7SDavid S. Miller
direct_pic_write(unsigned long reg_num,u64 val)7909d053c7SDavid S. Miller static void direct_pic_write(unsigned long reg_num, u64 val)
8009d053c7SDavid S. Miller {
8109d053c7SDavid S. Miller WARN_ON_ONCE(reg_num != 0);
8209d053c7SDavid S. Miller
8309d053c7SDavid S. Miller /* Blackbird errata workaround. See commentary in
8409d053c7SDavid S. Miller * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt()
8509d053c7SDavid S. Miller * for more information.
8609d053c7SDavid S. Miller */
8709d053c7SDavid S. Miller __asm__ __volatile__("ba,pt %%xcc, 99f\n\t"
8809d053c7SDavid S. Miller " nop\n\t"
8909d053c7SDavid S. Miller ".align 64\n"
9009d053c7SDavid S. Miller "99:wr %0, 0x0, %%pic\n\t"
9109d053c7SDavid S. Miller "rd %%pic, %%g0" : : "r" (val));
923eb8057bSDavid S. Miller }
933eb8057bSDavid S. Miller
direct_picl_value(unsigned int nmi_hz)9473a6b053SDavid S. Miller static u64 direct_picl_value(unsigned int nmi_hz)
9573a6b053SDavid S. Miller {
9673a6b053SDavid S. Miller u32 delta = local_cpu_data().clock_tick / nmi_hz;
9773a6b053SDavid S. Miller
9873a6b053SDavid S. Miller return ((u64)((0 - delta) & 0xffffffff)) << 32;
9973a6b053SDavid S. Miller }
10073a6b053SDavid S. Miller
1013eb8057bSDavid S. Miller static const struct pcr_ops direct_pcr_ops = {
10209d053c7SDavid S. Miller .read_pcr = direct_pcr_read,
10309d053c7SDavid S. Miller .write_pcr = direct_pcr_write,
10409d053c7SDavid S. Miller .read_pic = direct_pic_read,
10509d053c7SDavid S. Miller .write_pic = direct_pic_write,
10673a6b053SDavid S. Miller .nmi_picl_value = direct_picl_value,
107ce4a925cSDavid S. Miller .pcr_nmi_enable = (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE),
108ce4a925cSDavid S. Miller .pcr_nmi_disable = PCR_PIC_PRIV,
1093eb8057bSDavid S. Miller };
1103eb8057bSDavid S. Miller
n2_pcr_write(unsigned long reg_num,u64 val)1110bab20baSDavid S. Miller static void n2_pcr_write(unsigned long reg_num, u64 val)
1123eb8057bSDavid S. Miller {
1133eb8057bSDavid S. Miller unsigned long ret;
1143eb8057bSDavid S. Miller
1150bab20baSDavid S. Miller WARN_ON_ONCE(reg_num != 0);
116314ff527SDavid S. Miller if (val & PCR_N2_HTRACE) {
1173eb8057bSDavid S. Miller ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val);
118c6fee081SDavid S. Miller if (ret != HV_EOK)
11909d053c7SDavid S. Miller direct_pcr_write(reg_num, val);
120314ff527SDavid S. Miller } else
12109d053c7SDavid S. Miller direct_pcr_write(reg_num, val);
1223eb8057bSDavid S. Miller }
1233eb8057bSDavid S. Miller
n2_picl_value(unsigned int nmi_hz)12473a6b053SDavid S. Miller static u64 n2_picl_value(unsigned int nmi_hz)
12573a6b053SDavid S. Miller {
12673a6b053SDavid S. Miller u32 delta = local_cpu_data().clock_tick / (nmi_hz << 2);
12773a6b053SDavid S. Miller
12873a6b053SDavid S. Miller return ((u64)((0 - delta) & 0xffffffff)) << 32;
12973a6b053SDavid S. Miller }
13073a6b053SDavid S. Miller
1313eb8057bSDavid S. Miller static const struct pcr_ops n2_pcr_ops = {
13209d053c7SDavid S. Miller .read_pcr = direct_pcr_read,
13309d053c7SDavid S. Miller .write_pcr = n2_pcr_write,
13409d053c7SDavid S. Miller .read_pic = direct_pic_read,
13509d053c7SDavid S. Miller .write_pic = direct_pic_write,
13673a6b053SDavid S. Miller .nmi_picl_value = n2_picl_value,
137ce4a925cSDavid S. Miller .pcr_nmi_enable = (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE |
138ce4a925cSDavid S. Miller PCR_N2_TOE_OV1 |
139ce4a925cSDavid S. Miller (2 << PCR_N2_SL1_SHIFT) |
140ce4a925cSDavid S. Miller (0xff << PCR_N2_MASK1_SHIFT)),
141ce4a925cSDavid S. Miller .pcr_nmi_disable = PCR_PIC_PRIV,
1423eb8057bSDavid S. Miller };
1433eb8057bSDavid S. Miller
n4_pcr_read(unsigned long reg_num)1446faaeb8eSDavid S. Miller static u64 n4_pcr_read(unsigned long reg_num)
1456faaeb8eSDavid S. Miller {
1466faaeb8eSDavid S. Miller unsigned long val;
1476faaeb8eSDavid S. Miller
1486faaeb8eSDavid S. Miller (void) sun4v_vt_get_perfreg(reg_num, &val);
1496faaeb8eSDavid S. Miller
1506faaeb8eSDavid S. Miller return val;
1516faaeb8eSDavid S. Miller }
1526faaeb8eSDavid S. Miller
n4_pcr_write(unsigned long reg_num,u64 val)1536faaeb8eSDavid S. Miller static void n4_pcr_write(unsigned long reg_num, u64 val)
1546faaeb8eSDavid S. Miller {
1556faaeb8eSDavid S. Miller (void) sun4v_vt_set_perfreg(reg_num, val);
1566faaeb8eSDavid S. Miller }
1576faaeb8eSDavid S. Miller
n4_pic_read(unsigned long reg_num)1586faaeb8eSDavid S. Miller static u64 n4_pic_read(unsigned long reg_num)
1596faaeb8eSDavid S. Miller {
1606faaeb8eSDavid S. Miller unsigned long val;
1616faaeb8eSDavid S. Miller
1626faaeb8eSDavid S. Miller __asm__ __volatile__("ldxa [%1] %2, %0"
1636faaeb8eSDavid S. Miller : "=r" (val)
1646faaeb8eSDavid S. Miller : "r" (reg_num * 0x8UL), "i" (ASI_PIC));
1656faaeb8eSDavid S. Miller
1666faaeb8eSDavid S. Miller return val;
1676faaeb8eSDavid S. Miller }
1686faaeb8eSDavid S. Miller
n4_pic_write(unsigned long reg_num,u64 val)1696faaeb8eSDavid S. Miller static void n4_pic_write(unsigned long reg_num, u64 val)
1706faaeb8eSDavid S. Miller {
1716faaeb8eSDavid S. Miller __asm__ __volatile__("stxa %0, [%1] %2"
1726faaeb8eSDavid S. Miller : /* no outputs */
1736faaeb8eSDavid S. Miller : "r" (val), "r" (reg_num * 0x8UL), "i" (ASI_PIC));
1746faaeb8eSDavid S. Miller }
1756faaeb8eSDavid S. Miller
n4_picl_value(unsigned int nmi_hz)1766faaeb8eSDavid S. Miller static u64 n4_picl_value(unsigned int nmi_hz)
1776faaeb8eSDavid S. Miller {
1786faaeb8eSDavid S. Miller u32 delta = local_cpu_data().clock_tick / (nmi_hz << 2);
1796faaeb8eSDavid S. Miller
1806faaeb8eSDavid S. Miller return ((u64)((0 - delta) & 0xffffffff));
1816faaeb8eSDavid S. Miller }
1826faaeb8eSDavid S. Miller
1836faaeb8eSDavid S. Miller static const struct pcr_ops n4_pcr_ops = {
1846faaeb8eSDavid S. Miller .read_pcr = n4_pcr_read,
1856faaeb8eSDavid S. Miller .write_pcr = n4_pcr_write,
1866faaeb8eSDavid S. Miller .read_pic = n4_pic_read,
1876faaeb8eSDavid S. Miller .write_pic = n4_pic_write,
1886faaeb8eSDavid S. Miller .nmi_picl_value = n4_picl_value,
1896faaeb8eSDavid S. Miller .pcr_nmi_enable = (PCR_N4_PICNPT | PCR_N4_STRACE |
1906faaeb8eSDavid S. Miller PCR_N4_UTRACE | PCR_N4_TOE |
1916faaeb8eSDavid S. Miller (26 << PCR_N4_SL_SHIFT)),
1926faaeb8eSDavid S. Miller .pcr_nmi_disable = PCR_N4_PICNPT,
1936faaeb8eSDavid S. Miller };
1946faaeb8eSDavid S. Miller
n5_pcr_read(unsigned long reg_num)19505aa1651Sbob picco static u64 n5_pcr_read(unsigned long reg_num)
19605aa1651Sbob picco {
19705aa1651Sbob picco unsigned long val;
19805aa1651Sbob picco
19905aa1651Sbob picco (void) sun4v_t5_get_perfreg(reg_num, &val);
20005aa1651Sbob picco
20105aa1651Sbob picco return val;
20205aa1651Sbob picco }
20305aa1651Sbob picco
n5_pcr_write(unsigned long reg_num,u64 val)20405aa1651Sbob picco static void n5_pcr_write(unsigned long reg_num, u64 val)
20505aa1651Sbob picco {
20605aa1651Sbob picco (void) sun4v_t5_set_perfreg(reg_num, val);
20705aa1651Sbob picco }
20805aa1651Sbob picco
20905aa1651Sbob picco static const struct pcr_ops n5_pcr_ops = {
21005aa1651Sbob picco .read_pcr = n5_pcr_read,
21105aa1651Sbob picco .write_pcr = n5_pcr_write,
21205aa1651Sbob picco .read_pic = n4_pic_read,
21305aa1651Sbob picco .write_pic = n4_pic_write,
21405aa1651Sbob picco .nmi_picl_value = n4_picl_value,
21505aa1651Sbob picco .pcr_nmi_enable = (PCR_N4_PICNPT | PCR_N4_STRACE |
21605aa1651Sbob picco PCR_N4_UTRACE | PCR_N4_TOE |
21705aa1651Sbob picco (26 << PCR_N4_SL_SHIFT)),
21805aa1651Sbob picco .pcr_nmi_disable = PCR_N4_PICNPT,
21905aa1651Sbob picco };
22005aa1651Sbob picco
m7_pcr_read(unsigned long reg_num)221b5aff55dSDavid Ahern static u64 m7_pcr_read(unsigned long reg_num)
222b5aff55dSDavid Ahern {
223b5aff55dSDavid Ahern unsigned long val;
224b5aff55dSDavid Ahern
225b5aff55dSDavid Ahern (void) sun4v_m7_get_perfreg(reg_num, &val);
226b5aff55dSDavid Ahern
227b5aff55dSDavid Ahern return val;
228b5aff55dSDavid Ahern }
229b5aff55dSDavid Ahern
m7_pcr_write(unsigned long reg_num,u64 val)230b5aff55dSDavid Ahern static void m7_pcr_write(unsigned long reg_num, u64 val)
231b5aff55dSDavid Ahern {
232b5aff55dSDavid Ahern (void) sun4v_m7_set_perfreg(reg_num, val);
233b5aff55dSDavid Ahern }
234b5aff55dSDavid Ahern
235b5aff55dSDavid Ahern static const struct pcr_ops m7_pcr_ops = {
236b5aff55dSDavid Ahern .read_pcr = m7_pcr_read,
237b5aff55dSDavid Ahern .write_pcr = m7_pcr_write,
238b5aff55dSDavid Ahern .read_pic = n4_pic_read,
239b5aff55dSDavid Ahern .write_pic = n4_pic_write,
240b5aff55dSDavid Ahern .nmi_picl_value = n4_picl_value,
241b5aff55dSDavid Ahern .pcr_nmi_enable = (PCR_N4_PICNPT | PCR_N4_STRACE |
242b5aff55dSDavid Ahern PCR_N4_UTRACE | PCR_N4_TOE |
243b5aff55dSDavid Ahern (26 << PCR_N4_SL_SHIFT)),
244b5aff55dSDavid Ahern .pcr_nmi_disable = PCR_N4_PICNPT,
245b5aff55dSDavid Ahern };
24605aa1651Sbob picco
2473eb8057bSDavid S. Miller static unsigned long perf_hsvc_group;
2483eb8057bSDavid S. Miller static unsigned long perf_hsvc_major;
2493eb8057bSDavid S. Miller static unsigned long perf_hsvc_minor;
2503eb8057bSDavid S. Miller
register_perf_hsvc(void)2513eb8057bSDavid S. Miller static int __init register_perf_hsvc(void)
2523eb8057bSDavid S. Miller {
25305aa1651Sbob picco unsigned long hverror;
25405aa1651Sbob picco
2553eb8057bSDavid S. Miller if (tlb_type == hypervisor) {
2563eb8057bSDavid S. Miller switch (sun4v_chip_type) {
2573eb8057bSDavid S. Miller case SUN4V_CHIP_NIAGARA1:
2583eb8057bSDavid S. Miller perf_hsvc_group = HV_GRP_NIAG_PERF;
2593eb8057bSDavid S. Miller break;
2603eb8057bSDavid S. Miller
2613eb8057bSDavid S. Miller case SUN4V_CHIP_NIAGARA2:
2623eb8057bSDavid S. Miller perf_hsvc_group = HV_GRP_N2_CPU;
2633eb8057bSDavid S. Miller break;
2643eb8057bSDavid S. Miller
2654ba991d3SDavid S. Miller case SUN4V_CHIP_NIAGARA3:
2664ba991d3SDavid S. Miller perf_hsvc_group = HV_GRP_KT_CPU;
2674ba991d3SDavid S. Miller break;
2684ba991d3SDavid S. Miller
2696faaeb8eSDavid S. Miller case SUN4V_CHIP_NIAGARA4:
2706faaeb8eSDavid S. Miller perf_hsvc_group = HV_GRP_VT_CPU;
2716faaeb8eSDavid S. Miller break;
2726faaeb8eSDavid S. Miller
27305aa1651Sbob picco case SUN4V_CHIP_NIAGARA5:
27405aa1651Sbob picco perf_hsvc_group = HV_GRP_T5_CPU;
27505aa1651Sbob picco break;
27605aa1651Sbob picco
277b5aff55dSDavid Ahern case SUN4V_CHIP_SPARC_M7:
278b5aff55dSDavid Ahern perf_hsvc_group = HV_GRP_M7_PERF;
279b5aff55dSDavid Ahern break;
280b5aff55dSDavid Ahern
2813eb8057bSDavid S. Miller default:
2823eb8057bSDavid S. Miller return -ENODEV;
2833eb8057bSDavid S. Miller }
2843eb8057bSDavid S. Miller
2853eb8057bSDavid S. Miller
2863eb8057bSDavid S. Miller perf_hsvc_major = 1;
2873eb8057bSDavid S. Miller perf_hsvc_minor = 0;
28805aa1651Sbob picco hverror = sun4v_hvapi_register(perf_hsvc_group,
2893eb8057bSDavid S. Miller perf_hsvc_major,
29005aa1651Sbob picco &perf_hsvc_minor);
29105aa1651Sbob picco if (hverror) {
29205aa1651Sbob picco pr_err("perfmon: Could not register hvapi(0x%lx).\n",
29305aa1651Sbob picco hverror);
2943eb8057bSDavid S. Miller return -ENODEV;
2953eb8057bSDavid S. Miller }
2963eb8057bSDavid S. Miller }
2973eb8057bSDavid S. Miller return 0;
2983eb8057bSDavid S. Miller }
2993eb8057bSDavid S. Miller
unregister_perf_hsvc(void)3003eb8057bSDavid S. Miller static void __init unregister_perf_hsvc(void)
3013eb8057bSDavid S. Miller {
3023eb8057bSDavid S. Miller if (tlb_type != hypervisor)
3033eb8057bSDavid S. Miller return;
3043eb8057bSDavid S. Miller sun4v_hvapi_unregister(perf_hsvc_group);
3053eb8057bSDavid S. Miller }
3063eb8057bSDavid S. Miller
setup_sun4v_pcr_ops(void)3076faaeb8eSDavid S. Miller static int __init setup_sun4v_pcr_ops(void)
3086faaeb8eSDavid S. Miller {
3096faaeb8eSDavid S. Miller int ret = 0;
3106faaeb8eSDavid S. Miller
3116faaeb8eSDavid S. Miller switch (sun4v_chip_type) {
3126faaeb8eSDavid S. Miller case SUN4V_CHIP_NIAGARA1:
3136faaeb8eSDavid S. Miller case SUN4V_CHIP_NIAGARA2:
3146faaeb8eSDavid S. Miller case SUN4V_CHIP_NIAGARA3:
3156faaeb8eSDavid S. Miller pcr_ops = &n2_pcr_ops;
3166faaeb8eSDavid S. Miller break;
3176faaeb8eSDavid S. Miller
3186faaeb8eSDavid S. Miller case SUN4V_CHIP_NIAGARA4:
3196faaeb8eSDavid S. Miller pcr_ops = &n4_pcr_ops;
3206faaeb8eSDavid S. Miller break;
3216faaeb8eSDavid S. Miller
32205aa1651Sbob picco case SUN4V_CHIP_NIAGARA5:
32305aa1651Sbob picco pcr_ops = &n5_pcr_ops;
32405aa1651Sbob picco break;
32505aa1651Sbob picco
326b5aff55dSDavid Ahern case SUN4V_CHIP_SPARC_M7:
327b5aff55dSDavid Ahern pcr_ops = &m7_pcr_ops;
328b5aff55dSDavid Ahern break;
329b5aff55dSDavid Ahern
3306faaeb8eSDavid S. Miller default:
3316faaeb8eSDavid S. Miller ret = -ENODEV;
3326faaeb8eSDavid S. Miller break;
3336faaeb8eSDavid S. Miller }
3346faaeb8eSDavid S. Miller
3356faaeb8eSDavid S. Miller return ret;
3366faaeb8eSDavid S. Miller }
3376faaeb8eSDavid S. Miller
pcr_arch_init(void)3383eb8057bSDavid S. Miller int __init pcr_arch_init(void)
3393eb8057bSDavid S. Miller {
3403eb8057bSDavid S. Miller int err = register_perf_hsvc();
3413eb8057bSDavid S. Miller
3423eb8057bSDavid S. Miller if (err)
3433eb8057bSDavid S. Miller return err;
3443eb8057bSDavid S. Miller
3453eb8057bSDavid S. Miller switch (tlb_type) {
3463eb8057bSDavid S. Miller case hypervisor:
3476faaeb8eSDavid S. Miller err = setup_sun4v_pcr_ops();
3486faaeb8eSDavid S. Miller if (err)
3496faaeb8eSDavid S. Miller goto out_unregister;
3503eb8057bSDavid S. Miller break;
3513eb8057bSDavid S. Miller
3523eb8057bSDavid S. Miller case cheetah:
3533eb8057bSDavid S. Miller case cheetah_plus:
3543eb8057bSDavid S. Miller pcr_ops = &direct_pcr_ops;
3553eb8057bSDavid S. Miller break;
3563eb8057bSDavid S. Miller
3571c2f61d4SDavid S. Miller case spitfire:
3581c2f61d4SDavid S. Miller /* UltraSPARC-I/II and derivatives lack a profile
3591c2f61d4SDavid S. Miller * counter overflow interrupt so we can't make use of
3601c2f61d4SDavid S. Miller * their hardware currently.
3611c2f61d4SDavid S. Miller */
362*df561f66SGustavo A. R. Silva fallthrough;
3633eb8057bSDavid S. Miller default:
3643eb8057bSDavid S. Miller err = -ENODEV;
3653eb8057bSDavid S. Miller goto out_unregister;
3663eb8057bSDavid S. Miller }
3673eb8057bSDavid S. Miller
368e5553a6dSDavid S. Miller return nmi_init();
3693eb8057bSDavid S. Miller
3703eb8057bSDavid S. Miller out_unregister:
3713eb8057bSDavid S. Miller unregister_perf_hsvc();
3723eb8057bSDavid S. Miller return err;
3733eb8057bSDavid S. Miller }
374