2005-11-10 14:26:51 +00:00
/*
* linux / arch / arm / mach - omap2 / devices . c
*
* OMAP2 platform device setup / initialization
*
* 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 .
*/
2011-07-26 10:53:52 +01:00
# include <linux/gpio.h>
2005-11-10 14:26:51 +00:00
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/platform_device.h>
2008-09-06 12:10:45 +01:00
# include <linux/io.h>
2008-12-10 17:37:17 -08:00
# include <linux/clk.h>
2010-09-23 20:02:42 +05:30
# include <linux/err.h>
2011-02-02 17:52:14 +05:30
# include <linux/slab.h>
2011-08-12 13:48:47 +02:00
# include <linux/of.h>
2012-09-17 16:26:11 -07:00
# include <linux/pinctrl/machine.h>
2013-01-28 17:21:58 -06:00
# include <linux/platform_data/mailbox-omap.h>
2005-11-10 14:26:51 +00:00
# include <asm/mach-types.h>
# include <asm/mach/map.h>
2012-11-30 08:41:50 -08:00
# include <linux/omap-dma.h>
2012-10-02 17:41:35 -07:00
2012-02-24 10:34:35 -08:00
# include "iomap.h"
2012-10-02 17:41:35 -07:00
# include "omap_hwmod.h"
2012-10-02 17:25:48 -07:00
# include "omap_device.h"
2005-11-10 14:26:51 +00:00
2012-08-27 17:43:01 -07:00
# include "soc.h"
# include "common.h"
2009-12-11 16:16:32 -08:00
# include "mux.h"
2010-10-08 11:40:20 -06:00
# include "control.h"
2013-09-16 12:48:31 +05:30
# include "display.h"
2009-12-11 16:16:32 -08:00
2011-02-08 14:10:45 +05:30
# define L3_MODULES_MAX_LEN 12
2011-03-09 16:00:29 +05:30
# define L3_MODULES 3
2011-02-08 14:10:45 +05:30
static int __init omap3_l3_init ( void )
{
struct omap_hwmod * oh ;
2011-07-21 13:48:45 -07:00
struct platform_device * pdev ;
2011-02-08 14:10:45 +05:30
char oh_name [ L3_MODULES_MAX_LEN ] ;
/*
* To avoid code running on other OMAPs in
* multi - omap builds
*/
2014-11-05 09:21:23 -08:00
if ( ! ( cpu_is_omap34xx ( ) ) | | of_have_populated_dt ( ) )
2011-02-08 14:10:45 +05:30
return - ENODEV ;
2012-04-13 06:34:32 -06:00
snprintf ( oh_name , L3_MODULES_MAX_LEN , " l3_main " ) ;
2011-02-08 14:10:45 +05:30
oh = omap_hwmod_lookup ( oh_name ) ;
if ( ! oh )
pr_err ( " could not look up %s \n " , oh_name ) ;
2013-01-26 00:48:53 -07:00
pdev = omap_device_build ( " omap_l3_smx " , 0 , oh , NULL , 0 ) ;
2011-02-08 14:10:45 +05:30
2011-07-21 13:48:45 -07:00
WARN ( IS_ERR ( pdev ) , " could not build omap_device for %s \n " , oh_name ) ;
2011-02-08 14:10:45 +05:30
2015-05-20 15:32:26 -04:00
return PTR_ERR_OR_ZERO ( pdev ) ;
2011-02-08 14:10:45 +05:30
}
2013-01-11 11:24:18 -08:00
omap_postcore_initcall ( omap3_l3_init ) ;
2011-02-08 14:10:45 +05:30
2013-03-12 17:55:29 -05:00
# if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
2012-02-20 09:43:30 -08:00
static inline void __init omap_init_mbox ( void )
2006-12-07 13:58:10 -08:00
{
2011-02-24 12:51:33 -08:00
struct omap_hwmod * oh ;
2011-07-21 13:48:45 -07:00
struct platform_device * pdev ;
2013-01-28 17:21:58 -06:00
struct omap_mbox_pdata * pdata ;
2011-02-24 12:51:33 -08:00
oh = omap_hwmod_lookup ( " mailbox " ) ;
if ( ! oh ) {
pr_err ( " %s: unable to find hwmod \n " , __func__ ) ;
2009-03-23 18:07:23 -07:00
return ;
}
2013-01-28 17:21:58 -06:00
if ( ! oh - > dev_attr ) {
pr_err ( " %s: hwmod doesn't have valid attrs \n " , __func__ ) ;
return ;
}
2011-02-24 12:51:33 -08:00
2013-01-28 17:21:58 -06:00
pdata = ( struct omap_mbox_pdata * ) oh - > dev_attr ;
pdev = omap_device_build ( " omap-mailbox " , - 1 , oh , pdata , sizeof ( * pdata ) ) ;
2011-07-21 13:48:45 -07:00
WARN ( IS_ERR ( pdev ) , " %s: could not build device, err %ld \n " ,
__func__ , PTR_ERR ( pdev ) ) ;
2006-12-07 13:58:10 -08:00
}
# else
static inline void omap_init_mbox ( void ) { }
2013-03-12 17:55:29 -05:00
# endif /* CONFIG_OMAP2PLUS_MBOX */
2006-12-07 13:58:10 -08:00
2006-04-02 17:46:30 +01:00
static inline void omap_init_sti ( void ) { }
2010-03-17 20:15:21 +00:00
# if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
static struct platform_device omap_pcm = {
. name = " omap-pcm-audio " ,
. id = - 1 ,
} ;
static void omap_init_audio ( void )
{
platform_device_register ( & omap_pcm ) ;
}
# else
static inline void omap_init_audio ( void ) { }
# endif
2008-10-06 15:49:36 +03:00
# if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
2006-06-26 16:16:10 -07:00
2012-08-24 15:21:06 +02:00
# include <linux/platform_data/spi-omap2-mcspi.h>
2006-06-26 16:16:10 -07:00
2012-02-20 09:43:30 -08:00
static int __init omap_mcspi_init ( struct omap_hwmod * oh , void * unused )
2009-09-24 16:23:05 -07:00
{
2011-07-21 13:48:45 -07:00
struct platform_device * pdev ;
2011-02-02 17:52:14 +05:30
char * name = " omap2_mcspi " ;
struct omap2_mcspi_platform_config * pdata ;
static int spi_num ;
struct omap2_mcspi_dev_attr * mcspi_attrib = oh - > dev_attr ;
pdata = kzalloc ( sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata ) {
pr_err ( " Memory allocation for McSPI device failed \n " ) ;
return - ENOMEM ;
}
2009-09-24 16:23:05 -07:00
2011-02-02 17:52:14 +05:30
pdata - > num_cs = mcspi_attrib - > num_chipselect ;
switch ( oh - > class - > rev ) {
case OMAP2_MCSPI_REV :
case OMAP3_MCSPI_REV :
pdata - > regs_offset = 0 ;
break ;
case OMAP4_MCSPI_REV :
pdata - > regs_offset = OMAP4_MCSPI_REG_OFFSET ;
break ;
default :
pr_err ( " Invalid McSPI Revision value \n " ) ;
2011-12-23 18:39:31 +01:00
kfree ( pdata ) ;
2011-02-02 17:52:14 +05:30
return - EINVAL ;
}
2009-09-24 16:23:05 -07:00
2011-02-02 17:52:14 +05:30
spi_num + + ;
2013-01-26 00:48:53 -07:00
pdev = omap_device_build ( name , spi_num , oh , pdata , sizeof ( * pdata ) ) ;
2011-07-21 13:48:45 -07:00
WARN ( IS_ERR ( pdev ) , " Can't build omap_device for %s:%s \n " ,
2011-02-02 17:52:14 +05:30
name , oh - > name ) ;
kfree ( pdata ) ;
return 0 ;
2009-09-24 16:23:05 -07:00
}
static void omap_init_mcspi ( void )
{
2011-02-02 17:52:14 +05:30
omap_hwmod_for_each_by_class ( " mcspi " , omap_mcspi_init , NULL ) ;
2006-06-26 16:16:10 -07:00
}
# else
static inline void omap_init_mcspi ( void ) { }
# endif
2012-09-23 17:28:27 -06:00
/**
* omap_init_rng - bind the RNG hwmod to the RNG omap_device
*
* Bind the RNG hwmod to the RNG omap_device . No return value .
*/
static void omap_init_rng ( void )
{
struct omap_hwmod * oh ;
struct platform_device * pdev ;
oh = omap_hwmod_lookup ( " rng " ) ;
if ( ! oh )
return ;
2013-01-26 00:48:53 -07:00
pdev = omap_device_build ( " omap_rng " , - 1 , oh , NULL , 0 ) ;
2012-09-23 17:28:27 -06:00
WARN ( IS_ERR ( pdev ) , " Can't build omap_device for omap_rng \n " ) ;
}
2010-04-09 13:54:43 +01:00
2013-03-18 10:06:32 -06:00
static void __init omap_init_sham ( void )
2008-10-06 15:49:36 +03:00
{
2013-03-18 10:06:33 -06:00
struct omap_hwmod * oh ;
struct platform_device * pdev ;
oh = omap_hwmod_lookup ( " sham " ) ;
if ( ! oh )
return ;
pdev = omap_device_build ( " omap-sham " , - 1 , oh , NULL , 0 ) ;
WARN ( IS_ERR ( pdev ) , " Can't build omap_device for omap-sham \n " ) ;
2008-10-06 15:49:36 +03:00
}
2012-12-21 09:28:10 -07:00
static void __init omap_init_aes ( void )
2010-09-03 19:13:55 +08:00
{
2012-12-21 09:28:11 -07:00
struct omap_hwmod * oh ;
struct platform_device * pdev ;
oh = omap_hwmod_lookup ( " aes " ) ;
if ( ! oh )
return ;
pdev = omap_device_build ( " omap-aes " , - 1 , oh , NULL , 0 ) ;
WARN ( IS_ERR ( pdev ) , " Can't build omap_device for omap-aes \n " ) ;
2010-09-03 19:13:55 +08:00
}
2008-12-10 17:37:16 -08:00
/*-------------------------------------------------------------------------*/
2010-05-10 14:29:14 -07:00
# if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
defined ( CONFIG_VIDEO_OMAP2_VOUT_MODULE )
# if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
static struct resource omap_vout_resource [ 3 - CONFIG_FB_OMAP2_NUM_FBS ] = {
} ;
# else
static struct resource omap_vout_resource [ 2 ] = {
} ;
# endif
static struct platform_device omap_vout_device = {
. name = " omap_vout " ,
. num_resources = ARRAY_SIZE ( omap_vout_resource ) ,
. resource = & omap_vout_resource [ 0 ] ,
. id = - 1 ,
} ;
2013-09-16 12:48:31 +05:30
int __init omap_init_vout ( void )
2010-05-10 14:29:14 -07:00
{
2013-09-16 12:48:31 +05:30
return platform_device_register ( & omap_vout_device ) ;
2010-05-10 14:29:14 -07:00
}
# else
2013-09-16 12:48:31 +05:30
int __init omap_init_vout ( void ) { return 0 ; }
2010-05-10 14:29:14 -07:00
# endif
2005-11-10 14:26:51 +00:00
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices ( void )
{
2012-09-17 16:26:11 -07:00
/* Enable dummy states for those platforms without pinctrl support */
if ( ! of_have_populated_dt ( ) )
pinctrl_provide_dummies ( ) ;
2010-12-21 19:56:17 -07:00
/*
* please keep these calls , and their implementations above ,
2005-11-10 14:26:51 +00:00
* in alphabetical order so they ' re easier to sort through .
*/
2010-03-17 20:15:21 +00:00
omap_init_audio ( ) ;
2012-01-20 14:15:58 +01:00
/* If dtb is there, the devices will be created dynamically */
2012-05-02 15:23:18 +03:00
if ( ! of_have_populated_dt ( ) ) {
2014-07-11 16:44:40 -05:00
omap_init_mbox ( ) ;
2012-01-20 14:15:58 +01:00
omap_init_mcspi ( ) ;
2013-03-18 10:06:33 -06:00
omap_init_sham ( ) ;
2012-12-21 09:28:12 -07:00
omap_init_aes ( ) ;
2013-08-05 20:17:22 +05:30
omap_init_rng ( ) ;
2012-05-02 15:23:18 +03:00
}
2006-04-02 17:46:30 +01:00
omap_init_sti ( ) ;
2005-11-10 14:26:51 +00:00
return 0 ;
}
2013-01-11 11:24:18 -08:00
omap_arch_initcall ( omap2_init_devices ) ;
2014-11-20 12:45:43 -08:00
static int __init omap_gpmc_init ( void )
{
struct omap_hwmod * oh ;
struct platform_device * pdev ;
char * oh_name = " gpmc " ;
/*
* if the board boots up with a populated DT , do not
* manually add the device from this initcall
*/
if ( of_have_populated_dt ( ) )
return - ENODEV ;
oh = omap_hwmod_lookup ( oh_name ) ;
if ( ! oh ) {
pr_err ( " Could not look up %s \n " , oh_name ) ;
return - ENODEV ;
}
pdev = omap_device_build ( " omap-gpmc " , - 1 , oh , NULL , 0 ) ;
WARN ( IS_ERR ( pdev ) , " could not build omap_device for %s \n " , oh_name ) ;
2015-05-20 15:32:26 -04:00
return PTR_ERR_OR_ZERO ( pdev ) ;
2014-11-20 12:45:43 -08:00
}
omap_postcore_initcall ( omap_gpmc_init ) ;