mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	upgrade to 2.6.39
SVN-Revision: 27030
This commit is contained in:
		
							parent
							
								
									7f0fc7b0cf
								
							
						
					
					
						commit
						f738ca7b9c
					
				@ -13,7 +13,7 @@ FEATURES:=squashfs fpu gpio
 | 
				
			|||||||
CFLAGS:=-Os -pipe -march=armv6k -mtune=mpcore -mfloat-abi=softfp -mfpu=vfp -fno-caller-saves
 | 
					CFLAGS:=-Os -pipe -march=armv6k -mtune=mpcore -mfloat-abi=softfp -mfpu=vfp -fno-caller-saves
 | 
				
			||||||
MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
 | 
					MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LINUX_VERSION:=2.6.31.14
 | 
					LINUX_VERSION:=2.6.39
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include $(INCLUDE_DIR)/target.mk
 | 
					include $(INCLUDE_DIR)/target.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,45 +1,28 @@
 | 
				
			|||||||
CONFIG_ALIGNMENT_TRAP=y
 | 
					CONFIG_ALIGNMENT_TRAP=y
 | 
				
			||||||
CONFIG_ARCH_CNS3XXX=y
 | 
					CONFIG_ARCH_CNS3XXX=y
 | 
				
			||||||
CONFIG_ARCH_REQUIRE_GPIOLIB=y
 | 
					# CONFIG_ARCH_EXYNOS4 is not set
 | 
				
			||||||
 | 
					CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 | 
				
			||||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 | 
					# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 | 
				
			||||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 | 
					# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 | 
				
			||||||
# CONFIG_ARCH_SUPPORTS_MSI is not set
 | 
					# CONFIG_ARCH_SUPPORTS_MSI is not set
 | 
				
			||||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
 | 
					CONFIG_ARCH_SUSPEND_POSSIBLE=y
 | 
				
			||||||
 | 
					# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
 | 
				
			||||||
 | 
					# CONFIG_ARCH_VT8500 is not set
 | 
				
			||||||
 | 
					CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 | 
				
			||||||
CONFIG_ARM=y
 | 
					CONFIG_ARM=y
 | 
				
			||||||
CONFIG_ARM_AMBA=y
 | 
					 | 
				
			||||||
CONFIG_ARM_GIC=y
 | 
					CONFIG_ARM_GIC=y
 | 
				
			||||||
 | 
					CONFIG_ARM_L1_CACHE_SHIFT=5
 | 
				
			||||||
 | 
					# CONFIG_ARM_PATCH_PHYS_VIRT is not set
 | 
				
			||||||
CONFIG_ARM_THUMB=y
 | 
					CONFIG_ARM_THUMB=y
 | 
				
			||||||
CONFIG_ASYNC_CORE=y
 | 
					 | 
				
			||||||
CONFIG_ASYNC_MEMCPY=y
 | 
					 | 
				
			||||||
CONFIG_ASYNC_XOR=y
 | 
					 | 
				
			||||||
CONFIG_ATA=y
 | 
					CONFIG_ATA=y
 | 
				
			||||||
# CONFIG_ATA_SFF is not set
 | 
					# CONFIG_ATA_SFF is not set
 | 
				
			||||||
CONFIG_BITREVERSE=y
 | 
					 | 
				
			||||||
# CONFIG_BLK_DEV_DM is not set
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_MD=y
 | 
					 | 
				
			||||||
CONFIG_BLK_DEV_RAM=y
 | 
					CONFIG_BLK_DEV_RAM=y
 | 
				
			||||||
CONFIG_BLK_DEV_RAM_COUNT=2
 | 
					CONFIG_BLK_DEV_RAM_COUNT=2
 | 
				
			||||||
CONFIG_BLK_DEV_RAM_SIZE=32768
 | 
					CONFIG_BLK_DEV_RAM_SIZE=32768
 | 
				
			||||||
CONFIG_BLK_DEV_SD=y
 | 
					CONFIG_BLK_DEV_SD=y
 | 
				
			||||||
CONFIG_CACHE_L2CC=y
 | 
					CONFIG_CACHE_L2X0=y
 | 
				
			||||||
# CONFIG_CACHE_L2CC_128KB is not set
 | 
					CONFIG_CNS3XXX_ETH=y
 | 
				
			||||||
CONFIG_CACHE_L2CC_256KB=y
 | 
					 | 
				
			||||||
# CONFIG_CACHE_L2CC_32KB is not set
 | 
					 | 
				
			||||||
# CONFIG_CACHE_L2CC_64KB is not set
 | 
					 | 
				
			||||||
# CONFIG_CACHE_L2CC_96KB is not set
 | 
					 | 
				
			||||||
CONFIG_CACHE_L2_I_PREFETCH=y
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_DMAC=y
 | 
					 | 
				
			||||||
# CONFIG_CNS3XXX_GPU_ENVIRONMENT is not set
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_GSW=y
 | 
					 | 
				
			||||||
# CONFIG_CNS3XXX_HCIE_TEST is not set
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_PM_API=y
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_RAID=y
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_SPPE=y
 | 
					 | 
				
			||||||
CONFIG_CNS3XXX_WATCHDOG=y
 | 
					 | 
				
			||||||
CONFIG_COMMON_CLKDEV=y
 | 
					 | 
				
			||||||
CONFIG_CPU_32=y
 | 
					 | 
				
			||||||
CONFIG_CPU_32v6=y
 | 
					CONFIG_CPU_32v6=y
 | 
				
			||||||
CONFIG_CPU_32v6K=y
 | 
					 | 
				
			||||||
CONFIG_CPU_ABRT_EV6=y
 | 
					CONFIG_CPU_ABRT_EV6=y
 | 
				
			||||||
# CONFIG_CPU_BPREDICT_DISABLE is not set
 | 
					# CONFIG_CPU_BPREDICT_DISABLE is not set
 | 
				
			||||||
CONFIG_CPU_CACHE_V6=y
 | 
					CONFIG_CPU_CACHE_V6=y
 | 
				
			||||||
@ -48,53 +31,59 @@ CONFIG_CPU_COPY_V6=y
 | 
				
			|||||||
CONFIG_CPU_CP15=y
 | 
					CONFIG_CPU_CP15=y
 | 
				
			||||||
CONFIG_CPU_CP15_MMU=y
 | 
					CONFIG_CPU_CP15_MMU=y
 | 
				
			||||||
CONFIG_CPU_HAS_ASID=y
 | 
					CONFIG_CPU_HAS_ASID=y
 | 
				
			||||||
 | 
					CONFIG_CPU_HAS_PMU=y
 | 
				
			||||||
# CONFIG_CPU_ICACHE_DISABLE is not set
 | 
					# CONFIG_CPU_ICACHE_DISABLE is not set
 | 
				
			||||||
CONFIG_CPU_NO_CACHE_BCAST=y
 | 
					CONFIG_CPU_PABRT_V6=y
 | 
				
			||||||
CONFIG_CPU_NO_CACHE_BCAST_DEBUG=y
 | 
					 | 
				
			||||||
CONFIG_CPU_PABRT_NOIFAR=y
 | 
					 | 
				
			||||||
CONFIG_CPU_TLB_V6=y
 | 
					CONFIG_CPU_TLB_V6=y
 | 
				
			||||||
 | 
					CONFIG_CPU_USE_DOMAINS=y
 | 
				
			||||||
CONFIG_CPU_V6=y
 | 
					CONFIG_CPU_V6=y
 | 
				
			||||||
 | 
					CONFIG_DEBUG_BUGVERBOSE=y
 | 
				
			||||||
# CONFIG_DEBUG_USER is not set
 | 
					# CONFIG_DEBUG_USER is not set
 | 
				
			||||||
CONFIG_DECOMPRESS_GZIP=y
 | 
					CONFIG_DECOMPRESS_GZIP=y
 | 
				
			||||||
CONFIG_DECOMPRESS_LZMA=y
 | 
					# CONFIG_DWC_DEBUG is not set
 | 
				
			||||||
CONFIG_DEVPORT=y
 | 
					# CONFIG_DWC_DEVICE_ONLY is not set
 | 
				
			||||||
# CONFIG_DM9000 is not set
 | 
					# CONFIG_DWC_HOST_ONLY is not set
 | 
				
			||||||
 | 
					CONFIG_DWC_OTG_MODE=y
 | 
				
			||||||
CONFIG_EEPROM_AT24=y
 | 
					CONFIG_EEPROM_AT24=y
 | 
				
			||||||
# CONFIG_FPE_FASTFPE is not set
 | 
					 | 
				
			||||||
# CONFIG_FPE_NWFPE is not set
 | 
					 | 
				
			||||||
# CONFIG_FPGA is not set
 | 
					 | 
				
			||||||
CONFIG_FRAME_POINTER=y
 | 
					CONFIG_FRAME_POINTER=y
 | 
				
			||||||
# CONFIG_FSNOTIFY is not set
 | 
					# CONFIG_FSNOTIFY is not set
 | 
				
			||||||
 | 
					# CONFIG_FTMAC100 is not set
 | 
				
			||||||
 | 
					CONFIG_GENERIC_ATOMIC64=y
 | 
				
			||||||
CONFIG_GENERIC_CLOCKEVENTS=y
 | 
					CONFIG_GENERIC_CLOCKEVENTS=y
 | 
				
			||||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 | 
					CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 | 
				
			||||||
CONFIG_GENERIC_FIND_LAST_BIT=y
 | 
					CONFIG_GENERIC_FIND_LAST_BIT=y
 | 
				
			||||||
CONFIG_GENERIC_GPIO=y
 | 
					CONFIG_GENERIC_GPIO=y
 | 
				
			||||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 | 
					CONFIG_GENERIC_IRQ_SHOW=y
 | 
				
			||||||
CONFIG_GENERIC_LOCKBREAK=y
 | 
					 | 
				
			||||||
CONFIG_GPIOLIB=y
 | 
					CONFIG_GPIOLIB=y
 | 
				
			||||||
CONFIG_GPIO_DEVICE=y
 | 
					 | 
				
			||||||
CONFIG_GPIO_PCA953X=y
 | 
					CONFIG_GPIO_PCA953X=y
 | 
				
			||||||
# CONFIG_GPIO_PL061 is not set
 | 
					CONFIG_GPIO_PCA953X_IRQ=y
 | 
				
			||||||
 | 
					CONFIG_GPIO_SYSFS=y
 | 
				
			||||||
CONFIG_HARDIRQS_SW_RESEND=y
 | 
					CONFIG_HARDIRQS_SW_RESEND=y
 | 
				
			||||||
CONFIG_HAS_DMA=y
 | 
					CONFIG_HAS_DMA=y
 | 
				
			||||||
CONFIG_HAS_IOMEM=y
 | 
					CONFIG_HAS_IOMEM=y
 | 
				
			||||||
CONFIG_HAS_IOPORT=y
 | 
					CONFIG_HAS_IOPORT=y
 | 
				
			||||||
CONFIG_HAS_TLS_REG=y
 | 
					 | 
				
			||||||
CONFIG_HAVE_AOUT=y
 | 
					CONFIG_HAVE_AOUT=y
 | 
				
			||||||
CONFIG_HAVE_ARCH_KGDB=y
 | 
					CONFIG_HAVE_ARCH_KGDB=y
 | 
				
			||||||
CONFIG_HAVE_ARM_SCU=y
 | 
					CONFIG_HAVE_C_RECORDMCOUNT=y
 | 
				
			||||||
CONFIG_HAVE_ARM_TWD=y
 | 
					CONFIG_HAVE_DMA_API_DEBUG=y
 | 
				
			||||||
CONFIG_HAVE_CLK=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_FUNCTION_TRACER=y
 | 
				
			||||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 | 
					CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 | 
				
			||||||
 | 
					CONFIG_HAVE_GENERIC_HARDIRQS=y
 | 
				
			||||||
CONFIG_HAVE_IDE=y
 | 
					CONFIG_HAVE_IDE=y
 | 
				
			||||||
 | 
					CONFIG_HAVE_IRQ_WORK=y
 | 
				
			||||||
CONFIG_HAVE_KERNEL_GZIP=y
 | 
					CONFIG_HAVE_KERNEL_GZIP=y
 | 
				
			||||||
CONFIG_HAVE_KERNEL_LZMA=y
 | 
					CONFIG_HAVE_KERNEL_LZMA=y
 | 
				
			||||||
CONFIG_HAVE_KERNEL_LZO=y
 | 
					CONFIG_HAVE_KERNEL_LZO=y
 | 
				
			||||||
CONFIG_HAVE_KPROBES=y
 | 
					CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 | 
				
			||||||
CONFIG_HAVE_KRETPROBES=y
 | 
					CONFIG_HAVE_MEMBLOCK=y
 | 
				
			||||||
CONFIG_HAVE_OPROFILE=y
 | 
					CONFIG_HAVE_OPROFILE=y
 | 
				
			||||||
CONFIG_HOTPLUG_CPU=y
 | 
					CONFIG_HAVE_PERF_EVENTS=y
 | 
				
			||||||
 | 
					CONFIG_HAVE_PROC_CPU=y
 | 
				
			||||||
 | 
					CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 | 
				
			||||||
 | 
					CONFIG_HAVE_SPARSE_IRQ=y
 | 
				
			||||||
CONFIG_HWMON=y
 | 
					CONFIG_HWMON=y
 | 
				
			||||||
# CONFIG_HWMON_DEBUG_CHIP is not set
 | 
					# CONFIG_HWMON_DEBUG_CHIP is not set
 | 
				
			||||||
CONFIG_HW_RANDOM=m
 | 
					CONFIG_HW_RANDOM=m
 | 
				
			||||||
@ -102,30 +91,18 @@ CONFIG_I2C=y
 | 
				
			|||||||
CONFIG_I2C_BOARDINFO=y
 | 
					CONFIG_I2C_BOARDINFO=y
 | 
				
			||||||
CONFIG_I2C_CHARDEV=y
 | 
					CONFIG_I2C_CHARDEV=y
 | 
				
			||||||
CONFIG_I2C_CNS3XXX=y
 | 
					CONFIG_I2C_CNS3XXX=y
 | 
				
			||||||
# CONFIG_I2C_DESIGNWARE is not set
 | 
					# CONFIG_I2C_PXA_PCI is not set
 | 
				
			||||||
CONFIG_INITRAMFS_SOURCE=""
 | 
					CONFIG_INITRAMFS_SOURCE=""
 | 
				
			||||||
# CONFIG_ISDN_CAPI is not set
 | 
					 | 
				
			||||||
# CONFIG_ISDN_I4L is not set
 | 
					 | 
				
			||||||
CONFIG_KERNEL_GZIP=y
 | 
					CONFIG_KERNEL_GZIP=y
 | 
				
			||||||
# CONFIG_KERNEL_LZMA is not set
 | 
					# CONFIG_KERNEL_LZMA is not set
 | 
				
			||||||
 | 
					CONFIG_KTIME_SCALAR=y
 | 
				
			||||||
CONFIG_LEDS_GPIO=y
 | 
					CONFIG_LEDS_GPIO=y
 | 
				
			||||||
# CONFIG_LEDS_TRIGGER_NETDEV is not set
 | 
					# CONFIG_LEDS_TRIGGER_NETDEV is not set
 | 
				
			||||||
CONFIG_LOCAL_TIMERS=y
 | 
					 | 
				
			||||||
CONFIG_LOCK_KERNEL=y
 | 
					 | 
				
			||||||
CONFIG_M25PXX_USE_FAST_READ=y
 | 
					CONFIG_M25PXX_USE_FAST_READ=y
 | 
				
			||||||
CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 | 
					CONFIG_MACH_CNS3420VB=y
 | 
				
			||||||
CONFIG_MACH_GW2388=y
 | 
					CONFIG_MACH_GW2388=y
 | 
				
			||||||
CONFIG_MD=y
 | 
					# CONFIG_MFD_MAX8997 is not set
 | 
				
			||||||
CONFIG_MD_AUTODETECT=y
 | 
					CONFIG_MIGHT_HAVE_PCI=y
 | 
				
			||||||
# CONFIG_MD_FAULTY is not set
 | 
					 | 
				
			||||||
# CONFIG_MD_LINEAR is not set
 | 
					 | 
				
			||||||
# CONFIG_MD_MULTIPATH is not set
 | 
					 | 
				
			||||||
CONFIG_MD_RAID0=y
 | 
					 | 
				
			||||||
CONFIG_MD_RAID1=y
 | 
					 | 
				
			||||||
# CONFIG_MD_RAID10 is not set
 | 
					 | 
				
			||||||
CONFIG_MD_RAID456=y
 | 
					 | 
				
			||||||
CONFIG_MD_RAID6_PQ=y
 | 
					 | 
				
			||||||
# CONFIG_MFD_T7L66XB is not set
 | 
					 | 
				
			||||||
CONFIG_MMC=y
 | 
					CONFIG_MMC=y
 | 
				
			||||||
CONFIG_MMC_BLOCK=y
 | 
					CONFIG_MMC_BLOCK=y
 | 
				
			||||||
CONFIG_MMC_SDHCI=y
 | 
					CONFIG_MMC_SDHCI=y
 | 
				
			||||||
@ -133,76 +110,79 @@ CONFIG_MMC_SDHCI_CNS3XXX=y
 | 
				
			|||||||
# CONFIG_MMC_SDHCI_PCI is not set
 | 
					# CONFIG_MMC_SDHCI_PCI is not set
 | 
				
			||||||
CONFIG_MMC_SDHCI_PLTFM=y
 | 
					CONFIG_MMC_SDHCI_PLTFM=y
 | 
				
			||||||
# CONFIG_MMC_TIFM_SD is not set
 | 
					# CONFIG_MMC_TIFM_SD is not set
 | 
				
			||||||
 | 
					CONFIG_MPCORE_WATCHDOG=y
 | 
				
			||||||
CONFIG_MTD_M25P80=y
 | 
					CONFIG_MTD_M25P80=y
 | 
				
			||||||
CONFIG_MTD_PHYSMAP=y
 | 
					CONFIG_MTD_PHYSMAP=y
 | 
				
			||||||
 | 
					CONFIG_NEED_DMA_MAP_STATE=y
 | 
				
			||||||
 | 
					CONFIG_NEED_PER_CPU_KM=y
 | 
				
			||||||
CONFIG_NLS=y
 | 
					CONFIG_NLS=y
 | 
				
			||||||
CONFIG_NR_CPUS=2
 | 
					 | 
				
			||||||
CONFIG_OUTER_CACHE=y
 | 
					CONFIG_OUTER_CACHE=y
 | 
				
			||||||
 | 
					CONFIG_OUTER_CACHE_SYNC=y
 | 
				
			||||||
CONFIG_PAGEFLAGS_EXTENDED=y
 | 
					CONFIG_PAGEFLAGS_EXTENDED=y
 | 
				
			||||||
CONFIG_PAGE_OFFSET=0xC0000000
 | 
					CONFIG_PAGE_OFFSET=0xC0000000
 | 
				
			||||||
CONFIG_PCI=y
 | 
					CONFIG_PCI=y
 | 
				
			||||||
CONFIG_PCIEAER=y
 | 
					 | 
				
			||||||
# CONFIG_PCIEAER_INJECT is not set
 | 
					 | 
				
			||||||
CONFIG_PCIEPORTBUS=y
 | 
					 | 
				
			||||||
# CONFIG_PCIE_ECRC is not set
 | 
					 | 
				
			||||||
CONFIG_PCI_DOMAINS=y
 | 
					CONFIG_PCI_DOMAINS=y
 | 
				
			||||||
CONFIG_PREEMPT=y
 | 
					CONFIG_PERF_USE_VMALLOC=y
 | 
				
			||||||
 | 
					CONFIG_PHYLIB=y
 | 
				
			||||||
 | 
					CONFIG_PL310_ERRATA_588369=y
 | 
				
			||||||
 | 
					CONFIG_PL310_ERRATA_727915=y
 | 
				
			||||||
 | 
					# CONFIG_PREEMPT_RCU is not set
 | 
				
			||||||
 | 
					# CONFIG_QUOTACTL is not set
 | 
				
			||||||
CONFIG_RAID_ATTRS=y
 | 
					CONFIG_RAID_ATTRS=y
 | 
				
			||||||
CONFIG_RD_GZIP=y
 | 
					CONFIG_RD_GZIP=y
 | 
				
			||||||
# CONFIG_RD_LZMA is not set
 | 
					# CONFIG_RD_LZMA is not set
 | 
				
			||||||
