2012-09-24 03:28:29 +04:00
/*
* OMAP2 ARM Performance Monitoring Unit ( PMU ) Support
*
* Copyright ( C ) 2012 Texas Instruments , Inc .
*
* Contacts :
* Jon Hunter < jon - hunter @ ti . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
2012-10-19 23:27:34 +04:00
# include <linux/of.h>
2012-09-24 03:28:29 +04:00
# include <asm/pmu.h>
2012-10-06 00:25:59 +04:00
# include "soc.h"
2012-10-03 04:41:35 +04:00
# include "omap_hwmod.h"
2012-10-03 04:25:48 +04:00
# include "omap_device.h"
2012-09-24 03:28:29 +04:00
static char * omap2_pmu_oh_names [ ] = { " mpu " } ;
static char * omap3_pmu_oh_names [ ] = { " mpu " , " debugss " } ;
2012-09-24 03:28:29 +04:00
static char * omap4430_pmu_oh_names [ ] = { " l3_main_3 " , " l3_instr " , " debugss " } ;
2012-09-24 03:28:29 +04:00
static struct platform_device * omap_pmu_dev ;
/**
* omap2_init_pmu - creates and registers PMU platform device
* @ oh_num : Number of OMAP HWMODs required to create PMU device
* @ oh_names : Array of OMAP HWMODS names required to create PMU device
*
* Uses OMAP HWMOD framework to create and register an ARM PMU device
2012-09-24 03:28:29 +04:00
* from a list of HWMOD names passed . Currently supports OMAP2 , OMAP3
2012-09-24 03:28:30 +04:00
* and OMAP4 devices .
2012-09-24 03:28:29 +04:00
*/
static int __init omap2_init_pmu ( unsigned oh_num , char * oh_names [ ] )
{
int i ;
2012-09-24 03:28:29 +04:00
struct omap_hwmod * oh [ 3 ] ;
2012-09-24 03:28:29 +04:00
char * dev_name = " arm-pmu " ;
2012-09-24 03:28:29 +04:00
if ( ( ! oh_num ) | | ( oh_num > 3 ) )
2012-09-24 03:28:29 +04:00
return - EINVAL ;
for ( i = 0 ; i < oh_num ; i + + ) {
oh [ i ] = omap_hwmod_lookup ( oh_names [ i ] ) ;
if ( ! oh [ i ] ) {
pr_err ( " Could not look up %s hwmod \n " , oh_names [ i ] ) ;
return - ENODEV ;
}
}
2013-01-26 11:48:53 +04:00
omap_pmu_dev = omap_device_build_ss ( dev_name , - 1 , oh , oh_num , NULL , 0 ) ;
2012-09-24 03:28:29 +04:00
WARN ( IS_ERR ( omap_pmu_dev ) , " Can't build omap_device for %s. \n " ,
dev_name ) ;
2013-06-01 13:44:44 +04:00
return PTR_RET ( omap_pmu_dev ) ;
2012-09-24 03:28:29 +04:00
}
static int __init omap_init_pmu ( void )
{
unsigned oh_num ;
char * * oh_names ;
2012-10-19 23:27:34 +04:00
/* XXX Remove this check when the CTI driver is available */
if ( cpu_is_omap443x ( ) ) {
pr_info ( " ARM PMU: not yet supported on OMAP4430 due to missing CTI driver \n " ) ;
return 0 ;
}
if ( of_have_populated_dt ( ) )
return 0 ;
2012-09-24 03:28:29 +04:00
/*
* To create an ARM - PMU device the following HWMODs
* are required for the various OMAP2 + devices .
*
* OMAP24xx : mpu
* OMAP3xxx : mpu , debugss
2012-09-24 03:28:29 +04:00
* OMAP4430 : l3_main_3 , l3_instr , debugss
2012-09-24 03:28:30 +04:00
* OMAP4460 / 70 : mpu , debugss
2012-09-24 03:28:29 +04:00
*/
2012-09-24 03:28:30 +04:00
if ( cpu_is_omap443x ( ) ) {
2012-09-24 03:28:29 +04:00
oh_num = ARRAY_SIZE ( omap4430_pmu_oh_names ) ;
oh_names = omap4430_pmu_oh_names ;
2012-09-24 03:28:30 +04:00
} else if ( cpu_is_omap34xx ( ) | | cpu_is_omap44xx ( ) ) {
oh_num = ARRAY_SIZE ( omap3_pmu_oh_names ) ;
oh_names = omap3_pmu_oh_names ;
2012-09-24 03:28:29 +04:00
} else {
2012-09-24 03:28:30 +04:00
oh_num = ARRAY_SIZE ( omap2_pmu_oh_names ) ;
oh_names = omap2_pmu_oh_names ;
2012-09-24 03:28:29 +04:00
}
return omap2_init_pmu ( oh_num , oh_names ) ;
}
2013-01-11 23:24:18 +04:00
omap_subsys_initcall ( omap_init_pmu ) ;