Linux教程

linux kernel setup arm machine

本文主要是介绍linux kernel setup arm machine,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

linux kernel setup arm machine

Linux version 3.4.39-s5p6818 NanoPi3

/* arch/arm/mach-s5p6818/cpu.c */
#include <mach/iomap.h>
extern struct sys_timer nxp_cpu_sys_timer;

#if defined(CFG_SYS_MACH_NAME)
#define NXP_MACH_NAME	CFG_SYS_MACH_NAME
#else
#define NXP_MACH_NAME	CFG_SYS_CPU_NAME
#endif

MACHINE_START(S5P6818, NXP_MACH_NAME)
	.atag_offset	=  0x00000100,
	.fixup			=  cpu_fixup,
	.map_io			=  cpu_map_io,
	.init_irq		=  nxp_cpu_irq_init,
	.handle_irq 	=  gic_handle_irq,
	.timer			= &nxp_cpu_sys_timer,
	.init_machine	=  cpu_init_machine,
#if defined CONFIG_CMA && defined CONFIG_ION
	.reserve		=  cpu_mem_reserve,
#endif
MACHINE_END

/* arch/arm/plat-s5p6818/nanopi3/include/cfg_main.h */
/*------------------------------------------------------------------------------
 * 	System Name
 */
#define CFG_SYS_CPU_NAME						"s5p6818"
#define CFG_SYS_MACH_NAME						"NANOPI3"
#define CFG_SYS_BOARD_NAME						"s5p6818-NanoPi3"

->
static const struct machine_desc __mach_desc_S5P6818 {
	.nr = MACH_TYPE_S5P6818,
	.name = "NANOPI3"

	.atag_offset	=  0x00000100,
	.fixup			=  cpu_fixup,
	.map_io			=  cpu_map_io,
	.init_irq		=  nxp_cpu_irq_init,
	.handle_irq 	=  gic_handle_irq,
	.timer			= &nxp_cpu_sys_timer,
	.init_machine	=  cpu_init_machine,
#if defined CONFIG_CMA && defined CONFIG_ION
	.reserve		=  cpu_mem_reserve,
#endif 

};
/* arch/arm/include/asm/mach/arch.h */
/**/
/*
 *  arch/arm/include/asm/mach/arch.h
 *
 *  Copyright (C) 2000 Russell King
 *
 * 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.
 */

#ifndef __ASSEMBLY__

struct tag;
struct meminfo;
struct sys_timer;
struct pt_regs;

struct machine_desc {
	unsigned int		nr;		/* architecture number	*/
	const char		*name;		/* architecture name	*/
	unsigned long		atag_offset;	/* tagged list (relative) */
	const char *const 	*dt_compat;	/* array of device tree
						 * 'compatible' strings	*/

	unsigned int		nr_irqs;	/* number of IRQs */

#ifdef CONFIG_ZONE_DMA
	unsigned long		dma_zone_size;	/* size of DMA-able area */
#endif

	unsigned int		video_start;	/* start of video RAM	*/
	unsigned int		video_end;	/* end of video RAM	*/

	unsigned char		reserve_lp0 :1;	/* never has lp0	*/
	unsigned char		reserve_lp1 :1;	/* never has lp1	*/
	unsigned char		reserve_lp2 :1;	/* never has lp2	*/
	char			restart_mode;	/* default restart mode	*/
	void			(*fixup)(struct tag *, char **,
					 struct meminfo *);
	void			(*reserve)(void);/* reserve mem blocks	*/
	void			(*map_io)(void);/* IO mapping function	*/
	void			(*init_early)(void);
	void			(*init_irq)(void);
	struct sys_timer	*timer;		/* system tick timer	*/
	void			(*init_machine)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
	void			(*handle_irq)(struct pt_regs *);
#endif
	void			(*restart)(char, const char *);
};

/*
 * Current machine - only accessible during boot.
 */
extern struct machine_desc *machine_desc;

