2010-05-03 07:39:02 +01:00
/*
* Copyright ( C ) ST - Ericsson SA 2010
*
* Author : Rabin Vincent < rabin . vincent @ stericsson . com > for ST - Ericsson
2012-02-06 11:22:24 -08:00
* Author : Lee Jones < lee . jones @ linaro . org > for ST - Ericsson
2010-05-03 07:39:02 +01:00
* License terms : GNU General Public License ( GPL ) version 2
*/
# include <linux/platform_device.h>
# include <linux/io.h>
# include <linux/clk.h>
2011-05-15 22:53:56 +02:00
# include <linux/mfd/db8500-prcmu.h>
2011-05-03 18:14:48 +02:00
# include <linux/mfd/db5500-prcmu.h>
2011-05-27 10:30:34 +02:00
# include <linux/clksrc-dbx500-prcmu.h>
2012-02-06 11:22:24 -08:00
# include <linux/sys_soc.h>
# include <linux/err.h>
# include <linux/slab.h>
# include <linux/stat.h>
2012-03-07 17:22:30 +00:00
# include <linux/of.h>
# include <linux/of_irq.h>
2010-05-03 07:39:02 +01:00
# include <asm/hardware/gic.h>
# include <asm/mach/map.h>
# include <mach/hardware.h>
# include <mach/setup.h>
2010-05-03 07:46:56 +01:00
# include <mach/devices.h>
2010-05-03 07:39:02 +01:00
# include "clock.h"
2011-03-29 16:53:29 +02:00
void __iomem * _PRCMU_BASE ;
2012-03-07 17:22:30 +00:00
static const struct of_device_id ux500_dt_irq_match [ ] = {
{ . compatible = " arm,cortex-a9-gic " , . data = gic_of_init , } ,
{ } ,
} ;
2010-05-03 07:39:02 +01:00
void __init ux500_init_irq ( void )
{
2010-12-08 11:07:57 +05:30
void __iomem * dist_base ;
void __iomem * cpu_base ;
if ( cpu_is_u5500 ( ) ) {
dist_base = __io_address ( U5500_GIC_DIST_BASE ) ;
cpu_base = __io_address ( U5500_GIC_CPU_BASE ) ;
2012-01-23 11:54:44 +01:00
} else if ( cpu_is_u8500_family ( ) ) {
2010-12-08 11:07:57 +05:30
dist_base = __io_address ( U8500_GIC_DIST_BASE ) ;
cpu_base = __io_address ( U8500_GIC_CPU_BASE ) ;
} else
ux500_unknown_soc ( ) ;
2012-03-07 17:22:30 +00:00
# ifdef CONFIG_OF
if ( of_have_populated_dt ( ) )
of_irq_init ( ux500_dt_irq_match ) ;
else
# endif
gic_init ( 0 , 29 , dist_base , cpu_base ) ;
2010-05-26 07:38:54 +01:00
/*
* Init clocks here so that they are available for system timer
* initialization .
*/
2011-05-03 18:14:48 +02:00
if ( cpu_is_u5500 ( ) )
db5500_prcmu_early_init ( ) ;
2012-01-23 11:54:44 +01:00
if ( cpu_is_u8500_family ( ) )
2011-08-12 10:28:10 +02:00
db8500_prcmu_early_init ( ) ;
2010-05-26 07:38:54 +01:00
clk_init ( ) ;
2010-05-03 07:39:02 +01:00
}
2012-02-06 11:22:24 -08:00
static const char * __init ux500_get_machine ( void )
{
return kasprintf ( GFP_KERNEL , " DB%4x " , dbx500_partnumber ( ) ) ;
}
static const char * __init ux500_get_family ( void )
{
return kasprintf ( GFP_KERNEL , " ux500 " ) ;
}
static const char * __init ux500_get_revision ( void )
{
unsigned int rev = dbx500_revision ( ) ;
if ( rev = = 0x01 )
return kasprintf ( GFP_KERNEL , " %s " , " ED " ) ;
else if ( rev > = 0xA0 )
return kasprintf ( GFP_KERNEL , " %d.%d " ,
( rev > > 4 ) - 0xA + 1 , rev & 0xf ) ;
return kasprintf ( GFP_KERNEL , " %s " , " Unknown " ) ;
}
static ssize_t ux500_get_process ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
{
if ( dbx500_id . process = = 0x00 )
return sprintf ( buf , " Standard \n " ) ;
return sprintf ( buf , " %02xnm \n " , dbx500_id . process ) ;
}
static void __init soc_info_populate ( struct soc_device_attribute * soc_dev_attr ,
const char * soc_id )
{
soc_dev_attr - > soc_id = soc_id ;
soc_dev_attr - > machine = ux500_get_machine ( ) ;
soc_dev_attr - > family = ux500_get_family ( ) ;
soc_dev_attr - > revision = ux500_get_revision ( ) ;
}
struct device_attribute ux500_soc_attr =
__ATTR ( process , S_IRUGO , ux500_get_process , NULL ) ;
struct device * __init ux500_soc_device_init ( const char * soc_id )
{
struct device * parent ;
struct soc_device * soc_dev ;
struct soc_device_attribute * soc_dev_attr ;
soc_dev_attr = kzalloc ( sizeof ( * soc_dev_attr ) , GFP_KERNEL ) ;
if ( ! soc_dev_attr )
return ERR_PTR ( - ENOMEM ) ;
soc_info_populate ( soc_dev_attr , soc_id ) ;
soc_dev = soc_device_register ( soc_dev_attr ) ;
if ( IS_ERR_OR_NULL ( soc_dev ) ) {
kfree ( soc_dev_attr ) ;
return NULL ;
}
parent = soc_device_to_device ( soc_dev ) ;
if ( ! IS_ERR_OR_NULL ( parent ) )
device_create_file ( parent , & ux500_soc_attr ) ;
return parent ;
}