|  | /* | 
|  | * linux/arch/arm/mach-tcc8k/devices.c | 
|  | * | 
|  | * Copyright (C) Telechips, Inc. | 
|  | * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> | 
|  | * | 
|  | * Licensed under the terms of GPL v2. | 
|  | * | 
|  | */ | 
|  |  | 
|  | #include <linux/dma-mapping.h> | 
|  | #include <linux/init.h> | 
|  | #include <linux/io.h> | 
|  | #include <linux/kernel.h> | 
|  | #include <linux/module.h> | 
|  |  | 
|  | #include <asm/mach/map.h> | 
|  |  | 
|  | #include <mach/tcc8k-regs.h> | 
|  | #include <mach/irqs.h> | 
|  |  | 
|  | #include "common.h" | 
|  |  | 
|  | static u64 tcc8k_dmamask = DMA_BIT_MASK(32); | 
|  |  | 
|  | #ifdef CONFIG_MTD_NAND_TCC | 
|  | /* NAND controller */ | 
|  | static struct resource tcc_nand_resources[] = { | 
|  | { | 
|  | .start	= (resource_size_t)NFC_BASE, | 
|  | .end	= (resource_size_t)NFC_BASE + 0x7f, | 
|  | .flags	= IORESOURCE_MEM, | 
|  | }, { | 
|  | .start	= INT_NFC, | 
|  | .end	= INT_NFC, | 
|  | .flags	= IORESOURCE_IRQ, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | struct platform_device tcc_nand_device = { | 
|  | .name = "tcc_nand", | 
|  | .id = 0, | 
|  | .num_resources = ARRAY_SIZE(tcc_nand_resources), | 
|  | .resource = tcc_nand_resources, | 
|  | }; | 
|  | #endif | 
|  |  | 
|  | #ifdef CONFIG_MMC_TCC8K | 
|  | /* MMC controller */ | 
|  | static struct resource tcc8k_mmc0_resource[] = { | 
|  | { | 
|  | .start = INT_SD0, | 
|  | .end   = INT_SD0, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | static struct resource tcc8k_mmc1_resource[] = { | 
|  | { | 
|  | .start = INT_SD1, | 
|  | .end   = INT_SD1, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | struct platform_device tcc8k_mmc0_device = { | 
|  | .name		= "tcc-mmc", | 
|  | .id		= 0, | 
|  | .num_resources	= ARRAY_SIZE(tcc8k_mmc0_resource), | 
|  | .resource	= tcc8k_mmc0_resource, | 
|  | .dev		= { | 
|  | .dma_mask		= &tcc8k_dmamask, | 
|  | .coherent_dma_mask	= DMA_BIT_MASK(32), | 
|  | } | 
|  | }; | 
|  |  | 
|  | struct platform_device tcc8k_mmc1_device = { | 
|  | .name		= "tcc-mmc", | 
|  | .id		= 1, | 
|  | .num_resources	= ARRAY_SIZE(tcc8k_mmc1_resource), | 
|  | .resource	= tcc8k_mmc1_resource, | 
|  | .dev		= { | 
|  | .dma_mask		= &tcc8k_dmamask, | 
|  | .coherent_dma_mask	= DMA_BIT_MASK(32), | 
|  | } | 
|  | }; | 
|  |  | 
|  | static inline void tcc8k_init_mmc(void) | 
|  | { | 
|  | u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS); | 
|  |  | 
|  | reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS; | 
|  | __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS); | 
|  |  | 
|  | platform_device_register(&tcc8k_mmc0_device); | 
|  | platform_device_register(&tcc8k_mmc1_device); | 
|  | } | 
|  | #else | 
|  | static inline void tcc8k_init_mmc(void) { } | 
|  | #endif | 
|  |  | 
|  | #ifdef CONFIG_USB_OHCI_HCD | 
|  | static int tcc8k_ohci_init(struct device *dev) | 
|  | { | 
|  | u32 reg; | 
|  |  | 
|  | /* Use GPIO PK19 as VBUS control output */ | 
|  | reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS); | 
|  | reg &= ~(1 << 19); | 
|  | __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS); | 
|  | reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS); | 
|  | reg &= ~(1 << 19); | 
|  | __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS); | 
|  |  | 
|  | reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS); | 
|  | reg |= (1 << 19); | 
|  | __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS); | 
|  | /* Turn on VBUS */ | 
|  | reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS); | 
|  | reg |= (1 << 19); | 
|  | __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static struct resource tcc8k_ohci0_resources[] = { | 
|  | [0] = { | 
|  | .start = (resource_size_t)USBH0_BASE, | 
|  | .end   = (resource_size_t)USBH0_BASE + 0x5c, | 
|  | .flags = IORESOURCE_MEM, | 
|  | }, | 
|  | [1] = { | 
|  | .start = INT_USBH0, | 
|  | .end   = INT_USBH0, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | } | 
|  | }; | 
|  |  | 
|  | static struct resource tcc8k_ohci1_resources[] = { | 
|  | [0] = { | 
|  | .start = (resource_size_t)USBH1_BASE, | 
|  | .end   = (resource_size_t)USBH1_BASE + 0x5c, | 
|  | .flags = IORESOURCE_MEM, | 
|  | }, | 
|  | [1] = { | 
|  | .start = INT_USBH1, | 
|  | .end   = INT_USBH1, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | } | 
|  | }; | 
|  |  | 
|  | static struct tccohci_platform_data tcc8k_ohci0_platform_data = { | 
|  | .controller	= 0, | 
|  | .port_mode	= PMM_PERPORT_MODE, | 
|  | .init		= tcc8k_ohci_init, | 
|  | }; | 
|  |  | 
|  | static struct tccohci_platform_data tcc8k_ohci1_platform_data = { | 
|  | .controller	= 1, | 
|  | .port_mode	= PMM_PERPORT_MODE, | 
|  | .init		= tcc8k_ohci_init, | 
|  | }; | 
|  |  | 
|  | static struct platform_device ohci0_device = { | 
|  | .name = "tcc-ohci", | 
|  | .id = 0, | 
|  | .dev = { | 
|  | .dma_mask = &tcc8k_dmamask, | 
|  | .coherent_dma_mask = DMA_BIT_MASK(32), | 
|  | .platform_data = &tcc8k_ohci0_platform_data, | 
|  | }, | 
|  | .num_resources  = ARRAY_SIZE(tcc8k_ohci0_resources), | 
|  | .resource       = tcc8k_ohci0_resources, | 
|  | }; | 
|  |  | 
|  | static struct platform_device ohci1_device = { | 
|  | .name = "tcc-ohci", | 
|  | .id = 1, | 
|  | .dev = { | 
|  | .dma_mask = &tcc8k_dmamask, | 
|  | .coherent_dma_mask = DMA_BIT_MASK(32), | 
|  | .platform_data = &tcc8k_ohci1_platform_data, | 
|  | }, | 
|  | .num_resources  = ARRAY_SIZE(tcc8k_ohci1_resources), | 
|  | .resource       = tcc8k_ohci1_resources, | 
|  | }; | 
|  |  | 
|  | static void __init tcc8k_init_usbhost(void) | 
|  | { | 
|  | platform_device_register(&ohci0_device); | 
|  | platform_device_register(&ohci1_device); | 
|  | } | 
|  | #else | 
|  | static void __init tcc8k_init_usbhost(void) { } | 
|  | #endif | 
|  |  | 
|  | /* USB device controller*/ | 
|  | #ifdef CONFIG_USB_GADGET_TCC8K | 
|  | static struct resource udc_resources[] = { | 
|  | [0] = { | 
|  | .start = INT_USBD, | 
|  | .end   = INT_USBD, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | }, | 
|  | [1] = { | 
|  | .start = INT_UDMA, | 
|  | .end   = INT_UDMA, | 
|  | .flags = IORESOURCE_IRQ, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | static struct platform_device tcc8k_udc_device = { | 
|  | .name = "tcc-udc", | 
|  | .id = 0, | 
|  | .resource = udc_resources, | 
|  | .num_resources = ARRAY_SIZE(udc_resources), | 
|  | .dev = { | 
|  | .dma_mask = &tcc8k_dmamask, | 
|  | .coherent_dma_mask = DMA_BIT_MASK(32), | 
|  | }, | 
|  | }; | 
|  |  | 
|  | static void __init tcc8k_init_usb_gadget(void) | 
|  | { | 
|  | platform_device_register(&tcc8k_udc_device); | 
|  | } | 
|  | #else | 
|  | static void __init tcc8k_init_usb_gadget(void) { } | 
|  | #endif	/* CONFIG_USB_GADGET_TCC83X */ | 
|  |  | 
|  | static int __init tcc8k_init_devices(void) | 
|  | { | 
|  | tcc8k_init_mmc(); | 
|  | tcc8k_init_usbhost(); | 
|  | tcc8k_init_usb_gadget(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | arch_initcall(tcc8k_init_devices); |