/*
 * Machine type table - also only accessible during boot
 */
extern struct machine_desc __arch_info_begin[], __arch_info_end[];
#define for_each_machine_desc(p)			\
	for (p = __arch_info_begin; p < __arch_info_end; p++)

/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

#define DT_MACHINE_START(_name, _namestr)		\
static const struct machine_desc __mach_desc_##_name	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= ~0,				\
	.name		= _namestr,

#endif
void __init start_kernel(void)
    |
    /* arch/arm/kernel/setup.c */
    void __init setup_arch(char **cmdline_p)
        |
        setup_processor();
        mdesc = setup_machine_fdt(__atags_pointer);
	    if (!mdesc)
		    mdesc = setup_machine_tags(machine_arch_type);
	    machine_desc = mdesc;
	    machine_name = mdesc->name;

            static struct machine_desc * __init setup_machine_tags(unsigned int nr)
                |
                /*
	            * locate machine in the list of supported machines.
	            */
	            for_each_machine_desc(p)
		        if (nr == p->nr) {
			        printk("Machine: %s\n", p->name);
			        mdesc = p;
			        break;
		        }

                /* match machine_arch_type, Machine: NANOPI3 */

                ...
                if (mdesc->fixup)
		            mdesc->fixup(tags, &from, &meminfo); 
                    /* set memory size 
                        struct meminfo {
                	        int nr_banks;
	                     struct membank bank[NR_BANKS];
                        };
                    */
                ...

    setup_arch()
        |
        #ifdef CONFIG_ZONE_DMA
	    if (mdesc->dma_zone_size) {
		    extern unsigned long arm_dma_zone_size;
		    arm_dma_zone_size = mdesc->dma_zone_size;
	    }
        #endif
	    if (mdesc->restart_mode)
		    reboot_setup(&mdesc->restart_mode);

	    init_mm.start_code = (unsigned long) _text;
	    init_mm.end_code   = (unsigned long) _etext;
	    init_mm.end_data   = (unsigned long) _edata;
	    init_mm.brk	   = (unsigned long) _end;

	    /* populate cmd_line too for later use, preserving boot_command_line */
	    strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
	    *cmdline_p = cmd_line;

	    parse_early_param();

        sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
	    sanity_check_meminfo();
	    arm_memblock_init(&meminfo, mdesc); 
        /* add memory to memblok, memory management, 还有保留一些内区域
        内核启动前期的内存管理memblok mm/memblock.c,memblock替代旧的bootmem */
            |
            /* reserve any platform specific memblock areas */
	        if (mdesc->reserve)
		        mdesc->reserve();

	    paging_init(mdesc);
            |
            /*
            * paging_init() sets up the page tables, initialises the zone memory
            * maps, and sets up the zero page, bad page and bad page tables.
            */
            void __init paging_init(struct machine_desc *mdesc)
            {
	            void *zero_page;

	            memblock_set_current_limit(lowmem_limit);

	            build_mem_type_table();
	            prepare_page_table();
	            map_lowmem();
	            devicemaps_init(mdesc);
                    |
                    ...
                    create_mapping(&map);
                    ...
                    /*
	                 * Ask the machine support to map in the statically mapped devices.
	                */
	                if (mdesc->map_io)
		                mdesc->map_io();
                    ...
	            kmap_init();

	            top_pmd = pmd_off_k(0xffff0000);

	            /* allocate the zero page. */
	            zero_page = early_alloc(PAGE_SIZE);

	            bootmem_init();

	            empty_zero_page = virt_to_page(zero_page);
	            __flush_dcache_page(NULL, empty_zero_page);
            }

	    request_standard_resources(mdesc);

	    if (mdesc->restart)
		    arm_pm_restart = mdesc->restart;

	    unflatten_device_tree();

        #ifdef CONFIG_SMP
	        if (is_smp())
		        smp_init_cpus();
         #endif
	    reserve_crashkernel();

	    tcm_init();

        #ifdef CONFIG_MULTI_IRQ_HANDLER
	        handle_arch_irq = mdesc->handle_irq;
        #endif

        #ifdef CONFIG_VT
        #if defined(CONFIG_VGA_CONSOLE)
	        conswitchp = &vga_con;
        #elif defined(CONFIG_DUMMY_CONSOLE)
	        conswitchp = &dummy_con;
        #endif
        #endif

	    if (mdesc->init_early)
		    mdesc->init_early();
    /* end setup_arch() */
    