CONFIG_RTC_CLASS=y
 | 
					CONFIG_RTC_CLASS=y
 | 
				
			||||||
CONFIG_RTC_DRV_DS1672=y
 | 
					CONFIG_RTC_DRV_DS1672=y
 | 
				
			||||||
# CONFIG_RTC_DRV_PL030 is not set
 | 
					 | 
				
			||||||
# CONFIG_RTC_DRV_PL031 is not set
 | 
					 | 
				
			||||||
CONFIG_SATA_AHCI=y
 | 
					CONFIG_SATA_AHCI=y
 | 
				
			||||||
CONFIG_SATA_CNS3XXX_AHCI=y
 | 
					CONFIG_SATA_AHCI_PLATFORM=y
 | 
				
			||||||
CONFIG_SCSI=y
 | 
					CONFIG_SCSI=y
 | 
				
			||||||
# CONFIG_SCSI_MULTI_LUN is not set
 | 
					# CONFIG_SCSI_MULTI_LUN is not set
 | 
				
			||||||
# CONFIG_SDIO_UART is not set
 | 
					# CONFIG_SDIO_UART is not set
 | 
				
			||||||
CONFIG_SENSORS_AD7418=y
 | 
					CONFIG_SENSORS_AD7418=y
 | 
				
			||||||
CONFIG_SENSORS_GSP=y
 | 
					CONFIG_SENSORS_GSP=y
 | 
				
			||||||
# CONFIG_SERIAL_8250_EXTENDED is not set
 | 
					CONFIG_SERIAL_8250_NR_UARTS=3
 | 
				
			||||||
CONFIG_SERIAL_8250_NR_UARTS=8
 | 
					CONFIG_SERIAL_8250_RUNTIME_UARTS=3
 | 
				
			||||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=8
 | 
					 | 
				
			||||||
# CONFIG_SERIAL_AMBA_PL010 is not set
 | 
					 | 
				
			||||||
# CONFIG_SERIAL_AMBA_PL011 is not set
 | 
					 | 
				
			||||||
CONFIG_SILICON=y
 | 
					 | 
				
			||||||
CONFIG_SMP=y
 | 
					 | 
				
			||||||
CONFIG_SPI=y
 | 
					CONFIG_SPI=y
 | 
				
			||||||
CONFIG_SPI_BITBANG=y
 | 
					CONFIG_SPI_BITBANG=y
 | 
				
			||||||
CONFIG_SPI_CNS3XXX=y
 | 
					CONFIG_SPI_CNS3XXX=y
 | 
				
			||||||
CONFIG_SPI_CNS3XXX_2IOREAD=y
 | 
					 | 
				
			||||||
# CONFIG_SPI_CNS3XXX_DEBUG is not set
 | 
					 | 
				
			||||||
CONFIG_SPI_CNS3XXX_USEDMA=y
 | 
					 | 
				
			||||||
# CONFIG_SPI_CNS3XXX_USEDMA_DEBUG is not set
 | 
					 | 
				
			||||||
# CONFIG_SPI_GPIO is not set
 | 
					# CONFIG_SPI_GPIO is not set
 | 
				
			||||||
CONFIG_SPI_MASTER=y
 | 
					CONFIG_SPI_MASTER=y
 | 
				
			||||||
# CONFIG_SPI_PL022 is not set
 | 
					 | 
				
			||||||
# CONFIG_SPI_SPIDEV is not set
 | 
					 | 
				
			||||||
# CONFIG_STAGING is not set
 | 
					# CONFIG_STAGING is not set
 | 
				
			||||||
CONFIG_STOP_MACHINE=y
 | 
					 | 
				
			||||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 | 
					CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 | 
				
			||||||
CONFIG_UID16=y
 | 
					CONFIG_UID16=y
 | 
				
			||||||
CONFIG_USB=y
 | 
					CONFIG_USB=y
 | 
				
			||||||
 | 
					CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 | 
				
			||||||
 | 
					# CONFIG_USB_CDC_COMPOSITE is not set
 | 
				
			||||||
CONFIG_USB_CNS3XXX_EHCI=y
 | 
					CONFIG_USB_CNS3XXX_EHCI=y
 | 
				
			||||||
CONFIG_USB_CNS3XXX_OHCI=y
 | 
					CONFIG_USB_CNS3XXX_OHCI=y
 | 
				
			||||||
CONFIG_USB_CNS3XXX_OTG=y
 | 
					CONFIG_USB_DEBUG=y
 | 
				
			||||||
CONFIG_USB_CNS3XXX_OTG_BOTH=y
 | 
					CONFIG_USB_DWC_OTG=y
 | 
				
			||||||
CONFIG_USB_CNS3XXX_OTG_ENABLE_OTG_DRVVBUS=y
 | 
					 | 
				
			||||||
# CONFIG_USB_CNS3XXX_OTG_HCD_ONLY is not set
 | 
					 | 
				
			||||||
# CONFIG_USB_CNS3XXX_OTG_PCD_ONLY is not set
 | 
					 | 
				
			||||||
CONFIG_USB_EHCI_HCD=y
 | 
					CONFIG_USB_EHCI_HCD=y
 | 
				
			||||||
 | 
					# CONFIG_USB_ETH is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_FILE_STORAGE is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_FUNCTIONFS is not set
 | 
				
			||||||
 | 
					CONFIG_USB_GADGET=y
 | 
				
			||||||
 | 
					# CONFIG_USB_GADGETFS is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_GADGET_DEBUG_FILES is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_GADGET_DEBUG_FS is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_GADGET_DUALSPEED is not set
 | 
				
			||||||
 | 
					CONFIG_USB_GADGET_SELECTED=y
 | 
				
			||||||
 | 
					CONFIG_USB_GADGET_VBUS_DRAW=2
 | 
				
			||||||
 | 
					# CONFIG_USB_G_DBGP is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_G_HID is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_G_NCM is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_G_PRINTER is not set
 | 
				
			||||||
 | 
					# CONFIG_USB_G_SERIAL is not set
 | 
				
			||||||
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 | 
					# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 | 
				
			||||||
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 | 
					# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 | 
				
			||||||
CONFIG_USB_OHCI_HCD=y
 | 
					CONFIG_USB_OHCI_HCD=y
 | 
				
			||||||
CONFIG_USB_SUPPORT=y
 | 
					CONFIG_USB_SUPPORT=y
 | 
				
			||||||
# CONFIG_USB_UHCI_HCD is not set
 | 
					# CONFIG_USB_UHCI_HCD is not set
 | 
				
			||||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
 | 
					# CONFIG_USB_ZERO is not set
 | 
				
			||||||
CONFIG_VB=y
 | 
					 | 
				
			||||||
CONFIG_VECTORS_BASE=0xffff0000
 | 
					CONFIG_VECTORS_BASE=0xffff0000
 | 
				
			||||||
CONFIG_VFP=y
 | 
					CONFIG_VFP=y
 | 
				
			||||||
CONFIG_WATCHDOG_NOWAYOUT=y
 | 
					CONFIG_WATCHDOG_NOWAYOUT=y
 | 
				
			||||||
CONFIG_XOR_BLOCKS=y
 | 
					CONFIG_XZ_DEC=y
 | 
				
			||||||
CONFIG_ZBOOT_ROM_BSS=0
 | 
					CONFIG_ZBOOT_ROM_BSS=0
 | 
				
			||||||
CONFIG_ZBOOT_ROM_TEXT=0
 | 
					CONFIG_ZBOOT_ROM_TEXT=0
 | 
				
			||||||
