1313#include <linux/perf_event.h>
1414#include <linux/platform_device.h>
1515#include <linux/slab.h>
16+ #include <linux/debugfs.h>
1617
1718/* Common registers */
1819#define NI_NODE_TYPE 0x000
@@ -110,6 +111,7 @@ struct arm_ni_cd {
110111 struct arm_ni_unit * units ;
111112 struct perf_event * evcnt [NI_NUM_COUNTERS ];
112113 struct perf_event * ccnt ;
114+ struct dentry * debug ;
113115};
114116
115117struct arm_ni {
@@ -476,6 +478,59 @@ static irqreturn_t arm_ni_handle_irq(int irq, void *dev_id)
476478 }
477479}
478480
481+ static struct dentry * arm_ni_cd_debugfs ;
482+
483+ #ifdef CONFIG_DEBUG_FS
484+ static const char * arm_ni_node_type (enum ni_node_type type )
485+ {
486+ switch (type ) {
487+ case NI_ASNI :
488+ return "| ASNI " ;
489+ case NI_AMNI :
490+ return "| AMNI " ;
491+ case NI_PMU :
492+ return "| PMU " ;
493+ case NI_HSNI :
494+ return "| HSNI " ;
495+ case NI_HMNI :
496+ return "| HMNI " ;
497+ case NI_PMNI :
498+ return "| PMNI " ;
499+ default :
500+ return "| ???? " ;
501+ }
502+ }
503+
504+ static int arm_ni_cd_map_show (struct seq_file * s , void * data )
505+ {
506+ struct arm_ni_cd * cd = s -> private ;
507+
508+ cd_for_each_unit (cd , unit ) {
509+ seq_printf (s , "%s#%-2d |" , arm_ni_node_type (unit -> type ), unit -> id );
510+ }
511+ seq_puts (s , "\n" );
512+
513+ return 0 ;
514+ }
515+
516+ DEFINE_SHOW_ATTRIBUTE (arm_ni_cd_map );
517+
518+ static void arm_ni_cd_debugfs_init (struct arm_ni_cd * cd , u64 res_start )
519+ {
520+ const char * name = "map" ;
521+
522+ if (res_start > 0 )
523+ name = devm_kasprintf (cd_to_ni (cd )-> dev , GFP_KERNEL , "map_%llx" ,
524+ res_start >> NI_PMU_PA_SHIFT );
525+ if (!name )
526+ return ;
527+
528+ cd -> debug = debugfs_create_file (name , 0444 , arm_ni_cd_debugfs , cd , & arm_ni_cd_map_fops );
529+ }
530+ #else
531+ static void arm_ni_cd_debugfs_init (struct arm_ni_cd * cd , u64 res_start ) {}
532+ #endif
533+
479534static int arm_ni_init_cd (struct arm_ni * ni , struct arm_ni_node * node , u64 res_start )
480535{
481536 struct arm_ni_cd * cd = ni -> cds + node -> id ;
@@ -563,6 +618,7 @@ static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_s
563618 name = devm_kasprintf (ni -> dev , GFP_KERNEL , "arm_ni_%llx" , res_start >> NI_PMU_PA_SHIFT );
564619 if (!name )
565620 return - ENOMEM ;
621+ arm_ni_cd_debugfs_init (cd , res_start );
566622
567623 return perf_pmu_register (& cd -> pmu , name , -1 );
568624}
@@ -575,6 +631,7 @@ static void arm_ni_remove(struct platform_device *pdev)
575631 writel_relaxed (0 , cd -> pmu_base + NI_PMCR );
576632 writel_relaxed (U32_MAX , cd -> pmu_base + NI_PMINTENCLR );
577633 perf_pmu_unregister (& cd -> pmu );
634+ debugfs_remove (cd -> debug );
578635 }
579636 cpuhp_state_remove_instance_nocalls (arm_ni_hp_state , & ni -> cpuhp_node );
580637}
@@ -787,16 +844,20 @@ static int __init arm_ni_init(void)
787844
788845 arm_ni_hp_state = ret ;
789846
847+ arm_ni_cd_debugfs = debugfs_create_dir ("arm-ni" , NULL );
790848 ret = platform_driver_register (& arm_ni_driver );
791- if (ret )
849+ if (ret ) {
792850 cpuhp_remove_multi_state (arm_ni_hp_state );
851+ debugfs_remove (arm_ni_cd_debugfs );
852+ }
793853 return ret ;
794854}
795855
796856static void __exit arm_ni_exit (void )
797857{
798858 platform_driver_unregister (& arm_ni_driver );
799859 cpuhp_remove_multi_state (arm_ni_hp_state );
860+ debugfs_remove (arm_ni_cd_debugfs );
800861}
801862
802863module_init (arm_ni_init );
0 commit comments