start_kernel()
    ...
    |
    early_irq_init();
        |
        /* kernel/irq/irqdesc.c*/
        int __init early_irq_init(void)
            |
            struct irq_desc desc,initialize
    init_IRQ();
        |
        /* arch/arm/kernel/irq.c*/
        void __init init_IRQ(void)
        {
        	printk("~~~ %s() call machine_desc->init_irq()\n", \
        		__func__);
        	machine_desc->init_irq();
                |
                void __init nxp_cpu_irq_init(void)
                    |
                    __gic_init(GIC_DIST_BASE, (void __iomem *)GIC_CPUI_BASE);
    	            gpio_init(GPIO_INT_BASE , IRQ_GPIO_START, GPIO_INT_MASK, 0);	/* 64 ~ 223 (A,B,C,D,E) */
                    etc.
        }
    ...
    time_init();
        |
        /* arch/arm/kernel/time.c */
        void __init time_init(void)
        {
	        system_timer = machine_desc->timer;
	        system_timer->init();
	        sched_clock_postinit();
	        printk("~~~ %s() done\n", __func__);
        }
    ...
    /* Do the rest non-__init'ed, we're now alive */
	rest_init();
/* end start_kernel() */
/* arch/arm/kernel/setup.c */
static int __init customize_machine(void)
{
	/* customizes platform devices, or adds new ones */
	if (machine_desc->init_machine)
		machine_desc->init_machine();
	return 0;
}
arch_initcall(customize_machine);
/* arch/arm/mach-s5p6818/cpu.c */

/*
 * (C) Copyright 2009
 * jung hyun kim, Nexell Co, <jhkim@nexell.co.kr>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/pgtable.h>
#include <asm/system_misc.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>

/* nexell soc headers */
#include <mach/platform.h>
#include <mach/devices.h>
#include <mach/map_desc.h>

#if (0)
#define DBGOUT(msg...)		do { printk("s5p6818: " msg); } while (0)
#else
#define DBGOUT(msg...)		do {} while (0)
#endif

#if (1)
#define _IOMAP()		{							\
	int i = 0;										\
	for (; i<ARRAY_SIZE(cpu_iomap_desc); i++) 		\
			printk(KERN_INFO "CPU : iomap[%2d]: p 0x%08x -> v 0x%08x len=0x%x\n", i,	\
			(u_int)(cpu_iomap_desc[i].pfn<<12),		\
			(u_int)(cpu_iomap_desc[i].virtual),		\
			(u_int)(cpu_iomap_desc[i].length));		\
	}
#else
#define _IOMAP()
#endif

#if defined(CFG_MEM_PHY_DMAZONE_SIZE)
extern void __init init_consistent_dma_size(unsigned long size);
#endif

/*------------------------------------------------------------------------------
 * 	cpu initialize and io/memory map.
 * 	procedure: fixup -> map_io -> init_irq -> timer init -> init_machine
 */