CONFIG_ZONE_DMA_FLAG=0
 | 
					CONFIG_ZONE_DMA_FLAG=0
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										419
									
								
								target/linux/cns3xxx/patches/049-cns3xxx_smp_support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								target/linux/cns3xxx/patches/049-cns3xxx_smp_support.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,419 @@
 | 
				
			|||||||
 | 
					--- a/arch/arm/mach-cns3xxx/Makefile
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/Makefile
 | 
				
			||||||
 | 
					@@ -1,3 +1,6 @@
 | 
				
			||||||
 | 
					 obj-$(CONFIG_ARCH_CNS3XXX)		+= core.o pm.o devices.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_PCI)			+= pcie.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_MACH_CNS3420VB)		+= cns3420vb.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/headsmp.S
 | 
				
			||||||
 | 
					@@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ *  linux/arch/arm/mach-cns3xxx/headsmp.S
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  Copyright (c) 2003 ARM Limited
 | 
				
			||||||
 | 
					+ *  Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		   Chris Lang <clang@gateworks.com
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  All Rights Reserved
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * 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/linkage.h>
 | 
				
			||||||
 | 
					+#include <linux/init.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	__INIT
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * CNS3XXX specific entry point for secondary CPUs.  This
 | 
				
			||||||
 | 
					+ * provides a "holding pen" into which all secondary cores are held
 | 
				
			||||||
 | 
					+ * until we're ready for them to initialise.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+ENTRY(cns3xxx_secondary_startup)
 | 
				
			||||||
 | 
					+	mrc	p15, 0, r0, c0, c0, 5
 | 
				
			||||||
 | 
					+	and	r0, r0, #15
 | 
				
			||||||
 | 
					+	adr	r4, 1f
 | 
				
			||||||
 | 
					+	ldmia	r4, {r5, r6}
 | 
				
			||||||
 | 
					+	sub	r4, r4, r5
 | 
				
			||||||
 | 
					+	add	r6, r6, r4
 | 
				
			||||||
 | 
					+pen:	ldr	r7, [r6]
 | 
				
			||||||
 | 
					+	cmp	r7, r0
 | 
				
			||||||
 | 
					+	bne	pen
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * we've been released from the holding pen: secondary_stack
 | 
				
			||||||
 | 
					+	 * should now contain the SVC stack for this core
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	b	secondary_startup
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	.align
 | 
				
			||||||
 | 
					+1:	.long	.
 | 
				
			||||||
 | 
					+	.long	pen_release
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/hotplug.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,131 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ *  linux/arch/arm/mach-cns3xxx/hotplug.c
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  Copyright (C) 2002 ARM Ltd.
 | 
				
			||||||
 | 
					+ *  Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		   Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  All Rights Reserved
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * 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/errno.h>
 | 
				
			||||||
 | 
					+#include <linux/smp.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <asm/cacheflush.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+extern volatile int pen_release;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void cpu_enter_lowpower(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned int v;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	flush_cache_all();
 | 
				
			||||||
 | 
					+	asm volatile(
 | 
				
			||||||
 | 
					+		"mcr	p15, 0, %1, c7, c5, 0\n"
 | 
				
			||||||
 | 
					+	"	mcr	p15, 0, %1, c7, c10, 4\n"
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Turn off coherency
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	"	mrc	p15, 0, %0, c1, c0, 1\n"
 | 
				
			||||||
 | 
					+	"	bic	%0, %0, %3\n"
 | 
				
			||||||
 | 
					+	"	mcr	p15, 0, %0, c1, c0, 1\n"
 | 
				
			||||||
 | 
					+	"	mrc	p15, 0, %0, c1, c0, 0\n"
 | 
				
			||||||
 | 
					+	"	bic	%0, %0, %2\n"
 | 
				
			||||||
 | 
					+	"	mcr	p15, 0, %0, c1, c0, 0\n"
 | 
				
			||||||
 | 
					+	  : "=&r" (v)
 | 
				
			||||||
 | 
					+	  : "r" (0), "Ir" (CR_C), "Ir" (0x40)
 | 
				
			||||||
 | 
					+	  : "cc");
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void cpu_leave_lowpower(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned int v;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	asm volatile(
 | 
				
			||||||
 | 
					+		"mrc	p15, 0, %0, c1, c0, 0\n"
 | 
				
			||||||
 | 
					+	"	orr	%0, %0, %1\n"
 | 
				
			||||||
 | 
					+	"	mcr	p15, 0, %0, c1, c0, 0\n"
 | 
				
			||||||
 | 
					+	"	mrc	p15, 0, %0, c1, c0, 1\n"
 | 
				
			||||||
 | 
					+	"	orr	%0, %0, %2\n"
 | 
				
			||||||
 | 
					+	"	mcr	p15, 0, %0, c1, c0, 1\n"
 | 
				
			||||||
 | 
					+	  : "=&r" (v)
 | 
				
			||||||
 | 
					+	  : "Ir" (CR_C), "Ir" (0x40)
 | 
				
			||||||
 | 
					+	  : "cc");
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * there is no power-control hardware on this platform, so all
 | 
				
			||||||
 | 
					+	 * we can do is put the core into WFI; this is safe as the calling
 | 
				
			||||||
 | 
					+	 * code will have already disabled interrupts
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	for (;;) {
 | 
				
			||||||
 | 
					+		/*
 | 
				
			||||||
 | 
					+		 * here's the WFI
 | 
				
			||||||
 | 
					+		 */
 | 
				
			||||||
 | 
					+		asm(".word	0xe320f003\n"
 | 
				
			||||||
 | 
					+		    :
 | 
				
			||||||
 | 
					+		    :
 | 
				
			||||||
 | 
					+		    : "memory", "cc");
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (pen_release == cpu) {
 | 
				
			||||||
 | 
					+			/*
 | 
				
			||||||
 | 
					+			 * OK, proper wakeup, we're done
 | 
				
			||||||
 | 
					+			 */
 | 
				
			||||||
 | 
					+			break;
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		/*
 | 
				
			||||||
 | 
					+		 * Getting here, means that we have come out of WFI without
 | 
				
			||||||
 | 
					+		 * having been woken up - this shouldn't happen
 | 
				
			||||||
 | 
					+		 *
 | 
				
			||||||
 | 
					+		 * Just note it happening - when we're woken, we can report
 | 
				
			||||||
 | 
					+		 * its occurrence.
 | 
				
			||||||
 | 
					+		 */
 | 
				
			||||||
 | 
					+		(*spurious)++;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int platform_cpu_kill(unsigned int cpu)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return 1;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * platform-specific code to shutdown a CPU
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Called with IRQs disabled
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+void platform_cpu_die(unsigned int cpu)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	int spurious = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * we're ready for shutdown now, so do it
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	cpu_enter_lowpower();
 | 
				
			||||||
 | 
					+	platform_do_lowpower(cpu, &spurious);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * bring this CPU back into the world of cache
 | 
				
			||||||
 | 
					+	 * coherency, and then restore interrupts
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	cpu_leave_lowpower();
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (spurious)
 | 
				
			||||||
 | 
					+		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int platform_cpu_disable(unsigned int cpu)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * we don't allow CPU 0 to be shutdown (it is still too special
 | 
				
			||||||
 | 
					+	 * e.g. clock tick interrupts)
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	return cpu == 0 ? -EPERM : 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/localtimer.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ *  linux/arch/arm/mach-cns3xxx/localtimer.c
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  Copyright (C) 2002 ARM Ltd.
 | 
				
			||||||
 | 
					+ *  Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		   Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  All Rights Reserved
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * 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/init.h>
 | 
				
			||||||
 | 
					+#include <linux/smp.h>
 | 
				
			||||||
 | 
					+#include <linux/clockchips.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <asm/smp_twd.h>
 | 
				
			||||||
 | 
					+#include <asm/localtimer.h>
 | 
				
			||||||
 | 
					+#include <mach/irqs.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Setup the local clock events for a CPU.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+void __cpuinit local_timer_setup(struct clock_event_device *evt)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	evt->irq = IRQ_LOCALTIMER;
 | 
				
			||||||
 | 
					+	twd_timer_setup(evt);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/platsmp.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,168 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ *  linux/arch/arm/mach-cns3xxx/platsmp.c
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  Copyright (C) 2002 ARM Ltd.
 | 
				
			||||||
 | 
					+ *  Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		   Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  All Rights Reserved
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * 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/init.h>
 | 
				
			||||||
 | 
					+#include <linux/errno.h>
 | 
				
			||||||
 | 
					+#include <linux/delay.h>
 | 
				
			||||||
 | 
					+#include <linux/device.h>
 | 
				
			||||||
 | 
					+#include <linux/jiffies.h>
 | 
				
			||||||
 | 
					+#include <linux/smp.h>
 | 
				
			||||||
 | 
					+#include <linux/io.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <asm/cacheflush.h>
 | 
				
			||||||
 | 
					+#include <asm/smp_scu.h>
 | 
				
			||||||
 | 
					+#include <asm/unified.h>
 | 
				
			||||||
 | 
					+#include <mach/hardware.h>
 | 
				
			||||||
 | 
					+#include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include "core.h"
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+extern void cns3xxx_secondary_startup(void);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * control for which core is the next to come out of the secondary
 | 
				
			||||||
 | 
					+ * boot "holding pen"
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+volatile int __cpuinitdata pen_release = -1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Write pen_release in a way that is guaranteed to be visible to all
 | 
				
			||||||
 | 
					+ * observers, irrespective of whether they're taking part in coherency
 | 
				
			||||||
 | 
					+ * or not.  This is necessary for the hotplug code to work reliably.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static void __cpuinit write_pen_release(int val)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	pen_release = val;
 | 
				
			||||||
 | 
					+	smp_wmb();
 | 
				
			||||||
 | 
					+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
 | 
				
			||||||
 | 
					+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __iomem *scu_base_addr(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return (void __iomem *)(CNS3XXX_TC11MP_SCU_BASE_VIRT);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static DEFINE_SPINLOCK(boot_lock);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void __cpuinit platform_secondary_init(unsigned int cpu)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * if any interrupts are already enabled for the primary
 | 
				
			||||||
 | 
					+	 * core (e.g. timer irq), then they will not have been enabled
 | 
				
			||||||
 | 
					+	 * for us: do so
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	gic_secondary_init(0);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * let the primary processor know we're out of the
 | 
				
			||||||
 | 
					+	 * pen, then head off into the C entry point
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	write_pen_release(-1);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Synchronise with the boot thread.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	spin_lock(&boot_lock);
 | 
				
			||||||
 | 
					+	spin_unlock(&boot_lock);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned long timeout;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Set synchronisation state between this boot processor
 | 
				
			||||||
 | 
					+	 * and the secondary one
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	spin_lock(&boot_lock);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * This is really belt and braces; we hold unintended secondary
 | 
				
			||||||
 | 
					+	 * CPUs in the holding pen until we're ready for them.  However,
 | 
				
			||||||
 | 
					+	 * since we haven't sent them a soft interrupt, they shouldn't
 | 
				
			||||||
 | 
					+	 * be there.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	write_pen_release(cpu);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Send the secondary CPU a soft interrupt, thereby causing
 | 
				
			||||||
 | 
					+	 * the boot monitor to read the system wide flags register,
 | 
				
			||||||
 | 
					+	 * and branch to the address found there.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	smp_cross_call(cpumask_of(cpu), 1);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	timeout = jiffies + (1 * HZ);
 | 
				
			||||||
 | 
					+	while (time_before(jiffies, timeout)) {
 | 
				
			||||||
 | 
					+		smp_rmb();
 | 
				
			||||||
 | 
					+		if (pen_release == -1)
 | 
				
			||||||
 | 
					+			break;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		udelay(10);
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * now the secondary core is starting up let it run its
 | 
				
			||||||
 | 
					+	 * calibrations, then wait for it to finish
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	spin_unlock(&boot_lock);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return pen_release != -1 ? -ENOSYS : 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Initialise the CPU possible map early - this describes the CPUs
 | 
				
			||||||
 | 
					+ * which may be present or become present in the system.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+void __init smp_init_cpus(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	void __iomem *scu_base = scu_base_addr();
 | 
				
			||||||
 | 
					+	unsigned int i, ncores;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* sanity check */
 | 
				
			||||||
 | 
					+	if (ncores > NR_CPUS) {
 | 
				
			||||||
 | 
					+		printk(KERN_WARNING
 | 
				
			||||||
 | 
					+		       "cns3xxx: no. of cores (%d) greater than configured "
 | 
				
			||||||
 | 
					+		       "maximum of %d - clipping\n",
 | 
				
			||||||
 | 
					+		       ncores, NR_CPUS);
 | 
				
			||||||
 | 
					+		ncores = NR_CPUS;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	for (i = 0; i < ncores; i++)
 | 
				
			||||||
 | 
					+		set_cpu_possible(i, true);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	int i;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Initialise the present map, which describes the set of CPUs
 | 
				
			||||||
 | 
					+	 * actually populated at the present time.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	for (i = 0; i < max_cpus; i++)
 | 
				
			||||||
 | 
					+		set_cpu_present(i, true);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	scu_enable(scu_base_addr());
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * Write the address of secondary startup into the
 | 
				
			||||||
 | 
					+	 * system-wide flags register. The boot monitor waits
 | 
				
			||||||
 | 
					+	 * until it receives a soft interrupt, and then the
 | 
				
			||||||
 | 
					+	 * secondary CPU branches to this address.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	__raw_writel(virt_to_phys(cns3xxx_secondary_startup),
 | 
				
			||||||
 | 
					+			(void __iomem *)(0xFFF07000 + 0x0600));
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/include/mach/smp.h
 | 
				
			||||||
 | 
					@@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					+#ifndef __MACH_SMP_H
 | 
				
			||||||
 | 
					+#define __MACH_SMP_H
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <asm/hardware/gic.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * We use IRQ1 as the IPI
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	gic_raise_softirq(mask, ipi);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					--- a/arch/arm/Kconfig
 | 
				
			||||||
 | 
					+++ b/arch/arm/Kconfig
 | 
				
			||||||
 | 
					@@ -1325,7 +1325,7 @@ config SMP
 | 
				
			||||||
 | 
					 	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
 | 
				
			||||||
 | 
					 		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
 | 
				
			||||||
 | 
					 		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
 | 
				
			||||||
 | 
					-		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
 | 
				
			||||||
 | 
					+		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_CNS3XXX
 | 
				
			||||||
 | 
					 	select USE_GENERIC_SMP_HELPERS
 | 
				
			||||||
 | 
					 	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
 | 
				
			||||||
 | 
					 	help
 | 
				
			||||||
							
								
								
									
										421
									
								
								target/linux/cns3xxx/patches/050-cns3xxx_i2c_controller.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								target/linux/cns3xxx/patches/050-cns3xxx_i2c_controller.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,421 @@
 | 
				
			|||||||
 | 
					--- a/drivers/i2c/busses/Kconfig
 | 
				
			||||||
 | 
					+++ b/drivers/i2c/busses/Kconfig
 | 
				
			||||||
 | 
					@@ -325,6 +325,18 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
 | 
				
			||||||
 | 
					 	help
 | 
				
			||||||
 | 
					 	  The unit of the TWI clock is kHz.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+config I2C_CNS3XXX
 | 
				
			||||||
 | 
					+	tristate "Cavium CNS3xxx I2C driver"
 | 
				
			||||||
 | 
					+	depends on ARCH_CNS3XXX
 | 
				
			||||||
 | 
					+	help
 | 
				
			||||||
 | 
					+	  Support for Cavium CNS3xxx I2C controller driver.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	  This driver can also be built as a module.  If so, the module
 | 
				
			||||||
 | 
					+	  will be called i2c-cns3xxx.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	  Please note that this driver might be needed to bring up other
 | 
				
			||||||
 | 
					+	  devices such as Cavium CNS3xxx Ethernet.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 config I2C_CPM
 | 
				
			||||||
 | 
					 	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
 | 
				
			||||||
 | 
					 	depends on (CPM1 || CPM2) && OF_I2C
 | 
				
			||||||
 | 
					--- a/drivers/i2c/busses/Makefile
 | 
				
			||||||
 | 
					+++ b/drivers/i2c/busses/Makefile
 | 
				
			||||||
 | 
					@@ -80,6 +80,7 @@ obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor
 | 
				
			||||||
 | 
					 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_I2C_CNS3XXX)	+= i2c-cns3xxx.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/drivers/i2c/busses/i2c-cns3xxx.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,387 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Cavium CNS3xxx I2C Host Controller
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Copyright 2010 Cavium Network
 | 
				
			||||||
 | 
					+ * Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		  Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * This file 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/module.h>
 | 
				
			||||||
 | 
					+#include <linux/init.h>
 | 
				
			||||||
 | 
					+#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					+#include <asm/io.h>
 | 
				
			||||||
 | 
					+#include <linux/wait.h>
 | 
				
			||||||
 | 
					+#include <linux/interrupt.h>
 | 
				
			||||||
 | 
					+#include <linux/delay.h>
 | 
				
			||||||
 | 
					+#include <linux/i2c.h>
 | 
				
			||||||
 | 
					+#include <linux/slab.h>
 | 
				
			||||||
 | 
					+#include <mach/pm.h>
 | 
				
			||||||
 | 
					+#include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * We need the memory map
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define MISC_MEM_MAP_VALUE(reg_offset)	(*((uint32_t volatile *)(CNS3XXX_MISC_BASE_VIRT + reg_offset)))
 | 
				
			||||||
 | 
					+#define MISC_IOCDB_CTRL				MISC_MEM_MAP_VALUE(0x020)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define I2C_MEM_MAP_ADDR(x)         (CNS3XXX_SSP_BASE_VIRT + x)
 | 
				
			||||||
 | 
					+#define I2C_MEM_MAP_VALUE(x)        (*((unsigned int volatile*)I2C_MEM_MAP_ADDR(x)))
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define I2C_CONTROLLER_REG                    I2C_MEM_MAP_VALUE(0x20)
 | 
				
			||||||
 | 
					+#define I2C_TIME_OUT_REG                      I2C_MEM_MAP_VALUE(0x24)
 | 
				
			||||||
 | 
					+#define I2C_SLAVE_ADDRESS_REG                 I2C_MEM_MAP_VALUE(0x28)
 | 
				
			||||||
 | 
					+#define I2C_WRITE_DATA_REG                    I2C_MEM_MAP_VALUE(0x2C)
 | 
				
			||||||
 | 
					+#define I2C_READ_DATA_REG                     I2C_MEM_MAP_VALUE(0x30)
 | 
				
			||||||
 | 
					+#define I2C_INTERRUPT_STATUS_REG              I2C_MEM_MAP_VALUE(0x34)
 | 
				
			||||||
 | 
					+#define I2C_INTERRUPT_ENABLE_REG              I2C_MEM_MAP_VALUE(0x38)
 | 
				
			||||||
 | 
					+#define I2C_TWI_OUT_DLY_REG			         			I2C_MEM_MAP_VALUE(0x3C)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define I2C_BUS_ERROR_FLAG     (0x1)
 | 
				
			||||||
 | 
					+#define I2C_ACTION_DONE_FLAG   (0x2)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define CNS3xxx_I2C_ENABLE()          (I2C_CONTROLLER_REG) |= ((unsigned int)0x1 << 31)
 | 
				
			||||||
 | 
					+#define CNS3xxx_I2C_DISABLE()         (I2C_CONTROLLER_REG) &= ~((unsigned int)0x1 << 31)
 | 
				
			||||||
 | 
					+#define CNS3xxx_I2C_ENABLE_INTR()     (I2C_INTERRUPT_ENABLE_REG) |= 0x03
 | 
				
			||||||
 | 
					+#define CNS3xxx_I2C_DISABLE_INTR()    (I2C_INTERRUPT_ENABLE_REG) &= 0xfc
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define TWI_TIMEOUT         (10*HZ)
 | 
				
			||||||
 | 
					+#define I2C_100KHZ          100000
 | 
				
			||||||
 | 
					+#define I2C_200KHZ          200000
 | 
				
			||||||
 | 
					+#define I2C_300KHZ          300000
 | 
				
			||||||
 | 
					+#define I2C_400KHZ          400000
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define CNS3xxx_I2C_CLK     I2C_100KHZ
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define STATE_DONE		1
 | 
				
			||||||
 | 
					+#define STATE_ERROR		2
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+struct cns3xxx_i2c {
 | 
				
			||||||
 | 
					+	void __iomem *base;
 | 
				
			||||||
 | 
					+	wait_queue_head_t wait;
 | 
				
			||||||
 | 
					+	struct i2c_adapter adap;
 | 
				
			||||||
 | 
					+	struct i2c_msg *msg;
 | 
				
			||||||
 | 
					+	int state;		/* see STATE_ */
 | 
				
			||||||
 | 
					+	int rd_wr_len;
 | 
				
			||||||
 | 
					+	u8 *buf;
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static u32 cns3xxx_i2c_func(struct i2c_adapter *adap)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int
 | 
				
			||||||
 | 
					+cns3xxx_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_i2c *i2c = i2c_get_adapdata(adap);
 | 
				
			||||||
 | 
					+	int i, j;
 | 
				
			||||||
 | 
					+	u8 buf[1] = { 0 };
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (msg->len == 0) {
 | 
				
			||||||
 | 
					+		/*
 | 
				
			||||||
 | 
					+		 *	We are probably doing a probe for a device here,
 | 
				
			||||||
 | 
					+		 *	so set the length to one, and data to 0
 | 
				
			||||||
 | 
					+		 */
 | 
				
			||||||
 | 
					+		msg->len = 1;
 | 
				
			||||||
 | 
					+		i2c->buf = buf;
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		i2c->buf = msg->buf;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (msg->flags & I2C_M_TEN) {
 | 
				
			||||||
 | 
					+		printk
 | 
				
			||||||
 | 
					+			("%s:%d: Presently the driver does not handle extended addressing\n",
 | 
				
			||||||
 | 
					+				__FUNCTION__, __LINE__);
 | 
				
			||||||
 | 
					+		return -EINVAL;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	i2c->msg = msg;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	for (i = 0; i < msg->len; i++) {
 | 
				
			||||||
 | 
					+		if (msg->len - i >= 4)
 | 
				
			||||||
 | 
					+			i2c->rd_wr_len = 3;
 | 
				
			||||||
 | 
					+		else
 | 
				
			||||||
 | 
					+			i2c->rd_wr_len = msg->len - i - 1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		// Set Data Width	and TWI_EN
 | 
				
			||||||
 | 
					+		I2C_CONTROLLER_REG = 0x80000000 | (i2c->rd_wr_len << 2) | (i2c->rd_wr_len);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		// Clear Write Reg
 | 
				
			||||||
 | 
					+		I2C_WRITE_DATA_REG = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		// Set the slave address
 | 
				
			||||||
 | 
					+		I2C_SLAVE_ADDRESS_REG = (msg->addr << 1);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		// Are we Writing
 | 
				
			||||||
 | 
					+		if (!(msg->flags & I2C_M_RD)) {
 | 
				
			||||||
 | 
					+			I2C_CONTROLLER_REG |= (1 << 4);
 | 
				
			||||||
 | 
					+			if (i != 0) {
 | 
				
			||||||
 | 
					+				/*
 | 
				
			||||||
 | 
					+				 * We need to set the address in the first byte.
 | 
				
			||||||
 | 
					+				 * The base address is going to be in buf[0] and then
 | 
				
			||||||
 | 
					+				 * it needs to be incremented by i - 1.
 | 
				
			||||||
 | 
					+				 */
 | 
				
			||||||
 | 
					+				i2c->buf--;
 | 
				
			||||||
 | 
					+				*i2c->buf = buf[0] + i - 1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+				if (i2c->rd_wr_len < 3) {
 | 
				
			||||||
 | 
					+					i += i2c->rd_wr_len;
 | 
				
			||||||
 | 
					+					i2c->rd_wr_len++;
 | 
				
			||||||
 | 
					+					I2C_CONTROLLER_REG = 0x80000000 | (1 << 4) | (i2c->rd_wr_len << 2) | (i2c->rd_wr_len);
 | 
				
			||||||
 | 
					+				} else {
 | 
				
			||||||
 | 
					+					i += i2c->rd_wr_len - 1;
 | 
				
			||||||
 | 
					+				}
 | 
				
			||||||
 | 
					+			} else {
 | 
				
			||||||
 | 
					+				i += i2c->rd_wr_len;
 | 
				
			||||||
 | 
					+				buf[0] = *i2c->buf;
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+			for (j = 0; j <= i2c->rd_wr_len; j++) {
 | 
				
			||||||
 | 
					+				I2C_WRITE_DATA_REG |= ((*i2c->buf++) << (8 * j));
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			i += i2c->rd_wr_len;
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		// Start the Transfer
 | 
				
			||||||
 | 
					+		i2c->state = 0;		// Clear out the State
 | 
				
			||||||
 | 
					+		I2C_CONTROLLER_REG |= (1 << 6);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
 | 
				
			||||||
 | 
					+				(i2c->state == STATE_DONE), TWI_TIMEOUT)) {
 | 
				
			||||||
 | 
					+			if (i2c->state == STATE_ERROR) {
 | 
				
			||||||
 | 
					+				return -EIO;
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			return -ETIMEDOUT;
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int
 | 
				
			||||||
 | 
					+cns3xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	int i;
 | 
				
			||||||
 | 
					+	int ret;
 | 
				
			||||||
 | 
					+	for (i = 0; i < num; i++)
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		ret = cns3xxx_i2c_xfer_msg(adap, &msgs[i]);
 | 
				
			||||||
 | 
					+		if (ret < 0) {
 | 
				
			||||||
 | 
					+			return ret;
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	return num;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct i2c_algorithm cns3xxx_i2c_algo = {
 | 
				
			||||||
 | 
					+	.master_xfer = cns3xxx_i2c_xfer,
 | 
				
			||||||
 | 
					+	.functionality = cns3xxx_i2c_func,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct i2c_adapter cns3xxx_i2c_adapter = {
 | 
				
			||||||
 | 
					+	.owner = THIS_MODULE,
 | 
				
			||||||
 | 
					+	.algo = &cns3xxx_i2c_algo,
 | 
				
			||||||
 | 
					+	.algo_data = NULL,
 | 
				
			||||||
 | 
					+	.nr = 0,
 | 
				
			||||||
 | 
					+	.name = "CNS3xxx I2C 0",
 | 
				
			||||||
 | 
					+	.retries = 5,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void cns3xxx_i2c_adapter_init(struct cns3xxx_i2c *i2c)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+        cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C);
 | 
				
			||||||
 | 
					+        cns3xxx_pwr_power_up(1 << PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C);
 | 
				
			||||||
 | 
					+        cns3xxx_pwr_soft_rst(1 << PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Disable the I2C */
 | 
				
			||||||
 | 
					+	I2C_CONTROLLER_REG = 0;	/* Disabled the I2C */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	//enable SCL and SDA which share pin with GPIOB_PIN_EN(0x18)
 | 
				
			||||||
 | 
					+	//GPIOB[12]: SCL
 | 
				
			||||||
 | 
					+	//GPIOB[13]: SDA
 | 
				
			||||||
 | 
					+	(*(u32*)(CNS3XXX_MISC_BASE_VIRT+0x18)) |= ((1<<12)|(1<<13));
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	MISC_IOCDB_CTRL &= ~0x300;
 | 
				
			||||||
 | 
					+	MISC_IOCDB_CTRL |= 0x300; //21mA...
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Check the Reg Dump when testing */
 | 
				
			||||||
 | 
					+	I2C_TIME_OUT_REG =
 | 
				
			||||||
 | 
					+	    ((((((cns3xxx_cpu_clock()*(1000000/8)) / (2 * CNS3xxx_I2C_CLK)) -
 | 
				
			||||||
 | 
					+		1) & 0x3FF) << 8) | (1 << 7) | 0x7F);
 | 
				
			||||||
 | 
					+	I2C_TWI_OUT_DLY_REG |= 0x3;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Enable The Interrupt */
 | 
				
			||||||
 | 
					+	CNS3xxx_I2C_ENABLE_INTR();
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Clear Interrupt Status (0x2 | 0x1) */
 | 
				
			||||||
 | 
					+	I2C_INTERRUPT_STATUS_REG |= (I2C_ACTION_DONE_FLAG | I2C_BUS_ERROR_FLAG);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Enable the I2C Controller */
 | 
				
			||||||
 | 
					+	CNS3xxx_I2C_ENABLE();
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static irqreturn_t cns3xxx_i2c_isr(int irq, void *dev_id)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_i2c *i2c = dev_id;
 | 
				
			||||||
 | 
					+	int i;
 | 
				
			||||||
 | 
					+	uint32_t stat = I2C_INTERRUPT_STATUS_REG;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Clear Interrupt */
 | 
				
			||||||
 | 
					+	I2C_INTERRUPT_STATUS_REG |= 0x1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (stat & I2C_BUS_ERROR_FLAG) {
 | 
				
			||||||
 | 
					+		i2c->state = STATE_ERROR;
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		if (i2c->msg->flags & I2C_M_RD) {
 | 
				
			||||||
 | 
					+			for (i = 0; i <= i2c->rd_wr_len; i++)
 | 
				
			||||||
 | 
					+			{
 | 
				
			||||||
 | 
					+				*i2c->buf++ = ((I2C_READ_DATA_REG >> (8 * i)) & 0xff);
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+		i2c->state = STATE_DONE;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	wake_up(&i2c->wait);
 | 
				
			||||||
 | 
					+	return IRQ_HANDLED;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __devinit cns3xxx_i2c_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_i2c *i2c;
 | 
				
			||||||
 | 
					+	struct resource *res, *res2;
 | 
				
			||||||
 | 
					+	int ret;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
				
			||||||
 | 
					+	if (!res) {
 | 
				
			||||||
 | 
					+		printk("%s: IORESOURCE_MEM not defined \n", __FUNCTION__);
 | 
				
			||||||
 | 
					+		return -ENODEV;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 | 
				
			||||||
 | 
					+	if (!res2) {
 | 
				
			||||||
 | 
					+		printk("%s: IORESOURCE_IRQ not defined \n", __FUNCTION__);
 | 
				
			||||||
 | 
					+		return -ENODEV;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
 | 
				
			||||||
 | 
					+	if (!i2c)
 | 
				
			||||||
 | 
					+		return -ENOMEM;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (!request_mem_region(res->start, res->end - res->start + 1,
 | 
				
			||||||
 | 
					+				pdev->name)) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "Memory region busy\n");
 | 
				
			||||||
 | 
					+		ret = -EBUSY;
 | 
				
			||||||
 | 
					+		goto request_mem_failed;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	i2c->base = ioremap(res->start, res->end - res->start + 1);
 | 
				
			||||||
 | 
					+	if (!i2c->base) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "Unable to map registers\n");
 | 
				
			||||||
 | 
					+		ret = -EIO;
 | 
				
			||||||
 | 
					+		goto map_failed;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	cns3xxx_i2c_adapter_init(i2c);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	init_waitqueue_head(&i2c->wait);
 | 
				
			||||||
 | 
					+	ret = request_irq(res2->start, cns3xxx_i2c_isr, 0, pdev->name, i2c);
 | 
				
			||||||
 | 
					+	if (ret) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "Cannot claim IRQ\n");
 | 
				
			||||||
 | 
					+		goto request_irq_failed;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	platform_set_drvdata(pdev, i2c);
 | 
				
			||||||
 | 
					+	i2c->adap = cns3xxx_i2c_adapter;
 | 
				
			||||||
 | 
					+	i2c_set_adapdata(&i2c->adap, i2c);
 | 
				
			||||||
 | 
					+	i2c->adap.dev.parent = &pdev->dev;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* add i2c adapter to i2c tree */
 | 
				
			||||||
 | 
					+	ret = i2c_add_numbered_adapter(&i2c->adap);
 | 
				
			||||||
 | 
					+	if (ret) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "Failed to add adapter\n");
 | 
				
			||||||
 | 
					+		goto add_adapter_failed;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+      add_adapter_failed:
 | 
				
			||||||
 | 
					+	free_irq(res2->start, i2c);
 | 
				
			||||||
 | 
					+      request_irq_failed:
 | 
				
			||||||
 | 
					+	iounmap(i2c->base);
 | 
				
			||||||
 | 
					+      map_failed:
 | 
				
			||||||
 | 
					+	release_mem_region(res->start, res->end - res->start + 1);
 | 
				
			||||||
 | 
					+      request_mem_failed:
 | 
				
			||||||
 | 
					+	kfree(i2c);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return ret;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __devexit cns3xxx_i2c_remove(struct platform_device *pdev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_i2c *i2c = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
					+	struct resource *res;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* disable i2c logic */
 | 
				
			||||||
 | 
					+	CNS3xxx_I2C_DISABLE_INTR();
 | 
				
			||||||
 | 
					+	CNS3xxx_I2C_DISABLE();
 | 
				
			||||||
 | 
					+	/* remove adapter & data */
 | 
				
			||||||
 | 
					+	i2c_del_adapter(&i2c->adap);
 | 
				
			||||||
 | 
					+	platform_set_drvdata(pdev, NULL);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 | 
				
			||||||
 | 
					+	if (res)
 | 
				
			||||||
 | 
					+		free_irq(res->start, i2c);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	iounmap(i2c->base);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
				
			||||||
 | 
					+	if (res)
 | 
				
			||||||
 | 
					+		release_mem_region(res->start, res->end - res->start + 1);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	kfree(i2c);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					+#warning "CONFIG_PM defined: suspend and resume not implemented"
 | 
				
			||||||
 | 
					+#define cns3xxx_i2c_suspend	NULL
 | 
				
			||||||
 | 
					+#define cns3xxx_i2c_resume	NULL
 | 
				
			||||||
 | 
					+#else
 | 
				
			||||||
 | 
					+#define cns3xxx_i2c_suspend	NULL
 | 
				
			||||||
 | 
					+#define cns3xxx_i2c_resume	NULL
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_driver cns3xxx_i2c_driver = {
 | 
				
			||||||
 | 
					+	.probe = cns3xxx_i2c_probe,
 | 
				
			||||||
 | 
					+	.remove = cns3xxx_i2c_remove,
 | 
				
			||||||
 | 
					+	.suspend = cns3xxx_i2c_suspend,
 | 
				
			||||||
 | 
					+	.resume = cns3xxx_i2c_resume,
 | 
				
			||||||
 | 
					+	.driver = {
 | 
				
			||||||
 | 
					+		.owner = THIS_MODULE,
 | 
				
			||||||
 | 
					+		.name = "cns3xxx-i2c",
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __init cns3xxx_i2c_init(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return platform_driver_register(&cns3xxx_i2c_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __exit cns3xxx_i2c_exit(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	platform_driver_unregister(&cns3xxx_i2c_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+module_init(cns3xxx_i2c_init);
 | 
				
			||||||
 | 
					+module_exit(cns3xxx_i2c_exit);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+MODULE_AUTHOR("Cavium Networks");
 | 
				
			||||||
 | 
					+MODULE_DESCRIPTION("Cavium CNS3XXX I2C Controller");
 | 
				
			||||||
 | 
					+MODULE_LICENSE("GPL");
 | 
				
			||||||
							
								
								
									
										1301
									
								
								target/linux/cns3xxx/patches/051-cns3xxx_gigabit.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1301
									
								
								target/linux/cns3xxx/patches/051-cns3xxx_gigabit.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										509
									
								
								target/linux/cns3xxx/patches/052-cns3xxx_spi.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										509
									
								
								target/linux/cns3xxx/patches/052-cns3xxx_spi.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,509 @@
 | 
				
			|||||||
 | 
					--- a/drivers/spi/Kconfig
 | 
				
			||||||
 | 
					+++ b/drivers/spi/Kconfig
 | 
				
			||||||
 | 
					@@ -114,6 +114,13 @@ config SPI_BUTTERFLY
 | 
				
			||||||
 | 
					 	  inexpensive battery powered microcontroller evaluation board.
 | 
				
			||||||
 | 
					 	  This same cable can be used to flash new firmware.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+config SPI_CNS3XXX
 | 
				
			||||||
 | 
					+	tristate "CNS3XXX SPI controller"
 | 
				
			||||||
 | 
					+	depends on ARCH_CNS3XXX && SPI_MASTER
 | 
				
			||||||
 | 
					+	select SPI_BITBANG
 | 
				
			||||||
 | 
					+	help
 | 
				
			||||||
 | 
					+	  This enables using the CNS3XXX SPI controller in master mode.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 config SPI_COLDFIRE_QSPI
 | 
				
			||||||
 | 
					 	tristate "Freescale Coldfire QSPI controller"
 | 
				
			||||||
 | 
					 	depends on (M520x || M523x || M5249 || M527x || M528x || M532x)
 | 
				
			||||||
 | 
					--- a/drivers/spi/Makefile
 | 
				
			||||||
 | 
					+++ b/drivers/spi/Makefile
 | 
				
			||||||
 | 
					@@ -55,6 +55,7 @@ obj-$(CONFIG_SPI_SH_SCI)		+= spi_sh_sci.
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SPI_SH_MSIOF)		+= spi_sh_msiof.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SPI_STMP3XXX)		+= spi_stmp.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SPI_NUC900)		+= spi_nuc900.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_SPI_CNS3XXX)		+= spi_cns3xxx.o
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 # special build for s3c24xx spi driver with fiq support
 | 
				
			||||||
 | 
					 spi_s3c24xx_hw-y			:= spi_s3c24xx.o
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/drivers/spi/spi_cns3xxx.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,449 @@
 | 
				
			||||||
 | 
					+/*******************************************************************************
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  CNS3XXX SPI controller driver (master mode only)
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  Copyright (c) 2008 Cavium Networks
 | 
				
			||||||
 | 
					+ *  Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		   Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  This file 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.
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  This file is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					+ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 | 
				
			||||||
 | 
					+ *  NONINFRINGEMENT.  See the GNU General Public License for more details.
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					+ *  along with this file; if not, write to the Free Software
 | 
				
			||||||
 | 
					+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or
 | 
				
			||||||
 | 
					+ *  visit http://www.gnu.org/licenses/.
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ *  This file may also be available under a different license from Cavium.
 | 
				
			||||||
 | 
					+ *  Contact Cavium Networks for more information
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ ******************************************************************************/
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <linux/init.h>
 | 
				
			||||||
 | 
					+#include <linux/spinlock.h>
 | 
				
			||||||
 | 
					+#include <linux/workqueue.h>
 | 
				
			||||||
 | 
					+#include <linux/interrupt.h>
 | 
				
			||||||
 | 
					+#include <linux/delay.h>
 | 
				
			||||||
 | 
					+#include <linux/errno.h>
 | 
				
			||||||
 | 
					+#include <linux/err.h>
 | 
				
			||||||
 | 
					+#include <linux/clk.h>
 | 
				
			||||||
 | 
					+#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <linux/spi/spi.h>
 | 
				
			||||||
 | 
					+#include <linux/spi/spi_bitbang.h>
 | 
				
			||||||
 | 
					+#include <linux/mtd/partitions.h>
 | 
				
			||||||
 | 
					+#include <linux/dma-mapping.h>
 | 
				
			||||||
 | 
					+#include <linux/slab.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <asm/io.h>
 | 
				
			||||||
 | 
					+#include <asm/memory.h>
 | 
				
			||||||
 | 
					+#include <asm/dma.h>
 | 
				
			||||||
 | 
					+#include <asm/delay.h>
 | 
				
			||||||
 | 
					+#include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					+#include <linux/module.h>
 | 
				
			||||||
 | 
					+#include <mach/pm.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * define access macros
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset)))
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define SPI_CONFIGURATION_REG			SPI_MEM_MAP_VALUE(0x40)
 | 
				
			||||||
 | 
					+#define SPI_SERVICE_STATUS_REG			SPI_MEM_MAP_VALUE(0x44)
 | 
				
			||||||
 | 
					+#define SPI_BIT_RATE_CONTROL_REG		SPI_MEM_MAP_VALUE(0x48)
 | 
				
			||||||
 | 
					+#define SPI_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x4C)
 | 
				
			||||||
 | 
					+#define SPI_TRANSMIT_BUFFER_REG			SPI_MEM_MAP_VALUE(0x50)
 | 
				
			||||||
 | 
					+#define SPI_RECEIVE_CONTROL_REG			SPI_MEM_MAP_VALUE(0x54)
 | 
				
			||||||
 | 
					+#define SPI_RECEIVE_BUFFER_REG			SPI_MEM_MAP_VALUE(0x58)
 | 
				
			||||||
 | 
					+#define SPI_FIFO_TRANSMIT_CONFIG_REG		SPI_MEM_MAP_VALUE(0x5C)
 | 
				
			||||||
 | 
					+#define SPI_FIFO_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x60)
 | 
				
			||||||
 | 
					+#define SPI_FIFO_RECEIVE_CONFIG_REG		SPI_MEM_MAP_VALUE(0x64)
 | 
				
			||||||
 | 
					+#define SPI_INTERRUPT_STATUS_REG		SPI_MEM_MAP_VALUE(0x68)
 | 
				
			||||||
 | 
					+#define SPI_INTERRUPT_ENABLE_REG		SPI_MEM_MAP_VALUE(0x6C)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define SPI_TRANSMIT_BUFFER_REG_ADDR		(CNS3XXX_SSP_BASE +0x50)
 | 
				
			||||||
 | 
					+#define SPI_RECEIVE_BUFFER_REG_ADDR		(CNS3XXX_SSP_BASE +0x58)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/* Structure for SPI controller of CNS3XXX SOCs */
 | 
				
			||||||
 | 
					+struct cns3xxx_spi {
 | 
				
			||||||
 | 
					+	/* bitbang has to be first */
 | 
				
			||||||
 | 
					+	struct spi_bitbang bitbang;
 | 
				
			||||||
 | 
					+	struct completion done;
 | 
				
			||||||
 | 
					+	wait_queue_head_t wait;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	int len;
 | 
				
			||||||
 | 
					+	int count;
 | 
				
			||||||
 | 
					+	int last_in_message_list;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* data buffers */
 | 
				
			||||||
 | 
					+	const unsigned char *tx;
 | 
				
			||||||
 | 
					+	unsigned char *rx;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	struct spi_master *master;
 | 
				
			||||||
 | 
					+	struct platform_device *pdev;
 | 
				
			||||||
 | 
					+	struct device *dev;
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline u8 cns3xxx_spi_bus_idle(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return ((SPI_SERVICE_STATUS_REG & 0x1) ? 0 : 1);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline u8 cns3xxx_spi_tx_buffer_empty(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 3)) ? 1 : 0);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline u8 cns3xxx_spi_rx_buffer_full(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 2)) ? 1 : 0);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+u8 cns3xxx_spi_tx_rx(u8 tx_channel, u8 tx_eof, u32 tx_data,
 | 
				
			||||||
 | 
					+			    u32 * rx_data)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	u8 rx_channel;
 | 
				
			||||||
 | 
					+	u8 rx_eof;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	while (!cns3xxx_spi_bus_idle()) ;	// do nothing
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	while (!cns3xxx_spi_tx_buffer_empty()) ;	// do nothing
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
 | 
				
			||||||
 | 
					+	SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	SPI_TRANSMIT_BUFFER_REG = tx_data;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	while (!cns3xxx_spi_rx_buffer_full()) ;	// do nothing
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	rx_channel = SPI_RECEIVE_CONTROL_REG & 0x3;
 | 
				
			||||||
 | 
					+	rx_eof = (SPI_RECEIVE_CONTROL_REG & (0x1 << 2)) ? 1 : 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	*rx_data = SPI_RECEIVE_BUFFER_REG;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if ((tx_channel != rx_channel) || (tx_eof != rx_eof)) {
 | 
				
			||||||
 | 
					+		return 0;
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		return 1;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+u8 cns3xxx_spi_tx(u8 tx_channel, u8 tx_eof, u32 tx_data)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+        while (!cns3xxx_spi_bus_idle()) ;       // do nothing
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+        while (!cns3xxx_spi_tx_buffer_empty()) ;        // do nothing
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+        SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
 | 
				
			||||||
 | 
					+        SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+        SPI_TRANSMIT_BUFFER_REG = tx_data;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+        return 1;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline struct cns3xxx_spi *to_hw(struct spi_device *sdev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return spi_master_get_devdata(sdev->master);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_spi_setup_transfer(struct spi_device *spi,
 | 
				
			||||||
 | 
					+				      struct spi_transfer *t)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void cns3xxx_spi_chipselect(struct spi_device *spi, int value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned int spi_config;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	switch (value) {
 | 
				
			||||||
 | 
					+	case BITBANG_CS_INACTIVE:
 | 
				
			||||||
 | 
					+		break;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	case BITBANG_CS_ACTIVE:
 | 
				
			||||||
 | 
					+		spi_config = SPI_CONFIGURATION_REG;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (spi->mode & SPI_CPHA)
 | 
				
			||||||
 | 
					+			spi_config |= (0x1 << 13);
 | 
				
			||||||
 | 
					+		else
 | 
				
			||||||
 | 
					+			spi_config &= ~(0x1 << 13);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (spi->mode & SPI_CPOL)
 | 
				
			||||||
 | 
					+			spi_config |= (0x1 << 14);
 | 
				
			||||||
 | 
					+		else
 | 
				
			||||||
 | 
					+			spi_config &= ~(0x1 << 14);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		/* write new configration */
 | 
				
			||||||
 | 
					+		SPI_CONFIGURATION_REG = spi_config;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
 | 
				
			||||||
 | 
					+		SPI_TRANSMIT_CONTROL_REG |= (spi->chip_select & 0x3);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		break;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_spi_setup(struct spi_device *spi)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (!spi->bits_per_word)
 | 
				
			||||||
 | 
					+		spi->bits_per_word = 8;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_spi *hw = to_hw(spi);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf,
 | 
				
			||||||
 | 
					+		t->len);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	hw->tx = t->tx_buf;
 | 
				
			||||||
 | 
					+	hw->rx = t->rx_buf;
 | 
				
			||||||
 | 
					+	hw->len = t->len;
 | 
				
			||||||
 | 
					+	hw->count = 0;
 | 
				
			||||||
 | 
					+	hw->last_in_message_list = t->last_in_message_list;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	init_completion(&hw->done);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (hw->tx) {
 | 
				
			||||||
 | 
					+		int i;
 | 
				
			||||||
 | 
					+		u32 rx_data;
 | 
				
			||||||
 | 
					+		for (i = 0; i < (hw->len - 1); i++) {
 | 
				
			||||||
 | 
					+			dev_dbg(&spi->dev,
 | 
				
			||||||
 | 
					+				"[SPI_CNS3XXX_DEBUG] hw->tx[%02d]: 0x%02x\n", i,
 | 
				
			||||||
 | 
					+				hw->tx[i]);
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 0, hw->tx[i],
 | 
				
			||||||
 | 
					+					  &rx_data);
 | 
				
			||||||
 | 
					+			if (hw->rx) {
 | 
				
			||||||
 | 
					+				hw->rx[i] = rx_data;
 | 
				
			||||||
 | 
					+				dev_dbg(&spi->dev,
 | 
				
			||||||
 | 
					+					"[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
 | 
				
			||||||
 | 
					+					i, hw->rx[i]);
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (t->last_in_message_list) {
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 1, hw->tx[i],
 | 
				
			||||||
 | 
					+					  &rx_data);
 | 
				
			||||||
 | 
					+			if (hw->rx) {
 | 
				
			||||||
 | 
					+				hw->rx[i] = rx_data;
 | 
				
			||||||
 | 
					+				dev_dbg(&spi->dev,
 | 
				
			||||||
 | 
					+					"[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
 | 
				
			||||||
 | 
					+					i, hw->rx[i]);
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 0, hw->tx[i],
 | 
				
			||||||
 | 
					+					  &rx_data);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+		goto done;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (hw->rx) {
 | 
				
			||||||
 | 
					+		int i;
 | 
				
			||||||
 | 
					+		u32 rx_data;
 | 
				
			||||||
 | 
					+		for (i = 0; i < (hw->len - 1); i++) {
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data);
 | 
				
			||||||
 | 
					+			hw->rx[i] = rx_data;
 | 
				
			||||||
 | 
					+			dev_dbg(&spi->dev,
 | 
				
			||||||
 | 
					+				"[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", i,
 | 
				
			||||||
 | 
					+				hw->rx[i]);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (t->last_in_message_list) {
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 1, 0xff, &rx_data);
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			cns3xxx_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+		hw->rx[i] = rx_data;
 | 
				
			||||||
 | 
					+		dev_dbg(&spi->dev, "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
 | 
				
			||||||
 | 
					+			i, hw->rx[i]);
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+done:
 | 
				
			||||||
 | 
					+	return hw->len;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __init cns3xxx_spi_initial(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	u32 __iomem *gpiob = __io(CNS3XXX_MISC_BASE_VIRT + 0x0018);
 | 
				
			||||||
 | 
					+	u32 gpiob_pins = __raw_readl(gpiob);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* MMC/SD pins share with GPIOA */
 | 
				
			||||||
 | 
					+	gpiob_pins |= 0xf80;
 | 
				
			||||||
 | 
					+	__raw_writel(gpiob_pins, gpiob);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* share pin config. */
 | 
				
			||||||
 | 
					+	//PM_PLL_HM_PD_CTRL_REG &= ~(0x1 << 5);
 | 
				
			||||||
 | 
					+	//HAL_MISC_ENABLE_SPI_PINS();
 | 
				
			||||||
 | 
					+	cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SPI_PCM_I2C));
 | 
				
			||||||
 | 
					+	cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SPI_PCM_I2C));
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	SPI_CONFIGURATION_REG = (((0x0 & 0x3) << 0) |	/* 8bits shift length */
 | 
				
			||||||
 | 
					+				 (0x0 << 9) |	/* SPI mode */
 | 
				
			||||||
 | 
					+				 (0x0 << 10) |	/* disable FIFO */
 | 
				
			||||||
 | 
					+				 (0x1 << 11) |	/* SPI master mode */
 | 
				
			||||||
 | 
					+				 (0x0 << 12) |	/* disable SPI loopback mode */
 | 
				
			||||||
 | 
					+				 (0x1 << 13) |	/* clock phase */
 | 
				
			||||||
 | 
					+				 (0x1 << 14) |	/* clock polarity */
 | 
				
			||||||
 | 
					+				 (0x0 << 24) |	/* disable - SPI data swap */
 | 
				
			||||||
 | 
					+				 (0x1 << 29) |	/* enable - 2IO Read mode */
 | 
				
			||||||
 | 
					+				 (0x0 << 30) |	/* disable - SPI high speed read for system boot up */
 | 
				
			||||||
 | 
					+				 (0x0 << 31));	/* disable - SPI */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Set SPI bit rate PCLK/2 */
 | 
				
			||||||
 | 
					+	SPI_BIT_RATE_CONTROL_REG = 0x1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Set SPI Tx channel 0 */
 | 
				
			||||||
 | 
					+	SPI_TRANSMIT_CONTROL_REG = 0x0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Set Tx FIFO Threshold, Tx FIFO has 2 words */
 | 
				
			||||||
 | 
					+	SPI_FIFO_TRANSMIT_CONFIG_REG &= ~(0x03 << 4);
 | 
				
			||||||
 | 
					+	SPI_FIFO_TRANSMIT_CONFIG_REG |= ((0x0 & 0x03) << 4);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Set Rx FIFO Threshold, Rx FIFO has 2 words */
 | 
				
			||||||
 | 
					+	SPI_FIFO_RECEIVE_CONFIG_REG &= ~(0x03 << 4);
 | 
				
			||||||
 | 
					+	SPI_FIFO_RECEIVE_CONFIG_REG |= ((0x0 & 0x03) << 4);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Disable all interrupt */
 | 
				
			||||||
 | 
					+	SPI_INTERRUPT_ENABLE_REG = 0x0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Clear spurious interrupt sources */
 | 
				
			||||||
 | 
					+	SPI_INTERRUPT_STATUS_REG = (0x0F << 4);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Enable SPI */
 | 
				
			||||||
 | 
					+	SPI_CONFIGURATION_REG |= (0x1 << 31);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __init cns3xxx_spi_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct spi_master *master;
 | 
				
			||||||
 | 
					+	struct cns3xxx_spi *hw;
 | 
				
			||||||
 | 
					+	int err = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	printk("%s: setup CNS3XXX SPI Controller\n", __FUNCTION__);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Allocate master with space for cns3xxx_spi */
 | 
				
			||||||
 | 
					+	master = spi_alloc_master(&pdev->dev, sizeof(struct cns3xxx_spi));
 | 
				
			||||||
 | 
					+	if (master == NULL) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "No memory for spi_master\n");
 | 
				
			||||||
 | 
					+		err = -ENOMEM;
 | 
				
			||||||
 | 
					+		goto err_nomem;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	hw = spi_master_get_devdata(master);
 | 
				
			||||||
 | 
					+	memset(hw, 0, sizeof(struct cns3xxx_spi));
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	hw->master = spi_master_get(master);
 | 
				
			||||||
 | 
					+	hw->dev = &pdev->dev;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	platform_set_drvdata(pdev, hw);
 | 
				
			||||||
 | 
					+	init_completion(&hw->done);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* setup the master state. */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	master->num_chipselect = 4;
 | 
				
			||||||
 | 
					+	master->bus_num = 1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* setup the state for the bitbang driver */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	hw->bitbang.master = hw->master;
 | 
				
			||||||
 | 
					+	hw->bitbang.setup_transfer = cns3xxx_spi_setup_transfer;
 | 
				
			||||||
 | 
					+	hw->bitbang.chipselect = cns3xxx_spi_chipselect;
 | 
				
			||||||
 | 
					+	hw->bitbang.txrx_bufs = cns3xxx_spi_txrx;
 | 
				
			||||||
 | 
					+	hw->bitbang.master->setup = cns3xxx_spi_setup;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* SPI controller initializations */
 | 
				
			||||||
 | 
					+	cns3xxx_spi_initial();
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* register SPI controller */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	err = spi_bitbang_start(&hw->bitbang);
 | 
				
			||||||
 | 
					+	if (err) {
 | 
				
			||||||
 | 
					+		dev_err(&pdev->dev, "Failed to register SPI master\n");
 | 
				
			||||||
 | 
					+		goto err_register;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+err_register:
 | 
				
			||||||
 | 
					+	spi_master_put(hw->master);;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+err_nomem:
 | 
				
			||||||
 | 
					+	return err;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __devexit cns3xxx_spi_remove(struct platform_device *dev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_spi *hw = platform_get_drvdata(dev);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	platform_set_drvdata(dev, NULL);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	spi_unregister_master(hw->master);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	spi_master_put(hw->master);
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_spi *hw = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_spi_resume(struct platform_device *pdev)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct cns3xxx_spi *hw = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#else
 | 
				
			||||||
 | 
					+#define cns3xxx_spi_suspend	NULL
 | 
				
			||||||
 | 
					+#define cns3xxx_spi_resume	NULL
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_driver cns3xxx_spi_driver = {
 | 
				
			||||||
 | 
					+	.probe		= cns3xxx_spi_probe,
 | 
				
			||||||
 | 
					+	.remove		= __devexit_p(cns3xxx_spi_remove),
 | 
				
			||||||
 | 
					+	.suspend	= cns3xxx_spi_suspend,
 | 
				
			||||||
 | 
					+	.resume		= cns3xxx_spi_resume,
 | 
				
			||||||
 | 
					+	.driver		= {
 | 
				
			||||||
 | 
					+		.name = "cns3xxx_spi",
 | 
				
			||||||
 | 
					+		.owner = THIS_MODULE,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __init cns3xxx_spi_init(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return platform_driver_register(&cns3xxx_spi_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __exit cns3xxx_spi_exit(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	platform_driver_unregister(&cns3xxx_spi_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+module_init(cns3xxx_spi_init);
 | 
				
			||||||
 | 
					+module_exit(cns3xxx_spi_exit);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+MODULE_AUTHOR("Cavium Networks");
 | 
				
			||||||
 | 
					+MODULE_DESCRIPTION("CNS3XXX SPI Controller Driver");
 | 
				
			||||||
 | 
					+MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					+MODULE_ALIAS("platform:cns3xxx_spi");
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+EXPORT_SYMBOL_GPL(cns3xxx_spi_tx_rx);
 | 
				
			||||||
 | 
					--- a/include/linux/spi/spi.h
 | 
				
			||||||
 | 
					+++ b/include/linux/spi/spi.h
 | 
				
			||||||
 | 
					@@ -446,6 +446,13 @@ struct spi_transfer {
 | 
				
			||||||
 | 
					 	u32		speed_hz;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	struct list_head transfer_list;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#ifdef CONFIG_ARCH_CNS3XXX
 | 
				
			||||||
 | 
					+	unsigned	last_in_message_list;
 | 
				
			||||||
 | 
					+#ifdef CONFIG_SPI_CNS3XXX_2IOREAD
 | 
				
			||||||
 | 
					+	u8		dio_read;
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
 | 
					--- a/drivers/spi/spi_bitbang.c
 | 
				
			||||||
 | 
					+++ b/drivers/spi/spi_bitbang.c
 | 
				
			||||||
 | 
					@@ -329,6 +329,12 @@ static void bitbang_work(struct work_str
 | 
				
			||||||
 | 
					 				 */
 | 
				
			||||||
 | 
					 				if (!m->is_dma_mapped)
 | 
				
			||||||
 | 
					 					t->rx_dma = t->tx_dma = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+				if (t->transfer_list.next == &m->transfers)
 | 
				
			||||||
 | 
					+					t->last_in_message_list = 1;
 | 
				
			||||||
 | 
					+				else
 | 
				
			||||||
 | 
					+					t->last_in_message_list = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 				status = bitbang->txrx_bufs(spi, t);
 | 
				
			||||||
 | 
					 			}
 | 
				
			||||||
 | 
					 			if (status > 0)
 | 
				
			||||||
							
								
								
									
										77
									
								
								target/linux/cns3xxx/patches/053-cns3xxx_wdt.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								target/linux/cns3xxx/patches/053-cns3xxx_wdt.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					--- a/drivers/watchdog/Kconfig
 | 
				
			||||||
 | 
					+++ b/drivers/watchdog/Kconfig
 | 
				
			||||||
 | 
					@@ -188,7 +188,7 @@ config SA1100_WATCHDOG
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 config MPCORE_WATCHDOG
 | 
				
			||||||
 | 
					 	tristate "MPcore watchdog"
 | 
				
			||||||
 | 
					-	depends on HAVE_ARM_TWD
 | 
				
			||||||
 | 
					+	depends on ARCH_CNS3XXX
 | 
				
			||||||
 | 
					 	help
 | 
				
			||||||
 | 
					 	  Watchdog timer embedded into the MPcore system.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/drivers/watchdog/mpcore_wdt.c
 | 
				
			||||||
 | 
					+++ b/drivers/watchdog/mpcore_wdt.c
 | 
				
			||||||
 | 
					@@ -32,11 +32,14 @@
 | 
				
			||||||
 | 
					 #include <linux/uaccess.h>
 | 
				
			||||||
 | 
					 #include <linux/slab.h>
 | 
				
			||||||
 | 
					 #include <linux/io.h>
 | 
				
			||||||
 | 
					+#include <linux/jiffies.h>
 | 
				
			||||||
 | 
					+#include <linux/delay.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #include <asm/smp_twd.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 struct mpcore_wdt {
 | 
				
			||||||
 | 
					 	unsigned long	timer_alive;
 | 
				
			||||||
 | 
					+	unsigned long	timer_rate;
 | 
				
			||||||
 | 
					 	struct device	*dev;
 | 
				
			||||||
 | 
					 	void __iomem	*base;
 | 
				
			||||||
 | 
					 	int		irq;
 | 
				
			||||||
 | 
					@@ -98,14 +101,12 @@ static void mpcore_wdt_keepalive(struct
 | 
				
			||||||
 | 
					 	unsigned long count;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	spin_lock(&wdt_lock);
 | 
				
			||||||
 | 
					-	/* Assume prescale is set to 256 */
 | 
				
			||||||
 | 
					-	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
 | 
				
			||||||
 | 
					-	count = (0xFFFFFFFFU - count) * (HZ / 5);
 | 
				
			||||||
 | 
					-	count = (count / 256) * mpcore_margin;
 | 
				
			||||||
 | 
					+	count = (wdt->timer_rate / 256) * mpcore_margin;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* Reload the counter */
 | 
				
			||||||
 | 
					 	writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
 | 
				
			||||||
 | 
					 	wdt->perturb = wdt->perturb ? 0 : 1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	spin_unlock(&wdt_lock);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -329,6 +330,8 @@ static int __devinit mpcore_wdt_probe(st
 | 
				
			||||||
 | 
					 	struct mpcore_wdt *wdt;
 | 
				
			||||||
 | 
					 	struct resource *res;
 | 
				
			||||||
 | 
					 	int ret;
 | 
				
			||||||
 | 
					+	unsigned long count;
 | 
				
			||||||
 | 
					+	u64 waitjiffies;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* We only accept one device, and it must have an id of -1 */
 | 
				
			||||||
 | 
					 	if (dev->id != -1)
 | 
				
			||||||
 | 
					@@ -375,6 +378,22 @@ static int __devinit mpcore_wdt_probe(st
 | 
				
			||||||
 | 
					 		goto err_irq;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	waitjiffies = get_jiffies_64() + 1;
 | 
				
			||||||
 | 
					+	while (get_jiffies_64() < waitjiffies)
 | 
				
			||||||
 | 
					+		udelay(10);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	waitjiffies += 5;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	__raw_writel(0x00000001, wdt->base + TWD_WDOG_CONTROL);
 | 
				
			||||||
 | 
					+	__raw_writel(0xFFFFFFFFU, wdt->base + TWD_WDOG_LOAD);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	while (get_jiffies_64() < waitjiffies)
 | 
				
			||||||
 | 
					+		udelay(10);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	wdt->timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	mpcore_wdt_stop(wdt);
 | 
				
			||||||
 | 
					 	platform_set_drvdata(dev, wdt);
 | 
				
			||||||
 | 
					 	mpcore_wdt_dev = dev;
 | 
				
			||||||
							
								
								
									
										902
									
								
								target/linux/cns3xxx/patches/100-laguna_support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										902
									
								
								target/linux/cns3xxx/patches/100-laguna_support.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,902 @@
 | 
				
			|||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/laguna.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,670 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Gateworks Corporation Laguna Platform
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Copyright 2000 Deep Blue Solutions Ltd
 | 
				
			||||||
 | 
					+ * Copyright 2008 ARM Limited
 | 
				
			||||||
 | 
					+ * Copyright 2008 Cavium Networks
 | 
				
			||||||
 | 
					+ *		  Scott Shu
 | 
				
			||||||
 | 
					+ * Copyright 2010 MontaVista Software, LLC.
 | 
				
			||||||
 | 
					+ *		  Anton Vorontsov <avorontsov@mvista.com>
 | 
				
			||||||
 | 
					+ * Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		  Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * This file 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/init.h>
 | 
				
			||||||
 | 
					+#include <linux/kernel.h>
 | 
				
			||||||
 | 
					+#include <linux/compiler.h>
 | 
				
			||||||
 | 
					+#include <linux/io.h>
 | 
				
			||||||
 | 
					+#include <linux/dma-mapping.h>
 | 
				
			||||||
 | 
					+#include <linux/serial_core.h>
 | 
				
			||||||
 | 
					+#include <linux/serial_8250.h>
 | 
				
			||||||
 | 
					+#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					+#include <linux/mtd/mtd.h>
 | 
				
			||||||
 | 
					+#include <linux/mtd/physmap.h>
 | 
				
			||||||
 | 
					+#include <linux/mtd/partitions.h>
 | 
				
			||||||
 | 
					+#include <linux/leds.h>
 | 
				
			||||||
 | 
					+#include <linux/i2c.h>
 | 
				
			||||||
 | 
					+#include <linux/i2c/at24.h>
 | 
				
			||||||
 | 
					+#include <linux/i2c/pca953x.h>
 | 
				
			||||||
 | 
					+#include <linux/spi/spi.h>
 | 
				
			||||||
 | 
					+#include <linux/spi/flash.h>
 | 
				
			||||||
 | 
					+#include <linux/if_ether.h>
 | 
				
			||||||
 | 
					+#include <asm/setup.h>
 | 
				
			||||||
 | 
					+#include <asm/mach-types.h>
 | 
				
			||||||
 | 
					+#include <asm/mach/arch.h>
 | 
				
			||||||
 | 
					+#include <asm/mach/map.h>
 | 
				
			||||||
 | 
					+#include <asm/mach/time.h>
 | 
				
			||||||
 | 
					+#include <mach/hardware.h>
 | 
				
			||||||
 | 
					+#include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					+#include <mach/irqs.h>
 | 
				
			||||||
 | 
					+#include <mach/pm.h>
 | 
				
			||||||
 | 
					+#include "core.h"
 | 
				
			||||||
 | 
					+#include "devices.h"
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+// Config 1 Bitmap
 | 
				
			||||||
 | 
					+#define ETH0_LOAD           BIT(0)
 | 
				
			||||||
 | 
					+#define ETH1_LOAD           BIT(1)
 | 
				
			||||||
 | 
					+#define ETH2_LOAD           BIT(2)
 | 
				
			||||||
 | 
					+#define SATA0_LOAD          BIT(3)
 | 
				
			||||||
 | 
					+#define SATA1_LOAD          BIT(4)
 | 
				
			||||||
 | 
					+#define PCM_LOAD            BIT(5)
 | 
				
			||||||
 | 
					+#define I2S_LOAD            BIT(6)
 | 
				
			||||||
 | 
					+#define SPI0_LOAD           BIT(7)
 | 
				
			||||||
 | 
					+#define SPI1_LOAD           BIT(8)
 | 
				
			||||||
 | 
					+#define PCIE0_LOAD          BIT(9)
 | 
				
			||||||
 | 
					+#define PCIE1_LOAD          BIT(10)
 | 
				
			||||||
 | 
					+#define USB0_LOAD           BIT(11)
 | 
				
			||||||
 | 
					+#define USB1_LOAD           BIT(12)
 | 
				
			||||||
 | 
					+#define USB1_ROUTE          BIT(13)
 | 
				
			||||||
 | 
					+#define SD_LOAD             BIT(14)
 | 
				
			||||||
 | 
					+#define UART0_LOAD          BIT(15)
 | 
				
			||||||
 | 
					+#define UART1_LOAD          BIT(16)
 | 
				
			||||||
 | 
					+#define UART2_LOAD          BIT(17)
 | 
				
			||||||
 | 
					+#define MPCI0_LOAD          BIT(18)
 | 
				
			||||||
 | 
					+#define MPCI1_LOAD          BIT(19)
 | 
				
			||||||
 | 
					+#define MPCI2_LOAD          BIT(20)
 | 
				
			||||||
 | 
					+#define MPCI3_LOAD          BIT(21)
 | 
				
			||||||
 | 
					+#define FP_BUT_LOAD         BIT(22)
 | 
				
			||||||
 | 
					+#define FP_BUT_HEADER_LOAD  BIT(23)
 | 
				
			||||||
 | 
					+#define FP_LED_LOAD         BIT(24)
 | 
				
			||||||
 | 
					+#define FP_LED_HEADER_LOAD  BIT(25)
 | 
				
			||||||
 | 
					+#define FP_TAMPER_LOAD      BIT(26)
 | 
				
			||||||
 | 
					+#define HEADER_33V_LOAD     BIT(27)
 | 
				
			||||||
 | 
					+#define SATA_POWER_LOAD     BIT(28)
 | 
				
			||||||
 | 
					+#define FP_POWER_LOAD       BIT(29)
 | 
				
			||||||
 | 
					+#define GPIO_HEADER_LOAD    BIT(30)
 | 
				
			||||||
 | 
					+#define GSP_BAT_LOAD        BIT(31)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+// Config 2 Bitmap
 | 
				
			||||||
 | 
					+#define FAN_LOAD            BIT(0)
 | 
				
			||||||
 | 
					+#define SPI_FLASH_LOAD      BIT(1)
 | 
				
			||||||
 | 
					+#define NOR_FLASH_LOAD      BIT(2)
 | 
				
			||||||
 | 
					+#define GPS_LOAD            BIT(3)
 | 
				
			||||||
 | 
					+#define SUPPLY_5V_LOAD      BIT(6)
 | 
				
			||||||
 | 
					+#define SUPPLY_33V_LOAD     BIT(7)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+struct laguna_board_info {
 | 
				
			||||||
 | 
					+	char model[16];
 | 
				
			||||||
 | 
					+	u32 config_bitmap;
 | 
				
			||||||
 | 
					+	u32 config2_bitmap;
 | 
				
			||||||
 | 
					+	u8 nor_flash_size;
 | 
				
			||||||
 | 
					+	u8 spi_flash_size;
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct laguna_board_info laguna_info __initdata;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * NOR Flash
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct mtd_partition laguna_nor_partitions[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.name		= "uboot",
 | 
				
			||||||
 | 
					+		.size		= SZ_256K,
 | 
				
			||||||
 | 
					+		.offset		= 0,
 | 
				
			||||||
 | 
					+		.mask_flags	= MTD_WRITEABLE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "params",
 | 
				
			||||||
 | 
					+		.size		= SZ_128K,
 | 
				
			||||||
 | 
					+		.offset		= SZ_256K,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "kernel",
 | 
				
			||||||
 | 
					+		.size		= SZ_2M,
 | 
				
			||||||
 | 
					+		.offset		= SZ_256K + SZ_128K,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "rootfs",
 | 
				
			||||||
 | 
					+		.size		= SZ_16M - SZ_256K - SZ_128K - SZ_2M,
 | 
				
			||||||
 | 
					+		.offset		= SZ_256K + SZ_128K + SZ_2M,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct physmap_flash_data laguna_nor_pdata = {
 | 
				
			||||||
 | 
					+	.width = 2,
 | 
				
			||||||
 | 
					+	.parts = laguna_nor_partitions,
 | 
				
			||||||
 | 
					+	.nr_parts = ARRAY_SIZE(laguna_nor_partitions),
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct resource laguna_nor_res = {
 | 
				
			||||||
 | 
					+	.start = CNS3XXX_FLASH_BASE,
 | 
				
			||||||
 | 
					+	.end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
 | 
				
			||||||
 | 
					+	.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_nor_pdev = {
 | 
				
			||||||
 | 
					+	.name = "physmap-flash",
 | 
				
			||||||
 | 
					+	.id = 0,
 | 
				
			||||||
 | 
					+	.resource = &laguna_nor_res,
 | 
				
			||||||
 | 
					+	.num_resources = 1,
 | 
				
			||||||
 | 
					+	.dev = {
 | 
				
			||||||
 | 
					+		.platform_data = &laguna_nor_pdata,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * SPI
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct mtd_partition laguna_spi_partitions[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.name		= "uboot",
 | 
				
			||||||
 | 
					+		.size		= SZ_256K,
 | 
				
			||||||
 | 
					+		.offset		= 0,
 | 
				
			||||||
 | 
					+		.mask_flags	= MTD_WRITEABLE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "params",
 | 
				
			||||||
 | 
					+		.size		= SZ_256K,
 | 
				
			||||||
 | 
					+		.offset		= SZ_256K,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "kernel",
 | 
				
			||||||
 | 
					+		.size		= SZ_1M + SZ_512K,
 | 
				
			||||||
 | 
					+		.offset		= SZ_512K,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.name		= "rootfs",
 | 
				
			||||||
 | 
					+		.size		= SZ_16M - SZ_2M,
 | 
				
			||||||
 | 
					+		.offset		= SZ_2M,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct flash_platform_data laguna_spi_pdata = {
 | 
				
			||||||
 | 
					+	.parts = laguna_spi_partitions,
 | 
				
			||||||
 | 
					+	.nr_parts = ARRAY_SIZE(laguna_spi_partitions),
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct spi_board_info __initdata laguna_spi_devices[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.modalias = "m25p80",
 | 
				
			||||||
 | 
					+		.platform_data = &laguna_spi_pdata,
 | 
				
			||||||
 | 
					+		.max_speed_hz = 50000000,
 | 
				
			||||||
 | 
					+		.bus_num = 1,
 | 
				
			||||||
 | 
					+		.chip_select = 0,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_spi_controller = {
 | 
				
			||||||
 | 
					+	.name = "cns3xxx_spi",
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * LED's
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct gpio_led laguna_gpio_leds[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.name = "user1", /* Green Led */
 | 
				
			||||||
 | 
					+		.gpio = 115,
 | 
				
			||||||
 | 
					+		.active_low = 1,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.name = "user2", /* Red Led */
 | 
				
			||||||
 | 
					+		.gpio = 114,
 | 
				
			||||||
 | 
					+		.active_low = 1,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct gpio_led_platform_data laguna_gpio_leds_data = {
 | 
				
			||||||
 | 
					+	.num_leds = 2,
 | 
				
			||||||
 | 
					+	.leds = laguna_gpio_leds,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_gpio_leds_device = {
 | 
				
			||||||
 | 
					+	.name = "leds-gpio",
 | 
				
			||||||
 | 
					+	.id = -1,
 | 
				
			||||||
 | 
					+	.dev.platform_data = &laguna_gpio_leds_data,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Ethernet
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct cns3xxx_plat_info laguna_net_data = {
 | 
				
			||||||
 | 
					+	.ports = 0,
 | 
				
			||||||
 | 
					+	.phy = {
 | 
				
			||||||
 | 
					+		0,
 | 
				
			||||||
 | 
					+		1,
 | 
				
			||||||
 | 
					+		2,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_net_device = {
 | 
				
			||||||
 | 
					+	.name = "cns3xxx_eth",
 | 
				
			||||||
 | 
					+	.id = 0,
 | 
				
			||||||
 | 
					+	.dev.platform_data = &laguna_net_data,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * UART
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static void __init laguna_early_serial_setup(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+#ifdef CONFIG_SERIAL_8250_CONSOLE
 | 
				
			||||||
 | 
					+	static struct uart_port laguna_serial_port = {
 | 
				
			||||||
 | 
					+		.membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.mapbase        = CNS3XXX_UART0_BASE,
 | 
				
			||||||
 | 
					+		.irq            = IRQ_CNS3XXX_UART0,
 | 
				
			||||||
 | 
					+		.iotype         = UPIO_MEM,
 | 
				
			||||||
 | 
					+		.flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
 | 
				
			||||||
 | 
					+		.regshift       = 2,
 | 
				
			||||||
 | 
					+		.uartclk        = 24000000,
 | 
				
			||||||
 | 
					+		.line           = 0,
 | 
				
			||||||
 | 
					+		.type           = PORT_16550A,
 | 
				
			||||||
 | 
					+		.fifosize       = 16,
 | 
				
			||||||
 | 
					+	};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	early_serial_setup(&laguna_serial_port);
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct resource laguna_uart_resources[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_UART0_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_UART0_BASE + SZ_4K - 1,
 | 
				
			||||||
 | 
					+		.flags    = IORESOURCE_MEM
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_UART2_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
 | 
				
			||||||
 | 
					+		.flags    = IORESOURCE_MEM
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_UART2_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
 | 
				
			||||||
 | 
					+		.flags    = IORESOURCE_MEM
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct plat_serial8250_port laguna_uart_data[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.membase        = (char*) (CNS3XXX_UART0_BASE_VIRT),
 | 
				
			||||||
 | 
					+		.mapbase        = (CNS3XXX_UART0_BASE),
 | 
				
			||||||
 | 
					+		.irq            = IRQ_CNS3XXX_UART0,
 | 
				
			||||||
 | 
					+		.iotype         = UPIO_MEM,
 | 
				
			||||||
 | 
					+		.flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
 | 
				
			||||||
 | 
					+		.regshift       = 2,
 | 
				
			||||||
 | 
					+		.uartclk        = 24000000,
 | 
				
			||||||
 | 
					+		.type           = PORT_16550A,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.membase        = (char*) (CNS3XXX_UART1_BASE_VIRT),
 | 
				
			||||||
 | 
					+		.mapbase        = (CNS3XXX_UART1_BASE),
 | 
				
			||||||
 | 
					+		.irq            = IRQ_CNS3XXX_UART1,
 | 
				
			||||||
 | 
					+		.iotype         = UPIO_MEM,
 | 
				
			||||||
 | 
					+		.flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
 | 
				
			||||||
 | 
					+		.regshift       = 2,
 | 
				
			||||||
 | 
					+		.uartclk        = 24000000,
 | 
				
			||||||
 | 
					+		.type           = PORT_16550A,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.membase        = (char*) (CNS3XXX_UART2_BASE_VIRT),
 | 
				
			||||||
 | 
					+		.mapbase        = (CNS3XXX_UART2_BASE),
 | 
				
			||||||
 | 
					+		.irq            = IRQ_CNS3XXX_UART2,
 | 
				
			||||||
 | 
					+		.iotype         = UPIO_MEM,
 | 
				
			||||||
 | 
					+		.flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
 | 
				
			||||||
 | 
					+		.regshift       = 2,
 | 
				
			||||||
 | 
					+		.uartclk        = 24000000,
 | 
				
			||||||
 | 
					+		.type           = PORT_16550A,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_uart = {
 | 
				
			||||||
 | 
					+	.name     = "serial8250",
 | 
				
			||||||
 | 
					+	.id     = PLAT8250_DEV_PLATFORM,
 | 
				
			||||||
 | 
					+	.dev.platform_data  = laguna_uart_data,
 | 
				
			||||||
 | 
					+	.num_resources    = 3,
 | 
				
			||||||
 | 
					+	.resource   = laguna_uart_resources
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * USB
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct resource cns3xxx_usb_ehci_resources[] = {
 | 
				
			||||||
 | 
					+	[0] = {
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_USB_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_USB_BASE + SZ_16M - 1,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_MEM,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+	[1] = {
 | 
				
			||||||
 | 
					+		.start = IRQ_CNS3XXX_USB_EHCI,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_IRQ,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device cns3xxx_usb_ehci_device = {
 | 
				
			||||||
 | 
					+	.name          = "cns3xxx-ehci",
 | 
				
			||||||
 | 
					+	.num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
 | 
				
			||||||
 | 
					+	.resource      = cns3xxx_usb_ehci_resources,
 | 
				
			||||||
 | 
					+	.dev           = {
 | 
				
			||||||
 | 
					+		.dma_mask          = &cns3xxx_usb_ehci_dma_mask,
 | 
				
			||||||
 | 
					+		.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct resource cns3xxx_usb_ohci_resources[] = {
 | 
				
			||||||
 | 
					+	[0] = {
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_USB_OHCI_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_MEM,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+	[1] = {
 | 
				
			||||||
 | 
					+		.start = IRQ_CNS3XXX_USB_OHCI,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_IRQ,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device cns3xxx_usb_ohci_device = {
 | 
				
			||||||
 | 
					+	.name          = "cns3xxx-ohci",
 | 
				
			||||||
 | 
					+	.num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
 | 
				
			||||||
 | 
					+	.resource      = cns3xxx_usb_ohci_resources,
 | 
				
			||||||
 | 
					+	.dev           = {
 | 
				
			||||||
 | 
					+		.dma_mask          = &cns3xxx_usb_ohci_dma_mask,
 | 
				
			||||||
 | 
					+		.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct resource cns3xxx_usb_otg_resources[] = {
 | 
				
			||||||
 | 
					+	[0] = {
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_USBOTG_BASE,
 | 
				
			||||||
 | 
					+		.end   = CNS3XXX_USBOTG_BASE + SZ_16M - 1,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_MEM,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+	[1] = {
 | 
				
			||||||
 | 
					+		.start = IRQ_CNS3XXX_USB_OTG,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_IRQ,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static u64 cns3xxx_usb_otg_dma_mask = DMA_BIT_MASK(32);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device cns3xxx_usb_otg_device = {
 | 
				
			||||||
 | 
					+	.name          = "dwc_otg",
 | 
				
			||||||
 | 
					+	.num_resources = ARRAY_SIZE(cns3xxx_usb_otg_resources),
 | 
				
			||||||
 | 
					+	.resource      = cns3xxx_usb_otg_resources,
 | 
				
			||||||
 | 
					+	.dev           = {
 | 
				
			||||||
 | 
					+		.dma_mask          = &cns3xxx_usb_otg_dma_mask,
 | 
				
			||||||
 | 
					+		.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * I2C
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static struct resource laguna_i2c_resource[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.start    = CNS3XXX_SSP_BASE + 0x20,
 | 
				
			||||||
 | 
					+		.end      = 0x7100003f,
 | 
				
			||||||
 | 
					+		.flags    = IORESOURCE_MEM,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.start    = IRQ_CNS3XXX_I2C,
 | 
				
			||||||
 | 
					+		.flags    = IORESOURCE_IRQ,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_i2c_controller = {
 | 
				
			||||||
 | 
					+	.name   = "cns3xxx-i2c",
 | 
				
			||||||
 | 
					+	.num_resources  = 2,
 | 
				
			||||||
 | 
					+	.resource = laguna_i2c_resource,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct memory_accessor *at24_mem_acc;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void at24_setup(struct memory_accessor *mem_acc, void *context)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	char buf[8];
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	at24_mem_acc = mem_acc;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Read MAC addresses */
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x100, 6) == 6)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_net_data.hwaddr[0], buf, ETH_ALEN);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x106, 6) == 6)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_net_data.hwaddr[1], buf, ETH_ALEN);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x10C, 6) == 6)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_net_data.hwaddr[2], buf, ETH_ALEN);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x112, 6) == 6)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_net_data.hwaddr[3], buf, ETH_ALEN);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Read out Model Information */
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x130, 16) == 16)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_info.model, buf, 16);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x140, 1) == 1)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_info.nor_flash_size, buf, 1);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x141, 1) == 1)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_info.spi_flash_size, buf, 1);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x142, 4) == 4)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_info.config_bitmap, buf, 4);
 | 
				
			||||||
 | 
					+	if (at24_mem_acc->read(at24_mem_acc, buf, 0x146, 4) == 4)
 | 
				
			||||||
 | 
					+		memcpy(&laguna_info.config2_bitmap, buf, 4);
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct at24_platform_data laguna_eeprom_info = {
 | 
				
			||||||
 | 
					+	.byte_len = 1024,
 | 
				
			||||||
 | 
					+	.page_size = 16,
 | 
				
			||||||
 | 
					+	.flags = AT24_FLAG_READONLY,
 | 
				
			||||||
 | 
					+	.setup = at24_setup,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct pca953x_platform_data laguna_pca_data = {
 | 
				
			||||||
 | 
					+ 	.gpio_base = 100,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct i2c_board_info __initdata laguna_i2c_devices[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		I2C_BOARD_INFO("pca9555", 0x23),
 | 
				
			||||||
 | 
					+		.platform_data = &laguna_pca_data,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		I2C_BOARD_INFO("gsp", 0x29),
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		I2C_BOARD_INFO ("24c08",0x50),
 | 
				
			||||||
 | 
					+		.platform_data = &laguna_eeprom_info,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		I2C_BOARD_INFO("ds1672", 0x68),
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Watchdog
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct resource laguna_watchdog_resource[] = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.start = CNS3XXX_TC11MP_TWD_BASE,
 | 
				
			||||||
 | 
					+		.end = CNS3XXX_TC11MP_TWD_BASE + SZ_4K - 1,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_MEM,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.start = IRQ_LOCALWDOG,
 | 
				
			||||||
 | 
					+		.end = IRQ_LOCALWDOG,
 | 
				
			||||||
 | 
					+		.flags = IORESOURCE_IRQ,
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct platform_device laguna_watchdog = {
 | 
				
			||||||
 | 
					+	.name = "mpcore_wdt",
 | 
				
			||||||
 | 
					+	.id = -1,
 | 
				
			||||||
 | 
					+	.num_resources = ARRAY_SIZE(laguna_watchdog_resource),
 | 
				
			||||||
 | 
					+	.resource = laguna_watchdog_resource,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Initialization
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __init laguna_init(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	platform_device_register(&laguna_watchdog);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	platform_device_register(&laguna_i2c_controller);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	i2c_register_board_info(0, laguna_i2c_devices,
 | 
				
			||||||
 | 
					+			ARRAY_SIZE(laguna_i2c_devices));
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	pm_power_off = cns3xxx_power_off;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct map_desc laguna_io_desc[] __initdata = {
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_UART0_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_UART0_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_UART1_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_UART1_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	},{
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_UART2_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_UART2_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __init laguna_map_io(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	cns3xxx_map_io();
 | 
				
			||||||
 | 
					+	iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	laguna_early_serial_setup();
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __init laguna_model_setup(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	u32 __iomem *mem;
 | 
				
			||||||
 | 
					+	u32 reg;
 | 
				
			||||||
 | 
					+	u8 pcie_bitmap = 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	printk("Running on Gateworks Laguna %s\n", laguna_info.model);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (strncmp(laguna_info.model, "GW", 2) == 0) {
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & ETH0_LOAD)
 | 
				
			||||||
 | 
					+			laguna_net_data.ports |= BIT(0);
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & ETH1_LOAD)
 | 
				
			||||||
 | 
					+			laguna_net_data.ports |= BIT(1);
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & ETH2_LOAD)
 | 
				
			||||||
 | 
					+			laguna_net_data.ports |= BIT(2);
 | 
				
			||||||
 | 
					+		if (laguna_net_data.ports)
 | 
				
			||||||
 | 
					+			platform_device_register(&laguna_net_device);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (SATA0_LOAD | SATA1_LOAD))
 | 
				
			||||||
 | 
					+			cns3xxx_ahci_init();
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (PCIE0_LOAD))
 | 
				
			||||||
 | 
					+			pcie_bitmap |= 0x1;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (PCIE1_LOAD))
 | 
				
			||||||
 | 
					+			pcie_bitmap |= 0x2;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		cns3xxx_pcie_init(pcie_bitmap);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (USB0_LOAD)) {
 | 
				
			||||||
 | 
					+			cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+			/* DRVVBUS pins share with GPIOA */
 | 
				
			||||||
 | 
					+			mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
 | 
				
			||||||
 | 
					+			reg = __raw_readl(mem);
 | 
				
			||||||
 | 
					+			reg |= 0x8;
 | 
				
			||||||
 | 
					+			__raw_writel(reg, mem);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+			/* Enable OTG */
 | 
				
			||||||
 | 
					+			mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
 | 
				
			||||||
 | 
					+			reg = __raw_readl(mem);
 | 
				
			||||||
 | 
					+			reg &= ~(1 << 10);
 | 
				
			||||||
 | 
					+			__raw_writel(reg, mem);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+			platform_device_register(&cns3xxx_usb_otg_device);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (USB1_LOAD)) {
 | 
				
			||||||
 | 
					+			platform_device_register(&cns3xxx_usb_ehci_device);
 | 
				
			||||||
 | 
					+			platform_device_register(&cns3xxx_usb_ohci_device);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (SD_LOAD))
 | 
				
			||||||
 | 
					+			cns3xxx_sdhci_init();
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (UART0_LOAD))
 | 
				
			||||||
 | 
					+			laguna_uart.num_resources = 1;
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (UART1_LOAD))
 | 
				
			||||||
 | 
					+			laguna_uart.num_resources = 2;
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (UART2_LOAD))
 | 
				
			||||||
 | 
					+			laguna_uart.num_resources = 3;
 | 
				
			||||||
 | 
					+		platform_device_register(&laguna_uart);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) {
 | 
				
			||||||
 | 
					+			switch (laguna_info.nor_flash_size) {
 | 
				
			||||||
 | 
					+				case 1:
 | 
				
			||||||
 | 
					+					laguna_nor_partitions[3].size = SZ_8M - SZ_256K - SZ_128K - SZ_2M;
 | 
				
			||||||
 | 
					+					laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 2:
 | 
				
			||||||
 | 
					+					laguna_nor_partitions[3].size = SZ_16M - SZ_256K - SZ_128K - SZ_2M;
 | 
				
			||||||
 | 
					+					laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 3:
 | 
				
			||||||
 | 
					+					laguna_nor_partitions[3].size = SZ_32M - SZ_256K - SZ_128K - SZ_2M;
 | 
				
			||||||
 | 
					+					laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 4:
 | 
				
			||||||
 | 
					+					laguna_nor_partitions[3].size = SZ_64M - SZ_256K - SZ_128K - SZ_2M;
 | 
				
			||||||
 | 
					+					laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 5:
 | 
				
			||||||
 | 
					+					laguna_nor_partitions[3].size = SZ_128M - SZ_256K - SZ_128K - SZ_2M;
 | 
				
			||||||
 | 
					+					laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+			platform_device_register(&laguna_nor_pdev);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config2_bitmap & (SPI_FLASH_LOAD)) {
 | 
				
			||||||
 | 
					+			switch (laguna_info.spi_flash_size) {
 | 
				
			||||||
 | 
					+				case 1:
 | 
				
			||||||
 | 
					+					laguna_spi_partitions[3].size = SZ_4M - SZ_2M;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 2:
 | 
				
			||||||
 | 
					+					laguna_spi_partitions[3].size = SZ_8M - SZ_2M;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 3:
 | 
				
			||||||
 | 
					+					laguna_spi_partitions[3].size = SZ_16M - SZ_2M;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 4:
 | 
				
			||||||
 | 
					+					laguna_spi_partitions[3].size = SZ_32M - SZ_2M;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+				case 5:
 | 
				
			||||||
 | 
					+					laguna_spi_partitions[3].size = SZ_64M - SZ_2M;
 | 
				
			||||||
 | 
					+				break;
 | 
				
			||||||
 | 
					+			}
 | 
				
			||||||
 | 
					+			spi_register_board_info(laguna_spi_devices, ARRAY_SIZE(laguna_spi_devices));
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (laguna_info.config_bitmap & (SPI0_LOAD | SPI1_LOAD)) {
 | 
				
			||||||
 | 
					+			platform_device_register(&laguna_spi_controller);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		/*
 | 
				
			||||||
 | 
					+		 * Do any model specific setup not known by the bitmap by matching
 | 
				
			||||||
 | 
					+		 *  the first 6 characters of the model name
 | 
				
			||||||
 | 
					+		 */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (strncmp(laguna_info.model, "GW2388", 6) == 0) {
 | 
				
			||||||
 | 
					+			platform_device_register(&laguna_gpio_leds_device);
 | 
				
			||||||
 | 
					+		} else if (strncmp(laguna_info.model, "GW2380", 6) == 0) {
 | 
				
			||||||
 | 
					+			laguna_gpio_leds[0].gpio = 107;
 | 
				
			||||||
 | 
					+			laguna_gpio_leds_data.num_leds = 1;
 | 
				
			||||||
 | 
					+			platform_device_register(&laguna_gpio_leds_device);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		// Do some defaults here, not sure what yet
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+late_initcall(laguna_model_setup);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+MACHINE_START(GW2388, "Gateworks Corporation Laguna Platform")
 | 
				
			||||||
 | 
					+	.boot_params	= 0x00000100,
 | 
				
			||||||
 | 
					+	.map_io		= laguna_map_io,
 | 
				
			||||||
 | 
					+	.init_irq	= cns3xxx_init_irq,
 | 
				
			||||||
 | 
					+	.timer		= &cns3xxx_timer,
 | 
				
			||||||
 | 
					+	.init_machine	= laguna_init,
 | 
				
			||||||
 | 
					+MACHINE_END
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/Kconfig
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/Kconfig
 | 
				
			||||||
 | 
					@@ -10,4 +10,13 @@ config MACH_CNS3420VB
 | 
				
			||||||
 | 
					 	  This is a platform with an on-board ARM11 MPCore and has support
 | 
				
			||||||
 | 
					 	  for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+config MACH_GW2388
 | 
				
			||||||
 | 
					+	bool "Support for Gateworks Laguna Platform"
 | 
				
			||||||
 | 
					+	select MIGHT_HAVE_PCI
 | 
				
			||||||
 | 
					+	help
 | 
				
			||||||
 | 
					+	  Include support for the Gateworks Laguna Platform
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	  This is a platform with an on-board ARM11 MPCore and has support
 | 
				
			||||||
 | 
					+	  for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, I2C, GIG, etc.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 endmenu
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					@@ -16,6 +16,7 @@
 | 
				
			||||||
 | 
					 #include <asm/mach/time.h>
 | 
				
			||||||
 | 
					 #include <asm/mach/irq.h>
 | 
				
			||||||
 | 
					 #include <asm/hardware/gic.h>
 | 
				
			||||||
 | 
					+#include <asm/smp_twd.h>
 | 
				
			||||||
 | 
					 #include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					 #include "core.h"
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -60,11 +61,24 @@ static struct map_desc cns3xxx_io_desc[]
 | 
				
			||||||
 | 
					 		.pfn		= __phys_to_pfn(CNS3XXX_PM_BASE),
 | 
				
			||||||
 | 
					 		.length		= SZ_4K,
 | 
				
			||||||
 | 
					 		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_SWITCH_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_SWITCH_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_SSP_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_SSP_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 void __init cns3xxx_map_io(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					+#ifdef CONFIG_LOCAL_TIMERS
 | 
				
			||||||
 | 
					+	twd_base = (void __iomem *) CNS3XXX_TC11MP_TWD_BASE_VIRT;
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					 	iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/arch/arm/Kconfig
 | 
				
			||||||
 | 
					+++ b/arch/arm/Kconfig
 | 
				
			||||||
 | 
					@@ -313,6 +313,7 @@ config ARCH_CLPS711X
 | 
				
			||||||
 | 
					 config ARCH_CNS3XXX
 | 
				
			||||||
 | 
					 	bool "Cavium Networks CNS3XXX family"
 | 
				
			||||||
 | 
					 	select CPU_V6
 | 
				
			||||||
 | 
					+	select ARCH_WANT_OPTIONAL_GPIOLIB
 | 
				
			||||||
 | 
					 	select GENERIC_CLOCKEVENTS
 | 
				
			||||||
 | 
					 	select ARM_GIC
 | 
				
			||||||
 | 
					 	select MIGHT_HAVE_PCI
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/include/mach/gpio.h
 | 
				
			||||||
 | 
					@@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * arch/arm/mach-cns3xxx/include/mach/gpio.h
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * CNS3xxx GPIO wrappers for arch-neutral GPIO calls
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Copyright 2011 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *		  Chris Lang <clang@gateworks.com>
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Based on IXP implementation by Milan Svoboda <msvoboda@ra.rockwell.com>
 | 
				
			||||||
 | 
					+ * Based on PXA implementation by Philipp Zabel <philipp.zabel@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#ifndef __ASM_ARCH_CNS3XXX_GPIO_H
 | 
				
			||||||
 | 
					+#define __ASM_ARCH_CNS3XXX_GPIO_H
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <linux/kernel.h>
 | 
				
			||||||
 | 
					+#include <linux/io.h>
 | 
				
			||||||
 | 
					+#include <mach/hardware.h>
 | 
				
			||||||
 | 
					+#include <asm-generic/gpio.h>			/* cansleep wrappers */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define NR_BUILTIN_GPIO 64
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_IN    0x0
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_OUT   0x1
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_LO   0
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_HI   1
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_OUTPUT         0x00
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_INPUT          0x04
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_DIR            0x08
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_SET            0x10
 | 
				
			||||||
 | 
					+#define CNS3XXX_GPIO_CLEAR          0x14
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void gpio_line_get(u8 line, int *value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (line < 32)
 | 
				
			||||||
 | 
					+		*value = ((__raw_readl(CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_INPUT) >> line) & 0x1);
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+		*value = ((__raw_readl(CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_INPUT) >> (line - 32)) & 0x1);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void gpio_line_set(u8 line, int value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (line < 32) {
 | 
				
			||||||
 | 
					+		if (value)
 | 
				
			||||||
 | 
					+			__raw_writel((1 << line), CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_SET);
 | 
				
			||||||
 | 
					+		else
 | 
				
			||||||
 | 
					+			__raw_writel((1 << line), CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_CLEAR);
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		if (value)
 | 
				
			||||||
 | 
					+			__raw_writel((1 << line), CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_SET);
 | 
				
			||||||
 | 
					+		else
 | 
				
			||||||
 | 
					+			__raw_writel((1 << line), CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_CLEAR);
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline int gpio_get_value(unsigned gpio)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (gpio < NR_BUILTIN_GPIO)
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		int value;
 | 
				
			||||||
 | 
					+		gpio_line_get(gpio, &value);
 | 
				
			||||||
 | 
					+		return value;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+		return __gpio_get_value(gpio);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void gpio_set_value(unsigned gpio, int value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (gpio < NR_BUILTIN_GPIO)
 | 
				
			||||||
 | 
					+		gpio_line_set(gpio, value);
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+		__gpio_set_value(gpio, value);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define gpio_cansleep __gpio_cansleep
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+extern int gpio_to_irq(int gpio);
 | 
				
			||||||
 | 
					+extern int irq_to_gpio(int gpio);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/Makefile
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/Makefile
 | 
				
			||||||
 | 
					@@ -1,6 +1,7 @@
 | 
				
			||||||
 | 
					 obj-$(CONFIG_ARCH_CNS3XXX)		+= core.o pm.o devices.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_PCI)			+= pcie.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_MACH_CNS3420VB)		+= cns3420vb.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_MACH_GW2388)		+= laguna.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 | 
				
			||||||
 | 
					--- a/arch/arm/tools/mach-types
 | 
				
			||||||
 | 
					+++ b/arch/arm/tools/mach-types
 | 
				
			||||||
 | 
					@@ -438,6 +438,7 @@ icontrol		MACH_ICONTROL		ICONTROL		2624
 | 
				
			||||||
 | 
					 qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
 | 
				
			||||||
 | 
					 mx23evk			MACH_MX23EVK		MX23EVK			2629
 | 
				
			||||||
 | 
					 ap4evb			MACH_AP4EVB		AP4EVB			2630
 | 
				
			||||||
 | 
					+gw2388			MACH_GW2388		GW2388			2635
 | 
				
			||||||
 | 
					 mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650
 | 
				
			||||||
 | 
					 guruplug		MACH_GURUPLUG		GURUPLUG		2659
 | 
				
			||||||
 | 
					 spear310		MACH_SPEAR310		SPEAR310		2660
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/pcie.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/pcie.c
 | 
				
			||||||
 | 
					@@ -365,7 +365,7 @@ static int cns3xxx_pcie_abort_handler(un
 | 
				
			||||||
 | 
					 	return 0;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static int __init cns3xxx_pcie_init(void)
 | 
				
			||||||
 | 
					+int cns3xxx_pcie_init(u8 bitmap)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	int i;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -373,6 +373,9 @@ static int __init cns3xxx_pcie_init(void
 | 
				
			||||||
 | 
					 			"imprecise external abort");
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
 | 
				
			||||||
 | 
					+		if (!(bitmap & (1 << i)))
 | 
				
			||||||
 | 
					+			continue;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 		iotable_init(cns3xxx_pcie[i].cfg_bases,
 | 
				
			||||||
 | 
					 			     ARRAY_SIZE(cns3xxx_pcie[i].cfg_bases));
 | 
				
			||||||
 | 
					 		cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i));
 | 
				
			||||||
 | 
					@@ -386,4 +389,3 @@ static int __init cns3xxx_pcie_init(void
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	return 0;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					-device_initcall(cns3xxx_pcie_init);
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/cns3420vb.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
 | 
				
			||||||
 | 
					@@ -175,6 +175,8 @@ static void __init cns3420_init(void)
 | 
				
			||||||
 | 
					 	cns3xxx_ahci_init();
 | 
				
			||||||
 | 
					 	cns3xxx_sdhci_init();
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	cns3xxx_pcie_init(0x3);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	pm_power_off = cns3xxx_power_off;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/include/mach/platform.h
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/include/mach/platform.h
 | 
				
			||||||
 | 
					@@ -22,5 +22,7 @@ struct cns3xxx_plat_info {
 | 
				
			||||||
 | 
					 	u32 phy[3];
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+extern int cns3xxx_pcie_init(u8 bitmap);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 #endif /* __ASM_ARCH_PLATFORM_H */
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					--- a/drivers/mmc/host/sdhci-cns3xxx.c
 | 
				
			||||||
 | 
					+++ b/drivers/mmc/host/sdhci-cns3xxx.c
 | 
				
			||||||
 | 
					@@ -90,8 +90,9 @@ struct sdhci_pltfm_data sdhci_cns3xxx_pd
 | 
				
			||||||
 | 
					 	.ops = &sdhci_cns3xxx_ops,
 | 
				
			||||||
 | 
					 	.quirks = SDHCI_QUIRK_BROKEN_DMA |
 | 
				
			||||||
 | 
					 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 | 
				
			||||||
 | 
					-		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 | 
				
			||||||
 | 
					+		  //SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 | 
				
			||||||
 | 
					 		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
 | 
				
			||||||
 | 
					 		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
 | 
				
			||||||
 | 
					-		  SDHCI_QUIRK_NONSTANDARD_CLOCK,
 | 
				
			||||||
 | 
					+		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
 | 
				
			||||||
 | 
					+		  SDHCI_QUIRK_BROKEN_CARD_DETECTION,
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
							
								
								
									
										109
									
								
								target/linux/cns3xxx/patches/102-cns3xxx_timers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								target/linux/cns3xxx/patches/102-cns3xxx_timers.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					@@ -117,12 +117,13 @@ static void cns3xxx_timer_set_mode(enum
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	switch (mode) {
 | 
				
			||||||
 | 
					 	case CLOCK_EVT_MODE_PERIODIC:
 | 
				
			||||||
 | 
					-		reload = pclk * 20 / (3 * HZ) * 0x25000;
 | 
				
			||||||
 | 
					+		reload = pclk * 1000000 / HZ;
 | 
				
			||||||
 | 
					 		writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | 
				
			||||||
 | 
					 		ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
 | 
				
			||||||
 | 
					 		break;
 | 
				
			||||||
 | 
					 	case CLOCK_EVT_MODE_ONESHOT:
 | 
				
			||||||
 | 
					 		/* period set, and timer enabled in 'next_event' hook */
 | 
				
			||||||
 | 
					+		writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | 
				
			||||||
 | 
					 		ctrl |= (1 << 2) | (1 << 9);
 | 
				
			||||||
 | 
					 		break;
 | 
				
			||||||
 | 
					 	case CLOCK_EVT_MODE_UNUSED:
 | 
				
			||||||
 | 
					@@ -147,11 +148,11 @@ static int cns3xxx_timer_set_next_event(
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static struct clock_event_device cns3xxx_tmr1_clockevent = {
 | 
				
			||||||
 | 
					 	.name		= "cns3xxx timer1",
 | 
				
			||||||
 | 
					-	.shift		= 8,
 | 
				
			||||||
 | 
					+	.shift		= 32,
 | 
				
			||||||
 | 
					 	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 | 
				
			||||||
 | 
					 	.set_mode	= cns3xxx_timer_set_mode,
 | 
				
			||||||
 | 
					 	.set_next_event	= cns3xxx_timer_set_next_event,
 | 
				
			||||||
 | 
					-	.rating		= 350,
 | 
				
			||||||
 | 
					+	.rating		= 300,
 | 
				
			||||||
 | 
					 	.cpumask	= cpu_all_mask,
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -193,6 +194,35 @@ static struct irqaction cns3xxx_timer_ir
 | 
				
			||||||
 | 
					 	.handler	= cns3xxx_timer_interrupt,
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+static cycle_t cns3xxx_get_cycles(struct clocksource *cs)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+  u64 val;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+  val = readl(cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					+  val &= 0xffff;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+  return ((val << 32) | readl(cns3xxx_tmr1 + TIMER_FREERUN_OFFSET));
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct clocksource clocksource_cns3xxx = {
 | 
				
			||||||
 | 
					+	.name = "freerun",
 | 
				
			||||||
 | 
					+	.rating = 200,
 | 
				
			||||||
 | 
					+	.read = cns3xxx_get_cycles,
 | 
				
			||||||
 | 
					+	.mask = CLOCKSOURCE_MASK(48),
 | 
				
			||||||
 | 
					+	.shift  = 16,
 | 
				
			||||||
 | 
					+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __init cns3xxx_clocksource_init(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	/* Reset the FreeRunning counter */
 | 
				
			||||||
 | 
					+	writel((1 << 16), cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	clocksource_cns3xxx.mult =
 | 
				
			||||||
 | 
					+		clocksource_khz2mult(100, clocksource_cns3xxx.shift);
 | 
				
			||||||
 | 
					+	clocksource_register(&clocksource_cns3xxx);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 /*
 | 
				
			||||||
 | 
					  * Set up the clock source and clock events devices
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					@@ -210,13 +240,12 @@ static void __init __cns3xxx_timer_init(
 | 
				
			||||||
 | 
					 	/* stop free running timer3 */
 | 
				
			||||||
 | 
					 	writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	/* timer1 */
 | 
				
			||||||
 | 
					-	writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
 | 
				
			||||||
 | 
					-	writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					 	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
 | 
				
			||||||
 | 
					 	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	val = (cns3xxx_cpu_clock() >> 3) * 1000000 / HZ;
 | 
				
			||||||
 | 
					+	writel(val, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	/* mask irq, non-mask timer1 overflow */
 | 
				
			||||||
 | 
					 	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | 
				
			||||||
 | 
					 	irq_mask &= ~(1 << 2);
 | 
				
			||||||
 | 
					@@ -228,23 +257,9 @@ static void __init __cns3xxx_timer_init(
 | 
				
			||||||
 | 
					 	val |= (1 << 9);
 | 
				
			||||||
 | 
					 	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	/* timer2 */
 | 
				
			||||||
 | 
					-	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
 | 
				
			||||||
 | 
					-	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-	/* mask irq */
 | 
				
			||||||
 | 
					-	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | 
				
			||||||
 | 
					-	irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
 | 
				
			||||||
 | 
					-	writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-	/* down counter */
 | 
				
			||||||
 | 
					-	val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					-	val |= (1 << 10);
 | 
				
			||||||
 | 
					-	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-	/* Make irqs happen for the system timer */
 | 
				
			||||||
 | 
					 	setup_irq(timer_irq, &cns3xxx_timer_irq);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	cns3xxx_clocksource_init();
 | 
				
			||||||
 | 
					 	cns3xxx_clockevents_init(timer_irq);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
							
								
								
									
										61
									
								
								target/linux/cns3xxx/patches/103-cns3xxx_l2cache.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								target/linux/cns3xxx/patches/103-cns3xxx_l2cache.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					@@ -15,6 +15,7 @@
 | 
				
			||||||
 | 
					 #include <asm/mach/map.h>
 | 
				
			||||||
 | 
					 #include <asm/mach/time.h>
 | 
				
			||||||
 | 
					 #include <asm/mach/irq.h>
 | 
				
			||||||
 | 
					+#include <asm/hardware/cache-l2x0.h>
 | 
				
			||||||
 | 
					 #include <asm/hardware/gic.h>
 | 
				
			||||||
 | 
					 #include <asm/smp_twd.h>
 | 
				
			||||||
 | 
					 #include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					@@ -71,15 +72,29 @@ static struct map_desc cns3xxx_io_desc[]
 | 
				
			||||||
 | 
					 		.pfn		= __phys_to_pfn(CNS3XXX_SSP_BASE),
 | 
				
			||||||
 | 
					 		.length		= SZ_4K,
 | 
				
			||||||
 | 
					 		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_L2C_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_L2C_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_4K,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 void __init cns3xxx_map_io(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					+	iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
 | 
				
			||||||
 | 
					+#ifdef CONFIG_CACHE_L2X0
 | 
				
			||||||
 | 
					+	void __iomem *l2x0_base = (void __iomem *) CNS3XXX_L2C_BASE_VIRT;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* set RAM latencies to 1 cycle for this core tile. */
 | 
				
			||||||
 | 
					+	writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
 | 
				
			||||||
 | 
					+	writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					 #ifdef CONFIG_LOCAL_TIMERS
 | 
				
			||||||
 | 
					 	twd_base = (void __iomem *) CNS3XXX_TC11MP_TWD_BASE_VIRT;
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
 | 
					-	iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 /* used by entry-macro.S */
 | 
				
			||||||
 | 
					--- a/arch/arm/mm/Kconfig
 | 
				
			||||||
 | 
					+++ b/arch/arm/mm/Kconfig
 | 
				
			||||||
 | 
					@@ -821,7 +821,7 @@ config CACHE_L2X0
 | 
				
			||||||
 | 
					 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
 | 
				
			||||||
 | 
					 		   REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \
 | 
				
			||||||
 | 
					 		   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
 | 
				
			||||||
 | 
					-		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE
 | 
				
			||||||
 | 
					+		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || ARCH_CNS3XXX
 | 
				
			||||||
 | 
					 	default y
 | 
				
			||||||
 | 
					 	select OUTER_CACHE
 | 
				
			||||||
 | 
					 	select OUTER_CACHE_SYNC
 | 
				
			||||||
 | 
					@@ -866,7 +866,7 @@ config ARM_L1_CACHE_SHIFT
 | 
				
			||||||
 | 
					 config ARM_DMA_MEM_BUFFERABLE
 | 
				
			||||||
 | 
					 	bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
 | 
				
			||||||
 | 
					 	depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
 | 
				
			||||||
 | 
					-		     MACH_REALVIEW_PB11MP)
 | 
				
			||||||
 | 
					+		     MACH_REALVIEW_PB11MP || ARCH_CNS3XXX)
 | 
				
			||||||
 | 
					 	default y if CPU_V6 || CPU_V6K || CPU_V7
 | 
				
			||||||
 | 
					 	help
 | 
				
			||||||
 | 
					 	  Historically, the kernel has used strongly ordered mappings to
 | 
				
			||||||
							
								
								
									
										142
									
								
								target/linux/cns3xxx/patches/104-cns3xxx_gpio.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								target/linux/cns3xxx/patches/104-cns3xxx_gpio.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					--- a/arch/arm/mach-cns3xxx/cns3420vb.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
 | 
				
			||||||
 | 
					@@ -191,7 +191,7 @@ static struct map_desc cns3420_io_desc[]
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static void __init cns3420_map_io(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	cns3xxx_map_io();
 | 
				
			||||||
 | 
					+	cns3xxx_common_init();
 | 
				
			||||||
 | 
					 	iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	cns3420_early_serial_setup();
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					@@ -18,6 +18,7 @@
 | 
				
			||||||
 | 
					 #include <asm/hardware/cache-l2x0.h>
 | 
				
			||||||
 | 
					 #include <asm/hardware/gic.h>
 | 
				
			||||||
 | 
					 #include <asm/smp_twd.h>
 | 
				
			||||||
 | 
					+#include <asm/gpio.h>
 | 
				
			||||||
 | 
					 #include <mach/cns3xxx.h>
 | 
				
			||||||
 | 
					 #include "core.h"
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -80,7 +81,89 @@ static struct map_desc cns3xxx_io_desc[]
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-void __init cns3xxx_map_io(void)
 | 
				
			||||||
 | 
					+int gpio_to_irq(int gpio)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (gpio > 63)
 | 
				
			||||||
 | 
					+		return -EINVAL;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (gpio < 32)
 | 
				
			||||||
 | 
					+		return IRQ_CNS3XXX_GPIOA;
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+		return IRQ_CNS3XXX_GPIOB;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+EXPORT_SYMBOL(gpio_to_irq);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int irq2gpio(int irq)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	if (irq == IRQ_CNS3XXX_GPIOA)
 | 
				
			||||||
 | 
					+		return 0;
 | 
				
			||||||
 | 
					+	else if (irq == IRQ_CNS3XXX_GPIOB)
 | 
				
			||||||
 | 
					+		return 32;
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+		return -EINVAL;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+EXPORT_SYMBOL(irq2gpio);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline void gpio_line_config(u8 line, u32 direction)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	u32 reg;
 | 
				
			||||||
 | 
					+	if (direction) {
 | 
				
			||||||
 | 
					+		if (line < 32) {
 | 
				
			||||||
 | 
					+			reg = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+			reg |= (1 << line);
 | 
				
			||||||
 | 
					+			__raw_writel(reg, CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			reg = __raw_readl(CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+			reg |= (1 << (line - 32));
 | 
				
			||||||
 | 
					+			__raw_writel(reg, CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	} else {
 | 
				
			||||||
 | 
					+		if (line < 32) {
 | 
				
			||||||
 | 
					+			reg = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+			reg &= ~(1 << line);
 | 
				
			||||||
 | 
					+			__raw_writel(reg, CNS3XXX_GPIOA_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+		} else {
 | 
				
			||||||
 | 
					+			reg = __raw_readl(CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+			reg &= ~(1 << (line - 32));
 | 
				
			||||||
 | 
					+			__raw_writel(reg, CNS3XXX_GPIOB_BASE_VIRT + CNS3XXX_GPIO_DIR);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	gpio_line_config(gpio, CNS3XXX_GPIO_IN);
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	gpio_line_set(gpio, level);
 | 
				
			||||||
 | 
					+	gpio_line_config(gpio, CNS3XXX_GPIO_OUT);
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int cns3xxx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return gpio_get_value(gpio);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void cns3xxx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	gpio_set_value(gpio, value);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct gpio_chip cns3xxx_gpio_chip = {
 | 
				
			||||||
 | 
					+	.label			= "CNS3XXX_GPIO_CHIP",
 | 
				
			||||||
 | 
					+	.direction_input	= cns3xxx_gpio_direction_input,
 | 
				
			||||||
 | 
					+	.direction_output	= cns3xxx_gpio_direction_output,
 | 
				
			||||||
 | 
					+	.get			= cns3xxx_gpio_get_value,
 | 
				
			||||||
 | 
					+	.set			= cns3xxx_gpio_set_value,
 | 
				
			||||||
 | 
					+	.base			= 0,
 | 
				
			||||||
 | 
					+	.ngpio			= 64,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void __init cns3xxx_common_init(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
 | 
				
			||||||
 | 
					 #ifdef CONFIG_CACHE_L2X0
 | 
				
			||||||
 | 
					@@ -95,6 +178,7 @@ void __init cns3xxx_map_io(void)
 | 
				
			||||||
 | 
					 #ifdef CONFIG_LOCAL_TIMERS
 | 
				
			||||||
 | 
					 	twd_base = (void __iomem *) CNS3XXX_TC11MP_TWD_BASE_VIRT;
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
 | 
					+	gpiochip_add(&cns3xxx_gpio_chip);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 /* used by entry-macro.S */
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.h
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.h
 | 
				
			||||||
 | 
					@@ -13,7 +13,7 @@
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 extern struct sys_timer cns3xxx_timer;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-void __init cns3xxx_map_io(void);
 | 
				
			||||||
 | 
					+void __init cns3xxx_common_init(void);
 | 
				
			||||||
 | 
					 void __init cns3xxx_init_irq(void);
 | 
				
			||||||
 | 
					 void cns3xxx_power_off(void);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/laguna.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/laguna.c
 | 
				
			||||||
 | 
					@@ -520,7 +520,7 @@ static struct map_desc laguna_io_desc[]
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static void __init laguna_map_io(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	cns3xxx_map_io();
 | 
				
			||||||
 | 
					+	cns3xxx_common_init();
 | 
				
			||||||
 | 
					 	iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	laguna_early_serial_setup();
 | 
				
			||||||
							
								
								
									
										88
									
								
								target/linux/cns3xxx/patches/105-cns3xxx_pcie_io.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								target/linux/cns3xxx/patches/105-cns3xxx_pcie_io.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					--- a/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/core.c
 | 
				
			||||||
 | 
					@@ -78,6 +78,16 @@ static struct map_desc cns3xxx_io_desc[]
 | 
				
			||||||
 | 
					 		.pfn		= __phys_to_pfn(CNS3XXX_L2C_BASE),
 | 
				
			||||||
 | 
					 		.length		= SZ_4K,
 | 
				
			||||||
 | 
					 		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_PCIE0_IO_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_PCIE0_IO_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_16M,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					+	}, {
 | 
				
			||||||
 | 
					+		.virtual	= CNS3XXX_PCIE1_IO_BASE_VIRT,
 | 
				
			||||||
 | 
					+		.pfn		= __phys_to_pfn(CNS3XXX_PCIE1_IO_BASE),
 | 
				
			||||||
 | 
					+		.length		= SZ_16M,
 | 
				
			||||||
 | 
					+		.type		= MT_DEVICE,
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -184,13 +194,13 @@ void __init cns3xxx_common_init(void)
 | 
				
			||||||
 | 
					 /* used by entry-macro.S */
 | 
				
			||||||
 | 
					 void __init cns3xxx_init_irq(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
 | 
				
			||||||
 | 
					-		 __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
 | 
				
			||||||
 | 
					+	gic_init(0, 29, (void __iomem *) CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
 | 
				
			||||||
 | 
					+		 (void __iomem *) CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 void cns3xxx_power_off(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT);
 | 
				
			||||||
 | 
					+	u32 __iomem *pm_base = (void __iomem *) CNS3XXX_PM_BASE_VIRT;
 | 
				
			||||||
 | 
					 	u32 clkctrl;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	printk(KERN_INFO "powering system down...\n");
 | 
				
			||||||
 | 
					@@ -364,7 +374,7 @@ static void __init __cns3xxx_timer_init(
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static void __init cns3xxx_timer_init(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT);
 | 
				
			||||||
 | 
					+	cns3xxx_tmr1 = (void __iomem *) CNS3XXX_TIMER1_2_3_BASE_VIRT;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	__cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/devices.c
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/devices.c
 | 
				
			||||||
 | 
					@@ -98,7 +98,7 @@ static struct platform_device cns3xxx_sd
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 void __init cns3xxx_sdhci_init(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	u32 __iomem *gpioa = __io(CNS3XXX_MISC_BASE_VIRT + 0x0014);
 | 
				
			||||||
 | 
					+	u32 __iomem *gpioa = (void __iomem *) (CNS3XXX_MISC_BASE_VIRT + 0x0014);
 | 
				
			||||||
 | 
					 	u32 gpioa_pins = __raw_readl(gpioa);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* MMC/SD pins share with GPIOA */
 | 
				
			||||||
 | 
					--- a/arch/arm/mach-cns3xxx/include/mach/io.h
 | 
				
			||||||
 | 
					+++ b/arch/arm/mach-cns3xxx/include/mach/io.h
 | 
				
			||||||
 | 
					@@ -9,9 +9,17 @@
 | 
				
			||||||
 | 
					 #ifndef __MACH_IO_H
 | 
				
			||||||
 | 
					 #define __MACH_IO_H
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+#include "cns3xxx.h"
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 #define IO_SPACE_LIMIT 0xffffffff
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-#define __io(a)			__typesafe_io(a)
 | 
				
			||||||
 | 
					+static inline void __iomem *__io(unsigned long addr)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return (void __iomem *)((addr - CNS3XXX_PCIE0_IO_BASE)
 | 
				
			||||||
 | 
					+		+ CNS3XXX_PCIE0_IO_BASE_VIRT);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define __io(a)			__io(a)
 | 
				
			||||||
 | 
					 #define __mem_pci(a)		(a)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
 | 
					--- a/drivers/spi/spi_cns3xxx.c
 | 
				
			||||||
 | 
					+++ b/drivers/spi/spi_cns3xxx.c
 | 
				
			||||||
 | 
					@@ -273,7 +273,7 @@ done:
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static void __init cns3xxx_spi_initial(void)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	u32 __iomem *gpiob = __io(CNS3XXX_MISC_BASE_VIRT + 0x0018);
 | 
				
			||||||
 | 
					+	u32 __iomem *gpiob = (void __iomem *) (CNS3XXX_MISC_BASE_VIRT + 0x0018);
 | 
				
			||||||
 | 
					 	u32 gpiob_pins = __raw_readl(gpiob);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* MMC/SD pins share with GPIOA */
 | 
				
			||||||
							
								
								
									
										339
									
								
								target/linux/cns3xxx/patches/110-gateworks_gsp_support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								target/linux/cns3xxx/patches/110-gateworks_gsp_support.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,339 @@
 | 
				
			|||||||
 | 
					--- a/drivers/hwmon/Kconfig
 | 
				
			||||||
 | 
					+++ b/drivers/hwmon/Kconfig
 | 
				
			||||||
 | 
					@@ -391,6 +391,15 @@ config SENSORS_GL520SM
 | 
				
			||||||
 | 
					 	  This driver can also be built as a module.  If so, the module
 | 
				
			||||||
 | 
					 	  will be called gl520sm.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+config SENSORS_GSP
 | 
				
			||||||
 | 
					+	tristate "Gateworks System Peripheral"
 | 
				
			||||||
 | 
					+	depends on I2C && EXPERIMENTAL
 | 
				
			||||||
 | 
					+	help
 | 
				
			||||||
 | 
					+	  If you say yes here you get support for the Gateworks System Peripherals.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	  This driver can also be built as a module. If so, the module
 | 
				
			||||||
 | 
					+	  will be called gsp.
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 config SENSORS_GPIO_FAN
 | 
				
			||||||
 | 
					 	tristate "GPIO fan"
 | 
				
			||||||
 | 
					 	depends on GENERIC_GPIO
 | 
				
			||||||
 | 
					--- a/drivers/hwmon/Makefile
 | 
				
			||||||
 | 
					+++ b/drivers/hwmon/Makefile
 | 
				
			||||||
 | 
					@@ -114,6 +114,7 @@ obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l7
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
 | 
				
			||||||
 | 
					 obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
 | 
				
			||||||
 | 
					+obj-$(CONFIG_SENSORS_GSP)	+= gsp.o
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 # PMBus drivers
 | 
				
			||||||
 | 
					 obj-$(CONFIG_PMBUS)		+= pmbus_core.o
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/drivers/hwmon/gsp.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,308 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * A hwmon driver for the Gateworks System Peripheral
 | 
				
			||||||
 | 
					+ * Copyright (C) 2009 Gateworks Corporation
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * Author: Chris Lang <clang@gateworks.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 - version 2.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <linux/module.h>
 | 
				
			||||||
 | 
					+#include <linux/i2c.h>
 | 
				
			||||||
 | 
					+#include <linux/hwmon.h>
 | 
				
			||||||
 | 
					+#include <linux/hwmon-sysfs.h>
 | 
				
			||||||
 | 
					+#include <linux/err.h>
 | 
				
			||||||
 | 
					+#include <linux/slab.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#define DRV_VERSION "0.2"
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+enum chips { gsp };
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/* AD7418 registers */
 | 
				
			||||||
 | 
					+#define GSP_REG_TEMP_IN		0x00
 | 
				
			||||||
 | 
					+#define GSP_REG_VIN		0x02
 | 
				
			||||||
 | 
					+#define GSP_REG_3P3		0x05
 | 
				
			||||||
 | 
					+#define GSP_REG_BAT		0x08
 | 
				
			||||||
 | 
					+#define GSP_REG_5P0		0x0b
 | 
				
			||||||
 | 
					+#define GSP_REG_CORE		0x0e
 | 
				
			||||||
 | 
					+#define GSP_REG_CPU1		0x11
 | 
				
			||||||
 | 
					+#define GSP_REG_CPU2		0x14
 | 
				
			||||||
 | 
					+#define GSP_REG_DRAM		0x17
 | 
				
			||||||
 | 
					+#define GSP_REG_EXT_BAT		0x1a
 | 
				
			||||||
 | 
					+#define GSP_REG_IO1		0x1d
 | 
				
			||||||
 | 
					+#define GSP_REG_IO2 		0x20
 | 
				
			||||||
 | 
					+#define GSP_REG_PCIE		0x23
 | 
				
			||||||
 | 
					+#define GSP_REG_CURRENT		0x26
 | 
				
			||||||
 | 
					+#define GSP_FAN_0		0x2C
 | 
				
			||||||
 | 
					+#define GSP_FAN_1		0x2E
 | 
				
			||||||
 | 
					+#define GSP_FAN_2		0x30
 | 
				
			||||||
 | 
					+#define GSP_FAN_3		0x32
 | 
				
			||||||
 | 
					+#define GSP_FAN_4		0x34
 | 
				
			||||||
 | 
					+#define GSP_FAN_5		0x36
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+struct gsp_sensor_info {
 | 
				
			||||||
 | 
					+	const char* name;
 | 
				
			||||||
 | 
					+	int reg;
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static const struct gsp_sensor_info gsp_sensors[] = {
 | 
				
			||||||
 | 
					+	{"temp", GSP_REG_TEMP_IN},
 | 
				
			||||||
 | 
					+	{"vin", GSP_REG_VIN},
 | 
				
			||||||
 | 
					+	{"3p3", GSP_REG_3P3},
 | 
				
			||||||
 | 
					+	{"bat", GSP_REG_BAT},
 | 
				
			||||||
 | 
					+	{"5p0", GSP_REG_5P0},
 | 
				
			||||||
 | 
					+	{"core", GSP_REG_CORE},
 | 
				
			||||||
 | 
					+	{"cpu1", GSP_REG_CPU1},
 | 
				
			||||||
 | 
					+	{"cpu2", GSP_REG_CPU2},
 | 
				
			||||||
 | 
					+	{"dram", GSP_REG_DRAM},
 | 
				
			||||||
 | 
					+	{"ext_bat", GSP_REG_EXT_BAT},
 | 
				
			||||||
 | 
					+	{"io1", GSP_REG_IO1},
 | 
				
			||||||
 | 
					+	{"io2", GSP_REG_IO2},
 | 
				
			||||||
 | 
					+	{"pci2", GSP_REG_PCIE},
 | 
				
			||||||
 | 
					+	{"current", GSP_REG_CURRENT},
 | 
				
			||||||
 | 
					+	{"fan_point0", GSP_FAN_0},
 | 
				
			||||||
 | 
					+	{"fan_point1", GSP_FAN_1},
 | 
				
			||||||
 | 
					+	{"fan_point2", GSP_FAN_2},
 | 
				
			||||||
 | 
					+	{"fan_point3", GSP_FAN_3},
 | 
				
			||||||
 | 
					+	{"fan_point4", GSP_FAN_4},
 | 
				
			||||||
 | 
					+	{"fan_point5", GSP_FAN_5},
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+struct gsp_data {
 | 
				
			||||||
 | 
					+	struct device		*hwmon_dev;
 | 
				
			||||||
 | 
					+	struct attribute_group	attrs;
 | 
				
			||||||
 | 
					+	enum chips		type;
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int gsp_probe(struct i2c_client *client,
 | 
				
			||||||
 | 
					+			const struct i2c_device_id *id);
 | 
				
			||||||
 | 
					+static int gsp_remove(struct i2c_client *client);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static const struct i2c_device_id gsp_id[] = {
 | 
				
			||||||
 | 
					+	{ "gsp", 0 },
 | 
				
			||||||
 | 
					+	{ }
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+MODULE_DEVICE_TABLE(i2c, gsp_id);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct i2c_driver gsp_driver = {
 | 
				
			||||||
 | 
					+	.driver = {
 | 
				
			||||||
 | 
					+		.name	= "gsp",
 | 
				
			||||||
 | 
					+	},
 | 
				
			||||||
 | 
					+	.probe		= gsp_probe,
 | 
				
			||||||
 | 
					+	.remove		= gsp_remove,
 | 
				
			||||||
 | 
					+	.id_table	= gsp_id,
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/* All registers are word-sized, except for the configuration registers.
 | 
				
			||||||
 | 
					+ * AD7418 uses a high-byte first convention. Do NOT use those functions to
 | 
				
			||||||
 | 
					+ * access the configuration registers CONF and CONF2, as they are byte-sized.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+static inline int gsp_read(struct i2c_client *client, u8 reg)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned int adc = 0;
 | 
				
			||||||
 | 
					+	if (reg == GSP_REG_TEMP_IN || reg > GSP_REG_CURRENT)
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		adc |= i2c_smbus_read_byte_data(client, reg);
 | 
				
			||||||
 | 
					+		adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
 | 
				
			||||||
 | 
					+		return adc;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+	else
 | 
				
			||||||
 | 
					+	{
 | 
				
			||||||
 | 
					+		adc |= i2c_smbus_read_byte_data(client, reg);
 | 
				
			||||||
 | 
					+		adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
 | 
				
			||||||
 | 
					+		adc |= i2c_smbus_read_byte_data(client, reg + 2) << 16;
 | 
				
			||||||
 | 
					+		return adc;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline int gsp_write(struct i2c_client *client, u8 reg, u16 value)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	i2c_smbus_write_byte_data(client, reg, value & 0xff);
 | 
				
			||||||
 | 
					+	i2c_smbus_write_byte_data(client, reg + 1, ((value >> 8) & 0xff));
 | 
				
			||||||
 | 
					+	return 1;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static ssize_t show_adc(struct device *dev, struct device_attribute *devattr,
 | 
				
			||||||
 | 
					+			char *buf)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 | 
				
			||||||
 | 
					+	struct i2c_client *client = to_i2c_client(dev);
 | 
				
			||||||
 | 
					+	return sprintf(buf, "%d\n", gsp_read(client, gsp_sensors[attr->index].reg));
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static ssize_t show_label(struct device *dev,
 | 
				
			||||||
 | 
					+			struct device_attribute *devattr, char *buf)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return sprintf(buf, "%s\n", gsp_sensors[attr->index].name);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static ssize_t store_fan(struct device *dev,
 | 
				
			||||||
 | 
					+			struct device_attribute *devattr, const char *buf, size_t count)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	u16 val;
 | 
				
			||||||
 | 
					+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 | 
				
			||||||
 | 
					+	struct i2c_client *client = to_i2c_client(dev);
 | 
				
			||||||
 | 
					+	val = simple_strtoul(buf, NULL, 10);
 | 
				
			||||||
 | 
					+	gsp_write(client, gsp_sensors[attr->index].reg, val);
 | 
				
			||||||
 | 
					+	return count;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(temp0_input, S_IRUGO, show_adc, NULL, 0);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(temp0_label, S_IRUGO, show_label, NULL, 0);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_adc, NULL, 1);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, 1);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 2);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_label, NULL, 2);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 3);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_label, NULL, 3);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 4);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 4);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 5);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, 5);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_adc, NULL, 6);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, 6);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_adc, NULL, 7);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, 7);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_adc, NULL, 8);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 8);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_adc, NULL, 9);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 9);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_adc, NULL, 10);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 10);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_adc, NULL, 11);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_label, NULL, 11);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_adc, NULL, 12);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_label, NULL, 12);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_adc, NULL, 13);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_label, NULL, 13);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point0, S_IRUGO | S_IWUSR, show_adc, store_fan, 14);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point1, S_IRUGO | S_IWUSR, show_adc, store_fan, 15);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point2, S_IRUGO | S_IWUSR, show_adc, store_fan, 16);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point3, S_IRUGO | S_IWUSR, show_adc, store_fan, 17);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point4, S_IRUGO | S_IWUSR, show_adc, store_fan, 18);
 | 
				
			||||||
 | 
					+static SENSOR_DEVICE_ATTR(fan0_point5, S_IRUGO | S_IWUSR, show_adc, store_fan, 19);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static struct attribute *gsp_attributes[] = {
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_temp0_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in0_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in1_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in2_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in3_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in4_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in5_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in6_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in7_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in8_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in9_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in10_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in11_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in12_input.dev_attr.attr,
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_temp0_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in0_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in1_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in2_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in3_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in4_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in5_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in6_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in7_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in8_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in9_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in10_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in11_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_in12_label.dev_attr.attr,
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point0.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point1.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point2.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point3.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point4.dev_attr.attr,
 | 
				
			||||||
 | 
					+	&sensor_dev_attr_fan0_point5.dev_attr.attr,
 | 
				
			||||||
 | 
					+	NULL
 | 
				
			||||||
 | 
					+};
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int gsp_probe(struct i2c_client *client,
 | 
				
			||||||
 | 
					+			 const struct i2c_device_id *id)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct i2c_adapter *adapter = client->adapter;
 | 
				
			||||||
 | 
					+	struct gsp_data *data;
 | 
				
			||||||
 | 
					+	int err;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 | 
				
			||||||
 | 
					+					I2C_FUNC_SMBUS_WORD_DATA)) {
 | 
				
			||||||
 | 
					+		err = -EOPNOTSUPP;
 | 
				
			||||||
 | 
					+		goto exit;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (!(data = kzalloc(sizeof(struct gsp_data), GFP_KERNEL))) {
 | 
				
			||||||
 | 
					+		err = -ENOMEM;
 | 
				
			||||||
 | 
					+		goto exit;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	i2c_set_clientdata(client, data);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	data->type = id->driver_data;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	switch (data->type) {
 | 
				
			||||||
 | 
					+	case 0:
 | 
				
			||||||
 | 
					+		data->attrs.attrs = gsp_attributes;
 | 
				
			||||||
 | 
					+		break;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	dev_info(&client->dev, "%s chip found\n", client->name);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Register sysfs hooks */
 | 
				
			||||||
 | 
					+	if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
 | 
				
			||||||
 | 
					+		goto exit_free;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	data->hwmon_dev = hwmon_device_register(&client->dev);
 | 
				
			||||||
 | 
					+	if (IS_ERR(data->hwmon_dev)) {
 | 
				
			||||||
 | 
					+		err = PTR_ERR(data->hwmon_dev);
 | 
				
			||||||
 | 
					+		goto exit_remove;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+exit_remove:
 | 
				
			||||||
 | 
					+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
 | 
				
			||||||
 | 
					+exit_free:
 | 
				
			||||||
 | 
					+	kfree(data);
 | 
				
			||||||
 | 
					+exit:
 | 
				
			||||||
 | 
					+	return err;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int gsp_remove(struct i2c_client *client)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct gsp_data *data = i2c_get_clientdata(client);
 | 
				
			||||||
 | 
					+	hwmon_device_unregister(data->hwmon_dev);
 | 
				
			||||||
 | 
					+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
 | 
				
			||||||
 | 
					+	kfree(data);
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static int __init gsp_init(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return i2c_add_driver(&gsp_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static void __exit gsp_exit(void)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	i2c_del_driver(&gsp_driver);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+module_init(gsp_init);
 | 
				
			||||||
 | 
					+module_exit(gsp_exit);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+MODULE_AUTHOR("Chris Lang <clang@gateworks.com>");
 | 
				
			||||||
 | 
					+MODULE_DESCRIPTION("GSP HWMON driver");
 | 
				
			||||||
 | 
					+MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					+MODULE_VERSION(DRV_VERSION);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
							
								
								
									
										22669
									
								
								target/linux/cns3xxx/patches/200-dwc_otg.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22669
									
								
								target/linux/cns3xxx/patches/200-dwc_otg.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user