2009-01-28 22:32:04 +03:00
/*
2010-04-23 03:26:08 +04:00
* omap iommu : omap device registration
2009-01-28 22:32:04 +03:00
*
* Copyright ( C ) 2008 - 2009 Nokia Corporation
*
* Written by Hiroshi DOYU < Hiroshi . DOYU @ nokia . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/platform_device.h>
2009-10-20 20:40:47 +04:00
# include <plat/iommu.h>
2010-04-23 03:26:09 +04:00
# include <plat/irqs.h>
2009-01-28 22:32:04 +03:00
2009-11-22 21:11:04 +03:00
struct iommu_device {
resource_size_t base ;
int irq ;
struct iommu_platform_data pdata ;
struct resource res [ 2 ] ;
2009-01-28 22:32:04 +03:00
} ;
2010-04-23 03:26:09 +04:00
static struct iommu_device * devices ;
static int num_iommu_devices ;
2009-01-28 22:32:04 +03:00
2010-04-23 03:26:08 +04:00
# ifdef CONFIG_ARCH_OMAP3
2010-04-23 03:26:09 +04:00
static struct iommu_device omap3_devices [ ] = {
2009-01-28 22:32:04 +03:00
{
2009-11-22 21:11:04 +03:00
. base = 0x480bd400 ,
. irq = 24 ,
. pdata = {
. name = " isp " ,
. nr_tlb_entries = 8 ,
. clk_name = " cam_ick " ,
} ,
2009-01-28 22:32:04 +03:00
} ,
2009-05-19 10:07:55 +04:00
# if defined(CONFIG_MPU_BRIDGE_IOMMU)
2009-01-28 22:32:04 +03:00
{
2009-11-22 21:11:04 +03:00
. base = 0x5d000000 ,
. irq = 28 ,
. pdata = {
. name = " iva2 " ,
. nr_tlb_entries = 32 ,
. clk_name = " iva2_ck " ,
} ,
2009-01-28 22:32:04 +03:00
} ,
2009-05-19 10:07:55 +04:00
# endif
2009-01-28 22:32:04 +03:00
} ;
2010-04-23 03:26:09 +04:00
# define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
static struct platform_device * omap3_iommu_pdev [ NR_OMAP3_IOMMU_DEVICES ] ;
# else
# define omap3_devices NULL
# define NR_OMAP3_IOMMU_DEVICES 0
# define omap3_iommu_pdev NULL
2010-04-23 03:26:08 +04:00
# endif
2010-04-23 03:26:09 +04:00
# ifdef CONFIG_ARCH_OMAP4
static struct iommu_device omap4_devices [ ] = {
{
. base = OMAP4_MMU1_BASE ,
. irq = INT_44XX_DUCATI_MMU_IRQ ,
. pdata = {
. name = " ducati " ,
. nr_tlb_entries = 32 ,
. clk_name = " ducati_ick " ,
} ,
} ,
# if defined(CONFIG_MPU_TESLA_IOMMU)
{
. base = OMAP4_MMU2_BASE ,
. irq = INT_44XX_DSP_MMU ,
. pdata = {
. name = " tesla " ,
. nr_tlb_entries = 32 ,
. clk_name = " tesla_ick " ,
} ,
} ,
# endif
} ;
# define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
static struct platform_device * omap4_iommu_pdev [ NR_OMAP4_IOMMU_DEVICES ] ;
# else
# define omap4_devices NULL
# define NR_OMAP4_IOMMU_DEVICES 0
# define omap4_iommu_pdev NULL
# endif
2009-01-28 22:32:04 +03:00
2010-04-23 03:26:09 +04:00
static struct platform_device * * omap_iommu_pdev ;
2009-01-28 22:32:04 +03:00
2010-04-23 03:26:08 +04:00
static int __init omap_iommu_init ( void )
2009-01-28 22:32:04 +03:00
{
int i , err ;
2009-11-22 21:11:04 +03:00
struct resource res [ ] = {
{ . flags = IORESOURCE_MEM } ,
{ . flags = IORESOURCE_IRQ } ,
} ;
2009-01-28 22:32:04 +03:00
2010-04-23 03:26:09 +04:00
if ( cpu_is_omap34xx ( ) ) {
devices = omap3_devices ;
omap_iommu_pdev = omap3_iommu_pdev ;
num_iommu_devices = NR_OMAP3_IOMMU_DEVICES ;
} else if ( cpu_is_omap44xx ( ) ) {
devices = omap4_devices ;
omap_iommu_pdev = omap4_iommu_pdev ;
num_iommu_devices = NR_OMAP4_IOMMU_DEVICES ;
} else
return - ENODEV ;
for ( i = 0 ; i < num_iommu_devices ; i + + ) {
2009-01-28 22:32:04 +03:00
struct platform_device * pdev ;
2009-11-22 21:11:04 +03:00
const struct iommu_device * d = & devices [ i ] ;
2009-01-28 22:32:04 +03:00
pdev = platform_device_alloc ( " omap-iommu " , i ) ;
if ( ! pdev ) {
err = - ENOMEM ;
goto err_out ;
}
2009-11-22 21:11:04 +03:00
res [ 0 ] . start = d - > base ;
res [ 0 ] . end = d - > base + MMU_REG_SIZE - 1 ;
res [ 1 ] . start = res [ 1 ] . end = d - > irq ;
2009-01-28 22:32:04 +03:00
err = platform_device_add_resources ( pdev , res ,
ARRAY_SIZE ( res ) ) ;
if ( err )
goto err_out ;
2009-11-22 21:11:04 +03:00
err = platform_device_add_data ( pdev , & d - > pdata ,
sizeof ( d - > pdata ) ) ;
2009-01-28 22:32:04 +03:00
if ( err )
goto err_out ;
err = platform_device_add ( pdev ) ;
if ( err )
goto err_out ;
2010-04-23 03:26:08 +04:00
omap_iommu_pdev [ i ] = pdev ;
2009-01-28 22:32:04 +03:00
}
return 0 ;
err_out :
while ( i - - )
2010-04-23 03:26:08 +04:00
platform_device_put ( omap_iommu_pdev [ i ] ) ;
2009-01-28 22:32:04 +03:00
return err ;
}
2010-04-23 03:26:08 +04:00
module_init ( omap_iommu_init ) ;
2009-01-28 22:32:04 +03:00
2010-04-23 03:26:08 +04:00
static void __exit omap_iommu_exit ( void )
2009-01-28 22:32:04 +03:00
{
int i ;
2010-04-23 03:26:09 +04:00
for ( i = 0 ; i < num_iommu_devices ; i + + )
2010-04-23 03:26:08 +04:00
platform_device_unregister ( omap_iommu_pdev [ i ] ) ;
2009-01-28 22:32:04 +03:00
}
2010-04-23 03:26:08 +04:00
module_exit ( omap_iommu_exit ) ;
2009-01-28 22:32:04 +03:00
MODULE_AUTHOR ( " Hiroshi DOYU " ) ;
2010-04-23 03:26:08 +04:00
MODULE_DESCRIPTION ( " omap iommu: omap device registration " ) ;
2009-01-28 22:32:04 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;