static void __init cpu_fixup(struct tag *tag, char **cmdline, struct meminfo *mi)
{
	DBGOUT("%s\n", __func__);

#if defined(CONFIG_PLAT_S5P6818_NANOPI3)
	for (; tag->hdr.size; tag = tag_next(tag))
		if (tag->hdr.tag == ATAG_MEM &&
				tag->u.mem.size > 0x40000000) {
			tag->u.mem.size = 0x80000000;	/* fixup to 2 GiB */
			return;
		}
#endif

	/*
	 * system momory  = system mem size + dma zone size
	 */
	mi->nr_banks      = 1;
	mi->bank[0].start = CFG_MEM_PHY_SYSTEM_BASE;
#if !defined(CFG_MEM_PHY_DMAZONE_SIZE)
	mi->bank[0].size  = CFG_MEM_PHY_SYSTEM_SIZE;
#else
	mi->bank[0].size  = CFG_MEM_PHY_SYSTEM_SIZE + CFG_MEM_PHY_DMAZONE_SIZE;
#endif

	printk("~~~ %s() meminfo banks:%d, start:%#x size:%#x\n", __func__, \
		mi->nr_banks, mi->bank[0].start, mi->bank[0].size);
    /*[    0.000000] ~~~ cpu_fixup() meminfo banks:1, start:0x40000000 size:0x40000000
    */
}

#if	defined(CONFIG_SMP)
#define	LIVE_NR_CPUS 	NR_CPUS
#else
#define	LIVE_NR_CPUS 	4
#endif

static void __init cpu_map_io(void)
{
	int cores = LIVE_NR_CPUS;

	printk("~~~ %s()\n", __func__);
	
	/*
	 * check memory map
	 */
	unsigned long io_end = cpu_iomap_desc[ARRAY_SIZE(cpu_iomap_desc)-1].virtual +
						   cpu_iomap_desc[ARRAY_SIZE(cpu_iomap_desc)-1].length;
#if defined(CFG_MEM_PHY_DMAZONE_SIZE)
	unsigned long dma_start = CONSISTENT_END - CFG_MEM_PHY_DMAZONE_SIZE;
#else
	unsigned long dma_start = CONSISTENT_END - SZ_2M;	// refer to dma-mapping.c
#endif
	if (io_end > dma_start)
		printk(KERN_ERR "\n****** BUG: Overlapped io mmap 0x%lx with dma start 0x%lx ******\n",
			io_end, dma_start);

	/* debug */
	_IOMAP();

	/* make iotable */
	iotable_init(cpu_iomap_desc, ARRAY_SIZE(cpu_iomap_desc));

#if defined(CFG_MEM_PHY_DMAZONE_SIZE)
	printk(KERN_INFO "CPU : DMA Zone Size =%2dM, CORE %d\n", CFG_MEM_PHY_DMAZONE_SIZE>>20, cores);
	init_consistent_dma_size(CFG_MEM_PHY_DMAZONE_SIZE);
#else
	printk(KERN_INFO "CPU : DMA Zone Size =%2dM, CORE %d\n", SZ_2M>>20, cores);
#endif

	nxp_cpu_arch_init();
	nxp_board_base_init();

	nxp_cpu_clock_init();
	nxp_cpu_clock_print();
}

static void __init cpu_init_machine(void)
{
	printk("~~~ %s()\n", __func__);

	/* set shutdown */
	pm_power_off = nxp_cpu_shutdown;
	arm_pm_restart = nxp_cpu_reset;

	/*
	 * register platform device
	 */
	nxp_cpu_devs_register();
	nxp_board_devs_register();
}

static void __init cpu_mem_reserve(void)
{
#ifdef CONFIG_CMA
extern void nxp_reserve_mem(void);
	nxp_reserve_mem();
#endif

#ifdef CONFIG_ANDROID_RAM_CONSOLE
	persistent_ram_console_reserve();
#endif
}

/*------------------------------------------------------------------------------
 * Maintainer: Nexell Co., Ltd.
 */
#include <mach/iomap.h>
extern struct sys_timer nxp_cpu_sys_timer;

#if defined(CFG_SYS_MACH_NAME)
#define NXP_MACH_NAME	CFG_SYS_MACH_NAME
#else
#define NXP_MACH_NAME	CFG_SYS_CPU_NAME
#endif

