gemini: remove 4.4 support
Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Roman Yeryomin <roman@advem.lv>
This commit is contained in:
		 Roman Yeryomin
					Roman Yeryomin
				
			
				
					committed by
					
						 John Crispin
						John Crispin
					
				
			
			
				
	
			
			
			 John Crispin
						John Crispin
					
				
			
						parent
						
							6409b159e8
						
					
				
				
					commit
					91930c0f99
				
			| @@ -1,165 +0,0 @@ | ||||
| CONFIG_ALIGNMENT_TRAP=y | ||||
| CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y | ||||
| CONFIG_ARCH_GEMINI=y | ||||
| CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y | ||||
| CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y | ||||
| CONFIG_ARCH_NR_GPIO=0 | ||||
| CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||||
| # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||||
| # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||||
| CONFIG_ARCH_USES_GETTIMEOFFSET=y | ||||
| CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y | ||||
| CONFIG_ARM=y | ||||
| # CONFIG_ARM_CPU_SUSPEND is not set | ||||
| CONFIG_ARM_L1_CACHE_SHIFT=5 | ||||
| CONFIG_ARM_NR_BANKS=8 | ||||
| CONFIG_ARM_PATCH_PHYS_VIRT=y | ||||
| # CONFIG_ARPD is not set | ||||
| CONFIG_ATA=y | ||||
| CONFIG_ATAGS=y | ||||
| # CONFIG_CACHE_L2X0 is not set | ||||
| CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||||
| CONFIG_CLONE_BACKWARDS=y | ||||
| CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,19200 mem=32M" | ||||
| CONFIG_CMDLINE_FROM_BOOTLOADER=y | ||||
| CONFIG_CPU_32v4=y | ||||
| CONFIG_CPU_ABRT_EV4=y | ||||
| # CONFIG_CPU_BPREDICT_DISABLE is not set | ||||
| CONFIG_CPU_CACHE_FA=y | ||||
| CONFIG_CPU_CACHE_VIVT=y | ||||
| CONFIG_CPU_COPY_FA=y | ||||
| CONFIG_CPU_CP15=y | ||||
| CONFIG_CPU_CP15_MMU=y | ||||
| # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||||
| CONFIG_CPU_FA526=y | ||||
| # CONFIG_CPU_ICACHE_DISABLE is not set | ||||
| CONFIG_CPU_PABRT_LEGACY=y | ||||
| CONFIG_CPU_TLB_FA=y | ||||
| CONFIG_CPU_USE_DOMAINS=y | ||||
| CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" | ||||
| # CONFIG_DEBUG_USER is not set | ||||
| CONFIG_DEBUG_UART_PHYS=0x42000000 | ||||
| CONFIG_DEBUG_UART_VIRT=0xf4200000 | ||||
| CONFIG_DEBUG_UART_8250_SHIFT=2 | ||||
| # CONFIG_DEBUG_UART_8250_WORD is not set | ||||
| # CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set | ||||
| # CONFIG_DLCI is not set | ||||
| CONFIG_DMADEVICES=y | ||||
| CONFIG_DNOTIFY=y | ||||
| # CONFIG_DW_DMAC_CORE is not set | ||||
| # CONFIG_DW_DMAC_PCI is not set | ||||
| CONFIG_FRAME_POINTER=y | ||||
| CONFIG_GEMINI_MEM_SWAP=y | ||||
| CONFIG_GEMINI_SL351X=y | ||||
| CONFIG_GEMINI_WATCHDOG=y | ||||
| CONFIG_GENERIC_ATOMIC64=y | ||||
| CONFIG_GENERIC_BUG=y | ||||
| CONFIG_GENERIC_IDLE_POLL_SETUP=y | ||||
| CONFIG_GENERIC_IO=y | ||||
| CONFIG_GENERIC_IRQ_SHOW=y | ||||
| CONFIG_GENERIC_PCI_IOMAP=y | ||||
| CONFIG_GENERIC_SMP_IDLE_THREAD=y | ||||
| CONFIG_GENERIC_STRNCPY_FROM_USER=y | ||||
| CONFIG_GENERIC_STRNLEN_USER=y | ||||
| CONFIG_GPIOLIB=y | ||||
| CONFIG_GPIO_DEVRES=y | ||||
| CONFIG_GPIO_SYSFS=y | ||||
| CONFIG_HARDIRQS_SW_RESEND=y | ||||
| CONFIG_HAS_DMA=y | ||||
| CONFIG_HAS_IOMEM=y | ||||
| CONFIG_HAS_IOPORT=y | ||||
| # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set | ||||
| CONFIG_HAVE_ARCH_JUMP_LABEL=y | ||||
| CONFIG_HAVE_ARCH_KGDB=y | ||||
| CONFIG_HAVE_ARCH_PFN_VALID=y | ||||
| CONFIG_HAVE_ARCH_SECCOMP_FILTER=y | ||||
| CONFIG_HAVE_ARCH_TRACEHOOK=y | ||||
| # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set | ||||
| CONFIG_HAVE_BPF_JIT=y | ||||
| CONFIG_HAVE_CONTEXT_TRACKING=y | ||||
| CONFIG_HAVE_C_RECORDMCOUNT=y | ||||
| CONFIG_HAVE_DEBUG_KMEMLEAK=y | ||||
| CONFIG_HAVE_DMA_API_DEBUG=y | ||||
| CONFIG_HAVE_DMA_ATTRS=y | ||||
| CONFIG_HAVE_DMA_CONTIGUOUS=y | ||||
| CONFIG_HAVE_DYNAMIC_FTRACE=y | ||||
| CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | ||||
| CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||||
| CONFIG_HAVE_FUNCTION_TRACER=y | ||||
| CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||||
| CONFIG_HAVE_GENERIC_HARDIRQS=y | ||||
| CONFIG_HAVE_IDE=y | ||||
| CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y | ||||
| CONFIG_HAVE_KERNEL_GZIP=y | ||||
| CONFIG_HAVE_KERNEL_LZMA=y | ||||
| CONFIG_HAVE_KERNEL_LZO=y | ||||
| CONFIG_HAVE_KERNEL_XZ=y | ||||
| CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||||
| CONFIG_HAVE_MEMBLOCK=y | ||||
| CONFIG_HAVE_NET_DSA=y | ||||
| CONFIG_HAVE_OPROFILE=y | ||||
| CONFIG_HAVE_PERF_EVENTS=y | ||||
| CONFIG_HAVE_PROC_CPU=y | ||||
| CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y | ||||
| CONFIG_HAVE_SYSCALL_TRACEPOINTS=y | ||||
| CONFIG_HAVE_UID16=y | ||||
| # CONFIG_HSU_DMA_PCI is not set | ||||
| CONFIG_HWMON=y | ||||
| CONFIG_HW_RANDOM=y | ||||
| CONFIG_I2C=y | ||||
| CONFIG_I2C_BOARDINFO=y | ||||
| CONFIG_I2C_CHARDEV=y | ||||
| CONFIG_INITRAMFS_SOURCE="" | ||||
| # CONFIG_IP_ADVANCED_ROUTER is not set | ||||
| CONFIG_IP_PIMSM_V1=y | ||||
| CONFIG_IP_PIMSM_V2=y | ||||
| CONFIG_IRQ_WORK=y | ||||
| CONFIG_KTIME_SCALAR=y | ||||
| CONFIG_LEGACY_PTYS=y | ||||
| CONFIG_LEGACY_PTY_COUNT=256 | ||||
| # CONFIG_MACH_NAS4220B is not set | ||||
| # CONFIG_MACH_RUT100 is not set | ||||
| CONFIG_MACH_WBD111=y | ||||
| CONFIG_MACH_WBD222=y | ||||
| CONFIG_MDIO_BITBANG=y | ||||
| CONFIG_MDIO_BOARDINFO=y | ||||
| CONFIG_MDIO_GPIO=y | ||||
| CONFIG_MIGHT_HAVE_PCI=y | ||||
| CONFIG_MODULES_USE_ELF_REL=y | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_NEED_DMA_MAP_STATE=y | ||||
| CONFIG_NEED_KUSER_HELPERS=y | ||||
| CONFIG_NEED_MACH_GPIO_H=y | ||||
| CONFIG_NEED_PER_CPU_KM=y | ||||
| CONFIG_NET_VENDOR_GEMINI=y | ||||
| # CONFIG_OF is not set | ||||
| CONFIG_OLD_SIGACTION=y | ||||
| CONFIG_OLD_SIGSUSPEND3=y | ||||
| CONFIG_PAGEFLAGS_EXTENDED=y | ||||
| CONFIG_PAGE_OFFSET=0xC0000000 | ||||
| CONFIG_PATA_GEMINI=y | ||||
| CONFIG_PCI=y | ||||
| CONFIG_PERF_USE_VMALLOC=y | ||||
| CONFIG_PHYLIB=y | ||||
| # CONFIG_PREEMPT_RCU is not set | ||||
| # CONFIG_RCU_STALL_COMMON is not set | ||||
| CONFIG_RTC_CLASS=y | ||||
| CONFIG_RTC_DRV_GEMINI=y | ||||
| # CONFIG_SCHED_HRTICK is not set | ||||
| # CONFIG_SCSI_DMA is not set | ||||
| CONFIG_SPLIT_PTLOCK_CPUS=999999 | ||||
| CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||||
| CONFIG_TICK_CPU_ACCOUNTING=y | ||||
| CONFIG_UID16=y | ||||
| CONFIG_UIDGID_CONVERTED=y | ||||
| CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h" | ||||
| CONFIG_USB_ARCH_HAS_XHCI=y | ||||
| CONFIG_USB_SUPPORT=y | ||||
| CONFIG_VECTORS_BASE=0xffff0000 | ||||
| CONFIG_VM_EVENT_COUNTERS=y | ||||
| CONFIG_WAN=y | ||||
| CONFIG_XZ_DEC_ARM=y | ||||
| CONFIG_XZ_DEC_BCJ=y | ||||
| CONFIG_ZBOOT_ROM_BSS=0x0 | ||||
| CONFIG_ZBOOT_ROM_TEXT=0x0 | ||||
| CONFIG_ZONE_DMA_FLAG=0 | ||||
| @@ -1,21 +0,0 @@ | ||||
| /* | ||||
|  * Gemini GMAC specific defines | ||||
|  * | ||||
|  * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@gmail.com> | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __NET_GEMINI_PLATFORM_H__ | ||||
| #define __NET_GEMINI_PLATFORM_H__ | ||||
|  | ||||
| #include <linux/phy.h> | ||||
|  | ||||
| struct gemini_gmac_platform_data { | ||||
| 	char *bus_id[2]; /* NULL means that this port is not used */ | ||||
| 	phy_interface_t interface[2]; | ||||
| }; | ||||
|  | ||||
| #endif /* __NET_GEMINI_PLATFORM_H__ */ | ||||
| @@ -1,318 +0,0 @@ | ||||
| /* | ||||
|  *  Support for Gemini PCI Controller | ||||
|  * | ||||
|  *  Copyright (C) 2009 Janos Laube <janos.dev@gmail.com> | ||||
|  *  Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||||
|  * | ||||
|  * based on SL2312 PCI controller code | ||||
|  *   Storlink (C) 2003 | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/irq.h> | ||||
| #include <linux/gpio.h> | ||||
|  | ||||
| #include <asm/mach/pci.h> | ||||
|  | ||||
| #include <mach/irqs.h> | ||||
| #include <mach/hardware.h> | ||||
|  | ||||
| #define GEMINI_PCI_IOSIZE_1M		0x0000 | ||||
|  | ||||
| #define GEMINI_PCI_PMC			0x40 | ||||
| #define GEMINI_PCI_PMCSR		0x44 | ||||
| #define GEMINI_PCI_CTRL1		0x48 | ||||
| #define GEMINI_PCI_CTRL2		0x4C | ||||
| #define GEMINI_PCI_MEM1_BASE_SIZE	0x50 | ||||
| #define GEMINI_PCI_MEM2_BASE_SIZE	0x54 | ||||
| #define GEMINI_PCI_MEM3_BASE_SIZE	0x58 | ||||
|  | ||||
| #define PCI_CTRL2_INTSTS_OFFSET		28 | ||||
| #define PCI_CTRL2_INTMASK_OFFSET	22 | ||||
|  | ||||
| #define GEMINI_PCI_DMA_MASK		0xFFF00000 | ||||
| #define GEMINI_PCI_DMA_MEM1_BASE	0x00000000 | ||||
| #define GEMINI_PCI_DMA_MEM2_BASE	0x00000000 | ||||
| #define GEMINI_PCI_DMA_MEM3_BASE	0x00000000 | ||||
| #define GEMINI_PCI_DMA_MEM1_SIZE	7 | ||||
| #define GEMINI_PCI_DMA_MEM2_SIZE	6 | ||||
| #define GEMINI_PCI_DMA_MEM3_SIZE	6 | ||||
|  | ||||
| #define PCI_CONF_ENABLE		(1 << 31) | ||||
| #define PCI_CONF_WHERE(r)	((r) & 0xFC) | ||||
| #define PCI_CONF_BUS(b)		(((b) & 0xFF) << 16) | ||||
| #define PCI_CONF_DEVICE(d)	(((d) & 0x1F) << 11) | ||||
| #define PCI_CONF_FUNCTION(f)	(((f) & 0x07) << 8) | ||||
|  | ||||
| #define PCI_IOSIZE_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE)) | ||||
| #define PCI_PROT_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x04) | ||||
| #define PCI_CTRL_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x08) | ||||
| #define PCI_SOFTRST_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x10) | ||||
| #define PCI_CONFIG_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x28) | ||||
| #define PCI_DATA_REG	(IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x2C) | ||||
|  | ||||
|  | ||||
| static DEFINE_SPINLOCK(gemini_pci_lock); | ||||
|  | ||||
| static int gemini_pci_read_config(struct pci_bus* bus, unsigned int fn, | ||||
| 				  int config, int size, u32* value) | ||||
| { | ||||
| 	unsigned long irq_flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&gemini_pci_lock, irq_flags); | ||||
|  | ||||
| 	__raw_writel(PCI_CONF_BUS(bus->number) | | ||||
| 			PCI_CONF_DEVICE(PCI_SLOT(fn)) | | ||||
| 			PCI_CONF_FUNCTION(PCI_FUNC(fn)) | | ||||
| 			PCI_CONF_WHERE(config) | | ||||
| 			PCI_CONF_ENABLE, | ||||
| 			PCI_CONFIG_REG); | ||||
|  | ||||
| 	*value = __raw_readl(PCI_DATA_REG); | ||||
|  | ||||
| 	if (size == 1) | ||||
| 		*value = (*value >> (8 * (config & 3))) & 0xFF; | ||||
| 	else if (size == 2) | ||||
| 		*value = (*value >> (8 * (config & 3))) & 0xFFFF; | ||||
|  | ||||
| 	spin_unlock_irqrestore(&gemini_pci_lock, irq_flags); | ||||
|  | ||||
| 	dev_dbg(&bus->dev, | ||||
| 		"[read]  slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", | ||||
| 		PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value); | ||||
|  | ||||
| 	return PCIBIOS_SUCCESSFUL; | ||||
| } | ||||
|  | ||||
| static int gemini_pci_write_config(struct pci_bus* bus, unsigned int fn, | ||||
| 				   int config, int size, u32 value) | ||||
| { | ||||
| 	unsigned long irq_flags = 0; | ||||
| 	int ret = PCIBIOS_SUCCESSFUL; | ||||
|  | ||||
| 	dev_dbg(&bus->dev, | ||||
| 		"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", | ||||
| 		PCI_SLOT(fn), PCI_FUNC(fn), config, size, value); | ||||
|  | ||||
| 	spin_lock_irqsave(&gemini_pci_lock, irq_flags); | ||||
|  | ||||
| 	__raw_writel(PCI_CONF_BUS(bus->number) | | ||||
| 			PCI_CONF_DEVICE(PCI_SLOT(fn)) | | ||||
| 			PCI_CONF_FUNCTION(PCI_FUNC(fn)) | | ||||
| 			PCI_CONF_WHERE(config) | | ||||
| 			PCI_CONF_ENABLE, | ||||
| 			PCI_CONFIG_REG); | ||||
|  | ||||
| 	switch(size) { | ||||
| 	case 4: | ||||
| 		__raw_writel(value, PCI_DATA_REG); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		__raw_writew(value, PCI_DATA_REG + (config & 3)); | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		__raw_writeb(value, PCI_DATA_REG + (config & 3)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		ret = PCIBIOS_BAD_REGISTER_NUMBER; | ||||
| 	} | ||||
|  | ||||
| 	spin_unlock_irqrestore(&gemini_pci_lock, irq_flags); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static struct pci_ops gemini_pci_ops = { | ||||
| 	.read	= gemini_pci_read_config, | ||||
| 	.write	= gemini_pci_write_config, | ||||
| }; | ||||
|  | ||||
| static struct resource gemini_pci_resource_io = { | ||||
| 	.name	= "PCI I/O Space", | ||||
| 	.start	= GEMINI_PCI_IO_BASE, | ||||
| 	.end	= GEMINI_PCI_IO_BASE + SZ_1M - 1, | ||||
| 	.flags	= IORESOURCE_IO, | ||||
| }; | ||||
|  | ||||
| static struct resource gemini_pci_resource_mem = { | ||||
| 	.name	= "PCI Memory Space", | ||||
| 	.start	= GEMINI_PCI_MEM_BASE, | ||||
| 	.end	= GEMINI_PCI_MEM_BASE + SZ_128M - 1, | ||||
| 	.flags	= IORESOURCE_MEM, | ||||
| }; | ||||
|  | ||||
| static int __init gemini_pci_request_resources(struct pci_sys_data *sys) | ||||
| { | ||||
| 	if (request_resource(&ioport_resource, &gemini_pci_resource_io)) | ||||
| 		goto bad_resources; | ||||
| 	if (request_resource(&iomem_resource, &gemini_pci_resource_mem)) | ||||
| 		goto bad_resources; | ||||
|  | ||||
| 	pci_add_resource(&sys->resources, &gemini_pci_resource_io); | ||||
| 	pci_add_resource(&sys->resources, &gemini_pci_resource_mem); | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| bad_resources: | ||||
| 	pr_err("Gemini PCI: request_resource() failed. " | ||||
| 			"Abort PCI bus enumeration.\n"); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int __init gemini_pci_setup(int nr, struct pci_sys_data *sys) | ||||
| { | ||||
| 	unsigned int cmd; | ||||
|  | ||||
| 	pcibios_min_io = 0x100; | ||||
| 	pcibios_min_mem = 0; | ||||
|  | ||||
| 	if ((nr > 0) || gemini_pci_request_resources(sys)) | ||||
| 		return 0; | ||||
|  | ||||
| 	/* setup I/O space to 1MB size */ | ||||
| 	__raw_writel(GEMINI_PCI_IOSIZE_1M, PCI_IOSIZE_REG); | ||||
|  | ||||
| 	/* setup hostbridge */ | ||||
| 	cmd = __raw_readl(PCI_CTRL_REG); | ||||
| 	cmd |= PCI_COMMAND_IO; | ||||
| 	cmd |= PCI_COMMAND_MEMORY; | ||||
| 	cmd |= PCI_COMMAND_MASTER; | ||||
| 	__raw_writel(cmd, PCI_CTRL_REG); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static struct pci_bus* __init gemini_pci_scan_bus(int nr, struct pci_sys_data* sys) | ||||
| { | ||||
| 	unsigned int reg = 0; | ||||
| 	struct pci_bus* bus = 0; | ||||
|  | ||||
| 	bus = pci_scan_bus(nr, &gemini_pci_ops, sys); | ||||
| 	if (bus) { | ||||
| 		dev_dbg(&bus->dev, "setting up PCI DMA\n"); | ||||
| 		reg = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK) | ||||
| 			| (GEMINI_PCI_DMA_MEM1_SIZE << 16); | ||||
| 		gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, reg); | ||||
| 		reg =	(GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK) | ||||
| 			| (GEMINI_PCI_DMA_MEM2_SIZE << 16); | ||||
| 		gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, reg); | ||||
| 		reg = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK) | ||||
| 			| (GEMINI_PCI_DMA_MEM3_SIZE << 16); | ||||
| 		gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, reg); | ||||
| 	} | ||||
|  | ||||
| 	return bus; | ||||
| } | ||||
|  | ||||
| /* Should work with all boards based on original Storlink EVB */ | ||||
| static int __init gemini_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||||
| { | ||||
| 	if (slot < 9 || slot > 12) | ||||
| 		return -1; | ||||
|  | ||||
| 	return PCI_IRQ_BASE + (((slot - 9) + (pin - 1)) & 0x3); | ||||
| } | ||||
|  | ||||
| static struct hw_pci gemini_hw_pci __initdata = { | ||||
| 	.nr_controllers	= 1, | ||||
| 	.setup		= gemini_pci_setup, | ||||
| 	.scan           = gemini_pci_scan_bus, | ||||
| 	.map_irq	= gemini_pci_map_irq, | ||||
| }; | ||||
|  | ||||
| /* we need this for muxed PCI interrupts handling */ | ||||
| static struct pci_bus bogus_pci_bus; | ||||
|  | ||||
| static void gemini_pci_ack_irq(struct irq_data *d) | ||||
| { | ||||
| 	unsigned int irq = d->irq; | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); | ||||
| 	reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET); | ||||
| 	reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTSTS_OFFSET); | ||||
| 	gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); | ||||
| } | ||||
|  | ||||
| static void gemini_pci_mask_irq(struct irq_data *d) | ||||
| { | ||||
| 	unsigned int irq = d->irq; | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); | ||||
| 	reg &= ~((0xF << PCI_CTRL2_INTSTS_OFFSET) | ||||
| 		| (1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET))); | ||||
| 	gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); | ||||
| } | ||||
|  | ||||
| static void gemini_pci_unmask_irq(struct irq_data *d) | ||||
| { | ||||
| 	unsigned int irq = d->irq; | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); | ||||
| 	reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET); | ||||
| 	reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET); | ||||
| 	gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); | ||||
| } | ||||
|  | ||||
| static void gemini_pci_irq_handler(struct irq_desc *desc) | ||||
| { | ||||
| 	unsigned int pci_irq_no, irq_stat, reg, i; | ||||
|  | ||||
| 	gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); | ||||
| 	irq_stat = reg >> PCI_CTRL2_INTSTS_OFFSET; | ||||
|  | ||||
| 	for (i = 0; i < 4; i++) { | ||||
|  | ||||
| 		if ((irq_stat & (1 << i)) == 0) | ||||
| 			continue; | ||||
|  | ||||
| 		pci_irq_no = PCI_IRQ_BASE + i; | ||||
|  | ||||
| 		BUG_ON(!(irq_desc[pci_irq_no].handle_irq)); | ||||
| 		irq_desc[pci_irq_no].handle_irq(&irq_desc[pci_irq_no]); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static struct irq_chip gemini_pci_irq_chip = { | ||||
| 	.name = "PCI", | ||||
| 	.irq_ack = gemini_pci_ack_irq, | ||||
| 	.irq_mask = gemini_pci_mask_irq, | ||||
| 	.irq_unmask = gemini_pci_unmask_irq, | ||||
| }; | ||||
|  | ||||
| static int __init gemini_pci_init(void) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 72; i <= 95; i++) | ||||
| 		gpio_request(i, "PCI"); | ||||
|  | ||||
| 	/* initialize our bogus bus */ | ||||
| 	dev_set_name(&bogus_pci_bus.dev, "PCI IRQ handler"); | ||||
| 	bogus_pci_bus.number = 0; | ||||
|  | ||||
| 	/* mask and clear all interrupts */ | ||||
| 	gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2 + 2, 2, | ||||
| 				0xF000); | ||||
|  | ||||
| 	for (i = PCI_IRQ_BASE; i < PCI_IRQ_BASE + 4; i++) { | ||||
| 		irq_set_chip_and_handler(i, &gemini_pci_irq_chip, | ||||
| 					 handle_level_irq); | ||||
| 	} | ||||
|  | ||||
| 	irq_set_chained_handler(IRQ_PCI, gemini_pci_irq_handler); | ||||
|  | ||||
| 	pci_common_init(&gemini_hw_pci); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| subsys_initcall(gemini_pci_init); | ||||
| @@ -1,234 +0,0 @@ | ||||
| /* | ||||
|  *  Support for Gemini PATA | ||||
|  * | ||||
|  *  Copyright (C) 2009 Janos Laube <janos.dev@gmail.com> | ||||
|  *  Copyright (C) 2010 Frederic Pecourt <opengemini@free.fr> | ||||
|  *  Copyright (C) 2011 Tobias Waldvogel <tobias.waldvogel@gmail.com> | ||||
|  * | ||||
|  * 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., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  */ | ||||
|  | ||||
| /* Values of IOMUX | ||||
|  * 26:24 bits is "IDE IO Select" | ||||
|  * 111:100 - Reserved | ||||
|  * 011 - ata0 <-> sata0, sata1; bring out ata1 | ||||
|  * 010 - ata1 <-> sata1, sata0; bring out ata0 | ||||
|  * 001 - ata0 <-> sata0, ata1 <-> sata1; bring out ata1 | ||||
|  * 000 - ata0 <-> sata0, ata1 <-> sata1; bring out ata0 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/moduleparam.h> | ||||
| #include <linux/libata.h> | ||||
| #include <linux/leds.h> | ||||
|  | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/global_reg.h> | ||||
|  | ||||
| #define DRV_NAME		"pata-gemini" | ||||
|  | ||||
| #define PATA_GEMINI_PORTS	1 | ||||
|  | ||||
| #define PIO_TIMING_REG		0x10 | ||||
| #define MDMA_TIMING_REG		0x11 | ||||
| #define UDMA_TIMING0_REG	0x12 | ||||
| #define UDMA_TIMING1_REG	0x13 | ||||
| #define CLK_MOD_REG		0x14 | ||||
|  | ||||
| #define CLK_MOD_66M_DEV0_BIT	0 | ||||
| #define CLK_MOD_66M_DEV1_BIT	1 | ||||
| #define CLK_MOD_UDMA_DEV0_BIT	4 | ||||
| #define CLK_MOD_UDMA_DEV1_BIT	5 | ||||
|  | ||||
| #define CLK_MOD_66M_DEV0	(1 << CLK_MOD_66M_DEV0_BIT) | ||||
| #define CLK_MOD_66M_DEV1	(1 << CLK_MOD_66M_DEV1_BIT) | ||||
| #define CLK_MOD_UDMA_DEV0	(1 << CLK_MOD_UDMA_DEV0_BIT) | ||||
| #define CLK_MOD_UDMA_DEV1	(1 << CLK_MOD_UDMA_DEV1_BIT) | ||||
|  | ||||
| #define SATA_ENABLE_PDEV_MASK		0x01 | ||||
| #define SATA_ENABLE_PDEV_PM		0x02 | ||||
| #define SATA_ENABLE_PDEV_ADDED		0x04 | ||||
| #define SATA_ENABLE_PDEV_REMOVED	0x08 | ||||
| #define SATA_ENABLE_SDEV_MASK		0x10 | ||||
| #define SATA_ENABLE_SDEV_PM		0x20 | ||||
| #define SATA_ENABLE_SDEV_ADDED		0x40 | ||||
| #define SATA_ENABLE_SDEV_REMOVED	0x80 | ||||
|  | ||||
| MODULE_AUTHOR("Janos Laube <janos.dev@gmail.com>"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_ALIAS("platform:" DRV_NAME); | ||||
|  | ||||
| static unsigned char PIO_TIMING[5] = { | ||||
| 	0xaa, 0xa3, 0xa1, 0x33, 0x31 | ||||
| }; | ||||
|  | ||||
| static unsigned char TIMING_MW_DMA[4][2] = { | ||||
| 	{ 0x44, 1 }, // 480        4.2 | ||||
| 	{ 0x42, 1 }, // 150       13.3 | ||||
| 	{ 0x31, 1 }, // 120       16.7 | ||||
| 	{ 0x21, 1 }, // 100       20 | ||||
| }; | ||||
|  | ||||
| static unsigned char TIMING_UDMA[7][2] = { | ||||
| 	{ 0x33, 0 }, //240        16.7 | ||||
| 	{ 0x31, 0 }, //160        25 | ||||
| 	{ 0x21, 0 }, //120        33.3 | ||||
| 	{ 0x21, 1 }, //90         44.4 | ||||
| 	{ 0x11, 1 }, //60         66.7 | ||||
| 	{ 0x11 | 0x80, 0 }, //40  100 | ||||
| 	{ 0x11 | 0x80, 1 }, //30  133 | ||||
| }; | ||||
|  | ||||
| static struct scsi_host_template pata_gemini_sht = { | ||||
| 	ATA_NCQ_SHT(DRV_NAME), | ||||
| 	.can_queue	= 1, | ||||
| 	.sg_tablesize	= 128, | ||||
| 	.dma_boundary	= 0xffffU, | ||||
| }; | ||||
|  | ||||
| static void gemini_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||||
| { | ||||
| 	void __iomem *clk_reg	= ap->ioaddr.bmdma_addr + CLK_MOD_REG; | ||||
| 	void __iomem *tim_reg	= ap->ioaddr.bmdma_addr + UDMA_TIMING0_REG; | ||||
| 	unsigned short udma	= adev->dma_mode; | ||||
| 	unsigned short speed	= udma; | ||||
| 	unsigned short devno	= adev->devno & 1; | ||||
| 	unsigned short i; | ||||
| 	u8 mod_udma_mask	= 1 << (CLK_MOD_UDMA_DEV0_BIT + devno); | ||||
| 	u8 mod_66m_mask		= 1 << (CLK_MOD_66M_DEV0_BIT + devno); | ||||
| 	u8 clk_mod; | ||||
| 	u8 timing; | ||||
|  | ||||
| 	clk_mod = ioread8(clk_reg); | ||||
| 	clk_mod &= ~mod_udma_mask; | ||||
|  | ||||
| 	if (speed & XFER_UDMA_0) { | ||||
| 		i = speed & ~XFER_UDMA_0; | ||||
| 		timing = TIMING_UDMA[i][0]; | ||||
| 		clk_mod |= mod_udma_mask; | ||||
| 		if (TIMING_UDMA[i][1]) | ||||
| 			clk_mod |= mod_66m_mask; | ||||
| 	} else { | ||||
| 		i = speed & ~XFER_MW_DMA_0; | ||||
| 		timing = TIMING_MW_DMA[i][0]; | ||||
| 		clk_mod |= mod_udma_mask; | ||||
| 		if (TIMING_MW_DMA[i][1]) | ||||
| 			clk_mod |= mod_66m_mask; | ||||
| 	} | ||||
|  | ||||
| 	iowrite8(clk_mod, clk_reg); | ||||
| 	iowrite8(timing, tim_reg + devno); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| static void gemini_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||||
| { | ||||
| 	void __iomem *pio_reg	= ap->ioaddr.bmdma_addr + PIO_TIMING_REG; | ||||
| 	unsigned int pio	= adev->pio_mode - XFER_PIO_0; | ||||
|  | ||||
| 	iowrite8(PIO_TIMING[pio], pio_reg); | ||||
| } | ||||
|  | ||||
| unsigned int gemini_qc_issue(struct ata_queued_cmd *qc) | ||||
| { | ||||
| 	ledtrig_ide_activity(); | ||||
| 	return ata_bmdma_qc_issue(qc); | ||||
| } | ||||
|  | ||||
| static struct ata_port_operations pata_gemini_port_ops = { | ||||
| 	.inherits	= &ata_bmdma_port_ops, | ||||
| 	.set_dmamode	= gemini_set_dmamode, | ||||
| 	.set_piomode	= gemini_set_piomode, | ||||
| 	.qc_issue	= gemini_qc_issue, | ||||
| }; | ||||
|  | ||||
| static struct ata_port_info pata_gemini_portinfo = { | ||||
| 	.flags		= 0, | ||||
| 	.udma_mask	= ATA_UDMA6, | ||||
| 	.pio_mask	= ATA_PIO4, | ||||
| 	.port_ops	= &pata_gemini_port_ops, | ||||
| }; | ||||
|  | ||||
| static const struct ata_port_info *pata_gemini_ports = &pata_gemini_portinfo; | ||||
|  | ||||
| static int pata_gemini_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct ata_host *host; | ||||
| 	struct resource *res; | ||||
| 	unsigned int irq, i; | ||||
| 	void __iomem *mmio_base; | ||||
|  | ||||
| 	/* standard bdma init */ | ||||
| 	irq = platform_get_irq(pdev, 0); | ||||
| 	if (irq < 0) | ||||
| 		return irq; | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	if (!res) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	pr_info(DRV_NAME ": irq %d, io base 0x%08x\n", irq, res->start); | ||||
|  | ||||
| 	mmio_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||||
|  | ||||
| 	host = ata_host_alloc_pinfo(&pdev->dev, &pata_gemini_ports, 1); | ||||
| 	if (!host) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	for (i = 0; i < host->n_ports; i++) { | ||||
| 		struct ata_port *ap = host->ports[i]; | ||||
| 		struct ata_ioports *ioaddr = &ap->ioaddr; | ||||
|  | ||||
| 		ioaddr->bmdma_addr		= mmio_base; | ||||
| 		ioaddr->cmd_addr		= mmio_base + 0x20; | ||||
| 		ioaddr->ctl_addr		= mmio_base + 0x36; | ||||
| 		ioaddr->altstatus_addr		= ioaddr->ctl_addr; | ||||
| 		ata_sff_std_ports(ioaddr); | ||||
| 		host->ports[i]->cbl = ATA_CBL_SATA; | ||||
| 	} | ||||
|  | ||||
| 	return ata_host_activate(host, irq, ata_bmdma_interrupt, | ||||
| 		IRQF_SHARED, &pata_gemini_sht); | ||||
| } | ||||
|  | ||||
| static int pata_gemini_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct device *dev = &pdev->dev; | ||||
| 	struct ata_host *host = dev_get_drvdata(dev); | ||||
| 	ata_host_detach(host); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct platform_driver pata_gemini_driver = { | ||||
| 	.probe		= pata_gemini_probe, | ||||
| 	.remove		= pata_gemini_remove, | ||||
| 	.driver.owner	= THIS_MODULE, | ||||
| 	.driver.name	= DRV_NAME, | ||||
| }; | ||||
|  | ||||
| static int __init pata_gemini_module_init(void) | ||||
| { | ||||
| 	return platform_driver_probe(&pata_gemini_driver, pata_gemini_probe); | ||||
| } | ||||
|  | ||||
| static void __exit pata_gemini_module_exit(void) | ||||
| { | ||||
| 	platform_driver_unregister(&pata_gemini_driver); | ||||
| } | ||||
|  | ||||
| module_init(pata_gemini_module_init); | ||||
| module_exit(pata_gemini_module_exit); | ||||
| @@ -1,31 +0,0 @@ | ||||
| # | ||||
| # Gemini device configuration | ||||
| # | ||||
|  | ||||
| config NET_VENDOR_GEMINI | ||||
| 	bool "Cortina Gemini devices" | ||||
| 	default y | ||||
| 	depends on ARCH_GEMINI | ||||
| 	---help--- | ||||
| 	  If you have a network (Ethernet) card belonging to this class, say Y | ||||
| 	  and read the Ethernet-HOWTO, available from | ||||
| 	  <http://www.tldp.org/docs.html#howto>. | ||||
|  | ||||
| 	  Note that the answer to this question doesn't directly affect the | ||||
| 	  kernel: saying N will just cause the configurator to skip all | ||||
| 	  the questions about D-Link devices. If you say Y, you will be asked for | ||||
| 	  your specific card in the following questions. | ||||
|  | ||||
| if NET_VENDOR_GEMINI | ||||
|  | ||||
| config GEMINI_SL351X | ||||
| 	tristate "StorLink SL351x Gigabit Ethernet support" | ||||
| 	depends on ARCH_GEMINI | ||||
| 	select PHYLIB | ||||
| 	select MDIO_BITBANG | ||||
| 	select MDIO_GPIO | ||||
| 	select CRC32 | ||||
| 	---help--- | ||||
| 	  This driver supports StorLink SL351x (Gemini) dual Gigabit Ethernet. | ||||
|  | ||||
| endif # NET_VENDOR_GEMINI | ||||
| @@ -1,5 +0,0 @@ | ||||
| # | ||||
| # Makefile for the Cortina Gemini network device drivers. | ||||
| # | ||||
|  | ||||
| obj-$(CONFIG_GEMINI_SL351X) += sl351x.o | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,258 +0,0 @@ | ||||
| /* | ||||
|  *  Gemini EHCI Host Controller driver | ||||
|  * | ||||
|  *  Copyright (C) 2014 Roman Yeryomin <roman@advem.lv> | ||||
|  *  Copyright (C) 2012 Tobias Waldvogel | ||||
|  *  based on GPLd code from Sony Computer Entertainment Inc. | ||||
|  * | ||||
|  *  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; version 2 of the License. | ||||
|  */ | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/hrtimer.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/usb.h> | ||||
| #include <linux/usb/hcd.h> | ||||
| #include <linux/usb/ehci_pdriver.h> | ||||
|  | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/global_reg.h> | ||||
|  | ||||
| #include "ehci.h" | ||||
|  | ||||
| #define DRV_NAME			"ehci-fotg2" | ||||
|  | ||||
| #define HCD_MISC			0x40 | ||||
|  | ||||
| #define OTGC_SCR			0x80 | ||||
| #define OTGC_INT_STS			0x84 | ||||
| #define OTGC_INT_EN			0x88 | ||||
|  | ||||
| #define GLOBAL_ISR			0xC0 | ||||
| #define GLOBAL_ICR			0xC4 | ||||
|  | ||||
| #define GLOBAL_INT_POLARITY		(1 << 3) | ||||
| #define GLOBAL_INT_MASK_HC		(1 << 2) | ||||
| #define GLOBAL_INT_MASK_OTG		(1 << 1) | ||||
| #define GLOBAL_INT_MASK_DEV		(1 << 0) | ||||
|  | ||||
| #define OTGC_SCR_ID			(1 << 21) | ||||
| #define OTGC_SCR_CROLE			(1 << 20) | ||||
| #define OTGC_SCR_VBUS_VLD		(1 << 19) | ||||
| #define OTGC_SCR_A_SRP_RESP_TYPE	(1 << 8) | ||||
| #define OTGC_SCR_A_SRP_DET_EN		(1 << 7) | ||||
| #define OTGC_SCR_A_SET_B_HNP_EN		(1 << 6) | ||||
| #define OTGC_SCR_A_BUS_DROP		(1 << 5) | ||||
| #define OTGC_SCR_A_BUS_REQ		(1 << 4) | ||||
|  | ||||
| #define OTGC_INT_APLGRMV		(1 << 12) | ||||
| #define OTGC_INT_BPLGRMV		(1 << 11) | ||||
| #define OTGC_INT_OVC			(1 << 10) | ||||
| #define OTGC_INT_IDCHG			(1 << 9) | ||||
| #define OTGC_INT_RLCHG			(1 << 8) | ||||
| #define OTGC_INT_AVBUSERR		(1 << 5) | ||||
| #define OTGC_INT_ASRPDET		(1 << 4) | ||||
| #define OTGC_INT_BSRPDN			(1 << 0) | ||||
|  | ||||
| #define OTGC_INT_A_TYPE	(		\ | ||||
|  		OTGC_INT_ASRPDET |	\ | ||||
| 		OTGC_INT_AVBUSERR |	\ | ||||
| 		OTGC_INT_OVC |		\ | ||||
| 		OTGC_INT_RLCHG |	\ | ||||
| 		OTGC_INT_IDCHG |	\ | ||||
| 		OTGC_INT_APLGRMV	\ | ||||
| 	) | ||||
| #define OTGC_INT_B_TYPE	(		\ | ||||
| 		OTGC_INT_AVBUSERR |	\ | ||||
| 		OTGC_INT_OVC |		\ | ||||
| 		OTGC_INT_RLCHG |	\ | ||||
| 		OTGC_INT_IDCHG		\ | ||||
| 	) | ||||
|  | ||||
|  | ||||
| static void fotg2_otg_init(struct usb_hcd *hcd) | ||||
| { | ||||
| 	u32 val; | ||||
|  | ||||
| 	writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | | ||||
| 	       GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, | ||||
| 		hcd->regs + GLOBAL_ICR); | ||||
|  | ||||
| 	val = readl(hcd->regs + OTGC_SCR); | ||||
| 	val &= ~(OTGC_SCR_A_SRP_RESP_TYPE | OTGC_SCR_A_SRP_DET_EN | | ||||
| 		 OTGC_SCR_A_BUS_DROP      | OTGC_SCR_A_SET_B_HNP_EN); | ||||
| 	val |= OTGC_SCR_A_BUS_REQ; | ||||
| 	writel(val, hcd->regs + OTGC_SCR); | ||||
|  | ||||
| 	writel(OTGC_INT_A_TYPE, hcd->regs + OTGC_INT_EN); | ||||
|  | ||||
| 	/* setup MISC register, fixes timing problems */ | ||||
| 	val = readl(hcd->regs + HCD_MISC); | ||||
| 	val |= 0xD; | ||||
| 	writel(val, hcd->regs + HCD_MISC); | ||||
|  | ||||
| 	writel(~0, hcd->regs + GLOBAL_ISR); | ||||
| 	writel(~0, hcd->regs + OTGC_INT_STS); | ||||
| } | ||||
|  | ||||
| static int fotg2_ehci_reset(struct usb_hcd *hcd) | ||||
| { | ||||
| 	int retval; | ||||
|  | ||||
| 	retval = ehci_setup(hcd); | ||||
| 	if (retval) | ||||
| 		return retval; | ||||
|  | ||||
| 	writel(GLOBAL_INT_POLARITY, hcd->regs + GLOBAL_ICR); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct hc_driver fotg2_ehci_hc_driver = { | ||||
| 	.description		= hcd_name, | ||||
| 	.product_desc		= "FOTG2 EHCI Host Controller", | ||||
| 	.hcd_priv_size		= sizeof(struct ehci_hcd), | ||||
| 	.irq			= ehci_irq, | ||||
| 	.flags			= HCD_MEMORY | HCD_USB2, | ||||
| 	.reset			= fotg2_ehci_reset, | ||||
| 	.start			= ehci_run, | ||||
| 	.stop			= ehci_stop, | ||||
| 	.shutdown		= ehci_shutdown, | ||||
| 	.urb_enqueue		= ehci_urb_enqueue, | ||||
| 	.urb_dequeue		= ehci_urb_dequeue, | ||||
| 	.endpoint_disable	= ehci_endpoint_disable, | ||||
| 	.endpoint_reset		= ehci_endpoint_reset, | ||||
| 	.get_frame_number	= ehci_get_frame, | ||||
| 	.hub_status_data	= ehci_hub_status_data, | ||||
| 	.hub_control		= ehci_hub_control, | ||||
| #if defined(CONFIG_PM) | ||||
| 	.bus_suspend		= ehci_bus_suspend, | ||||
| 	.bus_resume		= ehci_bus_resume, | ||||
| #endif | ||||
| 	.relinquish_port	= ehci_relinquish_port, | ||||
| 	.port_handed_over	= ehci_port_handed_over, | ||||
|  | ||||
| 	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||||
| }; | ||||
|  | ||||
| static irqreturn_t fotg2_ehci_irq(int irq, void *data) | ||||
| { | ||||
| 	struct usb_hcd *hcd = data; | ||||
| 	u32 icr, sts; | ||||
| 	irqreturn_t retval; | ||||
|  | ||||
| 	icr = readl(hcd->regs + GLOBAL_ICR); | ||||
| 	writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | | ||||
| 	       GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, | ||||
| 		hcd->regs + GLOBAL_ICR); | ||||
|  | ||||
| 	retval = IRQ_NONE; | ||||
|  | ||||
| 	sts = ~icr; | ||||
| 	sts &= GLOBAL_INT_MASK_HC | GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV; | ||||
| 	sts &= readl(hcd->regs + GLOBAL_ISR); | ||||
| 	writel(sts, hcd->regs + GLOBAL_ISR); | ||||
|  | ||||
| 	if (unlikely(sts & GLOBAL_INT_MASK_DEV)) { | ||||
| 		ehci_warn(hcd_to_ehci(hcd), | ||||
| 			"Received unexpected irq for device role\n"); | ||||
| 		retval = IRQ_HANDLED; | ||||
| 	} | ||||
|  | ||||
| 	if (unlikely(sts & GLOBAL_INT_MASK_OTG)) { | ||||
| 		u32	otg_sts; | ||||
|  | ||||
| 		otg_sts = readl(hcd->regs + OTGC_INT_STS); | ||||
| 		writel(otg_sts, hcd->regs + OTGC_INT_STS); | ||||
|  | ||||
| 		ehci_warn(hcd_to_ehci(hcd), | ||||
| 			"Received unexpected irq for OTG management\n"); | ||||
| 		retval = IRQ_HANDLED; | ||||
| 	} | ||||
|  | ||||
| 	if (sts & GLOBAL_INT_MASK_HC) { | ||||
| 		retval = IRQ_NONE; | ||||
| 	} | ||||
|  | ||||
| 	writel(icr, hcd->regs + GLOBAL_ICR); | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| static int fotg2_ehci_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct usb_hcd *hcd; | ||||
| 	struct resource *res; | ||||
| 	int irq , err; | ||||
|  | ||||
| 	irq = platform_get_irq(pdev, 0); | ||||
| 	if (irq < 0) { | ||||
| 		pr_err("no irq provided"); | ||||
| 		return irq; | ||||
| 	} | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	if (!res) { | ||||
| 		pr_err("no memory resource provided"); | ||||
| 		return -ENXIO; | ||||
| 	} | ||||
|  | ||||
| 	hcd = usb_create_hcd(&fotg2_ehci_hc_driver, &pdev->dev, | ||||
| 			     dev_name(&pdev->dev)); | ||||
| 	if (!hcd) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	hcd->rsrc_start = res->start; | ||||
| 	hcd->rsrc_len = resource_size(res); | ||||
|  | ||||
| 	hcd->regs = devm_ioremap_resource(&pdev->dev, res); | ||||
| 	if (IS_ERR(hcd->regs)) { | ||||
| 		err = -ENOMEM; | ||||
| 		goto err_put_hcd; | ||||
| 	} | ||||
|  | ||||
| 	hcd->has_tt = 1; | ||||
| 	hcd_to_ehci(hcd)->caps = hcd->regs; | ||||
|  | ||||
| 	fotg2_otg_init(hcd); | ||||
|  | ||||
| 	err = request_irq(irq, &fotg2_ehci_irq, IRQF_SHARED, "fotg2", hcd); | ||||
| 	if (err) | ||||
| 		goto err_put_hcd; | ||||
|  | ||||
| 	err = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||||
| 	if (err) | ||||
| 		goto err_put_hcd; | ||||
|  | ||||
| 	platform_set_drvdata(pdev, hcd); | ||||
| 	return 0; | ||||
|  | ||||
| err_put_hcd: | ||||
| 	usb_put_hcd(hcd); | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| static int fotg2_ehci_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | | ||||
| 	       GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, | ||||
| 		hcd->regs + GLOBAL_ICR); | ||||
|  | ||||
| 	free_irq(hcd->irq, hcd); | ||||
| 	usb_remove_hcd(hcd); | ||||
| 	usb_put_hcd(hcd); | ||||
| 	platform_set_drvdata(pdev, NULL); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| MODULE_ALIAS("platform:" DRV_NAME); | ||||
|  | ||||
| static struct platform_driver ehci_fotg2_driver = { | ||||
| 	.probe		= fotg2_ehci_probe, | ||||
| 	.remove		= fotg2_ehci_remove, | ||||
| 	.driver.name	= DRV_NAME, | ||||
| }; | ||||
| @@ -1,378 +0,0 @@ | ||||
| /* | ||||
|  *  Watchdog driver for Cortina Systems Gemini SoC | ||||
|  * | ||||
|  *  Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||||
|  * | ||||
|  * 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/kernel.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/fs.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <linux/miscdevice.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/watchdog.h> | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #define GEMINI_WDCOUNTER	0x0 | ||||
| #define GEMINI_WDLOAD		0x4 | ||||
| #define GEMINI_WDRESTART	0x8 | ||||
|  | ||||
| #define WDRESTART_MAGIC		0x5AB9 | ||||
|  | ||||
| #define GEMINI_WDCR		0xC | ||||
|  | ||||
| #define WDCR_CLOCK_5MHZ		(1 << 4) | ||||
| #define WDCR_SYS_RST		(1 << 1) | ||||
| #define WDCR_ENABLE		(1 << 0) | ||||
|  | ||||
| #define WDT_CLOCK		5000000		/* 5 MHz */ | ||||
| #define WDT_DEFAULT_TIMEOUT	13 | ||||
| #define WDT_MAX_TIMEOUT		(0xFFFFFFFF / WDT_CLOCK) | ||||
|  | ||||
| /* status bits */ | ||||
| #define WDT_ACTIVE		0 | ||||
| #define WDT_OK_TO_CLOSE		1 | ||||
|  | ||||
| static unsigned int timeout = WDT_DEFAULT_TIMEOUT; | ||||
| static int nowayout = WATCHDOG_NOWAYOUT; | ||||
|  | ||||
| static DEFINE_SPINLOCK(gemini_wdt_lock); | ||||
|  | ||||
| static struct platform_device *gemini_wdt_dev; | ||||
|  | ||||
| struct gemini_wdt_struct { | ||||
| 	struct resource		*res; | ||||
| 	struct device		*dev; | ||||
| 	void __iomem		*base; | ||||
| 	unsigned long		status; | ||||
| }; | ||||
|  | ||||
| static struct watchdog_info gemini_wdt_info = { | ||||
| 	.identity	= "Gemini watchdog", | ||||
| 	.options	= WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | | ||||
| 			  WDIOF_SETTIMEOUT, | ||||
| }; | ||||
|  | ||||
| /* Disable the watchdog. */ | ||||
| static void gemini_wdt_stop(struct gemini_wdt_struct *gemini_wdt) | ||||
| { | ||||
| 	spin_lock(&gemini_wdt_lock); | ||||
|  | ||||
| 	__raw_writel(0, gemini_wdt->base + GEMINI_WDCR); | ||||
|  | ||||
| 	clear_bit(WDT_ACTIVE, &gemini_wdt->status); | ||||
|  | ||||
| 	spin_unlock(&gemini_wdt_lock); | ||||
| } | ||||
|  | ||||
| /* Service the watchdog */ | ||||
| static void gemini_wdt_service(struct gemini_wdt_struct *gemini_wdt) | ||||
| { | ||||
| 	__raw_writel(WDRESTART_MAGIC, gemini_wdt->base + GEMINI_WDRESTART); | ||||
| } | ||||
|  | ||||
| /* Enable and reset the watchdog. */ | ||||
| static void gemini_wdt_start(struct gemini_wdt_struct *gemini_wdt) | ||||
| { | ||||
| 	spin_lock(&gemini_wdt_lock); | ||||
|  | ||||
| 	__raw_writel(timeout * WDT_CLOCK, gemini_wdt->base + GEMINI_WDLOAD); | ||||
|  | ||||
| 	gemini_wdt_service(gemini_wdt); | ||||
|  | ||||
| 	/* set clock before enabling */ | ||||
| 	__raw_writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST, | ||||
| 			gemini_wdt->base + GEMINI_WDCR); | ||||
|  | ||||
| 	__raw_writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE, | ||||
| 			gemini_wdt->base + GEMINI_WDCR); | ||||
|  | ||||
| 	set_bit(WDT_ACTIVE, &gemini_wdt->status); | ||||
|  | ||||
| 	spin_unlock(&gemini_wdt_lock); | ||||
| } | ||||
|  | ||||
| /* Watchdog device is opened, and watchdog starts running. */ | ||||
| static int gemini_wdt_open(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(gemini_wdt_dev); | ||||
|  | ||||
| 	if (test_bit(WDT_ACTIVE, &gemini_wdt->status)) | ||||
| 		return -EBUSY; | ||||
|  | ||||
| 	file->private_data = gemini_wdt; | ||||
|  | ||||
| 	gemini_wdt_start(gemini_wdt); | ||||
|  | ||||
| 	return nonseekable_open(inode, file); | ||||
| } | ||||
|  | ||||
| /* Close the watchdog device. */ | ||||
| static int gemini_wdt_close(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = file->private_data; | ||||
|  | ||||
| 	/* Disable the watchdog if possible */ | ||||
| 	if (test_bit(WDT_OK_TO_CLOSE, &gemini_wdt->status)) | ||||
| 		gemini_wdt_stop(gemini_wdt); | ||||
| 	else | ||||
| 		dev_warn(gemini_wdt->dev, "Device closed unexpectedly - timer will not stop\n"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* Handle commands from user-space. */ | ||||
| static long gemini_wdt_ioctl(struct file *file, unsigned int cmd, | ||||
| 			     unsigned long arg) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = file->private_data; | ||||
|  | ||||
| 	int value; | ||||
|  | ||||
| 	switch (cmd) { | ||||
| 	case WDIOC_KEEPALIVE: | ||||
| 		gemini_wdt_service(gemini_wdt); | ||||
| 		return 0; | ||||
|  | ||||
| 	case WDIOC_GETSUPPORT: | ||||
| 		return copy_to_user((struct watchdog_info *)arg, &gemini_wdt_info, | ||||
| 			sizeof(gemini_wdt_info)) ? -EFAULT : 0; | ||||
|  | ||||
| 	case WDIOC_SETTIMEOUT: | ||||
| 		if (get_user(value, (int *)arg)) | ||||
| 			return -EFAULT; | ||||
|  | ||||
| 		if ((value < 1) || (value > WDT_MAX_TIMEOUT)) | ||||
| 			return -EINVAL; | ||||
|  | ||||
| 		timeout = value; | ||||
|  | ||||
| 		/* restart wdt to use new timeout */ | ||||
| 		gemini_wdt_stop(gemini_wdt); | ||||
| 		gemini_wdt_start(gemini_wdt); | ||||
|  | ||||
| 		/* Fall through */ | ||||
| 	case WDIOC_GETTIMEOUT: | ||||
| 		return put_user(timeout, (int *)arg); | ||||
|  | ||||
| 	case WDIOC_GETTIMELEFT: | ||||
| 		value = __raw_readl(gemini_wdt->base + GEMINI_WDCOUNTER); | ||||
| 		return put_user(value / WDT_CLOCK, (int *)arg); | ||||
|  | ||||
| 	default: | ||||
| 		return -ENOTTY; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Refresh the watchdog whenever device is written to. */ | ||||
| static ssize_t gemini_wdt_write(struct file *file, const char *data, | ||||
| 						size_t len, loff_t *ppos) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = file->private_data; | ||||
|  | ||||
| 	if (len) { | ||||
| 		if (!nowayout) { | ||||
| 			size_t i; | ||||
|  | ||||
| 			clear_bit(WDT_OK_TO_CLOSE, &gemini_wdt->status); | ||||
| 			for (i = 0; i != len; i++) { | ||||
| 				char c; | ||||
|  | ||||
| 				if (get_user(c, data + i)) | ||||
| 					return -EFAULT; | ||||
| 				if (c == 'V') | ||||
| 					set_bit(WDT_OK_TO_CLOSE, | ||||
| 						&gemini_wdt->status); | ||||
| 			} | ||||
| 		} | ||||
| 		gemini_wdt_service(gemini_wdt); | ||||
| 	} | ||||
|  | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| static const struct file_operations gemini_wdt_fops = { | ||||
| 	.owner		= THIS_MODULE, | ||||
| 	.llseek		= no_llseek, | ||||
| 	.unlocked_ioctl = gemini_wdt_ioctl, | ||||
| 	.open		= gemini_wdt_open, | ||||
| 	.release	= gemini_wdt_close, | ||||
| 	.write		= gemini_wdt_write, | ||||
| }; | ||||
|  | ||||
| static struct miscdevice gemini_wdt_miscdev = { | ||||
| 	.minor		= WATCHDOG_MINOR, | ||||
| 	.name		= "watchdog", | ||||
| 	.fops		= &gemini_wdt_fops, | ||||
| }; | ||||
|  | ||||
| static void gemini_wdt_shutdown(struct platform_device *pdev) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	gemini_wdt_stop(gemini_wdt); | ||||
| } | ||||
|  | ||||
| static int gemini_wdt_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	int ret; | ||||
| 	int res_size; | ||||
| 	struct resource *res; | ||||
| 	void __iomem *base; | ||||
| 	struct gemini_wdt_struct *gemini_wdt; | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	if (!res) { | ||||
| 		dev_err(&pdev->dev, "can't get device resources\n"); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
|  | ||||
| 	res_size = resource_size(res); | ||||
| 	if (!request_mem_region(res->start, res_size, res->name)) { | ||||
| 		dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", | ||||
| 			res_size, res->start); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | ||||
| 	base = ioremap(res->start, res_size); | ||||
| 	if (!base) { | ||||
| 		dev_err(&pdev->dev, "ioremap failed\n"); | ||||
| 		ret = -EIO; | ||||
| 		goto fail0; | ||||
| 	} | ||||
|  | ||||
| 	gemini_wdt = kzalloc(sizeof(struct gemini_wdt_struct), GFP_KERNEL); | ||||
| 	if (!gemini_wdt) { | ||||
| 		dev_err(&pdev->dev, "can't allocate interface\n"); | ||||
| 		ret = -ENOMEM; | ||||
| 		goto fail1; | ||||
| 	} | ||||
|  | ||||
| 	/* Setup gemini_wdt driver structure */ | ||||
| 	gemini_wdt->base = base; | ||||
| 	gemini_wdt->res = res; | ||||
|  | ||||
| 	/* Set up platform driver data */ | ||||
| 	platform_set_drvdata(pdev, gemini_wdt); | ||||
| 	gemini_wdt_dev = pdev; | ||||
|  | ||||
| 	if (gemini_wdt_miscdev.parent) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto fail2; | ||||
| 	} | ||||
|  | ||||
| 	gemini_wdt_miscdev.parent = &pdev->dev; | ||||
|  | ||||
| 	reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); | ||||
| 	if (reg & WDCR_ENABLE) { | ||||
| 		/* Watchdog was enabled by the bootloader, disable it. */ | ||||
| 		reg &= ~(WDCR_ENABLE); | ||||
| 		__raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); | ||||
| 	} | ||||
|  | ||||
| 	ret = misc_register(&gemini_wdt_miscdev); | ||||
| 	if (ret) | ||||
| 		goto fail2; | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| fail2: | ||||
| 	platform_set_drvdata(pdev, NULL); | ||||
| 	kfree(gemini_wdt); | ||||
| fail1: | ||||
| 	iounmap(base); | ||||
| fail0: | ||||
| 	release_mem_region(res->start, res_size); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int gemini_wdt_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	platform_set_drvdata(pdev, NULL); | ||||
| 	misc_deregister(&gemini_wdt_miscdev); | ||||
| 	gemini_wdt_dev = NULL; | ||||
| 	iounmap(gemini_wdt->base); | ||||
| 	release_mem_region(gemini_wdt->res->start, resource_size(gemini_wdt->res)); | ||||
|  | ||||
| 	kfree(gemini_wdt); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_PM | ||||
| static int gemini_wdt_suspend(struct platform_device *pdev, pm_message_t message) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); | ||||
| 	reg &= ~(WDCR_WDENABLE); | ||||
| 	__raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int gemini_wdt_resume(struct platform_device *pdev) | ||||
| { | ||||
| 	struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); | ||||
| 	unsigned int reg; | ||||
|  | ||||
| 	if (gemini_wdt->status) { | ||||
| 		reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); | ||||
| 		reg |= WDCR_WDENABLE; | ||||
| 		__raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| #else | ||||
| #define gemini_wdt_suspend	NULL | ||||
| #define gemini_wdt_resume	NULL | ||||
| #endif | ||||
|  | ||||
| static struct platform_driver gemini_wdt_driver = { | ||||
| 	.probe		= gemini_wdt_probe, | ||||
| 	.remove		= gemini_wdt_remove, | ||||
| 	.shutdown	= gemini_wdt_shutdown, | ||||
| 	.suspend	= gemini_wdt_suspend, | ||||
| 	.resume		= gemini_wdt_resume, | ||||
| 	.driver		= { | ||||
| 		.name	= "gemini-wdt", | ||||
| 		.owner	= THIS_MODULE, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static int __init gemini_wdt_init(void) | ||||
| { | ||||
| 	return platform_driver_probe(&gemini_wdt_driver, gemini_wdt_probe); | ||||
| } | ||||
|  | ||||
| static void __exit gemini_wdt_exit(void) | ||||
| { | ||||
| 	platform_driver_unregister(&gemini_wdt_driver); | ||||
| } | ||||
|  | ||||
| module_init(gemini_wdt_init); | ||||
| module_exit(gemini_wdt_exit); | ||||
|  | ||||
| module_param(timeout, uint, 0); | ||||
| MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); | ||||
|  | ||||
| module_param(nowayout, int, 0); | ||||
| MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | ||||
|  | ||||
| MODULE_AUTHOR("Paulius Zaleckas"); | ||||
| MODULE_DESCRIPTION("Watchdog driver for Gemini"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||||
| MODULE_ALIAS("platform:gemini-wdt"); | ||||
| @@ -1,21 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/gpio.c | ||||
| +++ b/arch/arm/mach-gemini/gpio.c | ||||
| @@ -196,12 +196,18 @@ static int gemini_gpio_direction_output( | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +static int gemini_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | ||||
| +{ | ||||
| +	return gpio + GPIO_IRQ_BASE; | ||||
| +} | ||||
| + | ||||
|  static struct gpio_chip gemini_gpio_chip = { | ||||
|  	.label			= "Gemini", | ||||
|  	.direction_input	= gemini_gpio_direction_input, | ||||
|  	.get			= gemini_gpio_get, | ||||
|  	.direction_output	= gemini_gpio_direction_output, | ||||
|  	.set			= gemini_gpio_set, | ||||
| +	.to_irq			= gemini_gpio_to_irq, | ||||
|  	.base			= 0, | ||||
|  	.ngpio			= GPIO_PORT_NUM * 32, | ||||
|  }; | ||||
| @@ -1,41 +0,0 @@ | ||||
| --- a/arch/arm/mm/cache-fa.S | ||||
| +++ b/arch/arm/mm/cache-fa.S | ||||
| @@ -24,7 +24,8 @@ | ||||
|  /* | ||||
|   * The size of one data cache line. | ||||
|   */ | ||||
| -#define CACHE_DLINESIZE	16 | ||||
| +#define CACHE_DLINESIZE		16 | ||||
| +#define CACHE_DLINESHIFT	4 | ||||
|   | ||||
|  /* | ||||
|   * The total size of the data cache. | ||||
| @@ -169,7 +170,17 @@ ENTRY(fa_flush_kern_dcache_area) | ||||
|   *	- start  - virtual start address | ||||
|   *	- end	 - virtual end address | ||||
|   */ | ||||
| +__flush_whole_dcache: | ||||
| +	mcr	p15, 0, r0, c7, c14, 0		@ clean/invalidate D cache | ||||
| +	mov	r0, #0 | ||||
| +	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer | ||||
| +	mov	pc, lr | ||||
| + | ||||
|  fa_dma_inv_range: | ||||
| +	sub	r3, r1, r0			@ calculate total size | ||||
| +	cmp	r3, #CACHE_DLIMIT		@ total size >= limit? | ||||
| +	bhs	__flush_whole_dcache		@ flush whole D cache | ||||
| + | ||||
|  	tst	r0, #CACHE_DLINESIZE - 1 | ||||
|  	bic	r0, r0, #CACHE_DLINESIZE - 1 | ||||
|  	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry | ||||
| @@ -193,6 +204,10 @@ fa_dma_inv_range: | ||||
|   *	- end	 - virtual end address | ||||
|   */ | ||||
|  fa_dma_clean_range: | ||||
| +	sub	r3, r1, r0			@ calculate total size | ||||
| +	cmp	r3, #CACHE_DLIMIT		@ total size >= limit? | ||||
| +	bhs	__flush_whole_dcache		@ flush whole D cache | ||||
| + | ||||
|  	bic	r0, r0, #CACHE_DLINESIZE - 1 | ||||
|  1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry | ||||
|  	add	r0, r0, #CACHE_DLINESIZE | ||||
| @@ -1,29 +0,0 @@ | ||||
| --- a/drivers/watchdog/Kconfig | ||||
| +++ b/drivers/watchdog/Kconfig | ||||
| @@ -229,6 +229,16 @@ config 977_WATCHDOG | ||||
|   | ||||
|  	  Not sure? It's safe to say N. | ||||
|   | ||||
| +config GEMINI_WATCHDOG | ||||
| +	tristate "Gemini watchdog" | ||||
| +	depends on ARCH_GEMINI | ||||
| +	help | ||||
| +	  Say Y here if to include support for the watchdog timer | ||||
| +	  embedded in the Cortina Systems Gemini family of devices. | ||||
| + | ||||
| +	  To compile this driver as a module, choose M here: the | ||||
| +	  module will be called gemini_wdt. | ||||
| + | ||||
|  config IXP4XX_WATCHDOG | ||||
|  	tristate "IXP4xx Watchdog" | ||||
|  	depends on ARCH_IXP4XX | ||||
| --- a/drivers/watchdog/Makefile | ||||
| +++ b/drivers/watchdog/Makefile | ||||
| @@ -37,6 +37,7 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt. | ||||
|  obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o | ||||
|  obj-$(CONFIG_21285_WATCHDOG) += wdt285.o | ||||
|  obj-$(CONFIG_977_WATCHDOG) += wdt977.o | ||||
| +obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o | ||||
|  obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o | ||||
|  obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o | ||||
|  obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o | ||||
| @@ -1,33 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/devices.c | ||||
| +++ b/arch/arm/mach-gemini/devices.c | ||||
| @@ -116,3 +116,20 @@ int __init platform_register_rtc(void) | ||||
|  	return platform_device_register(&gemini_rtc_device); | ||||
|  } | ||||
|   | ||||
| +static struct resource wdt_resource = { | ||||
| +	.start	= GEMINI_WAQTCHDOG_BASE, | ||||
| +	.end	= GEMINI_WAQTCHDOG_BASE + 0x18, | ||||
| +	.flags  = IORESOURCE_MEM, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device wdt_device = { | ||||
| +	.name		= "gemini-wdt", | ||||
| +	.id		= 0, | ||||
| +	.resource	= &wdt_resource, | ||||
| +	.num_resources	= 1, | ||||
| +}; | ||||
| + | ||||
| +int __init platform_register_watchdog(void) | ||||
| +{ | ||||
| +	return platform_device_register(&wdt_device); | ||||
| +} | ||||
| --- a/arch/arm/mach-gemini/common.h | ||||
| +++ b/arch/arm/mach-gemini/common.h | ||||
| @@ -27,6 +27,7 @@ extern int platform_register_uart(void); | ||||
|  extern int platform_register_pflash(unsigned int size, | ||||
|  				    struct mtd_partition *parts, | ||||
|  				    unsigned int nr_parts); | ||||
| +extern int platform_register_watchdog(void); | ||||
|   | ||||
|  extern void gemini_restart(enum reboot_mode mode, const char *cmd); | ||||
|   | ||||
| @@ -1,40 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/board-nas4220b.c | ||||
| +++ b/arch/arm/mach-gemini/board-nas4220b.c | ||||
| @@ -94,6 +94,7 @@ static void __init ib4220b_init(void) | ||||
|  	platform_device_register(&ib4220b_led_device); | ||||
|  	platform_device_register(&ib4220b_key_device); | ||||
|  	platform_register_rtc(); | ||||
| +	platform_register_watchdog(); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") | ||||
| --- a/arch/arm/mach-gemini/board-wbd111.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd111.c | ||||
| @@ -121,6 +121,7 @@ static void __init wbd111_init(void) | ||||
|  	platform_device_register(&wbd111_leds_device); | ||||
|  	platform_device_register(&wbd111_keys_device); | ||||
|  	platform_register_rtc(); | ||||
| +	platform_register_watchdog(); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD111, "Wiliboard WBD-111") | ||||
| --- a/arch/arm/mach-gemini/board-wbd222.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd222.c | ||||
| @@ -121,6 +121,7 @@ static void __init wbd222_init(void) | ||||
|  	platform_device_register(&wbd222_leds_device); | ||||
|  	platform_device_register(&wbd222_keys_device); | ||||
|  	platform_register_rtc(); | ||||
| +	platform_register_watchdog(); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD222, "Wiliboard WBD-222") | ||||
| --- a/arch/arm/mach-gemini/board-rut1xx.c | ||||
| +++ b/arch/arm/mach-gemini/board-rut1xx.c | ||||
| @@ -80,6 +80,7 @@ static void __init rut1xx_init(void) | ||||
|  	platform_device_register(&rut1xx_leds); | ||||
|  	platform_device_register(&rut1xx_keys_device); | ||||
|  	platform_register_rtc(); | ||||
| +	platform_register_watchdog(); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(RUT100, "Teltonika RUT100") | ||||
| @@ -1,20 +0,0 @@ | ||||
| --- a/drivers/net/ethernet/Kconfig | ||||
| +++ b/drivers/net/ethernet/Kconfig | ||||
| @@ -73,6 +73,7 @@ source "drivers/net/ethernet/neterion/Kc | ||||
|  source "drivers/net/ethernet/faraday/Kconfig" | ||||
|  source "drivers/net/ethernet/freescale/Kconfig" | ||||
|  source "drivers/net/ethernet/fujitsu/Kconfig" | ||||
| +source "drivers/net/ethernet/gemini/Kconfig" | ||||
|  source "drivers/net/ethernet/hisilicon/Kconfig" | ||||
|  source "drivers/net/ethernet/hp/Kconfig" | ||||
|  source "drivers/net/ethernet/ibm/Kconfig" | ||||
| --- a/drivers/net/ethernet/Makefile | ||||
| +++ b/drivers/net/ethernet/Makefile | ||||
| @@ -36,6 +36,7 @@ obj-$(CONFIG_NET_VENDOR_EXAR) += neterio | ||||
|  obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/ | ||||
|  obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ | ||||
|  obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ | ||||
| +obj-$(CONFIG_NET_VENDOR_GEMINI) += gemini/ | ||||
|  obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ | ||||
|  obj-$(CONFIG_NET_VENDOR_HP) += hp/ | ||||
|  obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ | ||||
| @@ -1,85 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/common.h | ||||
| +++ b/arch/arm/mach-gemini/common.h | ||||
| @@ -15,6 +15,7 @@ | ||||
|  #include <linux/reboot.h> | ||||
|   | ||||
|  struct mtd_partition; | ||||
| +struct gemini_gmac_platform_data; | ||||
|   | ||||
|  extern void gemini_map_io(void); | ||||
|  extern void gemini_init_irq(void); | ||||
| @@ -28,6 +29,7 @@ extern int platform_register_pflash(unsi | ||||
|  				    struct mtd_partition *parts, | ||||
|  				    unsigned int nr_parts); | ||||
|  extern int platform_register_watchdog(void); | ||||
| +extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); | ||||
|   | ||||
|  extern void gemini_restart(enum reboot_mode mode, const char *cmd); | ||||
|   | ||||
| --- a/arch/arm/mach-gemini/devices.c | ||||
| +++ b/arch/arm/mach-gemini/devices.c | ||||
| @@ -17,6 +17,7 @@ | ||||
|  #include <mach/irqs.h> | ||||
|  #include <mach/hardware.h> | ||||
|  #include <mach/global_reg.h> | ||||
| +#include <mach/gmac.h> | ||||
|   | ||||
|  static struct plat_serial8250_port serial_platform_data[] = { | ||||
|  	{ | ||||
| @@ -133,3 +134,56 @@ int __init platform_register_watchdog(vo | ||||
|  { | ||||
|  	return platform_device_register(&wdt_device); | ||||
|  } | ||||
| + | ||||
| +static struct resource gmac_resources[] = { | ||||
| +	{ | ||||
| +		.start	= GEMINI_TOE_BASE, | ||||
| +		.end	= GEMINI_TOE_BASE + 0xffff, | ||||
| +		.flags	= IORESOURCE_MEM, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.start	= IRQ_GMAC0, | ||||
| +		.end	= IRQ_GMAC0, | ||||
| +		.flags	= IORESOURCE_IRQ, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.start	= IRQ_GMAC1, | ||||
| +		.end	= IRQ_GMAC1, | ||||
| +		.flags	= IORESOURCE_IRQ, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static u64 gmac_dmamask = 0xffffffffUL; | ||||
| + | ||||
| +static struct platform_device ethernet_device = { | ||||
| +	.name	= "gmac-gemini", | ||||
| +	.id	= 0, | ||||
| +	.dev	= { | ||||
| +		.dma_mask		= &gmac_dmamask, | ||||
| +		.coherent_dma_mask	= 0xffffffff, | ||||
| +	}, | ||||
| +	.num_resources	= ARRAY_SIZE(gmac_resources), | ||||
| +	.resource	= gmac_resources, | ||||
| +}; | ||||
| + | ||||
| +int platform_register_ethernet(struct gemini_gmac_platform_data *pdata) | ||||
| +{ | ||||
| +	unsigned int reg; | ||||
| + | ||||
| +	reg = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| + | ||||
| +	reg &= ~(GMAC_GMII | GMAC_1_ENABLE); | ||||
| + | ||||
| +	if (pdata->bus_id[1]) | ||||
| +		reg |= GMAC_1_ENABLE; | ||||
| +	else if (pdata->interface[0] == PHY_INTERFACE_MODE_GMII) | ||||
| +		reg |= GMAC_GMII; | ||||
| + | ||||
| +	writel(reg, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| + | ||||
| +	ethernet_device.dev.platform_data = pdata; | ||||
| + | ||||
| +	return platform_device_register(ðernet_device); | ||||
| +} | ||||
| @@ -1,227 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/board-nas4220b.c | ||||
| +++ b/arch/arm/mach-gemini/board-nas4220b.c | ||||
| @@ -19,6 +19,7 @@ | ||||
|  #include <linux/input.h> | ||||
|  #include <linux/gpio_keys.h> | ||||
|  #include <linux/io.h> | ||||
| +#include <linux/platform_data/mdio-gpio.h> | ||||
|   | ||||
|  #include <asm/setup.h> | ||||
|  #include <asm/mach-types.h> | ||||
| @@ -27,9 +28,27 @@ | ||||
|   | ||||
|  #include <mach/hardware.h> | ||||
|  #include <mach/global_reg.h> | ||||
| +#include <mach/gmac.h> | ||||
|   | ||||
|  #include "common.h" | ||||
|   | ||||
| +static struct mdio_gpio_platform_data ib4220b_mdio = { | ||||
| +	.mdc		= 22, | ||||
| +	.mdio		= 21, | ||||
| +	.phy_mask	= ~(1 << 1), | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device ib4220b_phy_device = { | ||||
| +	.name	= "mdio-gpio", | ||||
| +	.id	= 0, | ||||
| +	.dev	= { .platform_data = &ib4220b_mdio, }, | ||||
| +}; | ||||
| + | ||||
| +static struct gemini_gmac_platform_data ib4220b_gmac_data = { | ||||
| +	.bus_id[0]	= "gpio-0:01", | ||||
| +	.interface[0]	= PHY_INTERFACE_MODE_RGMII, | ||||
| +}; | ||||
| + | ||||
|  static struct gpio_led ib4220b_leds[] = { | ||||
|  	{ | ||||
|  		.name			= "nas4220b:orange:hdd", | ||||
| @@ -86,15 +105,47 @@ static struct platform_device ib4220b_ke | ||||
|  	}, | ||||
|  }; | ||||
|   | ||||
| +static void __init ib4220b_gmac_init(void) | ||||
| +{ | ||||
| +	unsigned int val; | ||||
| + | ||||
| +	val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_IO_DRIVING_CTRL)); | ||||
| +	val |= (0x3 << GMAC0_PADS_SHIFT) | (0x3 << GMAC1_PADS_SHIFT); | ||||
| +	writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_IO_DRIVING_CTRL)); | ||||
| + | ||||
| +	val = (0x0 << GMAC0_RXDV_SKEW_SHIFT) | (0xf << GMAC0_RXC_SKEW_SHIFT) | | ||||
| +		(0x7 << GMAC0_TXEN_SKEW_SHIFT) | (0xb << GMAC0_TXC_SKEW_SHIFT) | | ||||
| +		(0x0 << GMAC1_RXDV_SKEW_SHIFT) | (0xf << GMAC1_RXC_SKEW_SHIFT) | | ||||
| +		(0x7 << GMAC1_TXEN_SKEW_SHIFT) | (0xa << GMAC1_TXC_SKEW_SHIFT); | ||||
| +	writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_GMAC_CTRL_SKEW_CTRL)); | ||||
| + | ||||
| +	writel(0x77777777, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_GMAC0_DATA_SKEW_CTRL)); | ||||
| +	writel(0x77777777, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_GMAC1_DATA_SKEW_CTRL)); | ||||
| + | ||||
| +	val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_ARBITRATION1_CTRL)) & ~BURST_LENGTH_MASK; | ||||
| +	val |= (0x20 << BURST_LENGTH_SHIFT) | GMAC0_HIGH_PRIO | GMAC1_HIGH_PRIO; | ||||
| +	writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_ARBITRATION1_CTRL)); | ||||
| +} | ||||
| + | ||||
|  static void __init ib4220b_init(void) | ||||
|  { | ||||
|  	gemini_gpio_init(); | ||||
| +	ib4220b_gmac_init(); | ||||
|  	platform_register_uart(); | ||||
|  	platform_register_pflash(SZ_16M, NULL, 0); | ||||
|  	platform_device_register(&ib4220b_led_device); | ||||
|  	platform_device_register(&ib4220b_key_device); | ||||
|  	platform_register_rtc(); | ||||
|  	platform_register_watchdog(); | ||||
| +	platform_device_register(&ib4220b_phy_device); | ||||
| +	platform_register_ethernet(&ib4220b_gmac_data); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") | ||||
| --- a/arch/arm/mach-gemini/board-wbd111.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd111.c | ||||
| @@ -17,13 +17,34 @@ | ||||
|  #include <linux/gpio_keys.h> | ||||
|  #include <linux/mtd/mtd.h> | ||||
|  #include <linux/mtd/partitions.h> | ||||
| +#include <linux/platform_data/mdio-gpio.h> | ||||
|  #include <asm/mach-types.h> | ||||
|  #include <asm/mach/arch.h> | ||||
|  #include <asm/mach/time.h> | ||||
|   | ||||
| +#include <mach/gmac.h> | ||||
|   | ||||
|  #include "common.h" | ||||
|   | ||||
| +static struct mdio_gpio_platform_data wbd111_mdio = { | ||||
| +	.mdc		= 22, | ||||
| +	.mdio		= 21, | ||||
| +	.phy_mask	= ~(1 << 1), | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device wbd111_phy_device = { | ||||
| +	.name	= "mdio-gpio", | ||||
| +	.id	= 0, | ||||
| +	.dev	= { | ||||
| +		.platform_data = &wbd111_mdio, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static struct gemini_gmac_platform_data gmac_data = { | ||||
| +	.bus_id[0] = "gpio-0:01", | ||||
| +	.interface[0] = PHY_INTERFACE_MODE_MII, | ||||
| +}; | ||||
| + | ||||
|  static struct gpio_keys_button wbd111_keys[] = { | ||||
|  	{ | ||||
|  		.code		= KEY_SETUP, | ||||
| @@ -122,6 +143,8 @@ static void __init wbd111_init(void) | ||||
|  	platform_device_register(&wbd111_keys_device); | ||||
|  	platform_register_rtc(); | ||||
|  	platform_register_watchdog(); | ||||
| +	platform_device_register(&wbd111_phy_device); | ||||
| +	platform_register_ethernet(&gmac_data); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD111, "Wiliboard WBD-111") | ||||
| --- a/arch/arm/mach-gemini/board-wbd222.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd222.c | ||||
| @@ -17,13 +17,36 @@ | ||||
|  #include <linux/gpio_keys.h> | ||||
|  #include <linux/mtd/mtd.h> | ||||
|  #include <linux/mtd/partitions.h> | ||||
| +#include <linux/platform_data/mdio-gpio.h> | ||||
|  #include <asm/mach-types.h> | ||||
|  #include <asm/mach/arch.h> | ||||
|  #include <asm/mach/time.h> | ||||
|   | ||||
| +#include <mach/gmac.h> | ||||
|   | ||||
|  #include "common.h" | ||||
|   | ||||
| +static struct mdio_gpio_platform_data wbd222_mdio = { | ||||
| +	.mdc		= 22, | ||||
| +	.mdio		= 21, | ||||
| +	.phy_mask	= ~((1 << 1) | (1 << 3)), | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device wbd222_phy_device = { | ||||
| +	.name	= "mdio-gpio", | ||||
| +	.id	= 0, | ||||
| +	.dev	= { | ||||
| +		.platform_data = &wbd222_mdio, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static struct gemini_gmac_platform_data gmac_data = { | ||||
| +	.bus_id[0] = "gpio-0:01", | ||||
| +	.interface[0] = PHY_INTERFACE_MODE_MII, | ||||
| +	.bus_id[1] = "gpio-0:03", | ||||
| +        .interface[1] = PHY_INTERFACE_MODE_MII, | ||||
| +}; | ||||
| + | ||||
|  static struct gpio_keys_button wbd222_keys[] = { | ||||
|  	{ | ||||
|  		.code		= KEY_SETUP, | ||||
| @@ -122,6 +145,8 @@ static void __init wbd222_init(void) | ||||
|  	platform_device_register(&wbd222_keys_device); | ||||
|  	platform_register_rtc(); | ||||
|  	platform_register_watchdog(); | ||||
| +	platform_device_register(&wbd222_phy_device); | ||||
| +	platform_register_ethernet(&gmac_data); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD222, "Wiliboard WBD-222") | ||||
| --- a/arch/arm/mach-gemini/board-rut1xx.c | ||||
| +++ b/arch/arm/mach-gemini/board-rut1xx.c | ||||
| @@ -15,13 +15,35 @@ | ||||
|  #include <linux/input.h> | ||||
|  #include <linux/gpio_keys.h> | ||||
|  #include <linux/sizes.h> | ||||
| +#include <linux/platform_data/mdio-gpio.h> | ||||
|   | ||||
|  #include <asm/mach-types.h> | ||||
|  #include <asm/mach/arch.h> | ||||
|  #include <asm/mach/time.h> | ||||
|   | ||||
| +#include <mach/gmac.h> | ||||
| + | ||||
|  #include "common.h" | ||||
|   | ||||
| +static struct mdio_gpio_platform_data rut1xx_mdio = { | ||||
| +	.mdc		= 22, | ||||
| +	.mdio		= 21, | ||||
| +	.phy_mask	= ~(1 << 1), | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device rut1xx_phy_device = { | ||||
| +	.name	= "mdio-gpio", | ||||
| +	.id	= 0, | ||||
| +	.dev	= { | ||||
| +		.platform_data = &rut1xx_mdio, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static struct gemini_gmac_platform_data gmac_data = { | ||||
| +	.bus_id[0] = "gpio-0:01", | ||||
| +	.interface[0] = PHY_INTERFACE_MODE_MII, | ||||
| +}; | ||||
| + | ||||
|  static struct gpio_keys_button rut1xx_keys[] = { | ||||
|  	{ | ||||
|  		.code		= KEY_SETUP, | ||||
| @@ -81,6 +103,8 @@ static void __init rut1xx_init(void) | ||||
|  	platform_device_register(&rut1xx_keys_device); | ||||
|  	platform_register_rtc(); | ||||
|  	platform_register_watchdog(); | ||||
| +	platform_device_register(&rut1xx_phy_device); | ||||
| +	platform_register_ethernet(&gmac_data); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(RUT100, "Teltonika RUT100") | ||||
| @@ -1,133 +0,0 @@ | ||||
| --- a/drivers/usb/host/ehci-hcd.c | ||||
| +++ b/drivers/usb/host/ehci-hcd.c | ||||
| @@ -352,11 +352,13 @@ static void ehci_silence_controller(stru | ||||
|  	ehci->rh_state = EHCI_RH_HALTED; | ||||
|  	ehci_turn_off_all_ports(ehci); | ||||
|   | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	/* make BIOS/etc use companion controller during reboot */ | ||||
|  	ehci_writel(ehci, 0, &ehci->regs->configured_flag); | ||||
|   | ||||
|  	/* unblock posted writes */ | ||||
|  	ehci_readl(ehci, &ehci->regs->configured_flag); | ||||
| +#endif | ||||
|  	spin_unlock_irq(&ehci->lock); | ||||
|  } | ||||
|   | ||||
| @@ -608,7 +610,9 @@ static int ehci_run (struct usb_hcd *hcd | ||||
|  	// Philips, Intel, and maybe others need CMD_RUN before the | ||||
|  	// root hub will detect new devices (why?); NEC doesn't | ||||
|  	ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	ehci->command |= CMD_RUN; | ||||
| +#endif | ||||
|  	ehci_writel(ehci, ehci->command, &ehci->regs->command); | ||||
|  	dbg_cmd (ehci, "init", ehci->command); | ||||
|   | ||||
| @@ -628,9 +632,11 @@ static int ehci_run (struct usb_hcd *hcd | ||||
|  	 */ | ||||
|  	down_write(&ehci_cf_port_reset_rwsem); | ||||
|  	ehci->rh_state = EHCI_RH_RUNNING; | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | ||||
|  	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */ | ||||
|  	msleep(5); | ||||
| +#endif | ||||
|  	up_write(&ehci_cf_port_reset_rwsem); | ||||
|  	ehci->last_periodic_enable = ktime_get_real(); | ||||
|   | ||||
| @@ -768,9 +774,10 @@ static irqreturn_t ehci_irq (struct usb_ | ||||
|  		pcd_status = status; | ||||
|   | ||||
|  		/* resume root hub? */ | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  		if (ehci->rh_state == EHCI_RH_SUSPENDED) | ||||
|  			usb_hcd_resume_root_hub(hcd); | ||||
| - | ||||
| +#endif | ||||
|  		/* get per-port change detect bits */ | ||||
|  		if (ehci->has_ppcd) | ||||
|  			ppcd = status >> 16; | ||||
| @@ -1296,6 +1303,11 @@ MODULE_LICENSE ("GPL"); | ||||
|  #define	PLATFORM_DRIVER		ehci_hcd_sead3_driver | ||||
|  #endif | ||||
|   | ||||
| +#ifdef CONFIG_ARCH_GEMINI | ||||
| +#include "ehci-fotg2.c" | ||||
| +#define PLATFORM_DRIVER		ehci_fotg2_driver | ||||
| +#endif | ||||
| + | ||||
|  static int __init ehci_hcd_init(void) | ||||
|  { | ||||
|  	int retval = 0; | ||||
| --- a/drivers/usb/host/ehci-timer.c | ||||
| +++ b/drivers/usb/host/ehci-timer.c | ||||
| @@ -208,7 +208,9 @@ static void ehci_handle_controller_death | ||||
|   | ||||
|  	/* Clean up the mess */ | ||||
|  	ehci->rh_state = EHCI_RH_HALTED; | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	ehci_writel(ehci, 0, &ehci->regs->configured_flag); | ||||
| +#endif | ||||
|  	ehci_writel(ehci, 0, &ehci->regs->intr_enable); | ||||
|  	ehci_work(ehci); | ||||
|  	end_unlink_async(ehci); | ||||
| --- a/drivers/usb/host/ehci.h | ||||
| +++ b/drivers/usb/host/ehci.h | ||||
| @@ -657,7 +657,12 @@ static inline unsigned int | ||||
|  ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) | ||||
|  { | ||||
|  	if (ehci_is_TDI(ehci)) { | ||||
| -		switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) { | ||||
| +#ifdef CONFIG_ARCH_GEMINI | ||||
| +		portsc = readl(ehci_to_hcd(ehci)->regs + 0x80); | ||||
| +		switch ((portsc>>22)&3) { | ||||
| +#else | ||||
| +		switch ((portsc>>26)&3) { | ||||
| +#endif | ||||
|  		case 0: | ||||
|  			return 0; | ||||
|  		case 1: | ||||
| --- a/drivers/usb/host/ehci-hub.c | ||||
| +++ b/drivers/usb/host/ehci-hub.c | ||||
| @@ -1076,6 +1076,11 @@ int ehci_hub_control( | ||||
|  			/* see what we found out */ | ||||
|  			temp = check_reset_complete (ehci, wIndex, status_reg, | ||||
|  					ehci_readl(ehci, status_reg)); | ||||
| +#ifdef CONFIG_ARCH_GEMINI | ||||
| +			/* restart schedule */ | ||||
| +		 	ehci->command |= CMD_RUN; | ||||
| +			ehci_writel(ehci, ehci->command, &ehci->regs->command); | ||||
| +#endif | ||||
|  		} | ||||
|   | ||||
|  		/* transfer dedicated ports to the companion hc */ | ||||
| --- a/include/linux/usb/ehci_def.h | ||||
| +++ b/include/linux/usb/ehci_def.h | ||||
| @@ -112,8 +112,13 @@ struct ehci_regs { | ||||
|  	u32		frame_list;	/* points to periodic list */ | ||||
|  	/* ASYNCLISTADDR: offset 0x18 */ | ||||
|  	u32		async_next;	/* address of next async queue head */ | ||||
| - | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	u32		reserved1[2]; | ||||
| +#else | ||||
| +	u32		reserved1; | ||||
| +	/* PORTSC: offset 0x20 for Faraday OTG */ | ||||
| +	u32		port_status[1]; | ||||
| +#endif | ||||
|   | ||||
|  	/* TXFILLTUNING: offset 0x24 */ | ||||
|  	u32		txfill_tuning;	/* TX FIFO Tuning register */ | ||||
| @@ -125,8 +130,11 @@ struct ehci_regs { | ||||
|  	u32		configured_flag; | ||||
|  #define FLAG_CF		(1<<0)		/* true: we'll support "high speed" */ | ||||
|   | ||||
| +#ifndef CONFIG_ARCH_GEMINI | ||||
|  	/* PORTSC: offset 0x44 */ | ||||
|  	u32		port_status[0];	/* up to N_PORTS */ | ||||
| +#endif | ||||
| + | ||||
|  /* EHCI 1.1 addendum */ | ||||
|  #define PORTSC_SUSPEND_STS_ACK 0 | ||||
|  #define PORTSC_SUSPEND_STS_NYET 1 | ||||
| @@ -1,77 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/devices.c | ||||
| +++ b/arch/arm/mach-gemini/devices.c | ||||
| @@ -187,3 +187,64 @@ int platform_register_ethernet(struct ge | ||||
|   | ||||
|  	return platform_device_register(ðernet_device); | ||||
|  } | ||||
| + | ||||
| +static struct resource usb0_resources[] = { | ||||
| +	{ | ||||
| +		.start  = GEMINI_USB0_BASE, | ||||
| +		.end    = GEMINI_USB0_BASE + 0xfff, | ||||
| +		.flags  = IORESOURCE_MEM, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.start  = IRQ_USB0, | ||||
| +		.end    = IRQ_USB0, | ||||
| +		.flags  = IORESOURCE_IRQ, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static struct resource usb1_resources[] = { | ||||
| +	{ | ||||
| +		.start  = GEMINI_USB1_BASE, | ||||
| +		.end    = GEMINI_USB1_BASE + 0xfff, | ||||
| +		.flags  = IORESOURCE_MEM, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.start  = IRQ_USB1, | ||||
| +		.end    = IRQ_USB1, | ||||
| +		.flags  = IORESOURCE_IRQ, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static u64 usb0_dmamask = 0xffffffffUL; | ||||
| +static u64 usb1_dmamask = 0xffffffffUL; | ||||
| + | ||||
| +static struct platform_device usb_device[] = { | ||||
| +	{ | ||||
| +		.name   = "ehci-fotg2", | ||||
| +		.id     = 0, | ||||
| +		.dev    = { | ||||
| +			.dma_mask = &usb0_dmamask, | ||||
| +			.coherent_dma_mask = 0xffffffff, | ||||
| +		}, | ||||
| +		.num_resources  = ARRAY_SIZE(usb0_resources), | ||||
| +		.resource       = usb0_resources, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.name   = "ehci-fotg2", | ||||
| +		.id     = 1, | ||||
| +		.dev    = { | ||||
| +			.dma_mask = &usb1_dmamask, | ||||
| +			.coherent_dma_mask = 0xffffffff, | ||||
| +		}, | ||||
| +		.num_resources  = ARRAY_SIZE(usb1_resources), | ||||
| +		.resource       = usb1_resources, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +int __init platform_register_usb(unsigned int id) | ||||
| +{ | ||||
| +	if (id > 1) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	return platform_device_register(&usb_device[id]); | ||||
| +} | ||||
| + | ||||
| --- a/arch/arm/mach-gemini/common.h | ||||
| +++ b/arch/arm/mach-gemini/common.h | ||||
| @@ -30,6 +30,7 @@ extern int platform_register_pflash(unsi | ||||
|  				    unsigned int nr_parts); | ||||
|  extern int platform_register_watchdog(void); | ||||
|  extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); | ||||
| +extern int platform_register_usb(unsigned int id); | ||||
|   | ||||
|  extern void gemini_restart(enum reboot_mode mode, const char *cmd); | ||||
|   | ||||
| @@ -1,65 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/board-wbd111.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd111.c | ||||
| @@ -145,6 +145,7 @@ static void __init wbd111_init(void) | ||||
|  	platform_register_watchdog(); | ||||
|  	platform_device_register(&wbd111_phy_device); | ||||
|  	platform_register_ethernet(&gmac_data); | ||||
| +	platform_register_usb(0); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD111, "Wiliboard WBD-111") | ||||
| --- a/arch/arm/mach-gemini/board-wbd222.c | ||||
| +++ b/arch/arm/mach-gemini/board-wbd222.c | ||||
| @@ -147,6 +147,7 @@ static void __init wbd222_init(void) | ||||
|  	platform_register_watchdog(); | ||||
|  	platform_device_register(&wbd222_phy_device); | ||||
|  	platform_register_ethernet(&gmac_data); | ||||
| +	platform_register_usb(0); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(WBD222, "Wiliboard WBD-222") | ||||
| --- a/arch/arm/mach-gemini/board-rut1xx.c | ||||
| +++ b/arch/arm/mach-gemini/board-rut1xx.c | ||||
| @@ -105,6 +105,7 @@ static void __init rut1xx_init(void) | ||||
|  	platform_register_watchdog(); | ||||
|  	platform_device_register(&rut1xx_phy_device); | ||||
|  	platform_register_ethernet(&gmac_data); | ||||
| +	platform_register_usb(0); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(RUT100, "Teltonika RUT100") | ||||
| --- a/arch/arm/mach-gemini/board-nas4220b.c | ||||
| +++ b/arch/arm/mach-gemini/board-nas4220b.c | ||||
| @@ -134,10 +134,23 @@ static void __init ib4220b_gmac_init(voi | ||||
|  		GLOBAL_ARBITRATION1_CTRL)); | ||||
|  } | ||||
|   | ||||
| +static void __init usb_ib4220b_init(void) | ||||
| +{ | ||||
| +	unsigned int val; | ||||
| + | ||||
| +	val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| +	val &= ~(USB0_PLUG_MINIB | USB1_PLUG_MINIB); | ||||
| +	val |= USB0_VBUS_ON | USB1_VBUS_ON; | ||||
| +	writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| +} | ||||
| + | ||||
|  static void __init ib4220b_init(void) | ||||
|  { | ||||
|  	gemini_gpio_init(); | ||||
|  	ib4220b_gmac_init(); | ||||
| +	usb_ib4220b_init(); | ||||
|  	platform_register_uart(); | ||||
|  	platform_register_pflash(SZ_16M, NULL, 0); | ||||
|  	platform_device_register(&ib4220b_led_device); | ||||
| @@ -146,6 +159,8 @@ static void __init ib4220b_init(void) | ||||
|  	platform_register_watchdog(); | ||||
|  	platform_device_register(&ib4220b_phy_device); | ||||
|  	platform_register_ethernet(&ib4220b_gmac_data); | ||||
| +	platform_register_usb(0); | ||||
| +	platform_register_usb(1); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") | ||||
| @@ -1,66 +0,0 @@ | ||||
| --- a/arch/arm/Kconfig | ||||
| +++ b/arch/arm/Kconfig | ||||
| @@ -399,6 +399,7 @@ config ARCH_GEMINI | ||||
|  	select CLKSRC_MMIO | ||||
|  	select CPU_FA526 | ||||
|  	select GENERIC_CLOCKEVENTS | ||||
| +	select MIGHT_HAVE_PCI | ||||
|  	help | ||||
|  	  Support for the Cortina Systems Gemini family SoCs | ||||
|   | ||||
| --- a/arch/arm/mach-gemini/include/mach/hardware.h | ||||
| +++ b/arch/arm/mach-gemini/include/mach/hardware.h | ||||
| @@ -68,4 +68,9 @@ | ||||
|   */ | ||||
|  #define IO_ADDRESS(x)	IOMEM((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) | ||||
|   | ||||
| +/* | ||||
| + * PCI subsystem macros | ||||
| + */ | ||||
| +#define pcibios_assign_all_busses()	1 | ||||
| + | ||||
|  #endif | ||||
| --- a/arch/arm/mach-gemini/include/mach/irqs.h | ||||
| +++ b/arch/arm/mach-gemini/include/mach/irqs.h | ||||
| @@ -43,11 +43,14 @@ | ||||
|   | ||||
|  #define NORMAL_IRQ_NUM	32 | ||||
|   | ||||
| -#define GPIO_IRQ_BASE	NORMAL_IRQ_NUM | ||||
| +#define PCI_IRQ_BASE	NORMAL_IRQ_NUM | ||||
| +#define PCI_IRQ_NUM	4 | ||||
| + | ||||
| +#define GPIO_IRQ_BASE	(NORMAL_IRQ_NUM + PCI_IRQ_NUM) | ||||
|  #define GPIO_IRQ_NUM	(3 * 32) | ||||
|   | ||||
|  #define ARCH_TIMER_IRQ	IRQ_TIMER2 | ||||
|   | ||||
| -#define NR_IRQS		(NORMAL_IRQ_NUM + GPIO_IRQ_NUM) | ||||
| +#define NR_IRQS		(NORMAL_IRQ_NUM + PCI_IRQ_NUM + GPIO_IRQ_NUM) | ||||
|   | ||||
|  #endif /* __MACH_IRQS_H__ */ | ||||
| --- a/arch/arm/mach-gemini/Makefile | ||||
| +++ b/arch/arm/mach-gemini/Makefile | ||||
| @@ -6,6 +6,8 @@ | ||||
|   | ||||
|  obj-y			:= irq.o mm.o time.o devices.o gpio.o idle.o reset.o | ||||
|   | ||||
| +obj-$(CONFIG_PCI)	+= pci.o | ||||
| + | ||||
|  # Board-specific support | ||||
|  obj-$(CONFIG_MACH_NAS4220B)	+= board-nas4220b.o | ||||
|  obj-$(CONFIG_MACH_RUT100)	+= board-rut1xx.o | ||||
| --- a/arch/arm/mach-gemini/mm.c | ||||
| +++ b/arch/arm/mach-gemini/mm.c | ||||
| @@ -59,6 +59,11 @@ static struct map_desc gemini_io_desc[] | ||||
|  		.length		= SZ_512K, | ||||
|  		.type 		= MT_DEVICE, | ||||
|  	}, { | ||||
| +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_PCI_IO_BASE), | ||||
| +		.pfn		= __phys_to_pfn(GEMINI_PCI_IO_BASE), | ||||
| +		.length		= SZ_512K, | ||||
| +		.type 		= MT_DEVICE, | ||||
| +	}, { | ||||
|  		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), | ||||
|  		.pfn		= __phys_to_pfn(GEMINI_FLASH_CTRL_BASE), | ||||
|  		.length		= SZ_512K, | ||||
| @@ -1,192 +0,0 @@ | ||||
| --- a/arch/arm/mach-gemini/include/mach/global_reg.h | ||||
| +++ b/arch/arm/mach-gemini/include/mach/global_reg.h | ||||
| @@ -227,7 +227,13 @@ | ||||
|  #define USB0_PLUG_MINIB			(1 << 29) | ||||
|  #define GMAC_GMII			(1 << 28) | ||||
|  #define GMAC_1_ENABLE			(1 << 27) | ||||
| -/* TODO: define ATA/SATA bits */ | ||||
| +/* 011 - ata0 <-> sata0, sata1; bring out ata1 | ||||
| + * 010 - ata1 <-> sata1, sata0; bring out ata0 | ||||
| + * 001 - ata0 <-> sata0, ata1 <-> sata1; bring out ata1 | ||||
| + * 000 - ata0 <-> sata0, ata1 <-> sata1; bring out ata0 */ | ||||
| +#define IDE_IOMUX_MASK			(7 << 24) | ||||
| +#define IDE_IOMUX_SATA1_SATA0	(2 << 24) | ||||
| +#define IDE_IOMUX_SATA0_SATA1	(3 << 24) | ||||
|  #define USB1_VBUS_ON			(1 << 23) | ||||
|  #define USB0_VBUS_ON			(1 << 22) | ||||
|  #define APB_CLKOUT_ENABLE		(1 << 21) | ||||
| --- a/arch/arm/mach-gemini/irq.c | ||||
| +++ b/arch/arm/mach-gemini/irq.c | ||||
| @@ -89,6 +89,9 @@ void __init gemini_init_irq(void) | ||||
|  			irq_set_handler(i, handle_edge_irq); | ||||
|  			mode |= 1 << i; | ||||
|  			level |= 1 << i; | ||||
| + 		} else if (i >= IRQ_IDE0 && i <= IRQ_IDE1) { | ||||
| + 			irq_set_handler(i, handle_edge_irq); | ||||
| + 			mode |= 1 << i; | ||||
|  		} else {			 | ||||
|  			irq_set_handler(i, handle_level_irq); | ||||
|  		} | ||||
| --- a/arch/arm/mach-gemini/common.h | ||||
| +++ b/arch/arm/mach-gemini/common.h | ||||
| @@ -31,6 +31,7 @@ extern int platform_register_pflash(unsi | ||||
|  extern int platform_register_watchdog(void); | ||||
|  extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); | ||||
|  extern int platform_register_usb(unsigned int id); | ||||
| +extern int platform_register_pata(unsigned int id); | ||||
|   | ||||
|  extern void gemini_restart(enum reboot_mode mode, const char *cmd); | ||||
|   | ||||
| --- a/arch/arm/mach-gemini/devices.c | ||||
| +++ b/arch/arm/mach-gemini/devices.c | ||||
| @@ -248,3 +248,67 @@ int __init platform_register_usb(unsigne | ||||
|  	return platform_device_register(&usb_device[id]); | ||||
|  } | ||||
|   | ||||
| +static u64 pata_gemini_dmamask0 = 0xffffffffUL; | ||||
| +static u64 pata_gemini_dmamask1 = 0xffffffffUL; | ||||
| + | ||||
| +static struct resource pata_gemini_resources0[] = | ||||
| +{ | ||||
| +	[0] =	{ | ||||
| +			.start	= GEMINI_IDE0_BASE, | ||||
| +			.end	= GEMINI_IDE0_BASE + 0x40, | ||||
| +			.flags	= IORESOURCE_MEM, | ||||
| +		}, | ||||
| +	[1] =	{ | ||||
| +			.start	= IRQ_IDE0, | ||||
| +			.end	= IRQ_IDE0, | ||||
| +			.flags  = IORESOURCE_IRQ, | ||||
| +		}, | ||||
| +}; | ||||
| + | ||||
| +static struct resource pata_gemini_resources1[] = | ||||
| +{ | ||||
| +	[0] =	{ | ||||
| +			.start	= GEMINI_IDE1_BASE, | ||||
| +			.end	= GEMINI_IDE1_BASE + 0x40, | ||||
| +			.flags	= IORESOURCE_MEM, | ||||
| +		}, | ||||
| +	[1] =	{ | ||||
| +			.start  = IRQ_IDE1, | ||||
| +			.end    = IRQ_IDE1, | ||||
| +			.flags  = IORESOURCE_IRQ, | ||||
| +		}, | ||||
| +}; | ||||
| + | ||||
| +static struct platform_device pata_gemini_devices[] = | ||||
| +{ | ||||
| +	{ | ||||
| +		.name		= "pata-gemini", | ||||
| +		.id		= 0, | ||||
| +		.dev		= | ||||
| +		{ | ||||
| +			.dma_mask		= &pata_gemini_dmamask0, | ||||
| +			.coherent_dma_mask	= 0xffffffff, | ||||
| +		}, | ||||
| +		.num_resources	= ARRAY_SIZE(pata_gemini_resources0), | ||||
| +		.resource	= pata_gemini_resources0, | ||||
| +	}, | ||||
| +	{ | ||||
| +		.name		= "pata-gemini", | ||||
| +		.id		= 1, | ||||
| +		.dev		= | ||||
| +		{ | ||||
| +			.dma_mask		= &pata_gemini_dmamask1, | ||||
| +			.coherent_dma_mask	= 0xffffffff, | ||||
| +		}, | ||||
| +		.num_resources	= ARRAY_SIZE(pata_gemini_resources1), | ||||
| +		.resource	= pata_gemini_resources1, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +int __init platform_register_pata(unsigned int id) | ||||
| +{ | ||||
| +	if (id > 1) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	return platform_device_register(&pata_gemini_devices[id]); | ||||
| +} | ||||
| --- a/arch/arm/mach-gemini/mm.c | ||||
| +++ b/arch/arm/mach-gemini/mm.c | ||||
| @@ -24,6 +24,11 @@ static struct map_desc gemini_io_desc[] | ||||
|  		.length		= SZ_512K, | ||||
|  		.type 		= MT_DEVICE, | ||||
|  	}, { | ||||
| +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_SATA_BASE), | ||||
| +		.pfn		= __phys_to_pfn(GEMINI_SATA_BASE), | ||||
| +		.length		= SZ_512K, | ||||
| +		.type		= MT_DEVICE, | ||||
| +	}, { | ||||
|  		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_UART_BASE), | ||||
|  		.pfn		= __phys_to_pfn(GEMINI_UART_BASE), | ||||
|  		.length		= SZ_512K, | ||||
| --- a/drivers/ata/Kconfig | ||||
| +++ b/drivers/ata/Kconfig | ||||
| @@ -567,6 +567,16 @@ config PATA_EP93XX | ||||
|   | ||||
|  	  If unsure, say N. | ||||
|   | ||||
| +config PATA_GEMINI | ||||
| +	tristate "Gemini PATA support (Experimental)" | ||||
| +	depends on ARCH_GEMINI | ||||
| +	help | ||||
| +	  This option enables support for the Gemini PATA-Controller. | ||||
| +	  Note that the Gemini SoC has no native SATA-Controller but an | ||||
| +	  onboard PATA-SATA bridge. | ||||
| + | ||||
| +	  If unsure, say N. | ||||
| + | ||||
|  config PATA_HPT366 | ||||
|  	tristate "HPT 366/368 PATA support" | ||||
|  	depends on PCI | ||||
| --- a/drivers/ata/Makefile | ||||
| +++ b/drivers/ata/Makefile | ||||
| @@ -56,6 +56,7 @@ obj-$(CONFIG_PATA_CS5536)	+= pata_cs5536 | ||||
|  obj-$(CONFIG_PATA_CYPRESS)	+= pata_cypress.o | ||||
|  obj-$(CONFIG_PATA_EFAR)		+= pata_efar.o | ||||
|  obj-$(CONFIG_PATA_EP93XX)	+= pata_ep93xx.o | ||||
| +obj-$(CONFIG_PATA_GEMINI)	+= pata_gemini.o | ||||
|  obj-$(CONFIG_PATA_HPT366)	+= pata_hpt366.o | ||||
|  obj-$(CONFIG_PATA_HPT37X)	+= pata_hpt37x.o | ||||
|  obj-$(CONFIG_PATA_HPT3X2N)	+= pata_hpt3x2n.o | ||||
| --- a/arch/arm/mach-gemini/board-nas4220b.c | ||||
| +++ b/arch/arm/mach-gemini/board-nas4220b.c | ||||
| @@ -146,11 +146,28 @@ static void __init usb_ib4220b_init(void | ||||
|  		GLOBAL_MISC_CTRL)); | ||||
|  } | ||||
|   | ||||
| +static void __init sata_ib4220b_init(void) | ||||
| +{ | ||||
| +	unsigned val; | ||||
| + | ||||
| +	val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| +	val &= ~(IDE_IOMUX_MASK | PFLASH_PADS_DISABLE); | ||||
| +	val |= IDE_PADS_ENABLE; | ||||
| +	writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + | ||||
| +		GLOBAL_MISC_CTRL)); | ||||
| + | ||||
| +	/* enabling ports for presence detection, master only */ | ||||
| +	writel(0x00000001, (void __iomem*)(IO_ADDRESS(GEMINI_SATA_BASE) + 0x18)); | ||||
| +	writel(0x00000001, (void __iomem*)(IO_ADDRESS(GEMINI_SATA_BASE) + 0x1c)); | ||||
| +} | ||||
| + | ||||
|  static void __init ib4220b_init(void) | ||||
|  { | ||||
|  	gemini_gpio_init(); | ||||
|  	ib4220b_gmac_init(); | ||||
|  	usb_ib4220b_init(); | ||||
| +	sata_ib4220b_init(); | ||||
|  	platform_register_uart(); | ||||
|  	platform_register_pflash(SZ_16M, NULL, 0); | ||||
|  	platform_device_register(&ib4220b_led_device); | ||||
| @@ -161,6 +178,8 @@ static void __init ib4220b_init(void) | ||||
|  	platform_register_ethernet(&ib4220b_gmac_data); | ||||
|  	platform_register_usb(0); | ||||
|  	platform_register_usb(1); | ||||
| +	platform_register_pata(0); | ||||
| +	platform_register_pata(1); | ||||
|  } | ||||
|   | ||||
|  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") | ||||
		Reference in New Issue
	
	Block a user