MACHINE_START(S5P6818, NXP_MACH_NAME)
	.atag_offset	=  0x00000100,
	.fixup			=  cpu_fixup,
	.map_io			=  cpu_map_io,
	.init_irq		=  nxp_cpu_irq_init,
	.handle_irq 	=  gic_handle_irq,
	.timer			= &nxp_cpu_sys_timer,
	.init_machine	=  cpu_init_machine,
#if defined CONFIG_CMA && defined CONFIG_ION
	.reserve		=  cpu_mem_reserve,
#endif
MACHINE_END
/* /arch/arm/mach-s5p6818/devices.c */

/*------------------------------------------------------------------------------
 * register cpu platform devices
 */
void __init nxp_cpu_devs_register(void)
{
#if defined(CONFIG_ARM_AMBA)
	int i;
#endif
	printk("[Register machine platform devices]\n");

#if defined(CONFIG_ARM_AMBA)
	for (i = 0; i < ARRAY_SIZE(amba_devices); i++) {
		struct amba_device *d = amba_devices[i];
		printk("mach: add amba device %s \n", d->dev.init_name);
		amba_device_register(d, &iomem_resource);
	}
#endif

	/* default uart hw prepare */
#if defined(CONFIG_SERIAL_NXP_UART0)
	printk("mach: add device uart0\n");
	uart_device_register(0);
#endif

#if defined(CONFIG_SERIAL_NXP_UART1)
	printk("mach: add device uart1\n");
	uart_device_register(1);
#endif

#if defined(CONFIG_SERIAL_NXP_UART2)
	printk("mach: add device uart2\n");
	uart_device_register(2);
#endif

#if defined(CONFIG_SERIAL_NXP_UART3)
	printk("mach: add device uart3\n");
	uart_device_register(3);
#endif

#if defined(CONFIG_SERIAL_NXP_UART4)
	printk("mach: add device uart4\n");
	uart_device_register(4);
#endif

#if defined(CONFIG_SERIAL_NXP_UART5)
	printk("mach: add device uart5\n");
	uart_device_register(5);
#endif

#if defined(CONFIG_NXP_DISPLAY)
	printk("mach: add device syncgen [%d]\n", ARRAY_SIZE(syncgen_devices));
	platform_add_devices(syncgen_devices, ARRAY_SIZE(syncgen_devices));
#endif

#if defined(CONFIG_NXP_DISPLAY_LCD)
	printk("mach: add device lcd \n");
	platform_device_register(&lcd_device);
#endif

#if defined(CONFIG_NXP_DISPLAY_LVDS)
	printk("mach: add device lvds \n");
	platform_device_register(&lvds_device);
#endif

#if defined(CONFIG_NXP_DISPLAY_MIPI)
	printk("mach: add device mipi \n");
	platform_device_register(&mipi_device);
#endif

#if defined(CONFIG_NXP_DISPLAY_HDMI)
	printk("mach: add device hdmi \n");
	platform_device_register(&hdmi_device);
#endif

#if defined(CONFIG_NXP_DISPLAY_RESC)
	printk("mach: add device resolution convertor \n");
	platform_device_register(&resc_device);
#endif

#if defined(CONFIG_NXP_DISPLAY_TVOUT)
	printk("mach: add device tvout \n");
	platform_device_register(&tvout_device);
#endif

#if defined(CONFIG_SERIAL_NXP)
	printk("mach: add device serial (array:%d)\n", ARRAY_SIZE(uart_devices));
	platform_add_devices(uart_devices, ARRAY_SIZE(uart_devices));
#endif

#if defined(CONFIG_I2C_NXP) || defined(CONFIG_I2C_SLSI)
	printk("mach: add device i2c bus (array:%d) \n", ARRAY_SIZE(i2c_devices));
	platform_add_devices(i2c_devices, ARRAY_SIZE(i2c_devices));
#endif
#if defined(CONFIG_RTC_DRV_NXP)
	printk("mach: add device Real Time Clock  \n");
	platform_device_register(&rtc_plat_device);
#endif

#if defined(CONFIG_HAVE_PWM)
	printk("mach: add device generic pwm (array:%d)\n", ARRAY_SIZE(pwm_devices));
	platform_add_devices(pwm_devices, ARRAY_SIZE(pwm_devices));
#endif

#if defined(CONFIG_GPIO_NXP)
	printk("mach: add device generic gpio (array:%d)\n", ARRAY_SIZE(gpio_devices));
	platform_add_devices(gpio_devices, ARRAY_SIZE(gpio_devices));
#endif

#if defined(CONFIG_SND_NXP_I2S) || defined(CONFIG_SND_NXP_I2S_MODULE)
	printk("+++ %s() mach: add device i2s (array:%d) \n", __func__, ARRAY_SIZE(i2s_devices));
	platform_add_devices(i2s_devices, ARRAY_SIZE(i2s_devices));
#endif

#if defined(CONFIG_SND_NXP_SPDIF_TX) || defined(CONFIG_SND_NXP_SPDIF_TX_MODULE)
	printk("mach: add device spdif tx\n");
	platform_device_register(&spdif_device_tx);
#endif

#if defined(CONFIG_SND_NXP_SPDIF_RX) || defined(CONFIG_SND_NXP_SPDIF_RX_MODULE)
	printk("mach: add device spdif rx\n");
	platform_device_register(&spdif_device_rx);
#endif

#if defined(CONFIG_SND_NXP_PDM) || defined(CONFIG_SND_NXP_PDM_MODULE)
	printk("mach: add device pdm\n");
	platform_device_register(&pdm_device);
#endif

#if defined(CONFIG_USB_EHCI_SYNOPSYS)
	printk("mach: add device usb_ehci\n");
	platform_device_register(&nxp_device_ehci);
#endif

#if defined(CONFIG_USB_OHCI_SYNOPSYS)
	printk("mach: add device usb_ohci\n");
	platform_device_register(&nxp_device_ohci);
#endif

#if defined(CONFIG_USB_DWCOTG)
	printk("mach: add device usb otg\n");
	platform_device_register(&otg_plat_device);
#endif

#if defined(CONFIG_ION_NXP)
	printk("mach: add device ion-nxp\n");
	nxp_ion_set_platdata();
	platform_device_register(&nxp_device_ion);
#endif

#if defined(CONFIG_NXP_ADC)
	printk("mach: add device adc\n");
	platform_device_register(&nxp_adc_device);
#endif

	/* Register the platform devices */
	printk("mach: add graphic device opengl|es\n");
	platform_device_register(&vr_gpu_device);

#if defined(CONFIG_NXP_WDT)
	printk("mach: add device watchdog\n");
	platform_device_register(&nxp_device_wdt);
#endif

#if defined(CONFIG_SPI_SLSI_PORT0)
	printk("mach: add device spi0 \n");
	platform_device_register(&s3c64xx_device_spi0);
#endif

#if defined(CONFIG_SPI_SLSI_PORT1)
	printk("mach: add device spi1 \n");
	platform_device_register(&s3c64xx_device_spi1);
#endif

#if defined(CONFIG_SPI_SLSI_PORT2)
	printk("mach: add device spi2 \n");
	platform_device_register(&s3c64xx_device_spi2);
#endif

#ifdef CONFIG_PM_RUNTIME
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
	pm_runtime_set_autosuspend_delay(&(vr_gpu_device.dev), 1000);
	pm_runtime_use_autosuspend(&(vr_gpu_device.dev));
#endif
	pm_runtime_enable(&(vr_gpu_device.dev));
#endif
}
/* arch/arm/plat-s5p6818/nanopi3/device.c */

/*------------------------------------------------------------------------------
 * register board platform devices
 */
void __init nxp_board_devs_register(void)
{
	struct nxp_lcd *lcd = nanopi3_get_lcd();

	printk("[Register board platform devices]\n");

	board_hwrev_init();

	if (board_is_nanopc() || board_is_smart6818() || board_is_S3()) {
#ifdef CONFIG_MMC_NXP_CH2
		board_fixup_dwmci2();
#endif
	} else {
		/* board without eMMC */
		bootdev = 0;
	}

#if defined(CONFIG_ARM_NXP_CPUFREQ)
	printk("plat: add dynamic frequency (pll.%d)\n", dfs_plat_data.pll_dev);
	platform_device_register(&dfs_plat_device);
#endif

#if defined(CONFIG_SENSORS_NXP_TMU)
	printk("plat: add device TMU\n");
	platform_device_register(&tmu_device);
#endif

#if defined(CONFIG_NXP_DISPLAY)
	nxp_platform_disp_init(lcd);
#endif

#if defined(CONFIG_FB_NXP)
	printk("plat: add framebuffer\n");
	nxp_platform_fb_data(lcd);
	platform_add_devices(fb_devices, ARRAY_SIZE(fb_devices));
#endif

#if defined(CONFIG_MMC_DW)
	printk("plat: boot from mmc.%d\n", bootdev);
	if (board_is_M3()) {
		_dwmci0_add_device();
		_dwmci1_add_device();
	} else if (bootdev == 2) {
		_dwmci2_add_device();
		_dwmci1_add_device();
		_dwmci0_add_device();
	} else {
		_dwmci0_add_device();
		_dwmci1_add_device();
		_dwmci2_add_device();
	}
#endif

#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
	printk("plat: add device dm9000 net\n");
	platform_device_register(&dm9000_plat_device);
#endif

#if defined(CONFIG_BACKLIGHT_PWM)
	printk("plat: add backlight pwm device\n");
	platform_device_register(&bl_plat_device);
#endif

#if defined(CONFIG_MTD_NAND_NXP) || defined(CONFIG_NXP_FTL)
	platform_device_register(&nand_plat_device);
#endif

#if defined(CONFIG_KEYBOARD_NXP_KEY) || defined(CONFIG_KEYBOARD_NXP_KEY_MODULE)
	printk("plat: add device keypad\n");
	platform_device_register(&key_plat_device);
#endif

	if (0) {
#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE)
		printk("plat: add device fixed voltage\n");
		platform_device_register(&fixed_supply_dummy_device);
#endif
	} else {
#if defined(CONFIG_I2C_NXP_PORT3)
		platform_add_devices(i2c_devices, ARRAY_SIZE(i2c_devices));
#endif
	}

#if defined(CONFIG_SND_SPDIF_TRANSCIEVER) || defined(CONFIG_SND_SPDIF_TRANSCIEVER_MODULE)
	printk("plat: add device spdif playback\n");
	platform_device_register(&spdif_transciever);
	platform_device_register(&spdif_trans_dai);
#endif

#if defined(CONFIG_SND_CODEC_ES8316) || defined(CONFIG_SND_CODEC_ES8316_MODULE)
	if (board_with_es8316()) {
		printk("+++ %s() plat: add device asoc-es8316\n", __func__);
		if (board_is_nanopc() || board_is_smart6818())
			i2s_dai_data.hp_jack.support = 1;
		i2c_register_board_info(ES8316_I2C_BUS, &es8316_i2c_bdi, 1);
		platform_device_register(&es8316_dai);
	}
#endif

#if defined(CONFIG_V4L2_NXP) || defined(CONFIG_V4L2_NXP_MODULE)
	printk("plat: add device nxp-v4l2\n");
	back_camera_power_enable(1);
	is_back_camera_power_state_changed = false;
	platform_device_register(&nxp_v4l2_dev);
#endif

#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
	if (ARRAY_SIZE(spi0_board_info) > 0)
		spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
	if (ARRAY_SIZE(spi2_board_info) > 0)
		spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
	printk("plat: register spidev\n");
#endif

#if defined(CONFIG_TOUCHSCREEN_GSLX680)
	printk("plat: add touch(gslX680) device\n");
	i2c_register_board_info(GSLX680_I2C_BUS, &gslX680_i2c_bdi, 1);
#endif

#if defined(CONFIG_TOUCHSCREEN_FT5X0X)
	printk("plat: add touch(ft5x0x) device\n");
	ft5x0x_pdata.screen_max_x = lcd->width;
	ft5x0x_pdata.screen_max_y = lcd->height;
	i2c_register_board_info(FT5X0X_I2C_BUS, &ft5x0x_i2c_bdi, 1);
#endif

#if defined(CONFIG_TOUCHSCREEN_IT7260)
	printk("plat: add touch(it7260) device\n");
	i2c_register_board_info(IT7260_I2C_BUS, &it7260_i2c_bdi, 1);
#endif

#if defined(CONFIG_TOUCHSCREEN_1WIRE)
	printk("plat: add onewire ts device\n");
	platform_device_register(&onewire_device);
#endif

#if defined(CONFIG_SENSORS_MMA865X) || defined(CONFIG_SENSORS_MMA865X_MODULE)
	printk("plat: add g-sensor mma865x\n");
	i2c_register_board_info(2, &mma865x_i2c_bdi, 1);
#elif defined(CONFIG_SENSORS_MMA7660) || defined(CONFIG_SENSORS_MMA7660_MODULE)
	printk("plat: add g-sensor mma7660\n");
	i2c_register_board_info(MMA7660_I2C_BUS, &mma7660_i2c_bdi, 1);
#endif

#if defined(CONFIG_INPUT_ADXL34X_I2C_MODULE)
	printk("plat: add adxl34x device\n");
	i2c_register_board_info(ADXL34X_I2C_BUS, &adxl34x_i2c_bdi, 1);
#endif

#if defined(CONFIG_BMP085_MODULE)
	printk("plat: add bmp085 device\n");
	i2c_register_board_info(BMP085_I2C_BUS, &bmp085_i2c_bdi, 1);
#endif

#if defined(CONFIG_RTC_DRV_DS1307_MODULE)
	printk("plat: add ds1307 device\n");
	i2c_register_board_info(DS1307_I2C_BUS, &ds1307_i2c_bdi, 1);
#endif

#if defined(CONFIG_SENSORS_PCF8591_MODULE)
	printk("plat: add pcf8591 device\n");
	i2c_register_board_info(DS1307_I2C_BUS, &pcf8591_i2c_bdi, 1);
#endif

#if defined(CONFIG_RFKILL_NXP)
	printk("plat: add device rfkill\n");
	platform_device_register(&rfkill_device);
#endif

#if defined(CONFIG_NXP_HDMI_CEC)
	printk("plat: add device hdmi-cec\n");
	platform_device_register(&hdmi_cec_device);
#endif

#if defined(CONFIG_NXPMAC_ETH)
	if (board_with_gmac_eth()) {
		make_ether_addr(nxpmac_plat_data.dev_addr);
		printk("plat: add device nxp-gmac\n");
		platform_device_register(&nxp_gmac_dev);
	}
#endif

#if defined(CONFIG_PPM_NXP)
	printk("plat: add device ppm\n");
	platform_device_register(&ppm_device);
#endif

#if defined(CONFIG_LEDS_GPIO)
	printk("plat: add device gpio_led\n");
	platform_device_register(&gpio_led_device);
#endif

#if defined(CONFIG_LEDS_PWM) || defined(CONFIG_LEDS_PWM_MODULE)
	printk("plat: add device pwm_led\n");
	platform_device_register(&pwm_led_device);
#endif

	platform_device_register(&wyk_led_plat_device);

	/* END */
	printk("\n");
}

Author: Yangkai Wang
wang_yangkai@163.com
Coding in 2021/05/06
转载请注明出处。

这篇关于linux kernel setup arm machine的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!